1 //===-- CSKYInstrInfo.h - CSKY Instruction Information --------*- C++ -*---===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the CSKY implementation of the TargetInstrInfo class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "CSKYInstrInfo.h" 14 #include "CSKYConstantPoolValue.h" 15 #include "CSKYMachineFunctionInfo.h" 16 #include "CSKYTargetMachine.h" 17 #include "llvm/MC/MCContext.h" 18 19 #define DEBUG_TYPE "csky-instr-info" 20 21 using namespace llvm; 22 23 #define GET_INSTRINFO_CTOR_DTOR 24 #include "CSKYGenInstrInfo.inc" 25 26 CSKYInstrInfo::CSKYInstrInfo(CSKYSubtarget &STI) 27 : CSKYGenInstrInfo(CSKY::ADJCALLSTACKDOWN, CSKY::ADJCALLSTACKUP), STI(STI) { 28 v2sf = STI.hasFPUv2SingleFloat(); 29 v2df = STI.hasFPUv2DoubleFloat(); 30 v3sf = STI.hasFPUv3SingleFloat(); 31 v3df = STI.hasFPUv3DoubleFloat(); 32 } 33 34 static void parseCondBranch(MachineInstr &LastInst, MachineBasicBlock *&Target, 35 SmallVectorImpl<MachineOperand> &Cond) { 36 // Block ends with fall-through condbranch. 37 assert(LastInst.getDesc().isConditionalBranch() && 38 "Unknown conditional branch"); 39 Target = LastInst.getOperand(1).getMBB(); 40 Cond.push_back(MachineOperand::CreateImm(LastInst.getOpcode())); 41 Cond.push_back(LastInst.getOperand(0)); 42 } 43 44 bool CSKYInstrInfo::analyzeBranch(MachineBasicBlock &MBB, 45 MachineBasicBlock *&TBB, 46 MachineBasicBlock *&FBB, 47 SmallVectorImpl<MachineOperand> &Cond, 48 bool AllowModify) const { 49 TBB = FBB = nullptr; 50 Cond.clear(); 51 52 // If the block has no terminators, it just falls into the block after it. 53 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); 54 if (I == MBB.end() || !isUnpredicatedTerminator(*I)) 55 return false; 56 57 // Count the number of terminators and find the first unconditional or 58 // indirect branch. 59 MachineBasicBlock::iterator FirstUncondOrIndirectBr = MBB.end(); 60 int NumTerminators = 0; 61 for (auto J = I.getReverse(); J != MBB.rend() && isUnpredicatedTerminator(*J); 62 J++) { 63 NumTerminators++; 64 if (J->getDesc().isUnconditionalBranch() || 65 J->getDesc().isIndirectBranch()) { 66 FirstUncondOrIndirectBr = J.getReverse(); 67 } 68 } 69 70 // If AllowModify is true, we can erase any terminators after 71 // FirstUncondOrIndirectBR. 72 if (AllowModify && FirstUncondOrIndirectBr != MBB.end()) { 73 while (std::next(FirstUncondOrIndirectBr) != MBB.end()) { 74 std::next(FirstUncondOrIndirectBr)->eraseFromParent(); 75 NumTerminators--; 76 } 77 I = FirstUncondOrIndirectBr; 78 } 79 80 // We can't handle blocks that end in an indirect branch. 81 if (I->getDesc().isIndirectBranch()) 82 return true; 83 84 // We can't handle blocks with more than 2 terminators. 85 if (NumTerminators > 2) 86 return true; 87 88 // Handle a single unconditional branch. 89 if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) { 90 TBB = getBranchDestBlock(*I); 91 return false; 92 } 93 94 // Handle a single conditional branch. 95 if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) { 96 parseCondBranch(*I, TBB, Cond); 97 return false; 98 } 99 100 // Handle a conditional branch followed by an unconditional branch. 101 if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() && 102 I->getDesc().isUnconditionalBranch()) { 103 parseCondBranch(*std::prev(I), TBB, Cond); 104 FBB = getBranchDestBlock(*I); 105 return false; 106 } 107 108 // Otherwise, we can't handle this. 109 return true; 110 } 111 112 unsigned CSKYInstrInfo::removeBranch(MachineBasicBlock &MBB, 113 int *BytesRemoved) const { 114 if (BytesRemoved) 115 *BytesRemoved = 0; 116 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); 117 if (I == MBB.end()) 118 return 0; 119 120 if (!I->getDesc().isUnconditionalBranch() && 121 !I->getDesc().isConditionalBranch()) 122 return 0; 123 124 // Remove the branch. 125 if (BytesRemoved) 126 *BytesRemoved += getInstSizeInBytes(*I); 127 I->eraseFromParent(); 128 129 I = MBB.end(); 130 131 if (I == MBB.begin()) 132 return 1; 133 --I; 134 if (!I->getDesc().isConditionalBranch()) 135 return 1; 136 137 // Remove the branch. 138 if (BytesRemoved) 139 *BytesRemoved += getInstSizeInBytes(*I); 140 I->eraseFromParent(); 141 return 2; 142 } 143 144 MachineBasicBlock * 145 CSKYInstrInfo::getBranchDestBlock(const MachineInstr &MI) const { 146 assert(MI.getDesc().isBranch() && "Unexpected opcode!"); 147 // The branch target is always the last operand. 148 int NumOp = MI.getNumExplicitOperands(); 149 assert(MI.getOperand(NumOp - 1).isMBB() && "Expected MBB!"); 150 return MI.getOperand(NumOp - 1).getMBB(); 151 } 152 153 unsigned CSKYInstrInfo::insertBranch( 154 MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, 155 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const { 156 if (BytesAdded) 157 *BytesAdded = 0; 158 159 // Shouldn't be a fall through. 160 assert(TBB && "insertBranch must not be told to insert a fallthrough"); 161 assert((Cond.size() == 2 || Cond.size() == 0) && 162 "CSKY branch conditions have two components!"); 163 164 // Unconditional branch. 165 if (Cond.empty()) { 166 MachineInstr &MI = *BuildMI(&MBB, DL, get(CSKY::BR32)).addMBB(TBB); 167 if (BytesAdded) 168 *BytesAdded += getInstSizeInBytes(MI); 169 return 1; 170 } 171 172 // Either a one or two-way conditional branch. 173 unsigned Opc = Cond[0].getImm(); 174 MachineInstr &CondMI = *BuildMI(&MBB, DL, get(Opc)).add(Cond[1]).addMBB(TBB); 175 if (BytesAdded) 176 *BytesAdded += getInstSizeInBytes(CondMI); 177 178 // One-way conditional branch. 179 if (!FBB) 180 return 1; 181 182 // Two-way conditional branch. 183 MachineInstr &MI = *BuildMI(&MBB, DL, get(CSKY::BR32)).addMBB(FBB); 184 if (BytesAdded) 185 *BytesAdded += getInstSizeInBytes(MI); 186 return 2; 187 } 188 189 static unsigned getOppositeBranchOpc(unsigned Opcode) { 190 switch (Opcode) { 191 default: 192 llvm_unreachable("Unknown conditional branch!"); 193 case CSKY::BT32: 194 return CSKY::BF32; 195 case CSKY::BT16: 196 return CSKY::BF16; 197 case CSKY::BF32: 198 return CSKY::BT32; 199 case CSKY::BF16: 200 return CSKY::BT16; 201 case CSKY::BHZ32: 202 return CSKY::BLSZ32; 203 case CSKY::BHSZ32: 204 return CSKY::BLZ32; 205 case CSKY::BLZ32: 206 return CSKY::BHSZ32; 207 case CSKY::BLSZ32: 208 return CSKY::BHZ32; 209 case CSKY::BNEZ32: 210 return CSKY::BEZ32; 211 case CSKY::BEZ32: 212 return CSKY::BNEZ32; 213 } 214 } 215 216 bool CSKYInstrInfo::reverseBranchCondition( 217 SmallVectorImpl<MachineOperand> &Cond) const { 218 assert((Cond.size() == 2) && "Invalid branch condition!"); 219 Cond[0].setImm(getOppositeBranchOpc(Cond[0].getImm())); 220 return false; 221 } 222 223 Register CSKYInstrInfo::movImm(MachineBasicBlock &MBB, 224 MachineBasicBlock::iterator MBBI, 225 const DebugLoc &DL, int64_t Val, 226 MachineInstr::MIFlag Flag) const { 227 assert(isUInt<32>(Val) && "should be uint32"); 228 229 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 230 231 Register DstReg; 232 if (STI.hasE2()) { 233 DstReg = MRI.createVirtualRegister(&CSKY::GPRRegClass); 234 235 if (isUInt<16>(Val)) { 236 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI32), DstReg) 237 .addImm(Val & 0xFFFF) 238 .setMIFlags(Flag); 239 } else if (isShiftedUInt<16, 16>(Val)) { 240 BuildMI(MBB, MBBI, DL, get(CSKY::MOVIH32), DstReg) 241 .addImm((Val >> 16) & 0xFFFF) 242 .setMIFlags(Flag); 243 } else { 244 BuildMI(MBB, MBBI, DL, get(CSKY::MOVIH32), DstReg) 245 .addImm((Val >> 16) & 0xFFFF) 246 .setMIFlags(Flag); 247 BuildMI(MBB, MBBI, DL, get(CSKY::ORI32), DstReg) 248 .addReg(DstReg) 249 .addImm(Val & 0xFFFF) 250 .setMIFlags(Flag); 251 } 252 253 } else { 254 DstReg = MRI.createVirtualRegister(&CSKY::mGPRRegClass); 255 if (isUInt<8>(Val)) { 256 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg) 257 .addImm(Val & 0xFF) 258 .setMIFlags(Flag); 259 } else if (isUInt<16>(Val)) { 260 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg) 261 .addImm((Val >> 8) & 0xFF) 262 .setMIFlags(Flag); 263 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 264 .addReg(DstReg) 265 .addImm(8) 266 .setMIFlags(Flag); 267 if ((Val & 0xFF) != 0) 268 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 269 .addReg(DstReg) 270 .addImm(Val & 0xFF) 271 .setMIFlags(Flag); 272 } else if (isUInt<24>(Val)) { 273 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg) 274 .addImm((Val >> 16) & 0xFF) 275 .setMIFlags(Flag); 276 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 277 .addReg(DstReg) 278 .addImm(8) 279 .setMIFlags(Flag); 280 if (((Val >> 8) & 0xFF) != 0) 281 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 282 .addReg(DstReg) 283 .addImm((Val >> 8) & 0xFF) 284 .setMIFlags(Flag); 285 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 286 .addReg(DstReg) 287 .addImm(8) 288 .setMIFlags(Flag); 289 if ((Val & 0xFF) != 0) 290 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 291 .addReg(DstReg) 292 .addImm(Val & 0xFF) 293 .setMIFlags(Flag); 294 } else { 295 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg) 296 .addImm((Val >> 24) & 0xFF) 297 .setMIFlags(Flag); 298 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 299 .addReg(DstReg) 300 .addImm(8) 301 .setMIFlags(Flag); 302 if (((Val >> 16) & 0xFF) != 0) 303 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 304 .addReg(DstReg) 305 .addImm((Val >> 16) & 0xFF) 306 .setMIFlags(Flag); 307 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 308 .addReg(DstReg) 309 .addImm(8) 310 .setMIFlags(Flag); 311 if (((Val >> 8) & 0xFF) != 0) 312 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 313 .addReg(DstReg) 314 .addImm((Val >> 8) & 0xFF) 315 .setMIFlags(Flag); 316 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 317 .addReg(DstReg) 318 .addImm(8) 319 .setMIFlags(Flag); 320 if ((Val & 0xFF) != 0) 321 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 322 .addReg(DstReg) 323 .addImm(Val & 0xFF) 324 .setMIFlags(Flag); 325 } 326 } 327 328 return DstReg; 329 } 330 331 unsigned CSKYInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, 332 int &FrameIndex) const { 333 switch (MI.getOpcode()) { 334 default: 335 return 0; 336 case CSKY::LD16B: 337 case CSKY::LD16H: 338 case CSKY::LD16W: 339 case CSKY::LD32B: 340 case CSKY::LD32BS: 341 case CSKY::LD32H: 342 case CSKY::LD32HS: 343 case CSKY::LD32W: 344 case CSKY::FLD_S: 345 case CSKY::FLD_D: 346 case CSKY::f2FLD_S: 347 case CSKY::f2FLD_D: 348 case CSKY::RESTORE_CARRY: 349 break; 350 } 351 352 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() && 353 MI.getOperand(2).getImm() == 0) { 354 FrameIndex = MI.getOperand(1).getIndex(); 355 return MI.getOperand(0).getReg(); 356 } 357 358 return 0; 359 } 360 361 unsigned CSKYInstrInfo::isStoreToStackSlot(const MachineInstr &MI, 362 int &FrameIndex) const { 363 switch (MI.getOpcode()) { 364 default: 365 return 0; 366 case CSKY::ST16B: 367 case CSKY::ST16H: 368 case CSKY::ST16W: 369 case CSKY::ST32B: 370 case CSKY::ST32H: 371 case CSKY::ST32W: 372 case CSKY::FST_S: 373 case CSKY::FST_D: 374 case CSKY::f2FST_S: 375 case CSKY::f2FST_D: 376 case CSKY::SPILL_CARRY: 377 break; 378 } 379 380 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() && 381 MI.getOperand(2).getImm() == 0) { 382 FrameIndex = MI.getOperand(1).getIndex(); 383 return MI.getOperand(0).getReg(); 384 } 385 386 return 0; 387 } 388 389 void CSKYInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 390 MachineBasicBlock::iterator I, 391 Register SrcReg, bool IsKill, int FI, 392 const TargetRegisterClass *RC, 393 const TargetRegisterInfo *TRI) const { 394 DebugLoc DL; 395 if (I != MBB.end()) 396 DL = I->getDebugLoc(); 397 398 MachineFunction &MF = *MBB.getParent(); 399 CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>(); 400 MachineFrameInfo &MFI = MF.getFrameInfo(); 401 402 unsigned Opcode = 0; 403 404 if (CSKY::GPRRegClass.hasSubClassEq(RC)) { 405 Opcode = CSKY::ST32W; // Optimize for 16bit 406 } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) { 407 Opcode = CSKY::SPILL_CARRY; 408 CFI->setSpillsCR(); 409 } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC)) 410 Opcode = CSKY::FST_S; 411 else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC)) 412 Opcode = CSKY::FST_D; 413 else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC)) 414 Opcode = CSKY::f2FST_S; 415 else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC)) 416 Opcode = CSKY::f2FST_D; 417 else { 418 llvm_unreachable("Unknown RegisterClass"); 419 } 420 421 MachineMemOperand *MMO = MF.getMachineMemOperand( 422 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore, 423 MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 424 425 BuildMI(MBB, I, DL, get(Opcode)) 426 .addReg(SrcReg, getKillRegState(IsKill)) 427 .addFrameIndex(FI) 428 .addImm(0) 429 .addMemOperand(MMO); 430 } 431 432 void CSKYInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 433 MachineBasicBlock::iterator I, 434 Register DestReg, int FI, 435 const TargetRegisterClass *RC, 436 const TargetRegisterInfo *TRI) const { 437 DebugLoc DL; 438 if (I != MBB.end()) 439 DL = I->getDebugLoc(); 440 441 MachineFunction &MF = *MBB.getParent(); 442 CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>(); 443 MachineFrameInfo &MFI = MF.getFrameInfo(); 444 445 unsigned Opcode = 0; 446 447 if (CSKY::GPRRegClass.hasSubClassEq(RC)) { 448 Opcode = CSKY::LD32W; 449 } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) { 450 Opcode = CSKY::RESTORE_CARRY; 451 CFI->setSpillsCR(); 452 } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC)) 453 Opcode = CSKY::FLD_S; 454 else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC)) 455 Opcode = CSKY::FLD_D; 456 else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC)) 457 Opcode = CSKY::f2FLD_S; 458 else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC)) 459 Opcode = CSKY::f2FLD_D; 460 else { 461 llvm_unreachable("Unknown RegisterClass"); 462 } 463 464 MachineMemOperand *MMO = MF.getMachineMemOperand( 465 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad, 466 MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 467 468 BuildMI(MBB, I, DL, get(Opcode), DestReg) 469 .addFrameIndex(FI) 470 .addImm(0) 471 .addMemOperand(MMO); 472 } 473 474 void CSKYInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 475 MachineBasicBlock::iterator I, 476 const DebugLoc &DL, MCRegister DestReg, 477 MCRegister SrcReg, bool KillSrc) const { 478 479 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 480 481 if (CSKY::GPRRegClass.contains(SrcReg) && 482 CSKY::CARRYRegClass.contains(DestReg)) { 483 if (STI.hasE2()) { 484 BuildMI(MBB, I, DL, get(CSKY::BTSTI32), DestReg) 485 .addReg(SrcReg, getKillRegState(KillSrc)) 486 .addImm(0); 487 } else { 488 assert(SrcReg < CSKY::R8); 489 BuildMI(MBB, I, DL, get(CSKY::BTSTI16), DestReg) 490 .addReg(SrcReg, getKillRegState(KillSrc)) 491 .addImm(0); 492 } 493 return; 494 } 495 496 if (CSKY::CARRYRegClass.contains(SrcReg) && 497 CSKY::GPRRegClass.contains(DestReg)) { 498 499 if (STI.hasE2()) { 500 BuildMI(MBB, I, DL, get(CSKY::MVC32), DestReg) 501 .addReg(SrcReg, getKillRegState(KillSrc)); 502 } else { 503 assert(DestReg < CSKY::R16); 504 assert(DestReg < CSKY::R8); 505 BuildMI(MBB, I, DL, get(CSKY::MOVI16), DestReg).addImm(0); 506 BuildMI(MBB, I, DL, get(CSKY::ADDC16)) 507 .addReg(DestReg, RegState::Define) 508 .addReg(SrcReg, RegState::Define) 509 .addReg(DestReg, getKillRegState(true)) 510 .addReg(DestReg, getKillRegState(true)) 511 .addReg(SrcReg, getKillRegState(true)); 512 BuildMI(MBB, I, DL, get(CSKY::BTSTI16)) 513 .addReg(SrcReg, RegState::Define | getDeadRegState(KillSrc)) 514 .addReg(DestReg) 515 .addImm(0); 516 } 517 return; 518 } 519 520 unsigned Opcode = 0; 521 if (CSKY::GPRRegClass.contains(DestReg, SrcReg)) 522 Opcode = CSKY::MOV32; 523 else if (v2sf && CSKY::sFPR32RegClass.contains(DestReg, SrcReg)) 524 Opcode = CSKY::FMOV_S; 525 else if (v3sf && CSKY::FPR32RegClass.contains(DestReg, SrcReg)) 526 Opcode = CSKY::f2FMOV_S; 527 else if (v2df && CSKY::sFPR64RegClass.contains(DestReg, SrcReg)) 528 Opcode = CSKY::FMOV_D; 529 else if (v3df && CSKY::FPR64RegClass.contains(DestReg, SrcReg)) 530 Opcode = CSKY::f2FMOV_D; 531 else if (v2sf && CSKY::sFPR32RegClass.contains(SrcReg) && 532 CSKY::GPRRegClass.contains(DestReg)) 533 Opcode = CSKY::FMFVRL; 534 else if (v3sf && CSKY::FPR32RegClass.contains(SrcReg) && 535 CSKY::GPRRegClass.contains(DestReg)) 536 Opcode = CSKY::f2FMFVRL; 537 else if (v2df && CSKY::sFPR64RegClass.contains(SrcReg) && 538 CSKY::GPRRegClass.contains(DestReg)) 539 Opcode = CSKY::FMFVRL_D; 540 else if (v3df && CSKY::FPR64RegClass.contains(SrcReg) && 541 CSKY::GPRRegClass.contains(DestReg)) 542 Opcode = CSKY::f2FMFVRL_D; 543 else if (v2sf && CSKY::GPRRegClass.contains(SrcReg) && 544 CSKY::sFPR32RegClass.contains(DestReg)) 545 Opcode = CSKY::FMTVRL; 546 else if (v3sf && CSKY::GPRRegClass.contains(SrcReg) && 547 CSKY::FPR32RegClass.contains(DestReg)) 548 Opcode = CSKY::f2FMTVRL; 549 else if (v2df && CSKY::GPRRegClass.contains(SrcReg) && 550 CSKY::sFPR64RegClass.contains(DestReg)) 551 Opcode = CSKY::FMTVRL_D; 552 else if (v3df && CSKY::GPRRegClass.contains(SrcReg) && 553 CSKY::FPR64RegClass.contains(DestReg)) 554 Opcode = CSKY::f2FMTVRL_D; 555 else { 556 LLVM_DEBUG(dbgs() << "src = " << SrcReg << ", dst = " << DestReg); 557 LLVM_DEBUG(I->dump()); 558 llvm_unreachable("Unknown RegisterClass"); 559 } 560 561 BuildMI(MBB, I, DL, get(Opcode), DestReg) 562 .addReg(SrcReg, getKillRegState(KillSrc)); 563 } 564 565 Register CSKYInstrInfo::getGlobalBaseReg(MachineFunction &MF) const { 566 CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>(); 567 MachineConstantPool *MCP = MF.getConstantPool(); 568 MachineRegisterInfo &MRI = MF.getRegInfo(); 569 570 Register GlobalBaseReg = CFI->getGlobalBaseReg(); 571 if (GlobalBaseReg != 0) 572 return GlobalBaseReg; 573 574 // Insert a pseudo instruction to set the GlobalBaseReg into the first 575 // MBB of the function 576 MachineBasicBlock &FirstMBB = MF.front(); 577 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 578 DebugLoc DL; 579 580 CSKYConstantPoolValue *CPV = CSKYConstantPoolSymbol::Create( 581 Type::getInt32Ty(MF.getFunction().getContext()), "_GLOBAL_OFFSET_TABLE_", 582 0, CSKYCP::ADDR); 583 584 unsigned CPI = MCP->getConstantPoolIndex(CPV, Align(4)); 585 586 MachineMemOperand *MO = 587 MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF), 588 MachineMemOperand::MOLoad, 4, Align(4)); 589 BuildMI(FirstMBB, MBBI, DL, get(CSKY::LRW32), CSKY::R28) 590 .addConstantPoolIndex(CPI) 591 .addMemOperand(MO); 592 593 GlobalBaseReg = MRI.createVirtualRegister(&CSKY::GPRRegClass); 594 BuildMI(FirstMBB, MBBI, DL, get(TargetOpcode::COPY), GlobalBaseReg) 595 .addReg(CSKY::R28); 596 597 CFI->setGlobalBaseReg(GlobalBaseReg); 598 return GlobalBaseReg; 599 } 600 601 unsigned CSKYInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { 602 switch (MI.getOpcode()) { 603 default: 604 return MI.getDesc().getSize(); 605 case CSKY::CONSTPOOL_ENTRY: 606 return MI.getOperand(2).getImm(); 607 case CSKY::SPILL_CARRY: 608 case CSKY::RESTORE_CARRY: 609 case CSKY::PseudoTLSLA32: 610 return 8; 611 case TargetOpcode::INLINEASM_BR: 612 case TargetOpcode::INLINEASM: { 613 const MachineFunction *MF = MI.getParent()->getParent(); 614 const char *AsmStr = MI.getOperand(0).getSymbolName(); 615 return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); 616 } 617 } 618 } 619