Index: lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp =================================================================== --- lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -73,6 +73,9 @@ // synthesize the desired immedate value into the destination register. void emitLoadImm(unsigned DestReg, int64_t Value, MCStreamer &Out); + // Helper to emit pseudo instruction "lla" that does a PC-rel load. + void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); + /// Helper for processing MC instructions that have been successfully matched /// by MatchAndEmitInstruction. Modifications to the emitted instructions, /// like the expansion of pseudo instructions (e.g., "li"), can be performed @@ -1184,6 +1187,36 @@ .addImm(Lo12)); } +void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, + MCStreamer &Out) { + // PC-rel addressing + MCContext &Ctx = getContext(); + + // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) + // ADDI rdest, %pcrel_lo(TmpLabel) + MCSymbol *TmpLabel = Ctx.createTempSymbol( + "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false); + Out.EmitLabel(TmpLabel); + + MCOperand DestReg = Inst.getOperand(0); + const RISCVMCExpr *Symbol = RISCVMCExpr::create( + Inst.getOperand(1).getExpr(), RISCVMCExpr::VK_RISCV_PCREL_HI, Ctx); + + MCInst &AUIPC = + MCInstBuilder(RISCV::AUIPC).addOperand(DestReg).addExpr(Symbol); + emitToStreamer(Out, AUIPC); + + const MCExpr *RefToLinkTmpLabel = + RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx), + RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx); + + MCInst &ADDI = MCInstBuilder(RISCV::ADDI) + .addOperand(DestReg) + .addOperand(DestReg) + .addExpr(RefToLinkTmpLabel); + emitToStreamer(Out, ADDI); +} + bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) { Inst.setLoc(IDLoc); @@ -1198,6 +1231,9 @@ Imm = SignExtend64<32>(Imm); emitLoadImm(Reg, Imm, Out); return false; + } else if (Inst.getOpcode() == RISCV::PseudoLLA) { + emitLoadLocalAddress(Inst, IDLoc, Out); + return false; } emitToStreamer(Out, Inst); Index: lib/Target/RISCV/RISCVInstrInfo.td =================================================================== --- lib/Target/RISCV/RISCVInstrInfo.td +++ lib/Target/RISCV/RISCVInstrInfo.td @@ -710,6 +710,12 @@ def : Pat<(Tail (iPTR texternalsym:$dst)), (PseudoTAIL texternalsym:$dst)>; +let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0, + isAsmParserOnly = 1 in +def PseudoLLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), []> { + let AsmString = "lla\t$dst,$src"; +} + /// Loads multiclass LdPat { Index: test/MC/RISCV/rvi-pseudos.s =================================================================== --- /dev/null +++ test/MC/RISCV/rvi-pseudos.s @@ -0,0 +1,21 @@ +# RUN: llvm-mc %s -triple=riscv32 | FileCheck %s +# RUN: llvm-mc %s -triple=riscv64 | FileCheck %s + +.data + +a_symbol: .word 42 +another_symbol: .word 5 + +.text + +foo: + +# CHECK: .Lpcrel_hi0: +# CHECK: auipc a0, %pcrel_hi(a_symbol) +# CHECK: addi a0, a0, %pcrel_lo(.Lpcrel_hi0) +lla a0, a_symbol + +# CHECK: .Lpcrel_hi1: +# CHECK: auipc a1, %pcrel_hi(another_symbol) +# CHECK: addi a1, a1, %pcrel_lo(.Lpcrel_hi1) +lla a1, another_symbol