[mips] Add assembler support for .set mips0 directive.
authorToma Tabacu <toma.tabacu@imgtec.com>
Tue, 9 Sep 2014 12:52:14 +0000 (12:52 +0000)
committerToma Tabacu <toma.tabacu@imgtec.com>
Tue, 9 Sep 2014 12:52:14 +0000 (12:52 +0000)
Summary:
This directive is used to reset the assembler options to their initial values.
Assembly programmers use it in conjunction with the ".set mipsX" directives.

This patch depends on the .set push/pop directive (http://reviews.llvm.org/D4821).

Contains work done by Matheus Almeida.

Reviewers: dsanders

Reviewed By: dsanders

Differential Revision: http://reviews.llvm.org/D4957

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217438 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-mips0-directive.s [new file with mode: 0644]

index 0a9b36fba4a014c2277063a19e71ca80fe887316..4f7b8c4231d832ec1a3a8dc28ca2bbea191d6d2b 100644 (file)
@@ -177,6 +177,7 @@ class MipsAsmParser : public MCTargetAsmParser {
   const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
 
   bool isEvaluated(const MCExpr *Expr);
+  bool parseSetMips0Directive();
   bool parseSetArchDirective();
   bool parseSetFeature(uint64_t Feature);
   bool parseDirectiveCPLoad(SMLoc Loc);
@@ -2731,6 +2732,19 @@ bool MipsAsmParser::parseSetAssignment() {
   return false;
 }
 
+bool MipsAsmParser::parseSetMips0Directive() {
+  Parser.Lex();
+  if (getLexer().isNot(AsmToken::EndOfStatement))
+    return reportParseError("unexpected token, expected end of statement");
+
+  // Reset assembler options to their initial values.
+  setAvailableFeatures(AssemblerOptions.front()->getFeatures());
+  AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
+
+  getTargetStreamer().emitDirectiveSetMips0();
+  return false;
+}
+
 bool MipsAsmParser::parseSetArchDirective() {
   Parser.Lex();
   if (getLexer().isNot(AsmToken::Equal))
@@ -2981,6 +2995,8 @@ bool MipsAsmParser::parseDirectiveSet() {
     return false;
   } else if (Tok.getString() == "micromips") {
     return parseSetFeature(Mips::FeatureMicroMips);
+  } else if (Tok.getString() == "mips0") {
+    return parseSetMips0Directive();
   } else if (Tok.getString() == "mips1") {
     return parseSetFeature(Mips::FeatureMips1);
   } else if (Tok.getString() == "mips2") {
index ddeef289fd5a6e83e560daf4c6b7ca590935dc5f..48e52a95ee04482a20722aaa586bb952b4cc063d 100644 (file)
@@ -59,6 +59,7 @@ void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) {
 void MipsTargetStreamer::emitDirectiveSetArch(StringRef Arch) {
   forbidModuleDirective();
 }
+void MipsTargetStreamer::emitDirectiveSetMips0() {}
 void MipsTargetStreamer::emitDirectiveSetMips1() { forbidModuleDirective(); }
 void MipsTargetStreamer::emitDirectiveSetMips2() { forbidModuleDirective(); }
 void MipsTargetStreamer::emitDirectiveSetMips3() { forbidModuleDirective(); }
@@ -184,6 +185,8 @@ void MipsTargetAsmStreamer::emitDirectiveSetArch(StringRef Arch) {
   MipsTargetStreamer::emitDirectiveSetArch(Arch);
 }
 
+void MipsTargetAsmStreamer::emitDirectiveSetMips0() { OS << "\t.set\tmips0\n"; }
+
 void MipsTargetAsmStreamer::emitDirectiveSetMips1() {
   OS << "\t.set\tmips1\n";
   MipsTargetStreamer::emitDirectiveSetMips1();
index 5da21e65899c59e942f38dd6ba4500d5b93b3897..182c526389ecce2158914b6dcb737856be21eacd 100644 (file)
@@ -49,6 +49,7 @@ public:
   virtual void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff);
 
   virtual void emitDirectiveSetArch(StringRef Arch);
+  virtual void emitDirectiveSetMips0();
   virtual void emitDirectiveSetMips1();
   virtual void emitDirectiveSetMips2();
   virtual void emitDirectiveSetMips3();
@@ -151,6 +152,7 @@ public:
   void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) override;
 
   void emitDirectiveSetArch(StringRef Arch) override;
+  void emitDirectiveSetMips0() override;
   void emitDirectiveSetMips1() override;
   void emitDirectiveSetMips2() override;
   void emitDirectiveSetMips3() override;
diff --git a/test/MC/Mips/set-mips0-directive.s b/test/MC/Mips/set-mips0-directive.s
new file mode 100644 (file)
index 0000000..5cb75bb
--- /dev/null
@@ -0,0 +1,27 @@
+# RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 | \
+# RUN:   FileCheck %s
+
+    .text
+    rotr  $7, $7, 22
+
+    .set mips32r6
+    mod   $2, $4, $6
+    .set mips0
+    rotr  $2, $2, 15
+
+    .set mips3
+    dadd  $4, $4, $4
+    .set mips0
+    rotr  $3, $3, 19
+
+# CHECK: rotr  $7, $7, 22
+
+# CHECK: .set mips32r6
+# CHECK: mod   $2, $4, $6
+# CHECK: .set mips0
+# CHECK: rotr  $2, $2, 15
+
+# CHECK: .set mips3
+# CHECK: dadd  $4, $4, $4
+# CHECK: .set mips0
+# CHECK: rotr  $3, $3, 19