LLVM: lib/Target/AVR/AVRInstrInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

14

20

26

27#define GET_INSTRINFO_CTOR_DTOR

28#include "AVRGenInstrInfo.inc"

29

30namespace llvm {

31

35

39 Register SrcReg, bool KillSrc,

40 bool RenamableDest, bool RenamableSrc) const {

42 unsigned Opc;

43

44 if (AVR::DREGSRegClass.contains(DestReg, SrcReg)) {

45

46

47 if (STI.hasMOVW() && AVR::DREGSMOVWRegClass.contains(DestReg, SrcReg)) {

50 } else {

51 Register DestLo, DestHi, SrcLo, SrcHi;

52

53 TRI.splitReg(DestReg, DestLo, DestHi);

54 TRI.splitReg(SrcReg, SrcLo, SrcHi);

55

56

57

58

59

60

61 if (DestLo == SrcHi) {

66 } else {

71 }

72 }

73 } else {

74 if (AVR::GPR8RegClass.contains(DestReg, SrcReg)) {

75 Opc = AVR::MOVRdRr;

76 } else if (SrcReg == AVR::SP && AVR::DREGSRegClass.contains(DestReg)) {

77 Opc = AVR::SPREAD;

78 } else if (DestReg == AVR::SP && AVR::DREGSRegClass.contains(SrcReg)) {

79 Opc = AVR::SPWRITE;

80 } else {

82 }

83

86 }

87}

88

90 int &FrameIndex) const {

91 switch (MI.getOpcode()) {

92 case AVR::LDDRdPtrQ:

93 case AVR::LDDWRdYQ: {

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

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

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

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

98 }

99 break;

100 }

101 default:

102 break;

103 }

104

105 return 0;

106}

107

109 int &FrameIndex) const {

110 switch (MI.getOpcode()) {

111 case AVR::STDPtrQRr:

112 case AVR::STDWPtrQRr: {

113 if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&

114 MI.getOperand(1).getImm() == 0) {

115 FrameIndex = MI.getOperand(0).getIndex();

116 return MI.getOperand(2).getReg();

117 }

118 break;

119 }

120 default:

121 break;

122 }

123

124 return 0;

125}

126

133

135

137

142

143 unsigned Opcode = 0;

144 if (RI.isTypeLegalForClass(*RC, MVT::i8)) {

145 Opcode = AVR::STDPtrQRr;

146 } else if (RI.isTypeLegalForClass(*RC, MVT::i16)) {

147 Opcode = AVR::STDWPtrQRr;

148 } else {

149 llvm_unreachable("Cannot store this register into a stack slot!");

150 }

151

157}

158

161 Register DestReg, int FrameIndex,

167

172

173 unsigned Opcode = 0;

174 if (TRI.isTypeLegalForClass(*RC, MVT::i8)) {

175 Opcode = AVR::LDDRdPtrQ;

176 } else if (TRI.isTypeLegalForClass(*RC, MVT::i16)) {

177

178

179 Opcode = AVR::LDDWRdYQ;

180 } else {

181 llvm_unreachable("Cannot load this register from a stack slot!");

182 }

183

188}

189

191 switch (CC) {

192 default:

195 return get(AVR::BREQk);

197 return get(AVR::BRNEk);

199 return get(AVR::BRGEk);

201 return get(AVR::BRLTk);

203 return get(AVR::BRSHk);

205 return get(AVR::BRLOk);

207 return get(AVR::BRMIk);

209 return get(AVR::BRPLk);

210 }

211}

212

214 switch (Opc) {

215 default:

217 case AVR::BREQk:

219 case AVR::BRNEk:

221 case AVR::BRSHk:

223 case AVR::BRLOk:

225 case AVR::BRMIk:

227 case AVR::BRPLk:

229 case AVR::BRGEk:

231 case AVR::BRLTk:

233 }

234}

235

237 switch (CC) {

238 default:

256 }

257}

258

