Mips assembler: Improve set register alias handling
authorJack Carter <jack.carter@imgtec.com>
Tue, 28 May 2013 22:21:05 +0000 (22:21 +0000)
committerJack Carter <jack.carter@imgtec.com>
Tue, 28 May 2013 22:21:05 +0000 (22:21 +0000)
This patch solves the problem of numeric register values not being accepted:

../set_alias.s:1:11: error: expected valid expression after comma
        .set    r4,$4
                    ^
The parsing of .set directive is changed and handling of symbols in code
as well to enable this feature.

The test example is added.

Patch by Vladimir Medic

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182807 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/AsmParser/MipsAsmParser.cpp
test/MC/Mips/mips_directives.s

index 0795cb963b35bff2b1bdae77d0eea2fe425d649c..c4e41de27913fe2b66c9bd8a58b22cca325852ef 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/MC/MCTargetAsmParser.h"
 #include "llvm/Support/TargetRegistry.h"
+#include "llvm/ADT/APInt.h"
 
 using namespace llvm;
 
@@ -1290,8 +1291,16 @@ bool MipsAsmParser::searchSymbolAlias(
       const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
       const StringRef DefSymbol = Ref->getSymbol().getName();
       if (DefSymbol.startswith("$")) {
-        // Lookup for the register with the corresponding name.
-        int RegNum = matchRegisterName(DefSymbol.substr(1), isMips64());
+        int RegNum = -1;
+        APInt IntVal(32, -1);
+        if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
+          RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
+                                         isMips64()
+                                           ? Mips::CPU64RegsRegClassID
+                                           : Mips::CPURegsRegClassID);
+        else
+          // Lookup for the register with corresponding name
+          RegNum = matchRegisterName(DefSymbol.substr(1), isMips64());
         if (RegNum > -1) {
           Parser.Lex();
           MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
@@ -1305,7 +1314,7 @@ bool MipsAsmParser::searchSymbolAlias(
       Parser.Lex();
       const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
       MipsOperand *op = MipsOperand::CreateImm(Const, S,
-          Parser.getTok().getLoc());
+                                               Parser.getTok().getLoc());
       Operands.push_back(op);
       return true;
     }
@@ -1741,8 +1750,22 @@ bool MipsAsmParser::parseSetAssignment() {
     return reportParseError("unexpected token in .set directive");
   Lex(); // Eat comma
 
-  if (Parser.parseExpression(Value))
-    reportParseError("expected valid expression after comma");
+  if (getLexer().is(AsmToken::Dollar)) {
+    MCSymbol *Symbol;
+    SMLoc DollarLoc = getLexer().getLoc();
+    // Consume the dollar sign, and check for a following identifier.
+    Parser.Lex();
+    // We have a '$' followed by something, make sure they are adjacent.
+    if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
+      return true;
+    StringRef Res = StringRef(DollarLoc.getPointer(),
+        getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
+    Symbol = getContext().GetOrCreateSymbol(Res);
+    Parser.Lex();
+    Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
+                                    getContext());
+  } else if (Parser.parseExpression(Value))
+    return reportParseError("expected valid expression after comma");
 
   // Check if the Name already exists as a symbol.
   MCSymbol *Sym = getContext().LookupSymbol(Name);
index 45247cd162b53180a85644ec9452b7d2b29461c5..24bef613c6b964ecb9be7d23f667aba3eee35ed2 100644 (file)
@@ -37,7 +37,8 @@ $JTI0_0:
     .set  at=$a0
     .set STORE_MASK,$t7
     .set FPU_MASK,$f7
+    .set r3,$3
 #CHECK:    abs.s   $f6, $f7           # encoding: [0x46,0x00,0x39,0x85]
 #CHECK:    and     $3, $15, $15       # encoding: [0x01,0xef,0x18,0x24]
-    abs.s      $f6,FPU_MASK
-    and $3,$t7,STORE_MASK
+    abs.s  $f6,FPU_MASK
+    and    r3,$t7,STORE_MASK