LLVM: lib/Target/CSKY/CSKYInstrInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

19

20#define DEBUG_TYPE "csky-instr-info"

21

22using namespace llvm;

23

24#define GET_INSTRINFO_CTOR_DTOR

25#include "CSKYGenInstrInfo.inc"

26

31 v2sf = STI.hasFPUv2SingleFloat();

32 v2df = STI.hasFPUv2DoubleFloat();

33 v3sf = STI.hasFPUv3SingleFloat();

34 v3df = STI.hasFPUv3DoubleFloat();

35}

36

39

41 "Unknown conditional branch");

45}

46

51 bool AllowModify) const {

52 TBB = FBB = nullptr;

54

55

57 if (I == MBB.end() || !isUnpredicatedTerminator(*I))

58 return false;

59

60

61

63 int NumTerminators = 0;

64 for (auto J = I.getReverse(); J != MBB.rend() && isUnpredicatedTerminator(*J);

65 J++) {

66 NumTerminators++;

67 if (J->getDesc().isUnconditionalBranch() ||

68 J->getDesc().isIndirectBranch()) {

69 FirstUncondOrIndirectBr = J.getReverse();

70 }

71 }

72

73

74

75 if (AllowModify && FirstUncondOrIndirectBr != MBB.end()) {

76 while (std::next(FirstUncondOrIndirectBr) != MBB.end()) {

77 std::next(FirstUncondOrIndirectBr)->eraseFromParent();

78 NumTerminators--;

79 }

80 I = FirstUncondOrIndirectBr;

81 }

82

83

84 if (I->getDesc().isIndirectBranch())

85 return true;

86

87

88 if (NumTerminators > 2)

89 return true;

90

91

92 if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) {

94 return false;

95 }

96

97

98 if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) {

100 return false;

101 }

102

103

104 if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() &&

105 I->getDesc().isUnconditionalBranch()) {

108 return false;

109 }

110

111

112 return true;

113}

114

116 int *BytesRemoved) const {

117 if (BytesRemoved)

118 *BytesRemoved = 0;

120 if (I == MBB.end())

121 return 0;

122

123 if (I->getDesc().isUnconditionalBranch() &&

124 I->getDesc().isConditionalBranch())

125 return 0;

126

127

128 if (BytesRemoved)

130 I->eraseFromParent();

131

132 I = MBB.end();

133

134 if (I == MBB.begin())

135 return 1;

136 --I;

137 if (I->getDesc().isConditionalBranch())

138 return 1;

139

140

141 if (BytesRemoved)

143 I->eraseFromParent();

144 return 2;

145}

146

149 assert(MI.getDesc().isBranch() && "Unexpected opcode!");

150

151 int NumOp = MI.getNumExplicitOperands();

152 assert(MI.getOperand(NumOp - 1).isMBB() && "Expected MBB!");

153 return MI.getOperand(NumOp - 1).getMBB();

154}

155

159 if (BytesAdded)

160 *BytesAdded = 0;

161

162

163 assert(TBB && "insertBranch must not be told to insert a fallthrough");

165 "CSKY branch conditions have two components!");

166

167

168 if (Cond.empty()) {

170 if (BytesAdded)

172 return 1;

173 }

174

175

176 unsigned Opc = Cond[0].getImm();

178 if (BytesAdded)

180

181

182 if (!FBB)

183 return 1;

184

185

187 if (BytesAdded)

189 return 2;

190}

191

193 switch (Opcode) {

194 default:

196 case CSKY::BT32:

197 return CSKY::BF32;

198 case CSKY::BT16:

199 return CSKY::BF16;

200 case CSKY::BF32:

201 return CSKY::BT32;

202 case CSKY::BF16:

203 return CSKY::BT16;

204 case CSKY::BHZ32:

205 return CSKY::BLSZ32;

206 case CSKY::BHSZ32:

207 return CSKY::BLZ32;

208 case CSKY::BLZ32:

209 return CSKY::BHSZ32;

210 case CSKY::BLSZ32:

211 return CSKY::BHZ32;

212 case CSKY::BNEZ32:

213 return CSKY::BEZ32;

214 case CSKY::BEZ32:

215 return CSKY::BNEZ32;

216 }

217}

218

221 assert((Cond.size() == 2) && "Invalid branch condition!");

223 return false;

