[llvm] r354430 - [RISCV] Implement pseudo instructions for load/store from a symbol address.

Kito Cheng via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 19 19:31:33 PST 2019


Author: kito
Date: Tue Feb 19 19:31:32 2019
New Revision: 354430

URL: http://llvm.org/viewvc/llvm-project?rev=354430&view=rev
Log:
[RISCV] Implement pseudo instructions for load/store from a symbol address.

Summary:
Those pseudo-instructions are making load/store instructions able to
load/store from/to a symbol, and its always using PC-relative addressing
to generating a symbol address.

Reviewers: asb, apazos, rogfer01, jrtc27

Differential Revision: https://reviews.llvm.org/D50496

Added:
    llvm/trunk/test/MC/RISCV/rv64i-pseudos.s
    llvm/trunk/test/MC/RISCV/rvd-pseudos.s
    llvm/trunk/test/MC/RISCV/rvf-pseudos.s
Modified:
    llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
    llvm/trunk/lib/Target/RISCV/RISCVInstrFormats.td
    llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td
    llvm/trunk/lib/Target/RISCV/RISCVInstrInfoD.td
    llvm/trunk/lib/Target/RISCV/RISCVInstrInfoF.td
    llvm/trunk/test/MC/RISCV/rv32d-invalid.s
    llvm/trunk/test/MC/RISCV/rv32f-invalid.s
    llvm/trunk/test/MC/RISCV/rv32i-invalid.s
    llvm/trunk/test/MC/RISCV/rvi-pseudos-invalid.s
    llvm/trunk/test/MC/RISCV/rvi-pseudos.s

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=354430&r1=354429&r2=354430&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp Tue Feb 19 19:31:32 2019
@@ -91,6 +91,10 @@ class RISCVAsmParser : public MCTargetAs
   // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing.
   void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
 
+  // Helper to emit pseudo load/store instruction with a symbol.
+  void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,
+                           MCStreamer &Out, bool HasTmpReg);
+
   /// 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
@@ -1105,11 +1109,22 @@ OperandMatchResultTy RISCVAsmParser::par
     return MatchOperand_NoMatch;
 
   StringRef Identifier;
+  AsmToken Tok = getLexer().getTok();
+
   if (getParser().parseIdentifier(Identifier))
     return MatchOperand_ParseFail;
 
   MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
-  Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
+
+  if (Sym->isVariable()) {
+    const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
+    if (!isa<MCSymbolRefExpr>(V)) {
+      getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
+      return MatchOperand_NoMatch;
+    }
+    Res = V;
+  } else
+    Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
   Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
   return MatchOperand_Success;
 }
@@ -1487,6 +1502,25 @@ void RISCVAsmParser::emitLoadAddress(MCI
   emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out);
 }
 
+void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode,
+                                         SMLoc IDLoc, MCStreamer &Out,
+                                         bool HasTmpReg) {
+  // The load/store pseudo-instruction does a pc-relative load with
+  // a symbol.
+  //
+  // The expansion looks like this
+  //
+  //   TmpLabel: AUIPC tmp, %pcrel_hi(symbol)
+  //             [S|L]X    rd, %pcrel_lo(TmpLabel)(tmp)
+  MCOperand DestReg = Inst.getOperand(0);
+  unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
+  unsigned TmpRegOpIdx = HasTmpReg ? 1 : 0;
+  MCOperand TmpReg = Inst.getOperand(TmpRegOpIdx);
+  const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr();
+  emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
+                    Opcode, IDLoc, Out);
+}
+
 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
                                         MCStreamer &Out) {
   Inst.setLoc(IDLoc);
@@ -1521,6 +1555,51 @@ bool RISCVAsmParser::processInstruction(
   case RISCV::PseudoLA:
     emitLoadAddress(Inst, IDLoc, Out);
     return false;
+  case RISCV::PseudoLB:
+    emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false);
+    return false;
+  case RISCV::PseudoLBU:
+    emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false);
+    return false;
+  case RISCV::PseudoLH:
+    emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false);
+    return false;
+  case RISCV::PseudoLHU:
+    emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false);
+    return false;
+  case RISCV::PseudoLW:
+    emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false);
+    return false;
+  case RISCV::PseudoLWU:
+    emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false);
+    return false;
+  case RISCV::PseudoLD:
+    emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false);
+    return false;
+  case RISCV::PseudoFLW:
+    emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true);
+    return false;
+  case RISCV::PseudoFLD:
+    emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true);
+    return false;
+  case RISCV::PseudoSB:
+    emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true);
+    return false;
+  case RISCV::PseudoSH:
+    emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true);
+    return false;
+  case RISCV::PseudoSW:
+    emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true);
+    return false;
+  case RISCV::PseudoSD:
+    emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true);
+    return false;
+  case RISCV::PseudoFSW:
+    emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true);
+    return false;
+  case RISCV::PseudoFSD:
+    emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true);
+    return false;
   }
 
   emitToStreamer(Out, Inst);

