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