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