Modified: llvm/trunk/lib/Target/RISCV/RISCVInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrFormats.td?rev=354430&r1=354429&r2=354430&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVInstrFormats.td (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVInstrFormats.td Tue Feb 19 19:31:32 2019
@@ -108,6 +108,35 @@ class Pseudo<dag outs, dag ins, list<dag
   let isCodeGenOnly = 1;
 }
 
+// Pseudo load instructions.
+class PseudoLoad<string opcodestr, RegisterClass rdty = GPR>
+    : Pseudo<(outs rdty:$rd), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr"> {
+  let hasSideEffects = 0;
+  let mayLoad = 1;
+  let mayStore = 0;
+  let isCodeGenOnly = 0;
+  let isAsmParserOnly = 1;
+}
+
+class PseudoFloatLoad<string opcodestr, RegisterClass rdty = GPR>
+    : Pseudo<(outs rdty:$rd, GPR:$tmp), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr, $tmp"> {
+  let hasSideEffects = 0;
+  let mayLoad = 1;
+  let mayStore = 0;
+  let isCodeGenOnly = 0;
+  let isAsmParserOnly = 1;
+}
+
+// Pseudo store instructions.
+class PseudoStore<string opcodestr, RegisterClass rsty = GPR>
+    : Pseudo<(outs rsty:$rs, GPR:$tmp), (ins bare_symbol:$addr), [], opcodestr, "$rs, $addr, $tmp"> {
+  let hasSideEffects = 0;
+  let mayLoad = 0;
+  let mayStore = 1;
+  let isCodeGenOnly = 0;
+  let isAsmParserOnly = 1;
+}
+
 // Instruction formats are listed in the order they appear in the RISC-V
 // instruction set manual (R, I, S, B, U, J) with sub-formats (e.g. RVInstR4,
 // RVInstRAtomic) sorted alphabetically.

Modified: llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td?rev=354430&r1=354429&r2=354430&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td Tue Feb 19 19:31:32 2019
@@ -10,8 +10,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-include "RISCVInstrFormats.td"
-
 //===----------------------------------------------------------------------===//
 // RISC-V specific DAG Nodes.
 //===----------------------------------------------------------------------===//
@@ -241,6 +239,12 @@ def HI20 : SDNodeXForm<imm, [{
 }]>;
 
 //===----------------------------------------------------------------------===//
+// Instruction Formats
+//===----------------------------------------------------------------------===//
+
+include "RISCVInstrFormats.td"
+
+//===----------------------------------------------------------------------===//
 // Instruction Class Templates
 //===----------------------------------------------------------------------===//
 
@@ -497,11 +501,6 @@ def SFENCE_VMA : RVInstR<0b0001001, 0b00
 // Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
 //===----------------------------------------------------------------------===//
 
-// TODO lb lh lw
-// TODO RV64I: ld
-// TODO sb sh sw
-// TODO RV64I: sd
-
 def : InstAlias<"nop",           (ADDI      X0,      X0,       0)>;
 
 // Note that the size is 32 because up to 8 32-bit instructions are needed to
@@ -513,6 +512,22 @@ let hasSideEffects = 0, mayLoad = 0, may
 def PseudoLI : Pseudo<(outs GPR:$rd), (ins ixlenimm_li:$imm), [],
                       "li", "$rd, $imm">;
 
+def PseudoLB  : PseudoLoad<"lb">;
+def PseudoLBU : PseudoLoad<"lbu">;
+def PseudoLH  : PseudoLoad<"lh">;
+def PseudoLHU : PseudoLoad<"lhu">;
+def PseudoLW  : PseudoLoad<"lw">;
+
+def PseudoSB  : PseudoStore<"sb">;
+def PseudoSH  : PseudoStore<"sh">;
+def PseudoSW  : PseudoStore<"sw">;
+
+let Predicates = [IsRV64] in {
+def PseudoLWU : PseudoLoad<"lwu">;
+def PseudoLD  : PseudoLoad<"ld">;
+def PseudoSD  : PseudoStore<"sd">;
+} // Predicates = [IsRV64]
+
 def : InstAlias<"mv $rd, $rs",   (ADDI GPR:$rd, GPR:$rs,       0)>;
 def : InstAlias<"not $rd, $rs",  (XORI GPR:$rd, GPR:$rs,      -1)>;
 def : InstAlias<"neg $rd, $rs",  (SUB  GPR:$rd,      X0, GPR:$rs)>;

