[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