37
37
#include "llvm/IR/Instructions.h"
38
38
#include "llvm/IR/IntrinsicsRISCV.h"
39
39
#include "llvm/IR/PatternMatch.h"
40
+ #include "llvm/MC/MCCodeEmitter.h"
41
+ #include "llvm/MC/MCInstBuilder.h"
40
42
#include "llvm/Support/CommandLine.h"
41
43
#include "llvm/Support/Debug.h"
42
44
#include "llvm/Support/ErrorHandling.h"
@@ -7293,6 +7295,14 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
7293
7295
if (!Subtarget.is64Bit())
7294
7296
llvm::report_fatal_error("Trampolines only implemented for RV64");
7295
7297
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
+
7296
7306
SDValue Root = Op.getOperand(0);
7297
7307
SDValue Trmp = Op.getOperand(1); // trampoline
7298
7308
SDLoc dl(Op);
@@ -7309,36 +7319,41 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
7309
7319
// 24: <FunctionAddressOffset>
7310
7320
// 32:
7311
7321
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
-
7322
7322
constexpr unsigned StaticChainOffset = 16;
7323
7323
constexpr unsigned FunctionAddressOffset = 24;
7324
7324
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
+
7325
7337
SDValue OutChains[6];
7326
7338
SDValue Addr = Trmp;
7327
7339
7328
7340
// auipc t2, 0
7329
7341
// 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);
7332
7346
OutChains[0] =
7333
7347
DAG.getTruncStore(Root, dl, DAG.getConstant(AUIPC_X7_0, dl, MVT::i64),
7334
7348
Addr, MachinePointerInfo(TrmpAddr), MVT::i32);
7335
7349
7336
7350
// ld t0, 24(t2)
7337
7351
// Loads the function address into t0. Note that we are using offsets
7338
7352
// 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);
7342
7357
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
7343
7358
DAG.getConstant(4, dl, MVT::i64));
7344
7359
OutChains[1] = DAG.getTruncStore(
@@ -7348,9 +7363,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
7348
7363
7349
7364
// ld t2, 16(t2)
7350
7365
// 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 );
7354
7369
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
7355
7370
DAG.getConstant(8, dl, MVT::i64));
7356
7371
OutChains[2] = DAG.getTruncStore(
@@ -7359,8 +7374,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
7359
7374
7360
7375
// jalr t0
7361
7376
// 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);
7364
7380
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
7365
7381
DAG.getConstant(12, dl, MVT::i64));
7366
7382
OutChains[3] =
0 commit comments