[mips] [IAS] Add support for the .set oddspreg/nooddspreg directives.
authorToma Tabacu <toma.tabacu@gmail.com>
Tue, 30 Jun 2015 09:36:50 +0000 (09:36 +0000)
committerToma Tabacu <toma.tabacu@gmail.com>
Tue, 30 Jun 2015 09:36:50 +0000 (09:36 +0000)
Differential Revision: http://reviews.llvm.org/D10657

llvm-svn: 241052

llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
llvm/lib/Target/Mips/MipsTargetStreamer.h
llvm/test/MC/Mips/set-oddspreg-nooddspreg-error.s [new file with mode: 0644]
llvm/test/MC/Mips/set-oddspreg-nooddspreg.s [new file with mode: 0644]

index 78f3884..8f79689 100644 (file)
@@ -258,6 +258,8 @@ class MipsAsmParser : public MCTargetAsmParser {
   bool parseSetMips16Directive();
   bool parseSetNoMips16Directive();
   bool parseSetFpDirective();
+  bool parseSetOddSPRegDirective();
+  bool parseSetNoOddSPRegDirective();
   bool parseSetPopDirective();
   bool parseSetPushDirective();
   bool parseSetSoftFloatDirective();
@@ -4098,6 +4100,34 @@ bool MipsAsmParser::parseSetFpDirective() {
   return false;
 }
 
+bool MipsAsmParser::parseSetOddSPRegDirective() {
+  MCAsmParser &Parser = getParser();
+
+  Parser.Lex(); // Eat "oddspreg".
+  if (getLexer().isNot(AsmToken::EndOfStatement)) {
+    reportParseError("unexpected token, expected end of statement");
+    return false;
+  }
+
+  clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
+  getTargetStreamer().emitDirectiveSetOddSPReg();
+  return false;
+}
+
+bool MipsAsmParser::parseSetNoOddSPRegDirective() {
+  MCAsmParser &Parser = getParser();
+
+  Parser.Lex(); // Eat "nooddspreg".
+  if (getLexer().isNot(AsmToken::EndOfStatement)) {
+    reportParseError("unexpected token, expected end of statement");
+    return false;
+  }
+
+  setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
+  getTargetStreamer().emitDirectiveSetNoOddSPReg();
+  return false;
+}
+
 bool MipsAsmParser::parseSetPopDirective() {
   MCAsmParser &Parser = getParser();
   SMLoc Loc = getLexer().getLoc();
@@ -4460,6 +4490,10 @@ bool MipsAsmParser::parseDirectiveSet() {
     return parseSetArchDirective();
   } else if (Tok.getString() == "fp") {
     return parseSetFpDirective();
+  } else if (Tok.getString() == "oddspreg") {
+    return parseSetOddSPRegDirective();
+  } else if (Tok.getString() == "nooddspreg") {
+    return parseSetNoOddSPRegDirective();
   } else if (Tok.getString() == "pop") {
     return parseSetPopDirective();
   } else if (Tok.getString() == "push") {
index 9ffa969..a560ce6 100644 (file)
@@ -103,6 +103,10 @@ void MipsTargetStreamer::emitDirectiveSetFp(
     MipsABIFlagsSection::FpABIKind Value) {
   forbidModuleDirective();
 }
+void MipsTargetStreamer::emitDirectiveSetOddSPReg() { forbidModuleDirective(); }
+void MipsTargetStreamer::emitDirectiveSetNoOddSPReg() {
+  forbidModuleDirective();
+}
 
 MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S,
                                              formatted_raw_ostream &OS)
@@ -390,6 +394,16 @@ void MipsTargetAsmStreamer::emitDirectiveModuleOddSPReg() {
   OS << "\t.module\t" << (ABIFlagsSection.OddSPReg ? "" : "no") << "oddspreg\n";
 }
 
+void MipsTargetAsmStreamer::emitDirectiveSetOddSPReg() {
+  MipsTargetStreamer::emitDirectiveSetOddSPReg();
+  OS << "\t.set\toddspreg\n";
+}
+
+void MipsTargetAsmStreamer::emitDirectiveSetNoOddSPReg() {
+  MipsTargetStreamer::emitDirectiveSetNoOddSPReg();
+  OS << "\t.set\tnooddspreg\n";
+}
+
 // This part is for ELF object output.
 MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S,
                                              const MCSubtargetInfo &STI)
index 35bdae3..54460fb 100644 (file)
@@ -84,6 +84,8 @@ public:
   virtual void emitDirectiveModuleFP();
   virtual void emitDirectiveModuleOddSPReg();
   virtual void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value);
+  virtual void emitDirectiveSetOddSPReg();
+  virtual void emitDirectiveSetNoOddSPReg();
 
   void forbidModuleDirective() { ModuleDirectiveAllowed = false; }
   void reallowModuleDirective() { ModuleDirectiveAllowed = true; }
@@ -191,6 +193,8 @@ public:
   void emitDirectiveModuleFP() override;
   void emitDirectiveModuleOddSPReg() override;
   void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value) override;
+  void emitDirectiveSetOddSPReg() override;
+  void emitDirectiveSetNoOddSPReg() override;
 };
 
 // This part is for ELF object output
diff --git a/llvm/test/MC/Mips/set-oddspreg-nooddspreg-error.s b/llvm/test/MC/Mips/set-oddspreg-nooddspreg-error.s
new file mode 100644 (file)
index 0000000..5fb1308
--- /dev/null
@@ -0,0 +1,10 @@
+# RUN: not llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32 -mattr=+nooddspreg 2>%t1
+# RUN: FileCheck %s < %t1
+
+  .set oddspreg
+  sub.s $f1, $f2, $f2
+  # CHECK-NOT: :[[@LINE-1]]:{{[0-9]+}}: error: -mno-odd-spreg prohibits the use of odd FPU registers
+
+  .set nooddspreg
+  sub.s $f1, $f2, $f2
+  # CHECK: :[[@LINE-1]]:9: error: -mno-odd-spreg prohibits the use of odd FPU registers
diff --git a/llvm/test/MC/Mips/set-oddspreg-nooddspreg.s b/llvm/test/MC/Mips/set-oddspreg-nooddspreg.s
new file mode 100644 (file)
index 0000000..a057c48
--- /dev/null
@@ -0,0 +1,10 @@
+# RUN: llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32r2 -mattr=+nooddspreg | \
+# RUN:   FileCheck %s
+
+  .set oddspreg
+  sub.s $f1, $f2, $f2
+  .set nooddspreg
+
+# CHECK: .set oddspreg
+# CHECK: sub.s $f1, $f2, $f2
+# CHECK: .set nooddspreg