diff options
| author | Kito Cheng <kito.cheng@gmail.com> | 2019-02-20 03:31:32 +0000 | 
|---|---|---|
| committer | Kito Cheng <kito.cheng@gmail.com> | 2019-02-20 03:31:32 +0000 | 
| commit | 303217e8b43d4d299aeb629ecb5b1e060fc77969 (patch) | |
| tree | 62dd596999b2506a13fd4b990fb172f102f76d67 /llvm/lib/Target/RISCV | |
| parent | 476e1b9937552b2dde191d0c3a6d3396ef9fa7e7 (diff) | |
| download | bcm5719-llvm-303217e8b43d4d299aeb629ecb5b1e060fc77969.tar.gz bcm5719-llvm-303217e8b43d4d299aeb629ecb5b1e060fc77969.zip  | |
[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
llvm-svn: 354430
Diffstat (limited to 'llvm/lib/Target/RISCV')
| -rw-r--r-- | llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 81 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrFormats.td | 29 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrInfo.td | 29 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrInfoD.td | 6 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrInfoF.td | 6 | 
5 files changed, 137 insertions, 14 deletions
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 2d797f3f1d6..239f7c407f3 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -91,6 +91,10 @@ class RISCVAsmParser : public MCTargetAsmParser {    // 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::parseBareSymbol(OperandVector &Operands) {      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(MCInst &Inst, SMLoc IDLoc,    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(MCInst &Inst, SMLoc IDLoc,    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); diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td index f2c6230938e..7229ebfe1db 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td +++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td @@ -108,6 +108,35 @@ class Pseudo<dag outs, dag ins, list<dag> pattern, string opcodestr = "", string    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. diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index de9ea199041..c13bcf5be9d 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -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, 0b000, OPC_SYSTEM, (outs),  // 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, mayStore = 0, Size = 32,  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)>; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td index 87efd36e9d2..1e48d24bfab 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td @@ -178,9 +178,6 @@ def FMV_D_X : FPUnaryOp_r<0b1111001, 0b000, FPR64, GPR, "fmv.d.x"> {  //===----------------------------------------------------------------------===//  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]  //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td index 0fb205202ff..c7fa72dfae1 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td @@ -206,9 +206,6 @@ def           : FPUnaryOpDynFrmAlias<FCVT_S_LU, "fcvt.s.lu", FPR32, GPR>;  //===----------------------------------------------------------------------===//  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",      (CSRRWI      X0, 0x001, uimm5:$imm), 2>;  // 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]  //===----------------------------------------------------------------------===//  | 

