<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Thu, Aug 9, 2018 at 12:08 AM Roger Ferrer Ibanez via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rogfer01<br>
Date: Thu Aug  9 00:08:20 2018<br>
New Revision: 339314<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=339314&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=339314&view=rev</a><br>
Log:<br>
[RISCV] Add "lla" pseudo-instruction to assembler<br>
<br>
This pseudo-instruction is similar to la but uses PC-relative addressing<br>
unconditionally. This is, la is only different to lla when using -fPIC. This<br>
pseudo-instruction seems often forgotten in several specs but it is definitely<br>
mentioned in binutils opcodes/riscv-opc.c. The semantics are defined both in<br>
page 37 of the "RISC-V Reader" book but also in function macro found in<br>
gas/config/tc-riscv.c.<br>
<br>
This is a very first step towards adding PIC support for Linux in the RISC-V<br>
backend.<br>
<br>
The lla pseudo-instruction expands to a sequence of auipc + addi with a couple<br>
of pc-rel relocations where the second points to the first one. This is<br>
described in<br>
<a href="https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#pc-relative-symbol-addresses" rel="noreferrer" target="_blank">https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#pc-relative-symbol-addresses</a><br>
<br>
For now, this patch only introduces support of that pseudo instruction at the<br>
assembler parser.<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D49661" rel="noreferrer" target="_blank">https://reviews.llvm.org/D49661</a><br>
<br>
<br>
Added:<br>
    llvm/trunk/test/MC/RISCV/lla-invalid.s<br>
    llvm/trunk/test/MC/RISCV/rvi-pseudos.s<br></blockquote><div><br></div><div>I'm seeing this test fail when building without asserts?</div><div><br></div><div><a class="GWVZpf gW" id="IloFPc-0" href="mailto:jorg@google.com" tabindex="-1">+Jorg Brown</a> <br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Modified:<br>
    llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp<br>
    llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td<br>
<br>
Modified: llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp?rev=339314&r1=339313&r2=339314&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp?rev=339314&r1=339313&r2=339314&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (original)<br>
+++ llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp Thu Aug  9 00:08:20 2018<br>
@@ -73,6 +73,9 @@ class RISCVAsmParser : public MCTargetAs<br>
   // synthesize the desired immedate value into the destination register.<br>
   void emitLoadImm(unsigned DestReg, int64_t Value, MCStreamer &Out);<br>
<br>
+  // Helper to emit pseudo instruction "lla" used in PC-rel addressing.<br>
+  void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);<br>
+<br>
   /// Helper for processing MC instructions that have been successfully matched<br>
   /// by MatchAndEmitInstruction. Modifications to the emitted instructions,<br>
   /// like the expansion of pseudo instructions (e.g., "li"), can be performed<br>
@@ -964,6 +967,26 @@ bool RISCVAsmParser::parseOperand(Operan<br>
   return true;<br>
 }<br>
<br>
+/// Return true if the operand at the OperandIdx for opcode Name should be<br>
+/// 'forced' to be parsed as an immediate. This is required for<br>
+/// pseudoinstructions such as tail or call, which allow bare symbols to be used<br>
+/// that could clash with register names.<br>
+static bool shouldForceImediateOperand(StringRef Name, unsigned OperandIdx) {<br>
+  // FIXME: This may not scale so perhaps we want to use a data-driven approach<br>
+  // instead.<br>
+  switch (OperandIdx) {<br>
+  case 0:<br>
+    // call imm<br>
+    // tail imm<br>
+    return Name == "tail" || Name == "call";<br>
+  case 1:<br>
+    // lla rdest, imm<br>
+    return Name == "lla";<br>
+  default:<br>
+    return false;<br>
+  }<br>
+}<br>
+<br>
 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,<br>
                                       StringRef Name, SMLoc NameLoc,<br>
                                       OperandVector &Operands) {<br>
@@ -975,18 +998,20 @@ bool RISCVAsmParser::ParseInstruction(Pa<br>
     return false;<br>
<br>
   // Parse first operand<br>
-  bool ForceImmediate = (Name == "call" || Name == "tail");<br>
-  if (parseOperand(Operands, ForceImmediate))<br>
+  if (parseOperand(Operands, shouldForceImediateOperand(Name, 0)))<br>
     return true;<br>
<br>
   // Parse until end of statement, consuming commas between operands<br>
+  unsigned OperandIdx = 1;<br>
   while (getLexer().is(AsmToken::Comma)) {<br>
     // Consume comma token<br>
     getLexer().Lex();<br>
<br>
     // Parse next operand<br>
-    if (parseOperand(Operands, false))<br>
+    if (parseOperand(Operands, shouldForceImediateOperand(Name, OperandIdx)))<br>
       return true;<br>
+<br>
+    ++OperandIdx;<br>
   }<br>
<br>
   if (getLexer().isNot(AsmToken::EndOfStatement)) {<br>
@@ -1184,6 +1209,39 @@ void RISCVAsmParser::emitLoadImm(unsigne<br>
                             .addImm(Lo12));<br>
 }<br>
<br>
+void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,<br>
+                                          MCStreamer &Out) {<br>
+  // The local load address pseudo-instruction "lla" is used in PC-relative<br>
+  // addressing of symbols:<br>
+  //   lla rdest, symbol<br>
+  // expands to<br>
+  //   TmpLabel: AUIPC rdest, %pcrel_hi(symbol)<br>
+  //             ADDI rdest, %pcrel_lo(TmpLabel)<br>
+  MCContext &Ctx = getContext();<br>
+<br>
+  MCSymbol *TmpLabel = Ctx.createTempSymbol(<br>
+      "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false);<br>
+  Out.EmitLabel(TmpLabel);<br>
+<br>
+  MCOperand DestReg = Inst.getOperand(0);<br>
+  const RISCVMCExpr *Symbol = RISCVMCExpr::create(<br>
+      Inst.getOperand(1).getExpr(), RISCVMCExpr::VK_RISCV_PCREL_HI, Ctx);<br>
+<br>
+  MCInst &AUIPC =<br>
+      MCInstBuilder(RISCV::AUIPC).addOperand(DestReg).addExpr(Symbol);<br>
+  emitToStreamer(Out, AUIPC);<br>
+<br>
+  const MCExpr *RefToLinkTmpLabel =<br>
+      RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx),<br>
+                          RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx);<br>
+<br>
+  MCInst &ADDI = MCInstBuilder(RISCV::ADDI)<br>
+                     .addOperand(DestReg)<br>
+                     .addOperand(DestReg)<br>
+                     .addExpr(RefToLinkTmpLabel);<br>
+  emitToStreamer(Out, ADDI);<br>
+}<br>
+<br>
 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,<br>
                                         MCStreamer &Out) {<br>
   Inst.setLoc(IDLoc);<br>
@@ -1198,6 +1256,9 @@ bool RISCVAsmParser::processInstruction(<br>
       Imm = SignExtend64<32>(Imm);<br>
     emitLoadImm(Reg, Imm, Out);<br>
     return false;<br>
+  } else if (Inst.getOpcode() == RISCV::PseudoLLA) {<br>
+    emitLoadLocalAddress(Inst, IDLoc, Out);<br>
+    return false;<br>
   }<br>
<br>
   emitToStreamer(Out, Inst);<br>
<br>
Modified: llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td?rev=339314&r1=339313&r2=339314&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td?rev=339314&r1=339313&r2=339314&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td (original)<br>
+++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td Thu Aug  9 00:08:20 2018<br>
@@ -759,6 +759,11 @@ def : Pat<(Tail (iPTR tglobaladdr:$dst))<br>
 def : Pat<(Tail (iPTR texternalsym:$dst)),<br>
           (PseudoTAIL texternalsym:$dst)>;<br>
<br>
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0,<br>
+    isAsmParserOnly = 1 in<br>
+def PseudoLLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],<br>
+                       "lla", "$dst, $src">;<br>
+<br>
 /// Loads<br>
