From 109447ff1b440c83bef4d1c251dc5070319520f6 Mon Sep 17 00:00:00 2001 From: Toma Tabacu Date: Tue, 19 Aug 2014 14:22:52 +0000 Subject: [PATCH] [mips] Add assembler support for .set arch=x directive. Summary: This directive is similar to ".set mipsX". It is used to change the CPU target of the assembler, enabling it to accept instructions for a specific CPU. This patch only implements the r4000 CPU (which is treated internally as generic mips3) and the generic ISAs. Contains work done by Matheus Almeida. Reviewers: dsanders Reviewed By: dsanders Differential Revision: http://reviews.llvm.org/D4884 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215978 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 38 +++++++++++++ .../Mips/MCTargetDesc/MipsTargetStreamer.cpp | 8 +++ lib/Target/Mips/MipsTargetStreamer.h | 2 + test/MC/Mips/set-arch.s | 55 +++++++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 test/MC/Mips/set-arch.s diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index fde2dc42851..d986625cc52 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -163,6 +163,7 @@ class MipsAsmParser : public MCTargetAsmParser { const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); bool isEvaluated(const MCExpr *Expr); + bool parseSetArchDirective(); bool parseSetFeature(uint64_t Feature); bool parseDirectiveCPLoad(SMLoc Loc); bool parseDirectiveCPSetup(); @@ -2667,6 +2668,41 @@ bool MipsAsmParser::parseSetAssignment() { return false; } +bool MipsAsmParser::parseSetArchDirective() { + Parser.Lex(); + if (getLexer().isNot(AsmToken::Equal)) + return reportParseError("unexpected token, expected equals sign"); + + Parser.Lex(); + StringRef Arch; + if (Parser.parseIdentifier(Arch)) + return reportParseError("expected arch identifier"); + + StringRef ArchFeatureName = + StringSwitch(Arch) + .Case("mips1", "mips1") + .Case("mips2", "mips2") + .Case("mips3", "mips3") + .Case("mips4", "mips4") + .Case("mips5", "mips5") + .Case("mips32", "mips32") + .Case("mips32r2", "mips32r2") + .Case("mips32r6", "mips32r6") + .Case("mips64", "mips64") + .Case("mips64r2", "mips64r2") + .Case("mips64r6", "mips64r6") + .Case("cnmips", "cnmips") + .Case("r4000", "mips3") // This is an implementation of Mips3. + .Default(""); + + if (ArchFeatureName.empty()) + return reportParseError("unsupported architecture"); + + selectArch(ArchFeatureName); + getTargetStreamer().emitDirectiveSetArch(Arch); + return false; +} + bool MipsAsmParser::parseSetFeature(uint64_t Feature) { Parser.Lex(); if (getLexer().isNot(AsmToken::EndOfStatement)) @@ -2856,6 +2892,8 @@ bool MipsAsmParser::parseDirectiveSet() { return parseSetNoAtDirective(); } else if (Tok.getString() == "at") { return parseSetAtDirective(); + } else if (Tok.getString() == "arch") { + return parseSetArchDirective(); } else if (Tok.getString() == "fp") { return parseSetFpDirective(); } else if (Tok.getString() == "reorder") { diff --git a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 2a373ee094c..d19307978d9 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -56,6 +56,9 @@ void MipsTargetStreamer::emitFrame(unsigned StackReg, unsigned StackSize, void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {} void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) { } +void MipsTargetStreamer::emitDirectiveSetArch(StringRef Arch) { + forbidModuleDirective(); +} void MipsTargetStreamer::emitDirectiveSetMips1() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetMips2() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetMips3() { forbidModuleDirective(); } @@ -174,6 +177,11 @@ void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize, << StringRef(MipsInstPrinter::getRegisterName(ReturnReg)).lower() << '\n'; } +void MipsTargetAsmStreamer::emitDirectiveSetArch(StringRef Arch) { + OS << "\t.set arch=" << Arch << "\n"; + MipsTargetStreamer::emitDirectiveSetArch(Arch); +} + void MipsTargetAsmStreamer::emitDirectiveSetMips1() { OS << "\t.set\tmips1\n"; MipsTargetStreamer::emitDirectiveSetMips1(); diff --git a/lib/Target/Mips/MipsTargetStreamer.h b/lib/Target/Mips/MipsTargetStreamer.h index 06fb66c1f1c..8b87aefa91a 100644 --- a/lib/Target/Mips/MipsTargetStreamer.h +++ b/lib/Target/Mips/MipsTargetStreamer.h @@ -48,6 +48,7 @@ public: virtual void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff); virtual void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff); + virtual void emitDirectiveSetArch(StringRef Arch); virtual void emitDirectiveSetMips1(); virtual void emitDirectiveSetMips2(); virtual void emitDirectiveSetMips3(); @@ -147,6 +148,7 @@ public: void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) override; void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) override; + void emitDirectiveSetArch(StringRef Arch) override; void emitDirectiveSetMips1() override; void emitDirectiveSetMips2() override; void emitDirectiveSetMips3() override; diff --git a/test/MC/Mips/set-arch.s b/test/MC/Mips/set-arch.s new file mode 100644 index 00000000000..626746836ad --- /dev/null +++ b/test/MC/Mips/set-arch.s @@ -0,0 +1,55 @@ +# RUN: llvm-mc %s -triple=mipsel-unknown-linux -show-encoding -mcpu=mips32 | \ +# RUN: FileCheck %s + + .text + .set arch=mips1 + add $2, $2, $2 + .set arch=mips2 + ll $2, -2($2) + .set arch=mips3 + dadd $2, $2, $2 + .set arch=mips4 + ldxc1 $f8, $2($4) + .set arch=mips5 + luxc1 $f19, $2($4) + .set arch=mips32 + clo $2, $2 + .set arch=mips32r2 + rotr $2, $2, 15 + .set arch=mips32r6 + mod $2, $4, $6 + .set arch=mips64 + daddi $2, $2, 10 + .set arch=mips64r2 + drotr32 $1, $14, 15 + .set arch=mips64r6 + mod $2, $4, $6 + .set arch=cnmips + .set arch=r4000 + dadd $2, $2, $2 + +# CHECK: .set arch=mips1 +# CHECK: add $2, $2, $2 +# CHECK: .set arch=mips2 +# CHECK: ll $2, -2($2) +# CHECK: .set arch=mips3 +# CHECK: dadd $2, $2, $2 +# CHECK: .set arch=mips4 +# CHECK: ldxc1 $f8, $2($4) +# CHECK: .set arch=mips5 +# CHECK: luxc1 $f19, $2($4) +# CHECK: .set arch=mips32 +# CHECK: clo $2, $2 +# CHECK: .set arch=mips32r2 +# CHECK: rotr $2, $2, 15 +# CHECK: .set arch=mips32r6 +# CHECK: mod $2, $4, $6 +# CHECK: .set arch=mips64 +# CHECK: daddi $2, $2, 10 +# CHECK: .set arch=mips64r2 +# CHECK: drotr32 $1, $14, 15 +# CHECK: .set arch=mips64r6 +# CHECK: mod $2, $4, $6 +# CHECK: .set arch=cnmips +# CHECK: .set arch=r4000 +# CHECK: dadd $2, $2, $2