Skip to content

Commit ebaf74f

Browse files
committed
Use MCCodeEmitter to encode instructions rather than hardcoded constants
1 parent cbc0aa2 commit ebaf74f

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

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

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

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

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

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

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

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

0 commit comments

Comments
 (0)