[llvm] r339314 - [RISCV] Add "lla" pseudo-instruction to assembler
Roger Ferrer Ibanez via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 9 00:08:21 PDT 2018
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
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
More information about the llvm-commits
mailing list