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"
@@ -7292,6 +7294,14 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
7292
7294
if (!Subtarget.is64Bit())
7293
7295
llvm::report_fatal_error("Trampolines only implemented for RV64");
7294
7296
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
+
7295
7305
SDValue Root = Op.getOperand(0);
7296
7306
SDValue Trmp = Op.getOperand(1); // trampoline
7297
7307
SDLoc dl(Op);
@@ -7308,36 +7318,41 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
7308
7318
// 24: <FunctionAddressOffset>
7309
7319
// 32:
7310
7320
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
-
7321
7321
constexpr unsigned StaticChainOffset = 16;
7322
7322
constexpr unsigned FunctionAddressOffset = 24;
7323
7323
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
+
7324
7336
SDValue OutChains[6];
7325
7337
SDValue Addr = Trmp;
7326
7338
7327
7339
// auipc t2, 0
7328
7340
// 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);
7331
7345
OutChains[0] =
7332
7346
DAG.getTruncStore(Root, dl, DAG.getConstant(AUIPC_X7_0, dl, MVT::i64),
7333
7347
Addr, MachinePointerInfo(TrmpAddr), MVT::i32);
7334
7348
7335
7349
// ld t0, 24(t2)
7336
7350
// Loads the function address into t0. Note that we are using offsets
7337
7351
// 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);
7341
7356
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
7342
7357
DAG.getConstant(4, dl, MVT::i64));
7343
7358
OutChains[1] = DAG.getTruncStore(
@@ -7347,9 +7362,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
7347
7362
7348
7363
// ld t2, 16(t2)
7349
7364
// 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 );
7353
7368
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
7354
7369
DAG.getConstant(8, dl, MVT::i64));
7355
7370
OutChains[2] = DAG.getTruncStore(
@@ -7358,8 +7373,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
7358
7373
7359
7374
// jalr t0
7360
7375
// 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);
7363
7379
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
7364
7380
DAG.getConstant(12, dl, MVT::i64));
7365
7381
OutChains[3] =
0 commit comments