Skip to content

Commit dc3990c

Browse files
committed
Use MCCodeEmitter to encode instructions rather than hardcoded constants
1 parent 1e5b136 commit dc3990c

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"
@@ -7293,6 +7295,14 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
72937295
if (!Subtarget.is64Bit())
72947296
llvm::report_fatal_error("Trampolines only implemented for RV64");
72957297

7298+
// Create an MCCodeEmitter to encode instructions.
7299+
TargetLoweringObjectFile *TLO = getTargetMachine().getObjFileLowering();
7300+
assert(TLO);
7301+
MCContext& MCCtx = TLO->getContext();
7302+
7303+
std::unique_ptr<MCCodeEmitter> CodeEmitter(
7304+
createRISCVMCCodeEmitter(*getTargetMachine().getMCInstrInfo(), MCCtx));
7305+
72967306
SDValue Root = Op.getOperand(0);
72977307
SDValue Trmp = Op.getOperand(1); // trampoline
72987308
SDLoc dl(Op);
@@ -7309,36 +7319,41 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
73097319
// 24: <FunctionAddressOffset>
73107320
// 32:
73117321

7312-
// Constants shamelessly taken from GCC.
7313-
constexpr unsigned Opcode_AUIPC = 0x17;
7314-
constexpr unsigned Opcode_LD = 0x3003;
7315-
constexpr unsigned Opcode_JALR = 0x67;
7316-
constexpr unsigned ShiftField_RD = 7;
7317-
constexpr unsigned ShiftField_RS1 = 15;
7318-
constexpr unsigned ShiftField_IMM = 20;
7319-
constexpr unsigned Reg_X5 = 0x5; // x5/t0 (holds the address to the function)
7320-
constexpr unsigned Reg_X7 = 0x7; // x7/t2 (holds the static chain)
7321-
73227322
constexpr unsigned StaticChainOffset = 16;
73237323
constexpr unsigned FunctionAddressOffset = 24;
73247324

7325+
auto GetEncoding = [&](const MCInst &MC) {
7326+
SmallVector<char, 4> CB;
7327+
SmallVector<MCFixup> Fixups;
7328+
const MCSubtargetInfo *STI = getTargetMachine().getMCSubtargetInfo();
7329+
assert(STI);
7330+
CodeEmitter->encodeInstruction(MC, CB, Fixups, *STI);
7331+
assert(CB.size() == 4);
7332+
assert(Fixups.empty());
7333+
uint32_t Encoding = support::endian::read32le(CB.data());
7334+
return Encoding;
7335+
};
7336+
73257337
SDValue OutChains[6];
73267338
SDValue Addr = Trmp;
73277339

73287340
// auipc t2, 0
73297341
// Loads the current PC into t2.
7330-
constexpr uint32_t AUIPC_X7_0 =
7331-
Opcode_AUIPC | (Reg_X7 << ShiftField_RD);
7342+
MCInst AUIPC_X7_0_Inst =
7343+
MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0);
7344+
7345+
uint32_t AUIPC_X7_0 = GetEncoding(AUIPC_X7_0_Inst);
73327346
OutChains[0] =
73337347
DAG.getTruncStore(Root, dl, DAG.getConstant(AUIPC_X7_0, dl, MVT::i64),
73347348
Addr, MachinePointerInfo(TrmpAddr), MVT::i32);
73357349

73367350
// ld t0, 24(t2)
73377351
// Loads the function address into t0. Note that we are using offsets
73387352
// pc-relative to the first instruction of the trampoline.
7339-
const uint32_t LD_X5_TargetFunctionOffset =
7340-
Opcode_LD | (Reg_X5 << ShiftField_RD) |
7341-
(Reg_X7 << ShiftField_RS1) | (FunctionAddressOffset << ShiftField_IMM);
7353+
MCInst LD_X5_TargetFunctionOffset_Inst =
7354+
MCInstBuilder(RISCV::LD).addReg(RISCV::X5).addReg(RISCV::X7).addImm(24);
7355+
uint32_t LD_X5_TargetFunctionOffset =
7356+
GetEncoding(LD_X5_TargetFunctionOffset_Inst);
73427357
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
73437358
DAG.getConstant(4, dl, MVT::i64));
73447359
OutChains[1] = DAG.getTruncStore(
@@ -7348,9 +7363,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
73487363

73497364
// ld t2, 16(t2)
73507365
// Load the value of the static chain.
7351-
const uint32_t LD_X7_StaticChainOffset =
7352-
Opcode_LD | (Reg_X7 << ShiftField_RD) |
7353-
(Reg_X7 << ShiftField_RS1) | (StaticChainOffset << ShiftField_IMM);
7366+
MCInst LD_X7_StaticChainOffset_Inst =
7367+
MCInstBuilder(RISCV::LD).addReg(RISCV::X7).addReg(RISCV::X7).addImm(16);
7368+
uint32_t LD_X7_StaticChainOffset = GetEncoding(LD_X7_StaticChainOffset_Inst);
73547369
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
73557370
DAG.getConstant(8, dl, MVT::i64));
73567371
OutChains[2] = DAG.getTruncStore(
@@ -7359,8 +7374,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
73597374

73607375
// jalr t0
73617376
// Jump to the function.
7362-
const uint32_t JALR_X5 =
7363-
Opcode_JALR | (Reg_X5 << ShiftField_RS1);
7377+
MCInst JALR_X5_Inst =
7378+
MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(RISCV::X5).addImm(0);
7379+
uint32_t JALR_X5 = GetEncoding(JALR_X5_Inst);
73647380
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
73657381
DAG.getConstant(12, dl, MVT::i64));
73667382
OutChains[3] =

0 commit comments

Comments
 (0)