263 bool AllowModify) const {

264

265

268

269 while (I != MBB.begin()) {

270 --I;

271 if (I->isDebugInstr()) {

272 continue;

273 }

274

275

276

277 if (!isUnpredicatedTerminator(*I)) {

278 break;

279 }

280

281

282

283 if (I->getDesc().isBranch()) {

284 return true;

285 }

286

287

288

289 if (I->getOpcode() == AVR::RJMPk) {

290 UnCondBrIter = I;

291

292 if (!AllowModify) {

293 TBB = I->getOperand(0).getMBB();

294 continue;

295 }

296

297

298 MBB.erase(std::next(I), MBB.end());

299

300 Cond.clear();

301 FBB = nullptr;

302

303

304 if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {

305 TBB = nullptr;

306 I->eraseFromParent();

307 I = MBB.end();

308 UnCondBrIter = MBB.end();

309 continue;

310 }

311

312

313 TBB = I->getOperand(0).getMBB();

314 continue;

315 }

316

317

320 return true;

321 }

322

323

324 if (Cond.empty()) {

326 if (AllowModify && UnCondBrIter != MBB.end() &&

327 MBB.isLayoutSuccessor(TargetBB)) {

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

348

350 .addMBB(UnCondBrIter->getOperand(0).getMBB());

353

354 OldInst->eraseFromParent();

355 UnCondBrIter->eraseFromParent();

356

357

358 UnCondBrIter = MBB.end();

359 I = MBB.end();

360 continue;

361 }

362

363 FBB = TBB;

364 TBB = I->getOperand(0).getMBB();

366 continue;

367 }

368

369

370

373

374

375

376 if (TBB != I->getOperand(0).getMBB()) {

377 return true;

378 }

379

381

382 if (OldBranchCode == BranchCode) {

383 continue;

384 }

385

386 return true;

387 }

388

389 return false;

390}

391

396 const DebugLoc &DL, int *BytesAdded) const {

397 if (BytesAdded)

398 *BytesAdded = 0;

399

400

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

403 "AVR branch conditions have one component!");

404

405 if (Cond.empty()) {

406 assert(!FBB && "Unconditional branch with multiple successors!");

408 if (BytesAdded)

410 return 1;

411 }

412

413

414 unsigned Count = 0;

417

418 if (BytesAdded)

421

422 if (FBB) {

423

425 if (BytesAdded)

428 }

429

431}

432

434 int *BytesRemoved) const {

435 if (BytesRemoved)

436 *BytesRemoved = 0;

437

439 unsigned Count = 0;

440

441 while (I != MBB.begin()) {

442 --I;

443 if (I->isDebugInstr()) {

444 continue;

445 }

446

447

448 if (I->getOpcode() != AVR::RJMPk &&

450 break;

451 }

452

453

454 if (BytesRemoved)

456 I->eraseFromParent();

457 I = MBB.end();

459 }

460

462}

463

466 assert(Cond.size() == 1 && "Invalid AVR branch condition!");

467

470

471 return false;

472}

473

475 unsigned Opcode = MI.getOpcode();

476

477 switch (Opcode) {

478

479 default: {

481 return Desc.getSize();

482 }

483 case TargetOpcode::EH_LABEL:

484 case TargetOpcode::IMPLICIT_DEF:

485 case TargetOpcode::KILL:

486 case TargetOpcode::DBG_VALUE:

487 return 0;

488 case TargetOpcode::INLINEASM:

489 case TargetOpcode::INLINEASM_BR: {

494 return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),

496 }

497 }

498}

499

502 switch (MI.getOpcode()) {

503 default:

505 case AVR::JMPk:

506 case AVR::CALLk:

507 case AVR::RCALLk:

508 case AVR::RJMPk:

509 case AVR::BREQk:

510 case AVR::BRNEk:

511 case AVR::BRSHk:

512 case AVR::BRLOk:

513 case AVR::BRMIk:

514 case AVR::BRPLk:

515 case AVR::BRGEk:

516 case AVR::BRLTk:

517 return MI.getOperand(0).getMBB();

518 case AVR::BRBSsk:

519 case AVR::BRBCsk:

520 return MI.getOperand(1).getMBB();

521 case AVR::SBRCRrB:

522 case AVR::SBRSRrB:

523 case AVR::SBICAb:

524 case AVR::SBISAb:

526 }