224}

225

232

234

236 if (STI.hasE2()) {

237 DstReg = MRI.createVirtualRegister(&CSKY::GPRRegClass);

238

241 .addImm(Val & 0xFFFF)

245 .addImm((Val >> 16) & 0xFFFF)

247 } else {

249 .addImm((Val >> 16) & 0xFFFF)

253 .addImm(Val & 0xFFFF)

255 }

256

257 } else {

258 DstReg = MRI.createVirtualRegister(&CSKY::mGPRRegClass);

265 .addImm((Val >> 8) & 0xFF)

271 if ((Val & 0xFF) != 0)

278 .addImm((Val >> 16) & 0xFF)

284 if (((Val >> 8) & 0xFF) != 0)

287 .addImm((Val >> 8) & 0xFF)

293 if ((Val & 0xFF) != 0)

298 } else {

300 .addImm((Val >> 24) & 0xFF)

306 if (((Val >> 16) & 0xFF) != 0)

309 .addImm((Val >> 16) & 0xFF)

315 if (((Val >> 8) & 0xFF) != 0)

318 .addImm((Val >> 8) & 0xFF)

324 if ((Val & 0xFF) != 0)

329 }

330 }

331

332 return DstReg;

333}

334

336 int &FrameIndex) const {

337 switch (MI.getOpcode()) {

338 default:

339 return 0;

340 case CSKY::LD16B:

341 case CSKY::LD16H:

342 case CSKY::LD16W:

343 case CSKY::LD32B:

344 case CSKY::LD32BS:

345 case CSKY::LD32H:

346 case CSKY::LD32HS:

347 case CSKY::LD32W:

348 case CSKY::FLD_S:

349 case CSKY::FLD_D:

350 case CSKY::f2FLD_S:

351 case CSKY::f2FLD_D:

352 case CSKY::RESTORE_CARRY:

353 break;

354 }

355

356 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&

357 MI.getOperand(2).getImm() == 0) {

358 FrameIndex = MI.getOperand(1).getIndex();

359 return MI.getOperand(0).getReg();

360 }

361

362 return 0;

363}

364

366 int &FrameIndex) const {

367 switch (MI.getOpcode()) {

368 default:

369 return 0;

370 case CSKY::ST16B:

371 case CSKY::ST16H:

372 case CSKY::ST16W:

373 case CSKY::ST32B:

374 case CSKY::ST32H:

375 case CSKY::ST32W:

376 case CSKY::FST_S:

377 case CSKY::FST_D:

378 case CSKY::f2FST_S:

379 case CSKY::f2FST_D:

380 case CSKY::SPILL_CARRY:

381 break;

382 }

383

384 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&

385 MI.getOperand(2).getImm() == 0) {

386 FrameIndex = MI.getOperand(1).getIndex();

387 return MI.getOperand(0).getReg();

388 }

389

390 return 0;

391}

392

395 Register SrcReg, bool IsKill, int FI,

400 if (I != MBB.end())

401 DL = I->getDebugLoc();

402

406

407 unsigned Opcode = 0;

408

409 if (CSKY::GPRRegClass.hasSubClassEq(RC)) {

410 Opcode = CSKY::ST32W;

411 } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) {

412 Opcode = CSKY::SPILL_CARRY;

414 } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC))

415 Opcode = CSKY::FST_S;

416 else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC))

417 Opcode = CSKY::FST_D;

418 else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC))

419 Opcode = CSKY::f2FST_S;

420 else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC))

421 Opcode = CSKY::f2FST_D;

422 else {

424 }

425

428 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));

429

435}

436

444 if (I != MBB.end())

445 DL = I->getDebugLoc();

446

450

451 unsigned Opcode = 0;

452

453 if (CSKY::GPRRegClass.hasSubClassEq(RC)) {

454 Opcode = CSKY::LD32W;

455 } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) {

456 Opcode = CSKY::RESTORE_CARRY;

458 } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC))

459 Opcode = CSKY::FLD_S;

460 else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC))

461 Opcode = CSKY::FLD_D;

462 else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC))

463 Opcode = CSKY::f2FLD_S;

464 else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC))

465 Opcode = CSKY::f2FLD_D;

466 else {

468 }

469

472 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));

473

478}

479

483 Register SrcReg, bool KillSrc,

