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