LLVM: lib/Target/Xtensa/XtensaInstrInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

24

25#define GET_INSTRINFO_CTOR_DTOR

26#include "XtensaGenInstrInfo.inc"

27

28using namespace llvm;

29

43

48}

49

51 : XtensaGenInstrInfo(Xtensa::ADJCALLSTACKDOWN, Xtensa::ADJCALLSTACKUP),

52 RI(STI), STI(STI) {}

53

55 int &FrameIndex) const {

56 if (MI.getOpcode() == Xtensa::L32I) {

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

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

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

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

61 }

62 }

64}

65

67 int &FrameIndex) const {

68 if (MI.getOpcode() == Xtensa::S32I) {

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

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

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

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

73 }

74 }

76}

77

78

83

84 if (Amount == 0)

85 return;

86

89

90

92

93 if (isInt<8>(Amount)) {

95 } else {

96 unsigned Reg1;

101 }

102

106}

107

112 bool RenamableDest, bool RenamableSrc) const {

113

114

115 if (Xtensa::ARRegClass.contains(DestReg, SrcReg))

119 else

121}

122

129 unsigned LoadOpcode, StoreOpcode;

134}

135

141 unsigned LoadOpcode, StoreOpcode;

144}

145

147 unsigned &LoadOpcode,

148 unsigned &StoreOpcode,

149 int64_t offset) const {

150 assert((RC == &Xtensa::ARRegClass) &&

151 "Unsupported regclass to load or store");

152

153 LoadOpcode = Xtensa::L32I;

154 StoreOpcode = Xtensa::S32I;

155}

156

159 unsigned *Reg, int64_t Value) const {

163

164

166 if (Value >= -2048 && Value <= 2047) {

168 } else if (Value >= -32768 && Value <= 32767) {

171

174 } else if (Value >= -4294967296LL && Value <= 4294967295LL) {

175

178 const Constant *CVal = ConstantInt::get(

180 false);

182

184 } else {

185

186

188 }

189}

190

192 switch (MI.getOpcode()) {

193 case TargetOpcode::INLINEASM: {

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

197 }

198 default:

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

200 }

201}

202

205 assert(Cond.size() <= 4 && "Invalid branch condition!");

206

207 switch (Cond[0].getImm()) {

208 case Xtensa::BEQ:

209 Cond[0].setImm(Xtensa::BNE);

210 return false;

211 case Xtensa::BNE:

212 Cond[0].setImm(Xtensa::BEQ);

213 return false;

214 case Xtensa::BLT:

215 Cond[0].setImm(Xtensa::BGE);

216 return false;

217 case Xtensa::BGE:

218 Cond[0].setImm(Xtensa::BLT);

219 return false;

220 case Xtensa::BLTU:

221 Cond[0].setImm(Xtensa::BGEU);

222 return false;

223 case Xtensa::BGEU:

224 Cond[0].setImm(Xtensa::BLTU);

225 return false;

226 case Xtensa::BEQI:

227 Cond[0].setImm(Xtensa::BNEI);

228 return false;

229 case Xtensa::BNEI:

230 Cond[0].setImm(Xtensa::BEQI);

231 return false;

232 case Xtensa::BGEI:

233 Cond[0].setImm(Xtensa::BLTI);

234 return false;

235 case Xtensa::BLTI:

236 Cond[0].setImm(Xtensa::BGEI);

237 return false;

238 case Xtensa::BGEUI:

239 Cond[0].setImm(Xtensa::BLTUI);

240 return false;

241 case Xtensa::BLTUI:

242 Cond[0].setImm(Xtensa::BGEUI);

243 return false;

244 case Xtensa::BEQZ:

245 Cond[0].setImm(Xtensa::BNEZ);

246 return false;

247 case Xtensa::BNEZ:

248 Cond[0].setImm(Xtensa::BEQZ);

249 return false;

250 case Xtensa::BLTZ:

251 Cond[0].setImm(Xtensa::BGEZ);

252 return false;

253 case Xtensa::BGEZ:

254 Cond[0].setImm(Xtensa::BLTZ);

255 return false;

256 default:

258 }

259}

260