527}

528

530 int64_t BrOffset) const {

531

532 switch (BranchOp) {

533 default:

535 case AVR::JMPk:

536 case AVR::CALLk:

537 return STI.hasJMPCALL();

538 case AVR::RCALLk:

539 case AVR::RJMPk:

540 return isIntN(13, BrOffset);

541 case AVR::BRBSsk:

542 case AVR::BRBCsk:

543 case AVR::BREQk:

544 case AVR::BRNEk:

545 case AVR::BRSHk:

546 case AVR::BRLOk:

547 case AVR::BRMIk:

548 case AVR::BRPLk:

549 case AVR::BRGEk:

550 case AVR::BRLTk:

551 return isIntN(7, BrOffset);

552 }

553}

554

558 const DebugLoc &DL, int64_t BrOffset,

560

561

562

563

564

565 if (STI.hasJMPCALL())

567 else

568

569

570

572}

573

574}

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

const TargetInstrInfo & TII

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

Register const TargetRegisterInfo * TRI

const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB

const SmallVectorImpl< MachineOperand > & Cond

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

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

Definition AVRInstrInfo.cpp:108

AVRCC::CondCodes getCondFromBranchOpc(unsigned Opc) const

Definition AVRInstrInfo.cpp:213

AVRCC::CondCodes getOppositeCondition(AVRCC::CondCodes CC) const

Definition AVRInstrInfo.cpp:236

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 AVRInstrInfo.cpp:36

void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset, RegScavenger *RS) const override

Definition AVRInstrInfo.cpp:555

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

Definition AVRInstrInfo.cpp:159

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

Definition AVRInstrInfo.cpp:392

MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override

Definition AVRInstrInfo.cpp:501

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

Definition AVRInstrInfo.cpp:259

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 AVRInstrInfo.cpp:127

AVRInstrInfo(const AVRSubtarget &STI)

Definition AVRInstrInfo.cpp:32

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

Definition AVRInstrInfo.cpp:464

unsigned getInstSizeInBytes(const MachineInstr &MI) const override

Definition AVRInstrInfo.cpp:474

bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override

Definition AVRInstrInfo.cpp:529

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

Definition AVRInstrInfo.cpp:433

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

Definition AVRInstrInfo.cpp:89

const MCInstrDesc & getBrCond(AVRCC::CondCodes CC) const

Definition AVRInstrInfo.cpp:190

Contains AVR-specific information for each MachineFunction.

void setHasSpills(bool B)

Utilities relating to AVR registers.

A specific AVR target MCU.

A generic AVR implementation.

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

Describe properties that are true of each instruction in the target description file.

unsigned getOpcode() const

Return the opcode number for this descriptor.

MachineInstrBundleIterator< MachineInstr > iterator

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

Align getObjectAlign(int ObjectIdx) const

Return the alignment of the specified stack object.

int64_t getObjectSize(int ObjectIdx) const

Return the size of the specified object.

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.

Ty * getInfo()

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

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 & addFrameIndex(int Idx) 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 & addMemOperand(MachineMemOperand *MMO) const

Representation of each machine instruction.

A description of a memory reference used in the backend.

@ MOLoad

The memory access reads data.

@ MOStore

The memory access writes data.

static MachineOperand CreateImm(int64_t Val)

Wrapper class representing virtual and physical registers.

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

TargetInstrInfo - Interface to description of machine instruction set.

const MCAsmInfo * getMCAsmInfo() const

Return target specific asm information.

#define llvm_unreachable(msg)

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

CondCodes

AVR specific condition codes.

@ COND_SH

Unsigned same or higher.

@ COND_GE

Greater than or equal.

Contains the AVR backend.

@ Undef

Value of the register doesn't matter.

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.

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

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

FunctionAddr VTableAddr Count

unsigned getKillRegState(bool B)

constexpr bool isIntN(unsigned N, int64_t x)

Checks if an signed integer fits into the given (dynamic) bit width.

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

Return a MachinePointerInfo record that refers to the specified FrameIndex.