1 //===-- Target.cpp ----------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 // The PowerPC ExegesisTarget.
8 //===----------------------------------------------------------------------===//
11 #include "PPCRegisterInfo.h"
16 // Helper to fill a memory operand with a value.
17 static void setMemOp(InstructionTemplate
&IT
, int OpIdx
,
18 const MCOperand
&OpVal
) {
19 const auto Op
= IT
.getInstr().Operands
[OpIdx
];
20 assert(Op
.isExplicit() && "invalid memory pattern");
21 IT
.getValueFor(Op
) = OpVal
;
24 #include "PPCGenExegesis.inc"
27 class ExegesisPowerPCTarget
: public ExegesisTarget
{
29 ExegesisPowerPCTarget() : ExegesisTarget(PPCCpuPfmCounters
) {}
32 std::vector
<MCInst
> setRegTo(const MCSubtargetInfo
&STI
, unsigned Reg
,
33 const APInt
&Value
) const override
;
34 bool matchesArch(Triple::ArchType Arch
) const override
{
35 return Arch
== Triple::ppc64le
;
37 unsigned getScratchMemoryRegister(const Triple
&) const override
;
38 void fillMemoryOperands(InstructionTemplate
&IT
, unsigned Reg
,
39 unsigned Offset
) const override
;
41 } // end anonymous namespace
43 static unsigned getLoadImmediateOpcode(unsigned RegBitWidth
) {
44 switch (RegBitWidth
) {
50 llvm_unreachable("Invalid Value Width");
53 // Generates instruction to load an immediate value into a register.
54 static MCInst
loadImmediate(unsigned Reg
, unsigned RegBitWidth
,
56 if (Value
.getBitWidth() > RegBitWidth
)
57 llvm_unreachable("Value must fit in the Register");
58 // We don't really care the value in reg, ignore the 16 bit
59 // restriction for now.
60 // TODO: make sure we get the exact value in reg if needed.
61 return MCInstBuilder(getLoadImmediateOpcode(RegBitWidth
))
63 .addImm(Value
.getZExtValue());
67 ExegesisPowerPCTarget::getScratchMemoryRegister(const Triple
&TT
) const {
68 // R13 is reserved as Thread Pointer, we won't use threading in benchmark, so
69 // use it as scratch memory register
70 return TT
.isArch64Bit() ? PPC::X13
: PPC::R13
;
73 void ExegesisPowerPCTarget::fillMemoryOperands(InstructionTemplate
&IT
,
75 unsigned Offset
) const {
77 if (IT
.getInstr().hasTiedRegisters())
79 int DispOpIdx
= MemOpIdx
+ 1;
80 const auto DispOp
= IT
.getInstr().Operands
[DispOpIdx
];
82 // We don't really care about the real address in snippets,
83 // So hardcode X1 for X-form Memory Operations for simplicity.
84 // TODO: materialize the offset into a reggister
85 setMemOp(IT
, DispOpIdx
, MCOperand::createReg(PPC::X1
));
87 setMemOp(IT
, DispOpIdx
, MCOperand::createImm(Offset
)); // Disp
88 setMemOp(IT
, MemOpIdx
+ 2, MCOperand::createReg(Reg
)); // BaseReg
91 std::vector
<MCInst
> ExegesisPowerPCTarget::setRegTo(const MCSubtargetInfo
&STI
,
93 const APInt
&Value
) const {
94 // X11 is optional use in function linkage, should be the least used one
95 // Use it as scratch reg to load immediate.
96 unsigned ScratchImmReg
= PPC::X11
;
98 if (PPC::GPRCRegClass
.contains(Reg
))
99 return {loadImmediate(Reg
, 32, Value
)};
100 if (PPC::G8RCRegClass
.contains(Reg
))
101 return {loadImmediate(Reg
, 64, Value
)};
102 if (PPC::F4RCRegClass
.contains(Reg
))
103 return {loadImmediate(ScratchImmReg
, 64, Value
),
104 MCInstBuilder(PPC::MTVSRD
).addReg(Reg
).addReg(ScratchImmReg
)};
105 // We don't care the real value in reg, so set 64 bits or duplicate 64 bits
107 // TODO: update these if we need a accurate 128 values in registers.
108 if (PPC::VRRCRegClass
.contains(Reg
))
109 return {loadImmediate(ScratchImmReg
, 64, Value
),
110 MCInstBuilder(PPC::MTVRD
).addReg(Reg
).addReg(ScratchImmReg
)};
111 if (PPC::VSRCRegClass
.contains(Reg
))
112 return {loadImmediate(ScratchImmReg
, 64, Value
),
113 MCInstBuilder(PPC::MTVSRDD
)
115 .addReg(ScratchImmReg
)
116 .addReg(ScratchImmReg
)};
117 if (PPC::VFRCRegClass
.contains(Reg
))
118 return {loadImmediate(ScratchImmReg
, 64, Value
),
119 MCInstBuilder(PPC::MTVSRD
).addReg(Reg
).addReg(ScratchImmReg
)};
120 // SPE not supported yet
121 if (PPC::SPERCRegClass
.contains(Reg
)) {
122 errs() << "Unsupported SPE Reg:" << Reg
<< "\n";
125 errs() << "setRegTo is not implemented, results will be unreliable:" << Reg
130 static ExegesisTarget
*getTheExegesisPowerPCTarget() {
131 static ExegesisPowerPCTarget Target
;
135 void InitializePowerPCExegesisTarget() {
136 ExegesisTarget::registerTarget(getTheExegesisPowerPCTarget());
139 } // namespace exegesis