263 unsigned OpCode = MI.getOpcode();

264 switch (OpCode) {

265 case Xtensa::BR_JT:

266 case Xtensa::JX:

267 return nullptr;

268 case Xtensa::J:

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

270 case Xtensa::BEQ:

271 case Xtensa::BNE:

272 case Xtensa::BLT:

273 case Xtensa::BLTU:

274 case Xtensa::BGE:

275 case Xtensa::BGEU:

276 return MI.getOperand(2).getMBB();

277 case Xtensa::BEQI:

278 case Xtensa::BNEI:

279 case Xtensa::BLTI:

280 case Xtensa::BLTUI:

281 case Xtensa::BGEI:

282 case Xtensa::BGEUI:

283 return MI.getOperand(2).getMBB();

284 case Xtensa::BEQZ:

285 case Xtensa::BNEZ:

286 case Xtensa::BLTZ:

287 case Xtensa::BGEZ:

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

289 default:

291 }

292}

293

295 int64_t BrOffset) const {

296 switch (BranchOp) {

297 case Xtensa::J:

298 BrOffset -= 4;

299 return isIntN(18, BrOffset);

300 case Xtensa::JX:

301 return true;

302 case Xtensa::BR_JT:

303 return true;

304 case Xtensa::BEQ:

305 case Xtensa::BNE:

306 case Xtensa::BLT:

307 case Xtensa::BLTU:

308 case Xtensa::BGE:

309 case Xtensa::BGEU:

310 case Xtensa::BEQI:

311 case Xtensa::BNEI:

312 case Xtensa::BLTI:

313 case Xtensa::BLTUI:

314 case Xtensa::BGEI:

315 case Xtensa::BGEUI:

316 BrOffset -= 4;

317 return isIntN(8, BrOffset);

318 case Xtensa::BEQZ:

319 case Xtensa::BNEZ:

320 case Xtensa::BLTZ:

321 case Xtensa::BGEZ:

322 BrOffset -= 4;

323 return isIntN(12, BrOffset);

324 default:

326 }

327}

328

333 bool AllowModify = false) const {

334

335

336

337

340 --I;

341 if (I->isDebugValue())

342 continue;

343

344

345

346 if (!isUnpredicatedTerminator(*I))

347 break;

348

349

350

354 if (isBranch(I, ThisCond, ThisTarget))

355 return true;

356

357

358 if (!ThisTarget->isMBB())

359 return true;

360

361 if (ThisCond[0].getImm() == Xtensa::J) {

362

363 if (!AllowModify) {

365 continue;

366 }

367

368

369 while (std::next(I) != MBB.end())

371

372 Cond.clear();

373 FBB = 0;

374

375

377 continue;

378 }

379

380

381 if (Cond.empty()) {

382

383 FBB = TBB;

386

387

388 for (unsigned int i = 0; i < (I->getNumExplicitOperands() - 1); i++)

389 Cond.push_back(I->getOperand(i));

390

391 continue;

392 }

393

394

397

398

399

401 return true;

402

403

404 unsigned OldCond = Cond[0].getImm();

405 if (OldCond == ThisCond[0].getImm())

406 continue;

407 }

408

409 return false;

410}

411

413 int *BytesRemoved) const {

414

416 unsigned Count = 0;

417 if (BytesRemoved)

418 *BytesRemoved = 0;

419

421 --I;

426 break;

427 if (Target->isMBB())

428 break;

429

430 if (BytesRemoved)

432 I->eraseFromParent();

434 ++Count;

435 }

436 return Count;

437}

438

442 unsigned Count = 0;

443 if (BytesAdded)

444 *BytesAdded = 0;

445 if (FBB) {

446

447

448

451 Count++;

452 if (BytesAdded)

454 return Count;

455 }

456

458 return Count;

459}

460

464 const DebugLoc &DL, int64_t BrOffset,

466 assert(RS && "RegScavenger required for long branching");

468 "new block should be inserted for expanding unconditional branch");

470

476

477 if (!isInt<32>(BrOffset))

479 "Branch offsets outside of the signed 32-bit range not supported");

480