484 bool RenamableDest, bool RenamableSrc) const {

485 if (CSKY::GPRRegClass.contains(SrcReg) &&

486 CSKY::CARRYRegClass.contains(DestReg)) {

487 if (STI.hasE2()) {

491 } else {

492 assert(SrcReg < CSKY::R8);

496 }

497 return;

498 }

499

500 if (CSKY::CARRYRegClass.contains(SrcReg) &&

501 CSKY::GPRRegClass.contains(DestReg)) {

502

503 if (STI.hasE2()) {

506 } else {

507 assert(DestReg < CSKY::R16);

508 assert(DestReg < CSKY::R8);

520 }

521 return;

522 }

523

524 unsigned Opcode = 0;

525 if (CSKY::GPRRegClass.contains(DestReg, SrcReg))

526 Opcode = STI.hasE2() ? CSKY::MOV32 : CSKY::MOV16;

527 else if (v2sf && CSKY::sFPR32RegClass.contains(DestReg, SrcReg))

528 Opcode = CSKY::FMOV_S;

529 else if (v3sf && CSKY::FPR32RegClass.contains(DestReg, SrcReg))

530 Opcode = CSKY::f2FMOV_S;

531 else if (v2df && CSKY::sFPR64RegClass.contains(DestReg, SrcReg))

532 Opcode = CSKY::FMOV_D;

533 else if (v3df && CSKY::FPR64RegClass.contains(DestReg, SrcReg))

534 Opcode = CSKY::f2FMOV_D;

535 else if (v2sf && CSKY::sFPR32RegClass.contains(SrcReg) &&

536 CSKY::GPRRegClass.contains(DestReg))

537 Opcode = CSKY::FMFVRL;

538 else if (v3sf && CSKY::FPR32RegClass.contains(SrcReg) &&

539 CSKY::GPRRegClass.contains(DestReg))

540 Opcode = CSKY::f2FMFVRL;

541 else if (v2df && CSKY::sFPR64RegClass.contains(SrcReg) &&

542 CSKY::GPRRegClass.contains(DestReg))

543 Opcode = CSKY::FMFVRL_D;

544 else if (v3df && CSKY::FPR64RegClass.contains(SrcReg) &&

545 CSKY::GPRRegClass.contains(DestReg))

546 Opcode = CSKY::f2FMFVRL_D;

547 else if (v2sf && CSKY::GPRRegClass.contains(SrcReg) &&

548 CSKY::sFPR32RegClass.contains(DestReg))

549 Opcode = CSKY::FMTVRL;

550 else if (v3sf && CSKY::GPRRegClass.contains(SrcReg) &&

551 CSKY::FPR32RegClass.contains(DestReg))

552 Opcode = CSKY::f2FMTVRL;

553 else if (v2df && CSKY::GPRRegClass.contains(SrcReg) &&

554 CSKY::sFPR64RegClass.contains(DestReg))

555 Opcode = CSKY::FMTVRL_D;

556 else if (v3df && CSKY::GPRRegClass.contains(SrcReg) &&

557 CSKY::FPR64RegClass.contains(DestReg))

558 Opcode = CSKY::f2FMTVRL_D;

559 else {

560 LLVM_DEBUG(dbgs() << "src = " << SrcReg << ", dst = " << DestReg);

563 }

564

567}

568

573

575 if (GlobalBaseReg != 0)

576 return GlobalBaseReg;

577

578

579

583

587

588 unsigned CPI = MCP->getConstantPoolIndex(CPV, Align(4));

589

596

597 GlobalBaseReg = MRI.createVirtualRegister(&CSKY::GPRRegClass);

598 BuildMI(FirstMBB, MBBI, DL, get(TargetOpcode::COPY), GlobalBaseReg)

600

602 return GlobalBaseReg;

603}

604

606 switch (MI.getOpcode()) {

607 default:

608 return MI.getDesc().getSize();

609 case CSKY::CONSTPOOL_ENTRY:

610 return MI.getOperand(2).getImm();

611 case CSKY::SPILL_CARRY:

612 case CSKY::RESTORE_CARRY:

613 case CSKY::PseudoTLSLA32:

614 return 8;

615 case TargetOpcode::INLINEASM_BR:

616 case TargetOpcode::INLINEASM: {

618 const char *AsmStr = MI.getOperand(0).getSymbolName();

620 }

621 }