Modified: llvm/trunk/lib/Target/RISCV/RISCVInstrInfoD.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrInfoD.td?rev=354430&r1=354429&r2=354430&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVInstrInfoD.td (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfoD.td Tue Feb 19 19:31:32 2019
@@ -178,9 +178,6 @@ def FMV_D_X : FPUnaryOp_r<0b1111001, 0b0
 //===----------------------------------------------------------------------===//
 
 let Predicates = [HasStdExtD] in {
-// TODO fld
-// TODO fsd
-
 def : InstAlias<"fmv.d $rd, $rs",  (FSGNJ_D  FPR64:$rd, FPR64:$rs, FPR64:$rs)>;
 def : InstAlias<"fabs.d $rd, $rs", (FSGNJX_D FPR64:$rd, FPR64:$rs, FPR64:$rs)>;
 def : InstAlias<"fneg.d $rd, $rs", (FSGNJN_D FPR64:$rd, FPR64:$rs, FPR64:$rs)>;
@@ -191,6 +188,9 @@ def : InstAlias<"fgt.d $rd, $rs, $rt",
                 (FLT_D GPR:$rd, FPR64:$rt, FPR64:$rs), 0>;
 def : InstAlias<"fge.d $rd, $rs, $rt",
                 (FLE_D GPR:$rd, FPR64:$rt, FPR64:$rs), 0>;
+
+def PseudoFLD  : PseudoFloatLoad<"fld", FPR64>;
+def PseudoFSD  : PseudoStore<"fsd", FPR64>;
 } // Predicates = [HasStdExtD]
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/Target/RISCV/RISCVInstrInfoF.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrInfoF.td?rev=354430&r1=354429&r2=354430&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVInstrInfoF.td (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfoF.td Tue Feb 19 19:31:32 2019
@@ -206,9 +206,6 @@ def           : FPUnaryOpDynFrmAlias<FCV
 //===----------------------------------------------------------------------===//
 
 let Predicates = [HasStdExtF] in {
-// TODO flw
-// TODO fsw
-
 def : InstAlias<"fmv.s $rd, $rs",  (FSGNJ_S  FPR32:$rd, FPR32:$rs, FPR32:$rs)>;
 def : InstAlias<"fabs.s $rd, $rs", (FSGNJX_S FPR32:$rd, FPR32:$rs, FPR32:$rs)>;
 def : InstAlias<"fneg.s $rd, $rs", (FSGNJN_S FPR32:$rd, FPR32:$rs, FPR32:$rs)>;
@@ -244,6 +241,9 @@ def : InstAlias<"fsflagsi $imm",      (C
 // spellings should be supported by standard tools.
 def : MnemonicAlias<"fmv.s.x", "fmv.w.x">;
 def : MnemonicAlias<"fmv.x.s", "fmv.x.w">;
+
+def PseudoFLW  : PseudoFloatLoad<"flw", FPR32>;
+def PseudoFSW  : PseudoStore<"fsw", FPR32>;
 } // Predicates = [HasStdExtF]
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/test/MC/RISCV/rv32d-invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32d-invalid.s?rev=354430&r1=354429&r2=354430&view=diff
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32d-invalid.s (original)
+++ llvm/trunk/test/MC/RISCV/rv32d-invalid.s Tue Feb 19 19:31:32 2019
@@ -6,8 +6,8 @@ fld ft1, -2049(a0) # CHECK: :[[@LINE]]:1
 fsd ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047]
 
 # Memory operand not formatted correctly
-fld ft1, a0, -200 # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047]
-fsd ft2, a1, 100 # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047]
+fld ft1, a0, -200 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
+fsd ft2, a1, 100 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
 
 # Invalid register names
 fld ft15, 100(a0) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction

Modified: llvm/trunk/test/MC/RISCV/rv32f-invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32f-invalid.s?rev=354430&r1=354429&r2=354430&view=diff
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32f-invalid.s (original)
+++ llvm/trunk/test/MC/RISCV/rv32f-invalid.s Tue Feb 19 19:31:32 2019
@@ -6,8 +6,8 @@ flw ft1, -2049(a0) # CHECK: :[[@LINE]]:1
 fsw ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047]
 
 # Memory operand not formatted correctly
-flw ft1, a0, -200 # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047]
-fsw ft2, a1, 100 # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047]
+flw ft1, a0, -200 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
+fsw ft2, a1, 100 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
 
 # Invalid register names
 flw ft15, 100(a0) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction

Modified: llvm/trunk/test/MC/RISCV/rv32i-invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32i-invalid.s?rev=354430&r1=354429&r2=354430&view=diff
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32i-invalid.s (original)
+++ llvm/trunk/test/MC/RISCV/rv32i-invalid.s Tue Feb 19 19:31:32 2019
@@ -158,7 +158,7 @@ add ra, zero, zero, zero # CHECK: :[[@LI
 sltiu s2, s3, 0x50, 0x60 # CHECK: :[[@LINE]]:21: error: invalid operand for instruction
 
 # Memory operand not formatted correctly
-lw a4, a5, 111 # CHECK: :[[@LINE]]:8: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047]
+lw a4, a5, 111 # CHECK: :[[@LINE]]:12: error: invalid operand for instruction
 
 # Too few operands
 ori a0, a1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

Added: llvm/trunk/test/MC/RISCV/rv64i-pseudos.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv64i-pseudos.s?rev=354430&view=auto
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv64i-pseudos.s (added)
+++ llvm/trunk/test/MC/RISCV/rv64i-pseudos.s Tue Feb 19 19:31:32 2019
@@ -0,0 +1,16 @@
+# RUN: llvm-mc %s -triple=riscv64 | FileCheck %s
+
+# CHECK: .Lpcrel_hi0:
+# CHECK: auipc a2, %pcrel_hi(a_symbol)
+# CHECK: lwu  a2, %pcrel_lo(.Lpcrel_hi0)(a2)
+lwu a2, a_symbol
+
+# CHECK: .Lpcrel_hi1:
+# CHECK: auipc a3, %pcrel_hi(a_symbol)
+# CHECK: ld  a3, %pcrel_lo(.Lpcrel_hi1)(a3)
+ld a3, a_symbol
+
+# CHECK: .Lpcrel_hi2:
+# CHECK: auipc a4, %pcrel_hi(a_symbol)
+# CHECK: sd  a3, %pcrel_lo(.Lpcrel_hi2)(a4)
+sd a3, a_symbol, a4

Added: llvm/trunk/test/MC/RISCV/rvd-pseudos.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rvd-pseudos.s?rev=354430&view=auto
==============================================================================
--- llvm/trunk/test/MC/RISCV/rvd-pseudos.s (added)
+++ llvm/trunk/test/MC/RISCV/rvd-pseudos.s Tue Feb 19 19:31:32 2019
@@ -0,0 +1,12 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+d | FileCheck %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+d | FileCheck %s
+
+# CHECK: .Lpcrel_hi0:
+# CHECK: auipc a2, %pcrel_hi(a_symbol)
+# CHECK: fld  fa2, %pcrel_lo(.Lpcrel_hi0)(a2)
+fld fa2, a_symbol, a2
+
+# CHECK: .Lpcrel_hi1:
+# CHECK: auipc a3, %pcrel_hi(a_symbol)
+# CHECK: fsd  fa2, %pcrel_lo(.Lpcrel_hi1)(a3)
+fsd fa2, a_symbol, a3

Added: llvm/trunk/test/MC/RISCV/rvf-pseudos.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rvf-pseudos.s?rev=354430&view=auto
==============================================================================
--- llvm/trunk/test/MC/RISCV/rvf-pseudos.s (added)
+++ llvm/trunk/test/MC/RISCV/rvf-pseudos.s Tue Feb 19 19:31:32 2019
@@ -0,0 +1,12 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+f | FileCheck %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+f | FileCheck %s
+
+# CHECK: .Lpcrel_hi0:
+# CHECK: auipc a2, %pcrel_hi(a_symbol)
+# CHECK: flw  fa2, %pcrel_lo(.Lpcrel_hi0)(a2)
+flw fa2, a_symbol, a2
+
+# CHECK: .Lpcrel_hi1:
+# CHECK: auipc a3, %pcrel_hi(a_symbol)
+# CHECK: fsw  fa2, %pcrel_lo(.Lpcrel_hi1)(a3)
+fsw fa2, a_symbol, a3

Modified: llvm/trunk/test/MC/RISCV/rvi-pseudos-invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rvi-pseudos-invalid.s?rev=354430&r1=354429&r2=354430&view=diff
==============================================================================
--- llvm/trunk/test/MC/RISCV/rvi-pseudos-invalid.s (original)
+++ llvm/trunk/test/MC/RISCV/rvi-pseudos-invalid.s Tue Feb 19 19:31:32 2019
@@ -20,3 +20,10 @@ la x1, %hi(1234) # CHECK: :[[@LINE]]:8:
 la x1, %lo(1234) # CHECK: :[[@LINE]]:8: error: operand must be a bare symbol name
 la x1, %hi(foo) # CHECK: :[[@LINE]]:8: error: operand must be a bare symbol name
 la x1, %lo(foo) # CHECK: :[[@LINE]]:8: error: operand must be a bare symbol name
+
+sw a2, %hi(a_symbol), a3 # CHECK: :[[@LINE]]:8: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047]
+sw a2, %lo(a_symbol), a3 # CHECK: :[[@LINE]]:23: error: invalid operand for instruction
+sw a2, %lo(a_symbol)(a4), a3 # CHECK: :[[@LINE]]:27: error: invalid operand for instruction
+
+# Too few operands must be rejected
+sw a2, a_symbol # CHECK: :[[@LINE]]:1: error: too few operands for instruction

Modified: llvm/trunk/test/MC/RISCV/rvi-pseudos.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rvi-pseudos.s?rev=354430&r1=354429&r2=354430&view=diff
==============================================================================
--- llvm/trunk/test/MC/RISCV/rvi-pseudos.s (original)
+++ llvm/trunk/test/MC/RISCV/rvi-pseudos.s Tue Feb 19 19:31:32 2019
@@ -71,3 +71,49 @@ la a3, ra
 # CHECK-PIC-RV32: lw    a4, %pcrel_lo(.Lpcrel_hi9)(a4)
 # CHECK-PIC-RV64: ld    a4, %pcrel_lo(.Lpcrel_hi9)(a4)
 la a4, f1
+
+# CHECK: .Lpcrel_hi10:
+# CHECK: auipc a0, %pcrel_hi(a_symbol)
+# CHECK: lb  a0, %pcrel_lo(.Lpcrel_hi10)(a0)
+lb a0, a_symbol
+
+# CHECK: .Lpcrel_hi11:
+# CHECK: auipc a1, %pcrel_hi(a_symbol)
+# CHECK: lh  a1, %pcrel_lo(.Lpcrel_hi11)(a1)
+lh a1, a_symbol
+
+# CHECK: .Lpcrel_hi12:
+# CHECK: auipc a2, %pcrel_hi(a_symbol)
+# CHECK: lhu  a2, %pcrel_lo(.Lpcrel_hi12)(a2)
+lhu a2, a_symbol
+
+# CHECK: .Lpcrel_hi13:
+# CHECK: auipc a3, %pcrel_hi(a_symbol)
+# CHECK: lw  a3, %pcrel_lo(.Lpcrel_hi13)(a3)
+lw a3, a_symbol
+
+# CHECK: .Lpcrel_hi14:
+# CHECK: auipc a4, %pcrel_hi(a_symbol)
+# CHECK: sb  a3, %pcrel_lo(.Lpcrel_hi14)(a4)
+sb a3, a_symbol, a4
+
+# CHECK: .Lpcrel_hi15:
+# CHECK: auipc a4, %pcrel_hi(a_symbol)
+# CHECK: sh  a3, %pcrel_lo(.Lpcrel_hi15)(a4)
+sh a3, a_symbol, a4
+
+# CHECK: .Lpcrel_hi16:
+# CHECK: auipc a4, %pcrel_hi(a_symbol)
+# CHECK: sw  a3, %pcrel_lo(.Lpcrel_hi16)(a4)
+sw a3, a_symbol, a4
+
+# Check that we can load the address of symbols that are spelled like a register
+# CHECK: .Lpcrel_hi17:
+# CHECK: auipc a2, %pcrel_hi(zero)
+# CHECK: lw  a2, %pcrel_lo(.Lpcrel_hi17)(a2)
+lw a2, zero
+
+# CHECK: .Lpcrel_hi18:
+# CHECK: auipc a4, %pcrel_hi(zero)
+# CHECK: sw  a3, %pcrel_lo(.Lpcrel_hi18)(a4)
+sw a3, zero, a4




More information about the llvm-commits mailing list