35 #include "tce_config.h"
36 #include <llvm/IR/Type.h>
37 #include <llvm/IR/Function.h>
38 #include <llvm/CodeGen/MachineInstrBuilder.h>
39 #include <llvm/CodeGen/MachineFrameInfo.h>
40 #include <llvm/CodeGen/TargetInstrInfo.h>
41 #include <llvm/Target/TargetOptions.h>
43 #include <llvm/ADT/STLExtras.h>
44 #include <llvm/CodeGen/RegisterScavenging.h>
52 #include "tce_config.h"
58 #define GET_REGINFO_MC_DESC
59 #define GET_REGINFO_TARGET_DESC
62 #include "TCEGenRegisterInfo.inc"
66 #define ADDIMM TCE::ADD64ssa
67 #define SUBIMM TCE::SUB64ssa
68 #define INTEGER_REG_CLASS TCE::R64IRegsRegClass
70 #define ADDIMM TCE::ADDrri
71 #define SUBIMM TCE::SUBrri
72 #define INTEGER_REG_CLASS TCE::R32IRegsRegClass
83 const TargetInstrInfo& tii) :
84 TCEGenRegisterInfo(TCE::
RA),
93 static const uint16_t calleeSavedRegs[] = { TCE::FP, 0 };
95 return calleeSavedRegs+1;
97 return calleeSavedRegs;
112 reserved.set(TCE::SP);
113 reserved.set(TCE::KLUDGE_REGISTER);
115 const MachineFrameInfo* mfi = &mf.getFrameInfo();
117 for (
int i = 0; i < argRegCount; i++) {
118 reserved.set(ArgRegs[i]);
123 reserved.set(TCE::FP);
130 MachineBasicBlock::iterator II,
int SPAdj,
131 unsigned FIOperandNum,
132 RegScavenger *RS)
const {
134 MachineInstr &MI = *II;
137 MI.getParent()->getParent()->getTarget());
141 && osalOpName.find(
"MOVE") == std::string::npos) {
143 "Error: Stack address space is not reachable with operation '"
145 +
"Forgot to add the operation to the stack LSU?");
147 static int lastBypassReg = 0;
149 assert(SPAdj == 0 &&
"Unexpected");
151 DebugLoc dl = MI.getDebugLoc();
152 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
155 MachineFunction &MF = *MI.getParent()->getParent();
157 auto& frameinfo = MF.getFrameInfo();
159 if (frameinfo.isSpillSlotObjectIndex(FrameIndex)) {
160 for (MachineInstr::mmo_iterator i = MI.memoperands_begin();
161 i != MI.memoperands_end(); i++) {
162 const PseudoSourceValue* psv = (*i)->getPseudoValue();
164 #ifdef LLVM_OLDER_THAN_15
165 (*i)->setValue(
new FixedStackPseudoSourceValue(FrameIndex, TII));
167 (*i)->setValue(
new FixedStackPseudoSourceValue(FrameIndex, tm));
171 if (MI.memoperands_begin() == MI.memoperands_end()) {
173 auto flags =
static_cast<MachineMemOperand::Flags
>(
174 MI.mayLoad() * MachineMemOperand::MOLoad
175 | MI.mayStore() * MachineMemOperand::MOStore);
176 auto mmo =
new MachineMemOperand(
178 #ifdef LLVM_OLDER_THAN_15
179 mmo->setValue(
new FixedStackPseudoSourceValue(FrameIndex, TII));
181 mmo->setValue(
new FixedStackPseudoSourceValue(FrameIndex, tm));
183 MI.addMemOperand(MF, mmo);
188 int Offset = frameinfo.getObjectOffset(FrameIndex);
193 if (FrameIndex < 0 && frameinfo.hasCalls()
209 if (originalOp ==
"LDW" || originalOp ==
"LDHU" ||
210 originalOp ==
"LDH" || originalOp ==
"LDQU" ||
211 originalOp ==
"LDQ" || originalOp ==
"STW" ||
212 originalOp ==
"STH" || originalOp ==
"STQ" ||
213 originalOp ==
"LD32" || originalOp ==
"LDU16" ||
214 originalOp ==
"LD16" || originalOp ==
"LDU8" ||
215 originalOp ==
"LD8" || originalOp ==
"ST32" ||
216 originalOp ==
"ST16" || originalOp ==
"ST8") {
217 baseOffsetOp =
TCEString(
"A") + originalOp;
219 if (baseOffsetOp !=
"" && tm.
hasOperation(baseOffsetOp)) {
220 const bool isStore = MI.getDesc().mayStore();
221 unsigned storeDataReg = 0;
222 uint64_t storeDataImm = 0;
228 int storeDataOp = FIOperandNum + 2;
229 if (MI.getOperand(storeDataOp).isReg()) {
230 storeDataReg = MI.getOperand(storeDataOp).getReg();
232 assert(MI.getOperand(storeDataOp).isImm());
233 storeDataImm = MI.getOperand(storeDataOp).getImm();
237 MI.setDesc(TII.get(tm.
opcode(baseOffsetOp)));
240 MI.getOperand(FIOperandNum).ChangeToRegister(TCE::FP,
false);
241 MI.getOperand(FIOperandNum + 1).setImm(Offset);
247 MI.getOperand(FIOperandNum + 2).ChangeToRegister(
248 storeDataReg,
false);
250 MI.getOperand(FIOperandNum + 2).ChangeToImmediate(
255 MI.getOperand(FIOperandNum).ChangeToRegister(
256 TCE::KLUDGE_REGISTER,
false,
false,
true);
260 *MI.getParent(), II, MI.getDebugLoc(),
261 TII.get(
ADDIMM), TCE::KLUDGE_REGISTER)
262 .addReg(TCE::FP).addImm(Offset);
266 *MI.getParent(), II, MI.getDebugLoc(),
267 TII.get(std::get<0>(spOpcAndOffset)),
268 TCE::KLUDGE_REGISTER)
270 .addImm(std::get<1>(spOpcAndOffset));
274 MI.getOperand(FIOperandNum).ChangeToRegister(TCE::FP,
false);
277 int Offset = frameinfo.getObjectOffset(FrameIndex) +
278 frameinfo.getStackSize();
281 MI.getOperand(FIOperandNum).ChangeToRegister(TCE::SP,
false);
291 MI.getParent()->getParent()->getTarget());
298 if (originalOp ==
"LDW" || originalOp ==
"LDHU" ||
299 originalOp ==
"LDH" || originalOp ==
"LDQU" ||
300 originalOp ==
"LDQ" || originalOp ==
"STW" ||
301 originalOp ==
"STH" || originalOp ==
"STQ" ||
302 originalOp ==
"LD32" || originalOp ==
"LDU16" ||
303 originalOp ==
"LD16" || originalOp ==
"LDU8" ||
304 originalOp ==
"LD8" || originalOp ==
"ST32" ||
305 originalOp ==
"ST16" || originalOp ==
"ST8") {
306 baseOffsetOp =
TCEString(
"A") + originalOp;
308 if (baseOffsetOp !=
"" && tm.
hasOperation(baseOffsetOp)) {
309 const bool isStore = MI.getDesc().mayStore();
310 unsigned storeDataReg = 0;
311 uint64_t storeDataImm = 0;
317 int storeDataOp = FIOperandNum + 2;
318 if (MI.getOperand(storeDataOp).isReg()) {
319 storeDataReg = MI.getOperand(storeDataOp).getReg();
321 assert(MI.getOperand(storeDataOp).isImm());
322 storeDataImm = MI.getOperand(storeDataOp).getImm();
326 MI.setDesc(TII.get(tm.
opcode(baseOffsetOp)));
329 MI.getOperand(FIOperandNum).ChangeToRegister(TCE::SP,
false);
330 MI.getOperand(FIOperandNum + 1).setImm(Offset);
336 MI.getOperand(FIOperandNum + 2).ChangeToRegister(
337 storeDataReg,
false);
339 MI.getOperand(FIOperandNum + 2).ChangeToImmediate(
345 unsigned int tmp = 0;
355 MI.getOperand(FIOperandNum).ChangeToRegister(
356 tmp,
false,
false,
true);
358 *MI.getParent(), II, MI.getDebugLoc(), TII.get(
ADDIMM),
359 tmp).addReg(TCE::SP).addImm(Offset);
361 MI.getOperand(FIOperandNum).ChangeToRegister(
362 TCE::KLUDGE_REGISTER,
false);
364 *MI.getParent(), II, MI.getDebugLoc(), TII.get(
ADDIMM),
365 TCE::KLUDGE_REGISTER).addReg(TCE::SP).addImm(Offset);
399 assert(
false &&
"Remove this assert if this is really called.");