[RISCV] Allow call pseudoinstruction to be used to call a function name that coincide...
authorAlex Bradbury <asb@lowrisc.org>
Wed, 25 Apr 2018 17:25:29 +0000 (17:25 +0000)
committerAlex Bradbury <asb@lowrisc.org>
Wed, 25 Apr 2018 17:25:29 +0000 (17:25 +0000)
Previously `call zero`, `call f0` etc would fail. This leads to compilation
failures if building programs that define functions with those names and using
-save-temps.

llvm-svn: 330846

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/test/MC/RISCV/function-call.s

index 02f075a..b5e46b6 100644 (file)
@@ -65,7 +65,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
   OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
   OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
 
-  bool parseOperand(OperandVector &Operands);
+  bool parseOperand(OperandVector &Operands, bool ForceImmediate);
 
 public:
   enum RISCVMatchResultTy {
@@ -881,12 +881,15 @@ RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
   return MatchOperand_Success;
 }
 
-/// Looks at a token type and creates the relevant operand
-/// from this information, adding to Operands.
-/// If operand was parsed, returns false, else true.
-bool RISCVAsmParser::parseOperand(OperandVector &Operands) {
-  // Attempt to parse token as register
-  if (parseRegister(Operands, true) == MatchOperand_Success)
+/// Looks at a token type and creates the relevant operand from this
+/// information, adding to Operands. If operand was parsed, returns false, else
+/// true. If ForceImmediate is true, no attempt will be made to parse the
+/// operand as a register, which is needed for pseudoinstructions such as
+/// call.
+bool RISCVAsmParser::parseOperand(OperandVector &Operands,
+                                  bool ForceImmediate) {
+  // Attempt to parse token as register, unless ForceImmediate.
+  if (!ForceImmediate && parseRegister(Operands, true) == MatchOperand_Success)
     return false;
 
   // Attempt to parse token as an immediate
@@ -913,7 +916,7 @@ bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
     return false;
 
   // Parse first operand
-  if (parseOperand(Operands))
+  if (parseOperand(Operands, Name == "call"))
     return true;
 
   // Parse until end of statement, consuming commas between operands
@@ -922,7 +925,7 @@ bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
     getLexer().Lex();
 
     // Parse next operand
-    if (parseOperand(Operands))
+    if (parseOperand(Operands, false))
       return true;
   }
 
index d52623e..d1a076e 100644 (file)
@@ -17,3 +17,23 @@ call bar
 # INSTR: auipc ra, 0
 # INSTR: jalr  ra
 # FIXUP: fixup A - offset: 0, value: bar, kind:
+
+# Ensure that calls to functions whose names coincide with register names work.
+
+call zero
+# RELOC: R_RISCV_CALL zero 0x0
+# INSTR: auipc ra, 0
+# INSTR: jalr  ra
+# FIXUP: fixup A - offset: 0, value: zero, kind:
+
+call f1
+# RELOC: R_RISCV_CALL f1 0x0
+# INSTR: auipc ra, 0
+# INSTR: jalr  ra
+# FIXUP: fixup A - offset: 0, value: f1, kind:
+
+call ra
+# RELOC: R_RISCV_CALL ra 0x0
+# INSTR: auipc ra, 0
+# INSTR: jalr  ra
+# FIXUP: fixup A - offset: 0, value: ra, kind: