[mips] Add assembler support for .set arch=x directive.
authorToma Tabacu <toma.tabacu@imgtec.com>
Tue, 19 Aug 2014 14:22:52 +0000 (14:22 +0000)
committerToma Tabacu <toma.tabacu@imgtec.com>
Tue, 19 Aug 2014 14:22:52 +0000 (14:22 +0000)
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
lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
lib/Target/Mips/MipsTargetStreamer.h
test/MC/Mips/set-arch.s [new file with mode: 0644]

index fde2dc4285169ed6bf6e3162da36f8fce80ceb35..d986625cc52edb3bb62ef4531e66fc5516baffaf 100644 (file)
@@ -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<StringRef>(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") {
index 2a373ee094ca35d69688e63c0bb293b5dd3a0e10..d19307978d9fd69e7ebacecb2f3e5ef769f97a7e 100644 (file)
@@ -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();
index 06fb66c1f1c4998c87ca3b05c84c201410e48569..8b87aefa91adbd01664e09f024d176e812eb14a4 100644 (file)
@@ -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 (file)
index 0000000..6267468
--- /dev/null
@@ -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