[mips] Replace custom parsing logic for data directives by the `addAliasForDirective`
authorSimon Atanasyan <simon@atanasyan.com>
Wed, 25 Jul 2018 07:07:43 +0000 (07:07 +0000)
committerSimon Atanasyan <simon@atanasyan.com>
Wed, 25 Jul 2018 07:07:43 +0000 (07:07 +0000)
The target independent AsmParser doesn't recognise .hword, .word, .dword
which are required for Mips. Currently MipsAsmParser recognises these
through dispatch to MipsAsmParser::parseDataDirective. This contains
equivalent logic to AsmParser::parseDirectiveValue. This patch allows
reuse of AsmParser::parseDirectiveValue by making use of
addAliasForDirective to support .hword, .word and .dword.

Original patch provided by Alex Bradbury at D47001 was modified to fix
handling of microMIPS symbols. The `AsmParser::parseDirectiveValue`
calls either `EmitIntValue` or `EmitValue`. In this patch we override
`EmitIntValue` in the `MipsELFStreamer` to clear a pending set of
microMIPS symbols.

Differential revision: https://reviews.llvm.org/D49539

llvm-svn: 337893

llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
llvm/test/MC/Mips/micromips-label-test.s

index 5ee7d0a..2acf701 100644 (file)
@@ -355,7 +355,6 @@ class MipsAsmParser : public MCTargetAsmParser {
 
   bool parseSetAssignment();
 
-  bool parseDataDirective(unsigned Size, SMLoc L);
   bool parseDirectiveGpWord();
   bool parseDirectiveGpDWord();
   bool parseDirectiveDtpRelWord();
@@ -487,6 +486,9 @@ public:
     MCAsmParserExtension::Initialize(parser);
 
     parser.addAliasForDirective(".asciiz", ".asciz");
+    parser.addAliasForDirective(".hword", ".2byte");
+    parser.addAliasForDirective(".word", ".4byte");
+    parser.addAliasForDirective(".dword", ".8byte");
 
     // Initialize the set of available features.
     setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
@@ -7357,31 +7359,6 @@ bool MipsAsmParser::parseDirectiveSet() {
   return parseSetAssignment();
 }
 
-/// parseDataDirective
-///  ::= .word [ expression (, expression)* ]
-bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
-  MCAsmParser &Parser = getParser();
-  if (getLexer().isNot(AsmToken::EndOfStatement)) {
-    while (true) {
-      const MCExpr *Value;
-      if (getParser().parseExpression(Value))
-        return true;
-
-      getParser().getStreamer().EmitValue(Value, Size);
-
-      if (getLexer().is(AsmToken::EndOfStatement))
-        break;
-
-      if (getLexer().isNot(AsmToken::Comma))
-        return Error(L, "unexpected token, expected comma");
-      Parser.Lex();
-    }
-  }
-
-  Parser.Lex();
-  return false;
-}
-
 /// parseDirectiveGpWord
 ///  ::= .gpword local_sym
 bool MipsAsmParser::parseDirectiveGpWord() {
@@ -7961,10 +7938,6 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
     parseDirectiveCpRestore(DirectiveID.getLoc());
     return false;
   }
-  if (IDVal == ".dword") {
-    parseDataDirective(8, DirectiveID.getLoc());
-    return false;
-  }
   if (IDVal == ".ent") {
     StringRef SymbolName;
 
@@ -8212,16 +8185,6 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
     return false;
   }
 
-  if (IDVal == ".word") {
-    parseDataDirective(4, DirectiveID.getLoc());
-    return false;
-  }
-
-  if (IDVal == ".hword") {
-    parseDataDirective(2, DirectiveID.getLoc());
-    return false;
-  }
-
   if (IDVal == ".option") {
     parseDirectiveOption();
     return false;
index 13cf5ba..7b9a025 100644 (file)
@@ -86,6 +86,11 @@ void MipsELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
   Labels.clear();
 }
 
+void MipsELFStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
+  MCELFStreamer::EmitIntValue(Value, Size);
+  Labels.clear();
+}
+
 void MipsELFStreamer::EmitMipsOptionRecords() {
   for (const auto &I : MipsOptionRecords)
     I->EmitMipsOptionRecord();
index 8ffca34..d141f5d 100644 (file)
@@ -54,9 +54,11 @@ public:
   void SwitchSection(MCSection *Section,
                      const MCExpr *Subsection = nullptr) override;
 
-  /// Overriding this function allows us to dismiss all labels that are
-  /// candidates for marking as microMIPS when .word directive is emitted.
+  /// Overriding these functions allows us to dismiss all labels that are
+  /// candidates for marking as microMIPS when .word/.long/.4byte etc
+  /// directives are emitted.
   void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override;
+  void EmitIntValue(uint64_t Value, unsigned Size) override;
 
   /// Emits all the option records stored up until the point it's called.
   void EmitMipsOptionRecords();
index 39c905c..357287e 100644 (file)
@@ -9,6 +9,16 @@ g:
   nop
 h:
   .word 0
+k:
+  .long 0
+l:
+  .hword 0
+m:
+  .2byte 0
+n:
+  .4byte 0
+o:
+  .8byte 0
 i:
   nop
 j:
@@ -54,5 +64,39 @@ j:
 # CHECK:     Other: 0
 # CHECK:     Section: .text
 # CHECK:   }
+# CHECK:   Symbol {
+# CHECK:     Name: k
+# CHECK:     Binding: Local
+# CHECK:     Type: None
+# CHECK:     Other: 0
+# CHECK:     Section: .text
+# CHECK:   }
+# CHECK:   Symbol {
+# CHECK:     Name: l
+# CHECK:     Binding: Local
+# CHECK:     Type: None
+# CHECK:     Other: 0
+# CHECK:     Section: .text
+# CHECK:   }
+# CHECK:   Symbol {
+# CHECK:     Name: m
+# CHECK:     Binding: Local
+# CHECK:     Type: None
+# CHECK:     Other: 0
+# CHECK:     Section: .text
+# CHECK:   }
+# CHECK:   Symbol {
+# CHECK:     Name: n
+# CHECK:     Binding: Local
+# CHECK:     Type: None
+# CHECK:     Other: 0
+# CHECK:     Section: .text
+# CHECK:   }
+# CHECK:   Symbol {
+# CHECK:     Name: o
+# CHECK:     Binding: Local
+# CHECK:     Type: None
+# CHECK:     Other: 0
+# CHECK:     Section: .text
+# CHECK:   }
 # CHECK: ]
-