<br>
 multiclass LdPat<PatFrag LoadOp, RVInst Inst> {<br>
<br>
Added: llvm/trunk/test/MC/RISCV/lla-invalid.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/lla-invalid.s?rev=339314&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/lla-invalid.s?rev=339314&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/MC/RISCV/lla-invalid.s (added)<br>
+++ llvm/trunk/test/MC/RISCV/lla-invalid.s Thu Aug  9 00:08:20 2018<br>
@@ -0,0 +1,6 @@<br>
+# RUN: not llvm-mc -triple=riscv32 < %s 2>&1 | FileCheck %s<br>
+# RUN: not llvm-mc -triple=riscv64 < %s 2>&1 | FileCheck %s<br>
+<br>
+# Non bare symbols must be rejected<br>
+lla a2, %lo(a_symbol) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name<br>
+lla a2, %hi(a_symbol) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name<br>
<br>
Added: llvm/trunk/test/MC/RISCV/rvi-pseudos.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rvi-pseudos.s?rev=339314&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rvi-pseudos.s?rev=339314&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/MC/RISCV/rvi-pseudos.s (added)<br>
+++ llvm/trunk/test/MC/RISCV/rvi-pseudos.s Thu Aug  9 00:08:20 2018<br>
@@ -0,0 +1,28 @@<br>
+# RUN: llvm-mc %s -triple=riscv32 | FileCheck %s<br>
+# RUN: llvm-mc %s -triple=riscv64 | FileCheck %s<br>
+<br>
+# CHECK: .Lpcrel_hi0:<br>
+# CHECK: auipc a0, %pcrel_hi(a_symbol)<br>
+# CHECK: addi  a0, a0, %pcrel_lo(.Lpcrel_hi0)<br>
+lla a0, a_symbol<br>
+<br>
+# CHECK: .Lpcrel_hi1:<br>
+# CHECK: auipc a1, %pcrel_hi(another_symbol)<br>
+# CHECK: addi  a1, a1, %pcrel_lo(.Lpcrel_hi1)<br>
+lla a1, another_symbol<br>
+<br>
+# Check that we can load the address of symbols that are spelled like a register<br>
+# CHECK: .Lpcrel_hi2:<br>
+# CHECK: auipc a2, %pcrel_hi(zero)<br>
+# CHECK: addi  a2, a2, %pcrel_lo(.Lpcrel_hi2)<br>
+lla a2, zero<br>
+<br>
+# CHECK: .Lpcrel_hi3:<br>
+# CHECK: auipc a3, %pcrel_hi(ra)<br>
+# CHECK: addi  a3, a3, %pcrel_lo(.Lpcrel_hi3)<br>
+lla a3, ra<br>
+<br>
+# CHECK: .Lpcrel_hi4:<br>
+# CHECK: auipc a4, %pcrel_hi(f1)<br>
+# CHECK: addi  a4, a4, %pcrel_lo(.Lpcrel_hi4)<br>
+lla a4, f1<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div>