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, int64_t Val, 227 MachineInstr::MIFlag Flag) const { 228 assert(isUInt<32>(Val) && "should be uint32"); 229 230 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 231 232 Register DstReg; 233 if (STI.hasE2()) { 234 DstReg = MRI.createVirtualRegister(&CSKY::GPRRegClass); 235 236 if (isUInt<16>(Val)) { 237 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI32), DstReg) 238 .addImm(Val & 0xFFFF) 239 .setMIFlags(Flag); 240 } else if (isShiftedUInt<16, 16>(Val)) { 241 BuildMI(MBB, MBBI, DL, get(CSKY::MOVIH32), DstReg) 242 .addImm((Val >> 16) & 0xFFFF) 243 .setMIFlags(Flag); 244 } else { 245 BuildMI(MBB, MBBI, DL, get(CSKY::MOVIH32), DstReg) 246 .addImm((Val >> 16) & 0xFFFF) 247 .setMIFlags(Flag); 248 BuildMI(MBB, MBBI, DL, get(CSKY::ORI32), DstReg) 249 .addReg(DstReg) 250 .addImm(Val & 0xFFFF) 251 .setMIFlags(Flag); 252 } 253 254 } else { 255 DstReg = MRI.createVirtualRegister(&CSKY::mGPRRegClass); 256 if (isUInt<8>(Val)) { 257 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg) 258 .addImm(Val & 0xFF) 259 .setMIFlags(Flag); 260 } else if (isUInt<16>(Val)) { 261 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg) 262 .addImm((Val >> 8) & 0xFF) 263 .setMIFlags(Flag); 264 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 265 .addReg(DstReg) 266 .addImm(8) 267 .setMIFlags(Flag); 268 if ((Val & 0xFF) != 0) 269 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 270 .addReg(DstReg) 271 .addImm(Val & 0xFF) 272 .setMIFlags(Flag); 273 } else if (isUInt<24>(Val)) { 274 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg) 275 .addImm((Val >> 16) & 0xFF) 276 .setMIFlags(Flag); 277 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 278 .addReg(DstReg) 279 .addImm(8) 280 .setMIFlags(Flag); 281 if (((Val >> 8) & 0xFF) != 0) 282 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 283 .addReg(DstReg) 284 .addImm((Val >> 8) & 0xFF) 285 .setMIFlags(Flag); 286 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 287 .addReg(DstReg) 288 .addImm(8) 289 .setMIFlags(Flag); 290 if ((Val & 0xFF) != 0) 291 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 292 .addReg(DstReg) 293 .addImm(Val & 0xFF) 294 .setMIFlags(Flag); 295 } else { 296 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg) 297 .addImm((Val >> 24) & 0xFF) 298 .setMIFlags(Flag); 299 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 300 .addReg(DstReg) 301 .addImm(8) 302 .setMIFlags(Flag); 303 if (((Val >> 16) & 0xFF) != 0) 304 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 305 .addReg(DstReg) 306 .addImm((Val >> 16) & 0xFF) 307 .setMIFlags(Flag); 308 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 309 .addReg(DstReg) 310 .addImm(8) 311 .setMIFlags(Flag); 312 if (((Val >> 8) & 0xFF) != 0) 313 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 314 .addReg(DstReg) 315 .addImm((Val >> 8) & 0xFF) 316 .setMIFlags(Flag); 317 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 318 .addReg(DstReg) 319 .addImm(8) 320 .setMIFlags(Flag); 321 if ((Val & 0xFF) != 0) 322 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 323 .addReg(DstReg) 324 .addImm(Val & 0xFF) 325 .setMIFlags(Flag); 326 } 327 } 328 329 return DstReg; 330 } 331 332 unsigned CSKYInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, 333 int &FrameIndex) const { 334 switch (MI.getOpcode()) { 335 default: 336 return 0; 337 case CSKY::LD16B: 338 case CSKY::LD16H: 339 case CSKY::LD16W: 340 case CSKY::LD32B: 341 case CSKY::LD32BS: 342 case CSKY::LD32H: 343 case CSKY::LD32HS: 344 case CSKY::LD32W: 345 case CSKY::FLD_S: 346 case CSKY::FLD_D: 347 case CSKY::f2FLD_S: 348 case CSKY::f2FLD_D: 349 case CSKY::RESTORE_CARRY: 350 break; 351 } 352 353 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() && 354 MI.getOperand(2).getImm() == 0) { 355 FrameIndex = MI.getOperand(1).getIndex(); 356 return MI.getOperand(0).getReg(); 357 } 358 359 return 0; 360 } 361 362 unsigned CSKYInstrInfo::isStoreToStackSlot(const MachineInstr &MI, 363 int &FrameIndex) const { 364 switch (MI.getOpcode()) { 365 default: 366 return 0; 367 case CSKY::ST16B: 368 case CSKY::ST16H: 369 case CSKY::ST16W: 370 case CSKY::ST32B: 371 case CSKY::ST32H: 372 case CSKY::ST32W: 373 case CSKY::FST_S: 374 case CSKY::FST_D: 375 case CSKY::f2FST_S: 376 case CSKY::f2FST_D: 377 case CSKY::SPILL_CARRY: 378 break; 379 } 380 381 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() && 382 MI.getOperand(2).getImm() == 0) { 383 FrameIndex = MI.getOperand(1).getIndex(); 384 return MI.getOperand(0).getReg(); 385 } 386 387 return 0; 388 } 389 390 void CSKYInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 391 MachineBasicBlock::iterator I, 392 Register SrcReg, bool IsKill, int FI, 393 const TargetRegisterClass *RC, 394 const TargetRegisterInfo *TRI) const { 395 DebugLoc DL; 396 if (I != MBB.end()) 397 DL = I->getDebugLoc(); 398 399 MachineFunction &MF = *MBB.getParent(); 400 CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>(); 401 MachineFrameInfo &MFI = MF.getFrameInfo(); 402 403 unsigned Opcode = 0; 404 405 if (CSKY::GPRRegClass.hasSubClassEq(RC)) { 406 Opcode = CSKY::ST32W; // Optimize for 16bit 407 } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) { 408 Opcode = CSKY::SPILL_CARRY; 409 CFI->setSpillsCR(); 410 } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC)) 411 Opcode = CSKY::FST_S; 412 else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC)) 413 Opcode = CSKY::FST_D; 414 else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC)) 415 Opcode = CSKY::f2FST_S; 416 else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC)) 417 Opcode = CSKY::f2FST_D; 418 else { 419 llvm_unreachable("Unknown RegisterClass"); 420 } 421 422 MachineMemOperand *MMO = MF.getMachineMemOperand( 423 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore, 424 MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 425 426 BuildMI(MBB, I, DL, get(Opcode)) 427 .addReg(SrcReg, getKillRegState(IsKill)) 428 .addFrameIndex(FI) 429 .addImm(0) 430 .addMemOperand(MMO); 431 } 432 433 void CSKYInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 434 MachineBasicBlock::iterator I, 435 Register DestReg, int FI, 436 const TargetRegisterClass *RC, 437 const TargetRegisterInfo *TRI) const { 438 DebugLoc DL; 439 if (I != MBB.end()) 440 DL = I->getDebugLoc(); 441 442 MachineFunction &MF = *MBB.getParent(); 443 CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>(); 444 MachineFrameInfo &MFI = MF.getFrameInfo(); 445 446 unsigned Opcode = 0; 447 448 if (CSKY::GPRRegClass.hasSubClassEq(RC)) { 449 Opcode = CSKY::LD32W; 450 } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) { 451 Opcode = CSKY::RESTORE_CARRY; 452 CFI->setSpillsCR(); 453 } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC)) 454 Opcode = CSKY::FLD_S; 455 else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC)) 456 Opcode = CSKY::FLD_D; 457 else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC)) 458 Opcode = CSKY::f2FLD_S; 459 else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC)) 460 Opcode = CSKY::f2FLD_D; 461 else { 462 llvm_unreachable("Unknown RegisterClass"); 463 } 464 465 MachineMemOperand *MMO = MF.getMachineMemOperand( 466 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad, 467 MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 468 469 BuildMI(MBB, I, DL, get(Opcode), DestReg) 470 .addFrameIndex(FI) 471 .addImm(0) 472 .addMemOperand(MMO); 473 } 474 475 void CSKYInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 476 MachineBasicBlock::iterator I, 477 const DebugLoc &DL, MCRegister DestReg, 478 MCRegister SrcReg, bool KillSrc) const { 479 if (CSKY::GPRRegClass.contains(SrcReg) && 480 CSKY::CARRYRegClass.contains(DestReg)) { 481 if (STI.hasE2()) { 482 BuildMI(MBB, I, DL, get(CSKY::BTSTI32), DestReg) 483 .addReg(SrcReg, getKillRegState(KillSrc)) 484 .addImm(0); 485 } else { 486 assert(SrcReg < CSKY::R8); 487 BuildMI(MBB, I, DL, get(CSKY::BTSTI16), DestReg) 488 .addReg(SrcReg, getKillRegState(KillSrc)) 489 .addImm(0); 490 } 491 return; 492 } 493 494 if (CSKY::CARRYRegClass.contains(SrcReg) && 495 CSKY::GPRRegClass.contains(DestReg)) { 496 497 if (STI.hasE2()) { 498 BuildMI(MBB, I, DL, get(CSKY::MVC32), DestReg) 499 .addReg(SrcReg, getKillRegState(KillSrc)); 500 } else { 501 assert(DestReg < CSKY::R16); 502 assert(DestReg < CSKY::R8); 503 BuildMI(MBB, I, DL, get(CSKY::MOVI16), DestReg).addImm(0); 504 BuildMI(MBB, I, DL, get(CSKY::ADDC16)) 505 .addReg(DestReg, RegState::Define) 506 .addReg(SrcReg, RegState::Define) 507 .addReg(DestReg, getKillRegState(true)) 508 .addReg(DestReg, getKillRegState(true)) 509 .addReg(SrcReg, getKillRegState(true)); 510 BuildMI(MBB, I, DL, get(CSKY::BTSTI16)) 511 .addReg(SrcReg, RegState::Define | getDeadRegState(KillSrc)) 512 .addReg(DestReg) 513 .addImm(0); 514 } 515 return; 516 } 517 518 unsigned Opcode = 0; 519 if (CSKY::GPRRegClass.contains(DestReg, SrcReg)) 520 Opcode = CSKY::MOV32; 521 else if (v2sf && CSKY::sFPR32RegClass.contains(DestReg, SrcReg)) 522 Opcode = CSKY::FMOV_S; 523 else if (v3sf && CSKY::FPR32RegClass.contains(DestReg, SrcReg)) 524 Opcode = CSKY::f2FMOV_S; 525 else if (v2df && CSKY::sFPR64RegClass.contains(DestReg, SrcReg)) 526 Opcode = CSKY::FMOV_D; 527 else if (v3df && CSKY::FPR64RegClass.contains(DestReg, SrcReg)) 528 Opcode = CSKY::f2FMOV_D; 529 else if (v2sf && CSKY::sFPR32RegClass.contains(SrcReg) && 530 CSKY::GPRRegClass.contains(DestReg)) 531 Opcode = CSKY::FMFVRL; 532 else if (v3sf && CSKY::FPR32RegClass.contains(SrcReg) && 533 CSKY::GPRRegClass.contains(DestReg)) 534 Opcode = CSKY::f2FMFVRL; 535 else if (v2df && CSKY::sFPR64RegClass.contains(SrcReg) && 536 CSKY::GPRRegClass.contains(DestReg)) 537 Opcode = CSKY::FMFVRL_D; 538 else if (v3df && CSKY::FPR64RegClass.contains(SrcReg) && 539 CSKY::GPRRegClass.contains(DestReg)) 540 Opcode = CSKY::f2FMFVRL_D; 541 else if (v2sf && CSKY::GPRRegClass.contains(SrcReg) && 542 CSKY::sFPR32RegClass.contains(DestReg)) 543 Opcode = CSKY::FMTVRL; 544 else if (v3sf && CSKY::GPRRegClass.contains(SrcReg) && 545 CSKY::FPR32RegClass.contains(DestReg)) 546 Opcode = CSKY::f2FMTVRL; 547 else if (v2df && CSKY::GPRRegClass.contains(SrcReg) && 548 CSKY::sFPR64RegClass.contains(DestReg)) 549 Opcode = CSKY::FMTVRL_D; 550 else if (v3df && CSKY::GPRRegClass.contains(SrcReg) && 551 CSKY::FPR64RegClass.contains(DestReg)) 552 Opcode = CSKY::f2FMTVRL_D; 553 else { 554 LLVM_DEBUG(dbgs() << "src = " << SrcReg << ", dst = " << DestReg); 555 LLVM_DEBUG(I->dump()); 556 llvm_unreachable("Unknown RegisterClass"); 557 } 558 559 BuildMI(MBB, I, DL, get(Opcode), DestReg) 560 .addReg(SrcReg, getKillRegState(KillSrc)); 561 } 562 563 Register CSKYInstrInfo::getGlobalBaseReg(MachineFunction &MF) const { 564 CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>(); 565 MachineConstantPool *MCP = MF.getConstantPool(); 566 MachineRegisterInfo &MRI = MF.getRegInfo(); 567 568 Register GlobalBaseReg = CFI->getGlobalBaseReg(); 569 if (GlobalBaseReg != 0) 570 return GlobalBaseReg; 571 572 // Insert a pseudo instruction to set the GlobalBaseReg into the first 573 // MBB of the function 574 MachineBasicBlock &FirstMBB = MF.front(); 575 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 576 DebugLoc DL; 577 578 CSKYConstantPoolValue *CPV = CSKYConstantPoolSymbol::Create( 579 Type::getInt32Ty(MF.getFunction().getContext()), "_GLOBAL_OFFSET_TABLE_", 580 0, CSKYCP::ADDR); 581 582 unsigned CPI = MCP->getConstantPoolIndex(CPV, Align(4)); 583 584 MachineMemOperand *MO = 585 MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF), 586 MachineMemOperand::MOLoad, 4, Align(4)); 587 BuildMI(FirstMBB, MBBI, DL, get(CSKY::LRW32), CSKY::R28) 588 .addConstantPoolIndex(CPI) 589 .addMemOperand(MO); 590 591 GlobalBaseReg = MRI.createVirtualRegister(&CSKY::GPRRegClass); 592 BuildMI(FirstMBB, MBBI, DL, get(TargetOpcode::COPY), GlobalBaseReg) 593 .addReg(CSKY::R28); 594 595 CFI->setGlobalBaseReg(GlobalBaseReg); 596 return GlobalBaseReg; 597 } 598 599 unsigned CSKYInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { 600 switch (MI.getOpcode()) { 601 default: 602 return MI.getDesc().getSize(); 603 case CSKY::CONSTPOOL_ENTRY: 604 return MI.getOperand(2).getImm(); 605 case CSKY::SPILL_CARRY: 606 case CSKY::RESTORE_CARRY: 607 case CSKY::PseudoTLSLA32: 608 return 8; 609 case TargetOpcode::INLINEASM_BR: 610 case TargetOpcode::INLINEASM: { 611 const MachineFunction *MF = MI.getParent()->getParent(); 612 const char *AsmStr = MI.getOperand(0).getSymbolName(); 613 return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); 614 } 615 } 616 } 617