Skip to content

Commit 3e3d9fc

Browse files
committed
Use MCCodeEmitter to encode instructions rather than hardcoded constants
1 parent 94f4194 commit 3e3d9fc

File tree

1 file changed

+36
-20
lines changed

1 file changed

+36
-20
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
#include "llvm/IR/Instructions.h"
3838
#include "llvm/IR/IntrinsicsRISCV.h"
3939
#include "llvm/IR/PatternMatch.h"
40+
#include "llvm/MC/MCCodeEmitter.h"
41+
#include "llvm/MC/MCInstBuilder.h"
4042
#include "llvm/Support/CommandLine.h"
4143
#include "llvm/Support/Debug.h"
4244
#include "llvm/Support/ErrorHandling.h"
@@ -7429,6 +7431,14 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
74297431
if (!Subtarget.is64Bit())
74307432
llvm::report_fatal_error("Trampolines only implemented for RV64");
74317433

7434+
// Create an MCCodeEmitter to encode instructions.
7435+
TargetLoweringObjectFile *TLO = getTargetMachine().getObjFileLowering();
7436+
assert(TLO);
7437+
MCContext& MCCtx = TLO->getContext();
7438+
7439+
std::unique_ptr<MCCodeEmitter> CodeEmitter(
7440+
createRISCVMCCodeEmitter(*getTargetMachine().getMCInstrInfo(), MCCtx));
7441+
74327442
SDValue Root = Op.getOperand(0);
74337443
SDValue Trmp = Op.getOperand(1); // trampoline
74347444
SDLoc dl(Op);
@@ -7445,36 +7455,41 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
74457455
// 24: <FunctionAddressOffset>
74467456
// 32:
74477457

7448-
// Constants shamelessly taken from GCC.
7449-
constexpr unsigned Opcode_AUIPC = 0x17;
7450-
constexpr unsigned Opcode_LD = 0x3003;
7451-
constexpr unsigned Opcode_JALR = 0x67;
7452-
constexpr unsigned ShiftField_RD = 7;
7453-
constexpr unsigned ShiftField_RS1 = 15;
7454-
constexpr unsigned ShiftField_IMM = 20;
7455-
constexpr unsigned Reg_X5 = 0x5; // x5/t0 (holds the address to the function)
7456-
constexpr unsigned Reg_X7 = 0x7; // x7/t2 (holds the static chain)
7457-
74587458
constexpr unsigned StaticChainOffset = 16;
74597459
constexpr unsigned FunctionAddressOffset = 24;
74607460

7461+
auto GetEncoding = [&](const MCInst &MC) {
7462+
SmallVector<char, 4> CB;
7463+
SmallVector<MCFixup> Fixups;
7464+
const MCSubtargetInfo *STI = getTargetMachine().getMCSubtargetInfo();
7465+
assert(STI);
7466+
CodeEmitter->encodeInstruction(MC, CB, Fixups, *STI);
7467+
assert(CB.size() == 4);
7468+
assert(Fixups.empty());
7469+
uint32_t Encoding = support::endian::read32le(CB.data());
7470+
return Encoding;
7471+
};
7472+
74617473
SDValue OutChains[6];
74627474
SDValue Addr = Trmp;
74637475

74647476
// auipc t2, 0
74657477
// Loads the current PC into t2.
7466-
constexpr uint32_t AUIPC_X7_0 =
7467-
Opcode_AUIPC | (Reg_X7 << ShiftField_RD);
7478+
MCInst AUIPC_X7_0_Inst =
7479+
MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0);
7480+
7481+
uint32_t AUIPC_X7_0 = GetEncoding(AUIPC_X7_0_Inst);
74687482
OutChains[0] =
74697483
DAG.getTruncStore(Root, dl, DAG.getConstant(AUIPC_X7_0, dl, MVT::i64),
74707484
Addr, MachinePointerInfo(TrmpAddr), MVT::i32);
74717485

74727486
// ld t0, 24(t2)
74737487
// Loads the function address into t0. Note that we are using offsets
74747488
// pc-relative to the first instruction of the trampoline.
7475-
const uint32_t LD_X5_TargetFunctionOffset =
7476-
Opcode_LD | (Reg_X5 << ShiftField_RD) |
7477-
(Reg_X7 << ShiftField_RS1) | (FunctionAddressOffset << ShiftField_IMM);
7489+
MCInst LD_X5_TargetFunctionOffset_Inst =
7490+
MCInstBuilder(RISCV::LD).addReg(RISCV::X5).addReg(RISCV::X7).addImm(24);
7491+
uint32_t LD_X5_TargetFunctionOffset =
7492+
GetEncoding(LD_X5_TargetFunctionOffset_Inst);
74787493
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
74797494
DAG.getConstant(4, dl, MVT::i64));
74807495
OutChains[1] = DAG.getTruncStore(
@@ -7484,9 +7499,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
74847499

74857500
// ld t2, 16(t2)
74867501
// Load the value of the static chain.
7487-
const uint32_t LD_X7_StaticChainOffset =
7488-
Opcode_LD | (Reg_X7 << ShiftField_RD) |
7489-
(Reg_X7 << ShiftField_RS1) | (StaticChainOffset << ShiftField_IMM);
7502+
MCInst LD_X7_StaticChainOffset_Inst =
7503+
MCInstBuilder(RISCV::LD).addReg(RISCV::X7).addReg(RISCV::X7).addImm(16);
7504+
uint32_t LD_X7_StaticChainOffset = GetEncoding(LD_X7_StaticChainOffset_Inst);
74907505
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
74917506
DAG.getConstant(8, dl, MVT::i64));
74927507
OutChains[2] = DAG.getTruncStore(
@@ -7495,8 +7510,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
74957510

74967511
// jalr t0
74977512
// Jump to the function.
7498-
const uint32_t JALR_X5 =
7499-
Opcode_JALR | (Reg_X5 << ShiftField_RS1);
7513+
MCInst JALR_X5_Inst =
7514+
MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(RISCV::X5).addImm(0);
7515+
uint32_t JALR_X5 = GetEncoding(JALR_X5_Inst);
75007516
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
75017517
DAG.getConstant(12, dl, MVT::i64));
75027518
OutChains[3] =

0 commit comments

Comments
 (0)