622}

unsigned const MachineRegisterInfo * MRI

static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

static unsigned getOppositeBranchOpc(unsigned Opcode)

Definition CSKYInstrInfo.cpp:192

Register const TargetRegisterInfo * TRI

const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB

const SmallVectorImpl< MachineOperand > & Cond

static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

static CSKYConstantPoolSymbol * Create(Type *Ty, const char *S, unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier)

CSKYConstantPoolValue - CSKY specific constantpool value.

unsigned getInstSizeInBytes(const MachineInstr &MI) const override

Definition CSKYInstrInfo.cpp:605

unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override

Definition CSKYInstrInfo.cpp:115

unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override

Definition CSKYInstrInfo.cpp:156

CSKYInstrInfo(const CSKYSubtarget &STI, const CSKYRegisterInfo &RI)

Definition CSKYInstrInfo.cpp:27

const CSKYSubtarget & STI

MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override

Definition CSKYInstrInfo.cpp:148

bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override

Definition CSKYInstrInfo.cpp:47

void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override

Definition CSKYInstrInfo.cpp:393

Register movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, uint64_t Val, MachineInstr::MIFlag Flag=MachineInstr::NoFlags) const

Definition CSKYInstrInfo.cpp:226

Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override

Definition CSKYInstrInfo.cpp:335

Register getGlobalBaseReg(MachineFunction &MF) const

Definition CSKYInstrInfo.cpp:569

bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override

Definition CSKYInstrInfo.cpp:219

void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override

Definition CSKYInstrInfo.cpp:437

Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override

Definition CSKYInstrInfo.cpp:365

void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override

Definition CSKYInstrInfo.cpp:480

Register getGlobalBaseReg() const

void setGlobalBaseReg(Register Reg)

LLVMContext & getContext() const

getContext - Return a reference to the LLVMContext associated with this function.

bool isConditionalBranch() const

Return true if this is a branch which may fall through to the next instruction or may transfer contro...

MachineInstrBundleIterator< MachineInstr > iterator

The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...

The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.

MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)

getMachineMemOperand - Allocate a new MachineMemOperand.

MachineFrameInfo & getFrameInfo()

getFrameInfo - Return the frame info object for the current function.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Function & getFunction()

Return the LLVM function that this machine code represents.

Ty * getInfo()

getInfo - Keep track of various per-function pieces of information for backends that would like to do...

MachineConstantPool * getConstantPool()

getConstantPool - Return the constant pool object for the current function.

const MachineBasicBlock & front() const

const TargetMachine & getTarget() const

getTarget - Return the target machine this machine code is compiled with

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

const MachineInstrBuilder & add(const MachineOperand &MO) const

const MachineInstrBuilder & addFrameIndex(int Idx) const

const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const

const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const

Add a new virtual register operand.

const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const

const MachineInstrBuilder & setMIFlags(unsigned Flags) const

const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const

reverse_iterator getReverse() const

Get a reverse iterator to the same node.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

const MCInstrDesc & getDesc() const

Returns the target instruction descriptor of this MachineInstr.

const MachineOperand & getOperand(unsigned i) const

A description of a memory reference used in the backend.

@ MOLoad

The memory access reads data.

@ MOStore

The memory access writes data.

MachineBasicBlock * getMBB() const

static MachineOperand CreateImm(int64_t Val)

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

Wrapper class representing virtual and physical registers.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

const MCAsmInfo * getMCAsmInfo() const

Return target specific asm information.

Target - Wrapper for Target specific information.

static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ Define

Register definition.

This is an optimization pass for GlobalISel generic memory operations.

MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)

Builder interface. Specify how to create the initial instruction itself.

constexpr bool isInt(int64_t x)

Checks if an integer fits into the given bit width.

unsigned getDeadRegState(bool B)

MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)

decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

constexpr bool isUInt(uint64_t x)

Checks if an unsigned integer fits into the given bit width.

unsigned getKillRegState(bool B)

constexpr bool isShiftedUInt(uint64_t x)

Checks if a unsigned integer is an N bit number shifted left by S.

This struct is a compact representation of a valid (non-zero power of two) alignment.

static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)

Return a MachinePointerInfo record that refers to the constant pool.

static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)

Return a MachinePointerInfo record that refers to the specified FrameIndex.