481 Register ScratchReg = MRI.createVirtualRegister(&Xtensa::ARRegClass);

483

484

485

488

492 false, 0,

493 false);

494 if (ScavRegister != Xtensa::NoRegister)

496 else {

497

498

499 ScavRegister = Xtensa::A12;

500

501 int FrameIndex = XtensaFI->getBranchRelaxationScratchFrameIndex();

502 if (FrameIndex == -1)

504 "Unable to properly handle scavenged register for indirect jump, "

505 "function code size is significantly larger than estimated");

506

508 &Xtensa::ARRegClass, &RI, Register());

510 0, 1);

511

513 &Xtensa::ARRegClass, &RI, Register());

515 0, 1);

516 JumpToMBB = &RestoreBB;

517 }

518

523

524 MRI.replaceRegWith(ScratchReg, ScavRegister);

525 MRI.clearVirtRegs();

526}

527

532 "Xtensa branch conditions have less than four components!");

533

534 if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {

535

537 if (BytesAdded && MI)

539 return 1;

540 }

541

542 unsigned Count = 0;

543 unsigned BR_C = Cond[0].getImm();

545 switch (BR_C) {

546 case Xtensa::BEQ:

547 case Xtensa::BNE:

548 case Xtensa::BLT:

549 case Xtensa::BLTU:

550 case Xtensa::BGE:

551 case Xtensa::BGEU:

556 break;

557 case Xtensa::BEQI:

558 case Xtensa::BNEI:

559 case Xtensa::BLTI:

560 case Xtensa::BLTUI:

561 case Xtensa::BGEI:

562 case Xtensa::BGEUI:

567 break;

568 case Xtensa::BEQZ:

569 case Xtensa::BNEZ:

570 case Xtensa::BLTZ:

571 case Xtensa::BGEZ:

573 break;

574 default:

576 }

577 if (BytesAdded && MI)

579 ++Count;

580 return Count;

581}

582

588 int *BytesAdded) const {

589

590 assert(TBB && "InsertBranch must not be told to insert a fallthrough");

592 "Xtensa branch conditions have less than four components!");

593

594 if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {

595

597 if (BytesAdded && MI)

599 return 1;

600 }

601

602 unsigned Count = 0;

603 unsigned BR_C = Cond[0].getImm();

605 switch (BR_C) {

606 case Xtensa::BEQ:

607 case Xtensa::BNE:

608 case Xtensa::BLT:

609 case Xtensa::BLTU:

610 case Xtensa::BGE:

611 case Xtensa::BGEU:

616 break;

617 case Xtensa::BEQI:

618 case Xtensa::BNEI:

619 case Xtensa::BLTI:

620 case Xtensa::BLTUI:

621 case Xtensa::BGEI:

622 case Xtensa::BGEUI:

627 break;

628 case Xtensa::BEQZ:

629 case Xtensa::BNEZ:

630 case Xtensa::BLTZ:

631 case Xtensa::BGEZ:

633 break;

634 default:

636 }

637 if (BytesAdded && MI)

639 ++Count;

640 return Count;

641}

642

646 unsigned OpCode = MI->getOpcode();

647 switch (OpCode) {

648 case Xtensa::J:

649 case Xtensa::JX:

650 case Xtensa::BR_JT:

651 Cond[0].setImm(OpCode);

653 return true;

654 case Xtensa::BEQ:

655 case Xtensa::BNE:

656 case Xtensa::BLT:

657 case Xtensa::BLTU:

658 case Xtensa::BGE:

659 case Xtensa::BGEU:

660 Cond[0].setImm(OpCode);

662 return true;

663

664 case Xtensa::BEQI:

665 case Xtensa::BNEI:

666 case Xtensa::BLTI:

667 case Xtensa::BLTUI:

668 case Xtensa::BGEI:

669 case Xtensa::BGEUI:

670 Cond[0].setImm(OpCode);

672 return true;

673

674 case Xtensa::BEQZ:

675 case Xtensa::BNEZ:

676 case Xtensa::BLTZ:

677 case Xtensa::BGEZ:

678 Cond[0].setImm(OpCode);

680 return true;

681

682 default:

683 assert(MI->getDesc().isBranch() && "Unknown branch opcode");

684 return false;

685 }

