Skip to content

[RISCV] Support Load/Store Global assembler pseudos for Zilsd. #134950

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 25 additions & 12 deletions llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class RISCVAsmParser : public MCTargetAsmParser {

// Helper to emit a combination of AUIPC and SecondOpcode. Used to implement
// helpers such as emitLoadLocalAddress and emitLoadAddress.
void emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
void emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
const MCExpr *Symbol, RISCVMCExpr::Specifier VKHi,
unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);

Expand Down Expand Up @@ -3302,7 +3302,7 @@ void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t Value,
}
}

void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
const MCExpr *Symbol,
RISCVMCExpr::Specifier VKHi,
unsigned SecondOpcode, SMLoc IDLoc,
Expand All @@ -3316,15 +3316,15 @@ void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
Out.emitLabel(TmpLabel);

const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx);
emitToStreamer(
Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi));
emitToStreamer(Out,
MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));

const MCExpr *RefToLinkTmpLabel = RISCVMCExpr::create(
MCSymbolRefExpr::create(TmpLabel, Ctx), RISCVMCExpr::VK_PCREL_LO, Ctx);

emitToStreamer(Out, MCInstBuilder(SecondOpcode)
.addOperand(DestReg)
.addOperand(TmpReg)
.addReg(DestReg)
.addReg(TmpReg)
.addExpr(RefToLinkTmpLabel));
}

Expand All @@ -3336,7 +3336,7 @@ void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
// expands to
// TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
// ADDI rdest, rdest, %pcrel_lo(TmpLabel)
MCOperand DestReg = Inst.getOperand(0);
MCRegister DestReg = Inst.getOperand(0).getReg();
const MCExpr *Symbol = Inst.getOperand(1).getExpr();
emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_PCREL_HI,
RISCV::ADDI, IDLoc, Out);
Expand All @@ -3350,7 +3350,7 @@ void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
// expands to
// TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol)
// Lx rdest, %pcrel_lo(TmpLabel)(rdest)
MCOperand DestReg = Inst.getOperand(0);
MCRegister DestReg = Inst.getOperand(0).getReg();
const MCExpr *Symbol = Inst.getOperand(1).getExpr();
unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_GOT_HI,
Expand Down Expand Up @@ -3380,7 +3380,7 @@ void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
// expands to
// TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol)
// Lx rdest, %pcrel_lo(TmpLabel)(rdest)
MCOperand DestReg = Inst.getOperand(0);
MCRegister DestReg = Inst.getOperand(0).getReg();
const MCExpr *Symbol = Inst.getOperand(1).getExpr();
unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_TLS_GOT_HI,
Expand All @@ -3395,7 +3395,7 @@ void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
// expands to
// TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol)
// ADDI rdest, rdest, %pcrel_lo(TmpLabel)
MCOperand DestReg = Inst.getOperand(0);
MCRegister DestReg = Inst.getOperand(0).getReg();
const MCExpr *Symbol = Inst.getOperand(1).getExpr();
emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_TLS_GD_HI,
RISCV::ADDI, IDLoc, Out);
Expand All @@ -3412,9 +3412,16 @@ void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode,
// TmpLabel: AUIPC tmp, %pcrel_hi(symbol)
// [S|L]X rd, %pcrel_lo(TmpLabel)(tmp)
unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
MCOperand DestReg = Inst.getOperand(DestRegOpIdx);
MCRegister DestReg = Inst.getOperand(DestRegOpIdx).getReg();
unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
MCOperand TmpReg = Inst.getOperand(0);
MCRegister TmpReg = Inst.getOperand(0).getReg();

// If TmpReg is a GPR pair, get the even register.
if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(TmpReg)) {
const MCRegisterInfo *RI = getContext().getRegisterInfo();
TmpReg = RI->getSubReg(TmpReg, RISCV::sub_gpr_even);
}

const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr();
emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_PCREL_HI, Opcode,
IDLoc, Out);
Expand Down Expand Up @@ -3766,6 +3773,9 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
case RISCV::PseudoLD:
emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false);
return false;
case RISCV::PseudoLD_RV32:
emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out, /*HasTmpReg=*/false);
return false;
case RISCV::PseudoFLH:
emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out, /*HasTmpReg=*/true);
return false;
Expand All @@ -3787,6 +3797,9 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
case RISCV::PseudoSD:
emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true);
return false;
case RISCV::PseudoSD_RV32:
emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out, /*HasTmpReg=*/true);
return false;
case RISCV::PseudoFSH:
emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out, /*HasTmpReg=*/true);
return false;
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Target/RISCV/RISCVInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,8 @@ class PseudoQuietFCMP<DAGOperand Ty>
}

// Pseudo load instructions.
class PseudoLoad<string opcodestr>
: Pseudo<(outs GPR:$rd), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr"> {
class PseudoLoad<string opcodestr, DAGOperand rdty = GPR>
: Pseudo<(outs rdty:$rd), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr"> {
let hasSideEffects = 0;
let mayLoad = 1;
let mayStore = 0;
Expand All @@ -320,7 +320,7 @@ class PseudoFloatLoad<string opcodestr, RegisterClass rdty>
}

// Pseudo store instructions.
class PseudoStore<string opcodestr, RegisterClass rsty = GPR>
class PseudoStore<string opcodestr, DAGOperand rsty = GPR>
: Pseudo<(outs GPR:$tmp), (ins rsty:$rs, bare_symbol:$addr), [], opcodestr, "$rs, $addr, $tmp"> {
let hasSideEffects = 0;
let mayLoad = 0;
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoZilsd.td
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ def SD_RV32 : PairStore_rri<"sd", GPRPairRV32>, Sched<[WriteSTD, ReadStoreData,
//===----------------------------------------------------------------------===//

let Predicates = [HasStdExtZilsd, IsRV32] in {
def PseudoLD_RV32 : PseudoLoad<"ld", GPRPairRV32>;
def PseudoSD_RV32 : PseudoStore<"sd", GPRPairRV32>;

def : InstAlias<"ld $rd, (${rs1})", (LD_RV32 GPRPairRV32:$rd, GPR:$rs1, 0), 0>;
def : InstAlias<"sd $rs2, (${rs1})", (SD_RV32 GPRPairRV32:$rs2, GPR:$rs1, 0), 0>;
}
11 changes: 11 additions & 0 deletions llvm/test/MC/RISCV/rv32zilsd-pseudos.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# RUN: llvm-mc %s -triple=riscv32 -mattr=+zilsd | FileCheck %s

# CHECK: .Lpcrel_hi0:
# CHECK: auipc a4, %pcrel_hi(a_symbol)
# CHECK: ld a4, %pcrel_lo(.Lpcrel_hi0)(a4)
ld a4, a_symbol

# CHECK: .Lpcrel_hi1:
# CHECK: auipc a3, %pcrel_hi(a_symbol)
# CHECK: sd a6, %pcrel_lo(.Lpcrel_hi1)(a3)
sd a6, a_symbol, a3