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 Register 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 Register 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, 396 Register VReg) const { 397 DebugLoc DL; 398 if (I != MBB.end()) 399 DL = I->getDebugLoc(); 400 401 MachineFunction &MF = *MBB.getParent(); 402 CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>(); 403 MachineFrameInfo &MFI = MF.getFrameInfo(); 404 405 unsigned Opcode = 0; 406 407 if (CSKY::GPRRegClass.hasSubClassEq(RC)) { 408 Opcode = CSKY::ST32W; // Optimize for 16bit 409 } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) { 410 Opcode = CSKY::SPILL_CARRY; 411 CFI->setSpillsCR(); 412 } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC)) 413 Opcode = CSKY::FST_S; 414 else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC)) 415 Opcode = CSKY::FST_D; 416 else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC)) 417 Opcode = CSKY::f2FST_S; 418 else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC)) 419 Opcode = CSKY::f2FST_D; 420 else { 421 llvm_unreachable("Unknown RegisterClass"); 422 } 423 424 MachineMemOperand *MMO = MF.getMachineMemOperand( 425 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore, 426 MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 427 428 BuildMI(MBB, I, DL, get(Opcode)) 429 .addReg(SrcReg, getKillRegState(IsKill)) 430 .addFrameIndex(FI) 431 .addImm(0) 432 .addMemOperand(MMO); 433 } 434 435 void CSKYInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 436 MachineBasicBlock::iterator I, 437 Register DestReg, int FI, 438 const TargetRegisterClass *RC, 439 const TargetRegisterInfo *TRI, 440 Register VReg) const { 441 DebugLoc DL; 442 if (I != MBB.end()) 443 DL = I->getDebugLoc(); 444 445 MachineFunction &MF = *MBB.getParent(); 446 CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>(); 447 MachineFrameInfo &MFI = MF.getFrameInfo(); 448 449 unsigned Opcode = 0; 450 451 if (CSKY::GPRRegClass.hasSubClassEq(RC)) { 452 Opcode = CSKY::LD32W; 453 } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) { 454 Opcode = CSKY::RESTORE_CARRY; 455 CFI->setSpillsCR(); 456 } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC)) 457 Opcode = CSKY::FLD_S; 458 else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC)) 459 Opcode = CSKY::FLD_D; 460 else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC)) 461 Opcode = CSKY::f2FLD_S; 462 else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC)) 463 Opcode = CSKY::f2FLD_D; 464 else { 465 llvm_unreachable("Unknown RegisterClass"); 466 } 467 468 MachineMemOperand *MMO = MF.getMachineMemOperand( 469 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad, 470 MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 471 472 BuildMI(MBB, I, DL, get(Opcode), DestReg) 473 .addFrameIndex(FI) 474 .addImm(0) 475 .addMemOperand(MMO); 476 } 477 478 void CSKYInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 479 MachineBasicBlock::iterator I, 480 const DebugLoc &DL, MCRegister DestReg, 481 MCRegister SrcReg, bool KillSrc) const { 482 if (CSKY::GPRRegClass.contains(SrcReg) && 483 CSKY::CARRYRegClass.contains(DestReg)) { 484 if (STI.hasE2()) { 485 BuildMI(MBB, I, DL, get(CSKY::BTSTI32), DestReg) 486 .addReg(SrcReg, getKillRegState(KillSrc)) 487 .addImm(0); 488 } else { 489 assert(SrcReg < CSKY::R8); 490 BuildMI(MBB, I, DL, get(CSKY::BTSTI16), DestReg) 491 .addReg(SrcReg, getKillRegState(KillSrc)) 492 .addImm(0); 493 } 494 return; 495 } 496 497 if (CSKY::CARRYRegClass.contains(SrcReg) && 498 CSKY::GPRRegClass.contains(DestReg)) { 499 500 if (STI.hasE2()) { 501 BuildMI(MBB, I, DL, get(CSKY::MVC32), DestReg) 502 .addReg(SrcReg, getKillRegState(KillSrc)); 503 } else { 504 assert(DestReg < CSKY::R16); 505 assert(DestReg < CSKY::R8); 506 BuildMI(MBB, I, DL, get(CSKY::MOVI16), DestReg).addImm(0); 507 BuildMI(MBB, I, DL, get(CSKY::ADDC16)) 508 .addReg(DestReg, RegState::Define) 509 .addReg(SrcReg, RegState::Define) 510 .addReg(DestReg, getKillRegState(true)) 511 .addReg(DestReg, getKillRegState(true)) 512 .addReg(SrcReg, getKillRegState(true)); 513 BuildMI(MBB, I, DL, get(CSKY::BTSTI16)) 514 .addReg(SrcReg, RegState::Define | getDeadRegState(KillSrc)) 515 .addReg(DestReg) 516 .addImm(0); 517 } 518 return; 519 } 520 521 unsigned Opcode = 0; 522 if (CSKY::GPRRegClass.contains(DestReg, SrcReg)) 523 Opcode = STI.hasE2() ? CSKY::MOV32 : CSKY::MOV16; 524 else if (v2sf && CSKY::sFPR32RegClass.contains(DestReg, SrcReg)) 525 Opcode = CSKY::FMOV_S; 526 else if (v3sf && CSKY::FPR32RegClass.contains(DestReg, SrcReg)) 527 Opcode = CSKY::f2FMOV_S; 528 else if (v2df && CSKY::sFPR64RegClass.contains(DestReg, SrcReg)) 529 Opcode = CSKY::FMOV_D; 530 else if (v3df && CSKY::FPR64RegClass.contains(DestReg, SrcReg)) 531 Opcode = CSKY::f2FMOV_D; 532 else if (v2sf && CSKY::sFPR32RegClass.contains(SrcReg) && 533 CSKY::GPRRegClass.contains(DestReg)) 534 Opcode = CSKY::FMFVRL; 535 else if (v3sf && CSKY::FPR32RegClass.contains(SrcReg) && 536 CSKY::GPRRegClass.contains(DestReg)) 537 Opcode = CSKY::f2FMFVRL; 538 else if (v2df && CSKY::sFPR64RegClass.contains(SrcReg) && 539 CSKY::GPRRegClass.contains(DestReg)) 540 Opcode = CSKY::FMFVRL_D; 541 else if (v3df && CSKY::FPR64RegClass.contains(SrcReg) && 542 CSKY::GPRRegClass.contains(DestReg)) 543 Opcode = CSKY::f2FMFVRL_D; 544 else if (v2sf && CSKY::GPRRegClass.contains(SrcReg) && 545 CSKY::sFPR32RegClass.contains(DestReg)) 546 Opcode = CSKY::FMTVRL; 547 else if (v3sf && CSKY::GPRRegClass.contains(SrcReg) && 548 CSKY::FPR32RegClass.contains(DestReg)) 549 Opcode = CSKY::f2FMTVRL; 550 else if (v2df && CSKY::GPRRegClass.contains(SrcReg) && 551 CSKY::sFPR64RegClass.contains(DestReg)) 552 Opcode = CSKY::FMTVRL_D; 553 else if (v3df && CSKY::GPRRegClass.contains(SrcReg) && 554 CSKY::FPR64RegClass.contains(DestReg)) 555 Opcode = CSKY::f2FMTVRL_D; 556 else { 557 LLVM_DEBUG(dbgs() << "src = " << SrcReg << ", dst = " << DestReg); 558 LLVM_DEBUG(I->dump()); 559 llvm_unreachable("Unknown RegisterClass"); 560 } 561 562 BuildMI(MBB, I, DL, get(Opcode), DestReg) 563 .addReg(SrcReg, getKillRegState(KillSrc)); 564 } 565 566 Register CSKYInstrInfo::getGlobalBaseReg(MachineFunction &MF) const { 567 CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>(); 568 MachineConstantPool *MCP = MF.getConstantPool(); 569 MachineRegisterInfo &MRI = MF.getRegInfo(); 570 571 Register GlobalBaseReg = CFI->getGlobalBaseReg(); 572 if (GlobalBaseReg != 0) 573 return GlobalBaseReg; 574 575 // Insert a pseudo instruction to set the GlobalBaseReg into the first 576 // MBB of the function 577 MachineBasicBlock &FirstMBB = MF.front(); 578 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 579 DebugLoc DL; 580 581 CSKYConstantPoolValue *CPV = CSKYConstantPoolSymbol::Create( 582 Type::getInt32Ty(MF.getFunction().getContext()), "_GLOBAL_OFFSET_TABLE_", 583 0, CSKYCP::ADDR); 584 585 unsigned CPI = MCP->getConstantPoolIndex(CPV, Align(4)); 586 587 MachineMemOperand *MO = 588 MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF), 589 MachineMemOperand::MOLoad, 4, Align(4)); 590 BuildMI(FirstMBB, MBBI, DL, get(CSKY::LRW32), CSKY::R28) 591 .addConstantPoolIndex(CPI) 592 .addMemOperand(MO); 593 594 GlobalBaseReg = MRI.createVirtualRegister(&CSKY::GPRRegClass); 595 BuildMI(FirstMBB, MBBI, DL, get(TargetOpcode::COPY), GlobalBaseReg) 596 .addReg(CSKY::R28); 597 598 CFI->setGlobalBaseReg(GlobalBaseReg); 599 return GlobalBaseReg; 600 } 601 602 unsigned CSKYInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { 603 switch (MI.getOpcode()) { 604 default: 605 return MI.getDesc().getSize(); 606 case CSKY::CONSTPOOL_ENTRY: 607 return MI.getOperand(2).getImm(); 608 case CSKY::SPILL_CARRY: 609 case CSKY::RESTORE_CARRY: 610 case CSKY::PseudoTLSLA32: 611 return 8; 612 case TargetOpcode::INLINEASM_BR: 613 case TargetOpcode::INLINEASM: { 614 const MachineFunction *MF = MI.getParent()->getParent(); 615 const char *AsmStr = MI.getOperand(0).getSymbolName(); 616 return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); 617 } 618 } 619 } 620