llvm.org GIT mirror llvm / 415b5e4
[RISCV] Attach VK_RISCV_CALL to symbols upon creation This patch replaces the addition of VK_RISCV_CALL in RISCVMCCodeEmitter by creating the RISCVMCExpr when tail/call are parsed, or in the codegen case when the callee symbols are created. This required adding a new CallSymbol operand to allow only adding VK_RISCV_CALL to tail/call instructions. This patch will allow further expansion of parsing and codegen to easily include PLT symbols which must generate the R_RISCV_CALL_PLT relocation. Differential Revision: https://reviews.llvm.org/D55560 Patch by Lewis Revill. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357396 91177308-0d34-0410-b5e6-96231b3b80d8 Alex Bradbury 1 year, 8 months ago
6 changed file(s) with 57 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
112112 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
113113 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
114114 OperandMatchResultTy parseBareSymbol(OperandVector &Operands);
115 OperandMatchResultTy parseCallSymbol(OperandVector &Operands);
115116 OperandMatchResultTy parseJALOffset(OperandVector &Operands);
116117
117118 bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
280281 return false;
281282 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
282283 VK == RISCVMCExpr::VK_RISCV_None;
284 }
285
286 bool isCallSymbol() const {
287 int64_t Imm;
288 RISCVMCExpr::VariantKind VK;
289 // Must be of 'immediate' type but not a constant.
290 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
291 return false;
292 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
293 VK == RISCVMCExpr::VK_RISCV_CALL;
283294 }
284295
285296 bool isCSRSystemRegister() const { return isSystemRegister(); }
903914 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
904915 return Error(ErrorLoc, "operand must be a bare symbol name");
905916 }
917 case Match_InvalidCallSymbol: {
918 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
919 return Error(ErrorLoc, "operand must be a bare symbol name");
920 }
906921 }
907922
908923 llvm_unreachable("Unknown match type detected!");
11371152 Res = V;
11381153 } else
11391154 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1155 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1156 return MatchOperand_Success;
1157 }
1158
1159 OperandMatchResultTy RISCVAsmParser::parseCallSymbol(OperandVector &Operands) {
1160 SMLoc S = getLoc();
1161 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1162 const MCExpr *Res;
1163
1164 if (getLexer().getKind() != AsmToken::Identifier)
1165 return MatchOperand_NoMatch;
1166
1167 StringRef Identifier;
1168 if (getParser().parseIdentifier(Identifier))
1169 return MatchOperand_ParseFail;
1170
1171 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1172 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1173 Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext());
11401174 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
11411175 return MatchOperand_Success;
11421176 }
100100
101101 assert(Func.isExpr() && "Expected expression");
102102
103 const MCExpr *Expr = Func.getExpr();
104
105 // Create function call expression CallExpr for AUIPC.
106 const MCExpr *CallExpr =
107 RISCVMCExpr::create(Expr, RISCVMCExpr::VK_RISCV_CALL, Ctx);
103 const MCExpr *CallExpr = Func.getExpr();
108104
109105 // Emit AUIPC Ra, Func with R_RISCV_CALL relocation type.
110106 TmpInst = MCInstBuilder(RISCV::AUIPC)
18101810 // TargetGlobalAddress/TargetExternalSymbol node so that legalize won't
18111811 // split it and then direct call can be matched by PseudoCALL.
18121812 if (GlobalAddressSDNode *S = dyn_cast(Callee)) {
1813 Callee = DAG.getTargetGlobalAddress(S->getGlobal(), DL, PtrVT, 0, 0);
1813 Callee = DAG.getTargetGlobalAddress(S->getGlobal(), DL, PtrVT, 0,
1814 RISCVII::MO_CALL);
18141815 } else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) {
1815 Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, 0);
1816 Callee =
1817 DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, RISCVII::MO_CALL);
18161818 }
18171819
18181820 // The first call operand is the chain and the second is the target address.
187187 // A bare symbol.
188188 def bare_symbol : Operand {
189189 let ParserMatchClass = BareSymbol;
190 }
191
192 def CallSymbol : AsmOperandClass {
193 let Name = "CallSymbol";
194 let RenderMethod = "addImmOperands";
195 let DiagnosticType = "InvalidCallSymbol";
196 let ParserMethod = "parseCallSymbol";
197 }
198
199 // A bare symbol used in call/tail only.
200 def call_symbol : Operand {
201 let ParserMatchClass = CallSymbol;
190202 }
191203
192204 def CSRSystemRegister : AsmOperandClass {
843855 // Define AsmString to print "call" when compile with -S flag.
844856 // Define isCodeGenOnly = 0 to support parsing assembly "call" instruction.
845857 let isCall = 1, Defs = [X1], isCodeGenOnly = 0 in
846 def PseudoCALL : Pseudo<(outs), (ins bare_symbol:$func),
858 def PseudoCALL : Pseudo<(outs), (ins call_symbol:$func),
847859 [(riscv_call tglobaladdr:$func)]> {
848860 let AsmString = "call\t$func";
849861 }
868880 // Define AsmString to print "tail" when compile with -S flag.
869881 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2],
870882 isCodeGenOnly = 0 in
871 def PseudoTAIL : Pseudo<(outs), (ins bare_symbol:$dst), []> {
883 def PseudoTAIL : Pseudo<(outs), (ins call_symbol:$dst), []> {
872884 let AsmString = "tail\t$dst";
873885 }
874886
3434 llvm_unreachable("Unknown target flag on GV operand");
3535 case RISCVII::MO_None:
3636 Kind = RISCVMCExpr::VK_RISCV_None;
37 break;
38 case RISCVII::MO_CALL:
39 Kind = RISCVMCExpr::VK_RISCV_CALL;
3740 break;
3841 case RISCVII::MO_LO:
3942 Kind = RISCVMCExpr::VK_RISCV_LO;
4747
4848 enum {
4949 MO_None,
50 MO_CALL,
5051 MO_LO,
5152 MO_HI,
5253 MO_PCREL_LO,