686}

unsigned const MachineRegisterInfo * MRI

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...

unsigned const TargetRegisterInfo * TRI

static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)

uint64_t IntrinsicInst * II

const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB

const SmallVectorImpl< MachineOperand > & Cond

This file declares the machine register scavenger class.

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

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

static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI)

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

This is an important base class in LLVM.

LLVMContext & getContext() const

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

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

bool mayStore() const

Return true if this instruction could possibly modify memory.

bool mayLoad() const

Return true if this instruction could possibly read memory.

Wrapper class representing physical registers. Should be passed by value.

unsigned pred_size() const

void eraseFromParent()

This method unlinks 'this' from the containing function and deletes it.

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

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

unsigned getConstantPoolIndex(const Constant *C, Align Alignment)

getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.

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.

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

Representation of each machine instruction.

void addOperand(MachineFunction &MF, const MachineOperand &Op)

Add the specified operand to the instruction.

A description of a memory reference used in the backend.

Flags

Flags values. These may be or'd together.

@ MOLoad

The memory access reads data.

@ MOStore

The memory access writes data.

MachineOperand class - Representation of each machine instruction operand.

MachineBasicBlock * getMBB() const

static MachineOperand CreateImm(int64_t Val)

static MachineOperand CreateCPI(unsigned Idx, int Offset, unsigned TargetFlags=0)

bool isMBB() const

isMBB - Tests if this is a MO_MachineBasicBlock operand.

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

Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")

createVirtualRegister - Create and return a new virtual register in the function with the specified r...

void enterBasicBlockEnd(MachineBasicBlock &MBB)

Start tracking liveness from the end of basic block MBB.

void setRegUsed(Register Reg, LaneBitmask LaneMask=LaneBitmask::getAll())

Tell the scavenger a register is used.

Register scavengeRegisterBackwards(const TargetRegisterClass &RC, MachineBasicBlock::iterator To, bool RestoreAfter, int SPAdj, bool AllowSpill=true)

Make a register of the specific register class available from the current position backwards to the p...

Wrapper class representing virtual and physical registers.

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

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

const MCAsmInfo * getMCAsmInfo() const

Return target specific asm information.

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

Target - Wrapper for Target specific information.

static IntegerType * getInt32Ty(LLVMContext &C)

LLVM Value Representation.

static XtensaConstantPoolMBB * Create(LLVMContext &C, const MachineBasicBlock *M, unsigned ID)

XtensaConstantPoolValue - Xtensa specific constantpool value.

bool isBranch(const MachineBasicBlock::iterator &MI, SmallVectorImpl< MachineOperand > &Cond, const MachineOperand *&Target) const

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

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

bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override

unsigned getInstSizeInBytes(const MachineInstr &MI) const override

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

void loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned *Reg, int64_t Value) const

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

void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &DestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset=0, RegScavenger *RS=nullptr) const override

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

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

unsigned insertConstBranchAtInst(MachineBasicBlock &MBB, MachineInstr *I, int64_t offset, ArrayRef< MachineOperand > Cond, DebugLoc DL, int *BytesAdded) const

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

void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const

Adjust SP by Amount bytes.

unsigned insertBranchAtInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MachineBasicBlock *TBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded) const

MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override

XtensaInstrInfo(const XtensaSubtarget &STI)

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

void getLoadStoreOpcodes(const TargetRegisterClass *RC, unsigned &LoadOpcode, unsigned &StoreOpcode, int64_t offset) const

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

bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override

self_iterator getIterator()

#define llvm_unreachable(msg)

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

@ C

The default llvm calling convention, compatible with C.

@ Kill

The last use of a register.

This is an optimization pass for GlobalISel generic memory operations.

@ Low

Lower the current thread's priority such that it does not affect foreground tasks significantly.

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

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

static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)

addFrameReference - This function is used to add a reference to the base of an abstract object on the...

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

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

unsigned getKillRegState(bool B)

bool isIntN(unsigned N, int64_t x)

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

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

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

Return a MachinePointerInfo record that refers to the specified FrameIndex.