1 //===- BlackfinRegisterInfo.cpp - Blackfin Register Information -*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the Blackfin implementation of the TargetRegisterInfo 11 // class. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "Blackfin.h" 16 #include "BlackfinRegisterInfo.h" 17 #include "BlackfinSubtarget.h" 18 #include "llvm/Support/Debug.h" 19 #include "llvm/Support/ErrorHandling.h" 20 #include "llvm/CodeGen/MachineInstrBuilder.h" 21 #include "llvm/CodeGen/MachineFunction.h" 22 #include "llvm/CodeGen/MachineFrameInfo.h" 23 #include "llvm/CodeGen/RegisterScavenging.h" 24 #include "llvm/Target/TargetFrameLowering.h" 25 #include "llvm/Target/TargetMachine.h" 26 #include "llvm/Target/TargetOptions.h" 27 #include "llvm/Target/TargetInstrInfo.h" 28 #include "llvm/Type.h" 29 #include "llvm/ADT/BitVector.h" 30 #include "llvm/ADT/STLExtras.h" 31 32 #define GET_REGINFO_TARGET_DESC 33 #include "BlackfinGenRegisterInfo.inc" 34 35 using namespace llvm; 36 37 BlackfinRegisterInfo::BlackfinRegisterInfo(BlackfinSubtarget &st, 38 const TargetInstrInfo &tii) 39 : BlackfinGenRegisterInfo(BF::RETS), Subtarget(st), TII(tii) {} 40 41 const unsigned* 42 BlackfinRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 43 using namespace BF; 44 static const unsigned CalleeSavedRegs[] = { 45 FP, 46 R4, R5, R6, R7, 47 P3, P4, P5, 48 0 }; 49 return CalleeSavedRegs; 50 } 51 52 BitVector 53 BlackfinRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 54 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 55 56 using namespace BF; 57 BitVector Reserved(getNumRegs()); 58 Reserved.set(AZ); 59 Reserved.set(AN); 60 Reserved.set(AQ); 61 Reserved.set(AC0); 62 Reserved.set(AC1); 63 Reserved.set(AV0); 64 Reserved.set(AV0S); 65 Reserved.set(AV1); 66 Reserved.set(AV1S); 67 Reserved.set(V); 68 Reserved.set(VS); 69 Reserved.set(CYCLES).set(CYCLES2); 70 Reserved.set(L0); 71 Reserved.set(L1); 72 Reserved.set(L2); 73 Reserved.set(L3); 74 Reserved.set(SP); 75 Reserved.set(RETS); 76 if (TFI->hasFP(MF)) 77 Reserved.set(FP); 78 return Reserved; 79 } 80 81 bool BlackfinRegisterInfo:: 82 requiresRegisterScavenging(const MachineFunction &MF) const { 83 return true; 84 } 85 86 // Emit instructions to add delta to D/P register. ScratchReg must be of the 87 // same class as Reg (P). 88 void BlackfinRegisterInfo::adjustRegister(MachineBasicBlock &MBB, 89 MachineBasicBlock::iterator I, 90 DebugLoc DL, 91 unsigned Reg, 92 unsigned ScratchReg, 93 int delta) const { 94 if (!delta) 95 return; 96 if (isInt<7>(delta)) { 97 BuildMI(MBB, I, DL, TII.get(BF::ADDpp_imm7), Reg) 98 .addReg(Reg) // No kill on two-addr operand 99 .addImm(delta); 100 return; 101 } 102 103 // We must load delta into ScratchReg and add that. 104 loadConstant(MBB, I, DL, ScratchReg, delta); 105 if (BF::PRegClass.contains(Reg)) { 106 assert(BF::PRegClass.contains(ScratchReg) && 107 "ScratchReg must be a P register"); 108 BuildMI(MBB, I, DL, TII.get(BF::ADDpp), Reg) 109 .addReg(Reg, RegState::Kill) 110 .addReg(ScratchReg, RegState::Kill); 111 } else { 112 assert(BF::DRegClass.contains(Reg) && "Reg must be a D or P register"); 113 assert(BF::DRegClass.contains(ScratchReg) && 114 "ScratchReg must be a D register"); 115 BuildMI(MBB, I, DL, TII.get(BF::ADD), Reg) 116 .addReg(Reg, RegState::Kill) 117 .addReg(ScratchReg, RegState::Kill); 118 } 119 } 120 121 // Emit instructions to load a constant into D/P register 122 void BlackfinRegisterInfo::loadConstant(MachineBasicBlock &MBB, 123 MachineBasicBlock::iterator I, 124 DebugLoc DL, 125 unsigned Reg, 126 int value) const { 127 if (isInt<7>(value)) { 128 BuildMI(MBB, I, DL, TII.get(BF::LOADimm7), Reg).addImm(value); 129 return; 130 } 131 132 if (isUInt<16>(value)) { 133 BuildMI(MBB, I, DL, TII.get(BF::LOADuimm16), Reg).addImm(value); 134 return; 135 } 136 137 if (isInt<16>(value)) { 138 BuildMI(MBB, I, DL, TII.get(BF::LOADimm16), Reg).addImm(value); 139 return; 140 } 141 142 // We must split into halves 143 BuildMI(MBB, I, DL, 144 TII.get(BF::LOAD16i), getSubReg(Reg, BF::hi16)) 145 .addImm((value >> 16) & 0xffff) 146 .addReg(Reg, RegState::ImplicitDefine); 147 BuildMI(MBB, I, DL, 148 TII.get(BF::LOAD16i), getSubReg(Reg, BF::lo16)) 149 .addImm(value & 0xffff) 150 .addReg(Reg, RegState::ImplicitKill) 151 .addReg(Reg, RegState::ImplicitDefine); 152 } 153 154 void BlackfinRegisterInfo:: 155 eliminateCallFramePseudoInstr(MachineFunction &MF, 156 MachineBasicBlock &MBB, 157 MachineBasicBlock::iterator I) const { 158 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 159 160 if (!TFI->hasReservedCallFrame(MF)) { 161 int64_t Amount = I->getOperand(0).getImm(); 162 if (Amount != 0) { 163 assert(Amount%4 == 0 && "Unaligned call frame size"); 164 if (I->getOpcode() == BF::ADJCALLSTACKDOWN) { 165 adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, -Amount); 166 } else { 167 assert(I->getOpcode() == BF::ADJCALLSTACKUP && 168 "Unknown call frame pseudo instruction"); 169 adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, Amount); 170 } 171 } 172 } 173 MBB.erase(I); 174 } 175 176 /// findScratchRegister - Find a 'free' register. Try for a call-clobbered 177 /// register first and then a spilled callee-saved register if that fails. 178 static unsigned findScratchRegister(MachineBasicBlock::iterator II, 179 RegScavenger *RS, 180 const TargetRegisterClass *RC, 181 int SPAdj) { 182 assert(RS && "Register scavenging must be on"); 183 unsigned Reg = RS->FindUnusedReg(RC); 184 if (Reg == 0) 185 Reg = RS->scavengeRegister(RC, II, SPAdj); 186 return Reg; 187 } 188 189 void 190 BlackfinRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 191 int SPAdj, RegScavenger *RS) const { 192 MachineInstr &MI = *II; 193 MachineBasicBlock &MBB = *MI.getParent(); 194 MachineFunction &MF = *MBB.getParent(); 195 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 196 DebugLoc DL = MI.getDebugLoc(); 197 198 unsigned FIPos; 199 for (FIPos=0; !MI.getOperand(FIPos).isFI(); ++FIPos) { 200 assert(FIPos < MI.getNumOperands() && 201 "Instr doesn't have FrameIndex operand!"); 202 } 203 int FrameIndex = MI.getOperand(FIPos).getIndex(); 204 assert(FIPos+1 < MI.getNumOperands() && MI.getOperand(FIPos+1).isImm()); 205 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) 206 + MI.getOperand(FIPos+1).getImm(); 207 unsigned BaseReg = BF::FP; 208 if (TFI->hasFP(MF)) { 209 assert(SPAdj==0 && "Unexpected SP adjust in function with frame pointer"); 210 } else { 211 BaseReg = BF::SP; 212 Offset += MF.getFrameInfo()->getStackSize() + SPAdj; 213 } 214 215 bool isStore = false; 216 217 switch (MI.getOpcode()) { 218 case BF::STORE32fi: 219 isStore = true; 220 case BF::LOAD32fi: { 221 assert(Offset%4 == 0 && "Unaligned i32 stack access"); 222 assert(FIPos==1 && "Bad frame index operand"); 223 MI.getOperand(FIPos).ChangeToRegister(BaseReg, false); 224 MI.getOperand(FIPos+1).setImm(Offset); 225 if (isUInt<6>(Offset)) { 226 MI.setDesc(TII.get(isStore 227 ? BF::STORE32p_uimm6m4 228 : BF::LOAD32p_uimm6m4)); 229 return; 230 } 231 if (BaseReg == BF::FP && isUInt<7>(-Offset)) { 232 MI.setDesc(TII.get(isStore 233 ? BF::STORE32fp_nimm7m4 234 : BF::LOAD32fp_nimm7m4)); 235 MI.getOperand(FIPos+1).setImm(-Offset); 236 return; 237 } 238 if (isInt<18>(Offset)) { 239 MI.setDesc(TII.get(isStore 240 ? BF::STORE32p_imm18m4 241 : BF::LOAD32p_imm18m4)); 242 return; 243 } 244 // Use RegScavenger to calculate proper offset... 245 MI.dump(); 246 llvm_unreachable("Stack frame offset too big"); 247 break; 248 } 249 case BF::ADDpp: { 250 assert(MI.getOperand(0).isReg() && "ADD instruction needs a register"); 251 unsigned DestReg = MI.getOperand(0).getReg(); 252 // We need to produce a stack offset in a P register. We emit: 253 // P0 = offset; 254 // P0 = BR + P0; 255 assert(FIPos==1 && "Bad frame index operand"); 256 loadConstant(MBB, II, DL, DestReg, Offset); 257 MI.getOperand(1).ChangeToRegister(DestReg, false, false, true); 258 MI.getOperand(2).ChangeToRegister(BaseReg, false); 259 break; 260 } 261 case BF::STORE16fi: 262 isStore = true; 263 case BF::LOAD16fi: { 264 assert(Offset%2 == 0 && "Unaligned i16 stack access"); 265 assert(FIPos==1 && "Bad frame index operand"); 266 // We need a P register to use as an address 267 unsigned ScratchReg = findScratchRegister(II, RS, &BF::PRegClass, SPAdj); 268 assert(ScratchReg && "Could not scavenge register"); 269 loadConstant(MBB, II, DL, ScratchReg, Offset); 270 BuildMI(MBB, II, DL, TII.get(BF::ADDpp), ScratchReg) 271 .addReg(ScratchReg, RegState::Kill) 272 .addReg(BaseReg); 273 MI.setDesc(TII.get(isStore ? BF::STORE16pi : BF::LOAD16pi)); 274 MI.getOperand(1).ChangeToRegister(ScratchReg, false, false, true); 275 MI.RemoveOperand(2); 276 break; 277 } 278 case BF::STORE8fi: { 279 // This is an AnyCC spill, we need a scratch register. 280 assert(FIPos==1 && "Bad frame index operand"); 281 MachineOperand SpillReg = MI.getOperand(0); 282 unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj); 283 assert(ScratchReg && "Could not scavenge register"); 284 if (SpillReg.getReg()==BF::NCC) { 285 BuildMI(MBB, II, DL, TII.get(BF::MOVENCC_z), ScratchReg) 286 .addOperand(SpillReg); 287 BuildMI(MBB, II, DL, TII.get(BF::BITTGL), ScratchReg) 288 .addReg(ScratchReg).addImm(0); 289 } else { 290 BuildMI(MBB, II, DL, TII.get(BF::MOVECC_zext), ScratchReg) 291 .addOperand(SpillReg); 292 } 293 // STORE D 294 MI.setDesc(TII.get(BF::STORE8p_imm16)); 295 MI.getOperand(0).ChangeToRegister(ScratchReg, false, false, true); 296 MI.getOperand(FIPos).ChangeToRegister(BaseReg, false); 297 MI.getOperand(FIPos+1).setImm(Offset); 298 break; 299 } 300 case BF::LOAD8fi: { 301 // This is an restore, we need a scratch register. 302 assert(FIPos==1 && "Bad frame index operand"); 303 MachineOperand SpillReg = MI.getOperand(0); 304 unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj); 305 assert(ScratchReg && "Could not scavenge register"); 306 MI.setDesc(TII.get(BF::LOAD32p_imm16_8z)); 307 MI.getOperand(0).ChangeToRegister(ScratchReg, true); 308 MI.getOperand(FIPos).ChangeToRegister(BaseReg, false); 309 MI.getOperand(FIPos+1).setImm(Offset); 310 ++II; 311 if (SpillReg.getReg()==BF::CC) { 312 // CC = D 313 BuildMI(MBB, II, DL, TII.get(BF::MOVECC_nz), BF::CC) 314 .addReg(ScratchReg, RegState::Kill); 315 } else { 316 // Restore NCC (CC = D==0) 317 BuildMI(MBB, II, DL, TII.get(BF::SETEQri_not), BF::NCC) 318 .addReg(ScratchReg, RegState::Kill) 319 .addImm(0); 320 } 321 break; 322 } 323 default: 324 llvm_unreachable("Cannot eliminate frame index"); 325 break; 326 } 327 } 328 329 unsigned 330 BlackfinRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 331 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 332 333 return TFI->hasFP(MF) ? BF::FP : BF::SP; 334 } 335 336 unsigned BlackfinRegisterInfo::getEHExceptionRegister() const { 337 llvm_unreachable("What is the exception register"); 338 return 0; 339 } 340 341 unsigned BlackfinRegisterInfo::getEHHandlerRegister() const { 342 llvm_unreachable("What is the exception handler register"); 343 return 0; 344 } 345