[llvm] r339314 - [RISCV] Add "lla" pseudo-instruction to assembler
Chandler Carruth via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 13 16:53:23 PDT 2018
On Thu, Aug 9, 2018 at 12:08 AM Roger Ferrer Ibanez via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: rogfer01
> Date: Thu Aug 9 00:08:20 2018
> New Revision: 339314
>
> URL: http://llvm.org/viewvc/llvm-project?rev=339314&view=rev
> Log:
> [RISCV] Add "lla" pseudo-instruction to assembler
>
> This pseudo-instruction is similar to la but uses PC-relative addressing
> unconditionally. This is, la is only different to lla when using -fPIC.
> This
> pseudo-instruction seems often forgotten in several specs but it is
> definitely
> mentioned in binutils opcodes/riscv-opc.c. The semantics are defined both
> in
> page 37 of the "RISC-V Reader" book but also in function macro found in
> gas/config/tc-riscv.c.
>
> This is a very first step towards adding PIC support for Linux in the
> RISC-V
> backend.
>
> The lla pseudo-instruction expands to a sequence of auipc + addi with a
> couple
> of pc-rel relocations where the second points to the first one. This is
> described in
>
> https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#pc-relative-symbol-addresses
>
> For now, this patch only introduces support of that pseudo instruction at
> the
> assembler parser.
>
> Differential Revision: https://reviews.llvm.org/D49661
>
>
> Added:
> llvm/trunk/test/MC/RISCV/lla-invalid.s
> llvm/trunk/test/MC/RISCV/rvi-pseudos.s
>
I'm seeing this test fail when building without asserts?
+Jorg Brown <jorg at google.com>
> Modified:
> llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
> llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td
>
> Modified: llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp?rev=339314&r1=339313&r2=339314&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (original)
> +++ llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp Thu Aug 9
> 00:08:20 2018
> @@ -73,6 +73,9 @@ class RISCVAsmParser : public MCTargetAs
> // synthesize the desired immedate value into the destination register.
> void emitLoadImm(unsigned DestReg, int64_t Value, MCStreamer &Out);
>
> + // Helper to emit pseudo instruction "lla" used in PC-rel addressing.
> + 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
> @@ -964,6 +967,26 @@ bool RISCVAsmParser::parseOperand(Operan
> return true;
> }
>
> +/// Return true if the operand at the OperandIdx for opcode Name should be
> +/// 'forced' to be parsed as an immediate. This is required for
> +/// pseudoinstructions such as tail or call, which allow bare symbols to
> be used
> +/// that could clash with register names.
> +static bool shouldForceImediateOperand(StringRef Name, unsigned
> OperandIdx) {
> + // FIXME: This may not scale so perhaps we want to use a data-driven
> approach
> + // instead.
> + switch (OperandIdx) {
> + case 0:
> + // call imm
> + // tail imm
> + return Name == "tail" || Name == "call";
> + case 1:
> + // lla rdest, imm
> + return Name == "lla";
> + default:
> + return false;
> + }
> +}
> +
> bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
> StringRef Name, SMLoc NameLoc,
> OperandVector &Operands) {
> @@ -975,18 +998,20 @@ bool RISCVAsmParser::ParseInstruction(Pa
> return false;
>
> // Parse first operand
> - bool ForceImmediate = (Name == "call" || Name == "tail");
> - if (parseOperand(Operands, ForceImmediate))
> + if (parseOperand(Operands, shouldForceImediateOperand(Name, 0)))
> return true;
>
> // Parse until end of statement, consuming commas between operands
> + unsigned OperandIdx = 1;
> while (getLexer().is(AsmToken::Comma)) {
> // Consume comma token
> getLexer().Lex();
>
> // Parse next operand
> - if (parseOperand(Operands, false))
> + if (parseOperand(Operands, shouldForceImediateOperand(Name,
> OperandIdx)))
> return true;
> +
> + ++OperandIdx;
> }
>
> if (getLexer().isNot(AsmToken::EndOfStatement)) {
> @@ -1184,6 +1209,39 @@ void RISCVAsmParser::emitLoadImm(unsigne
> .addImm(Lo12));
> }
>
> +void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
> + MCStreamer &Out) {
> + // The local load address pseudo-instruction "lla" is used in
> PC-relative
> + // addressing of symbols:
> + // lla rdest, symbol
> + // expands to
> + // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
> + // ADDI rdest, %pcrel_lo(TmpLabel)
> + MCContext &Ctx = getContext();
> +
> + 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 +1256,9 @@ bool RISCVAsmParser::processInstruction(
> 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);
>
> Modified: llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td?rev=339314&r1=339313&r2=339314&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td (original)
> +++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td Thu Aug 9 00:08:20 2018
> @@ -759,6 +759,11 @@ def : Pat<(Tail (iPTR tglobaladdr:$dst))
> def : Pat<(Tail (iPTR texternalsym:$dst)),
> (PseudoTAIL texternalsym:$dst)>;
>
> +let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0,
> + isAsmParserOnly = 1 in
> +def PseudoLLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
> + "lla", "$dst, $src">;
> +
> /// Loads
>
> multiclass LdPat<PatFrag LoadOp, RVInst Inst> {
>
> Added: llvm/trunk/test/MC/RISCV/lla-invalid.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/lla-invalid.s?rev=339314&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/RISCV/lla-invalid.s (added)
> +++ llvm/trunk/test/MC/RISCV/lla-invalid.s Thu Aug 9 00:08:20 2018
> @@ -0,0 +1,6 @@
> +# RUN: not llvm-mc -triple=riscv32 < %s 2>&1 | FileCheck %s
> +# RUN: not llvm-mc -triple=riscv64 < %s 2>&1 | FileCheck %s
> +
> +# Non bare symbols must be rejected
> +lla a2, %lo(a_symbol) # CHECK: :[[@LINE]]:9: error: operand must be a
> bare symbol name
> +lla a2, %hi(a_symbol) # CHECK: :[[@LINE]]:9: error: operand must be a
> bare symbol name
>
> Added: llvm/trunk/test/MC/RISCV/rvi-pseudos.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rvi-pseudos.s?rev=339314&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/RISCV/rvi-pseudos.s (added)
> +++ llvm/trunk/test/MC/RISCV/rvi-pseudos.s Thu Aug 9 00:08:20 2018
> @@ -0,0 +1,28 @@
> +# RUN: llvm-mc %s -triple=riscv32 | FileCheck %s
> +# RUN: llvm-mc %s -triple=riscv64 | FileCheck %s
> +
> +# 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
> +
> +# Check that we can load the address of symbols that are spelled like a
> register
> +# CHECK: .Lpcrel_hi2:
> +# CHECK: auipc a2, %pcrel_hi(zero)
> +# CHECK: addi a2, a2, %pcrel_lo(.Lpcrel_hi2)
> +lla a2, zero
> +
> +# CHECK: .Lpcrel_hi3:
> +# CHECK: auipc a3, %pcrel_hi(ra)
> +# CHECK: addi a3, a3, %pcrel_lo(.Lpcrel_hi3)
> +lla a3, ra
> +
> +# CHECK: .Lpcrel_hi4:
> +# CHECK: auipc a4, %pcrel_hi(f1)
> +# CHECK: addi a4, a4, %pcrel_lo(.Lpcrel_hi4)
> +lla a4, f1
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180813/74f86921/attachment.html>
More information about the llvm-commits
mailing list