llvm.org GIT mirror llvm / d49ea77
Split thumb-related stuff into separate classes. Step 1: ARMInstructionInfo => {ARM,Thumb}InstructionInfo git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74329 91177308-0d34-0410-b5e6-96231b3b80d8 Anton Korobeynikov 11 years ago
12 changed file(s) with 597 addition(s) and 350 deletion(s). Raw diff Collapse all Expand all
1919
2020 namespace llvm {
2121
22 class ARMTargetMachine;
22 class ARMBaseTargetMachine;
2323 class FunctionPass;
2424 class MachineCodeEmitter;
2525 class JITCodeEmitter;
2727
2828 // Enums corresponding to ARM condition codes
2929 namespace ARMCC {
30 // The CondCodes constants map directly to the 4-bit encoding of the
31 // condition field for predicated instructions.
30 // The CondCodes constants map directly to the 4-bit encoding of the
31 // condition field for predicated instructions.
3232 enum CondCodes {
3333 EQ,
3434 NE,
4646 LE,
4747 AL
4848 };
49
49
5050 inline static CondCodes getOppositeCondition(CondCodes CC){
5151 switch (CC) {
5252 default: assert(0 && "Unknown condition code");
8989 }
9090 }
9191
92 FunctionPass *createARMISelDag(ARMTargetMachine &TM);
92 FunctionPass *createARMISelDag(ARMBaseTargetMachine &TM);
9393 FunctionPass *createARMCodePrinterPass(raw_ostream &O,
94 ARMTargetMachine &TM,
94 ARMBaseTargetMachine &TM,
9595 CodeGenOpt::Level OptLevel,
9696 bool Verbose);
97 FunctionPass *createARMCodeEmitterPass(ARMTargetMachine &TM,
97 FunctionPass *createARMCodeEmitterPass(ARMBaseTargetMachine &TM,
9898 MachineCodeEmitter &MCE);
9999
100 FunctionPass *createARMCodeEmitterPass(ARMTargetMachine &TM,
100 FunctionPass *createARMCodeEmitterPass(ARMBaseTargetMachine &TM,
101101 MachineCodeEmitter &MCE);
102 FunctionPass *createARMJITCodeEmitterPass(ARMTargetMachine &TM,
102 FunctionPass *createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM,
103103 JITCodeEmitter &JCE);
104104
105105 FunctionPass *createARMLoadStoreOptimizationPass(bool PreAlloc = false);
175175
176176 namespace llvm {
177177
178 FunctionPass *createARMCodeEmitterPass(ARMTargetMachine &TM,
178 FunctionPass *createARMCodeEmitterPass(ARMBaseTargetMachine &TM,
179179 MachineCodeEmitter &MCE) {
180180 return new Emitter(TM, MCE);
181181 }
182 FunctionPass *createARMJITCodeEmitterPass(ARMTargetMachine &TM,
182 FunctionPass *createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM,
183183 JITCodeEmitter &JCE) {
184184 return new Emitter(TM, JCE);
185185 }
4040 ///
4141 namespace {
4242 class ARMDAGToDAGISel : public SelectionDAGISel {
43 ARMTargetMachine &TM;
43 ARMBaseTargetMachine &TM;
4444
4545 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
4646 /// make the right decision when generating code for different targets.
4747 const ARMSubtarget *Subtarget;
4848
4949 public:
50 explicit ARMDAGToDAGISel(ARMTargetMachine &tm)
50 explicit ARMDAGToDAGISel(ARMBaseTargetMachine &tm)
5151 : SelectionDAGISel(tm), TM(tm),
5252 Subtarget(&TM.getSubtarget()) {
5353 }
10011001 /// createARMISelDag - This pass converts a legalized DAG into a
10021002 /// ARM-specific DAG, ready for instruction scheduling.
10031003 ///
1004 FunctionPass *llvm::createARMISelDag(ARMTargetMachine &TM) {
1004 FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM) {
10051005 return new ARMDAGToDAGISel(TM);
10061006 }
3838 return MIB.addReg(0);
3939 }
4040
41 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
41 ARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget &STI)
4242 : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)),
4343 RI(*this, STI) {
4444 }
4545
46 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
47 : ARMBaseInstrInfo(STI) {
48 }
4649
4750 /// Return true if the instruction is a register to register move and
4851 /// leave the source and dest operands in the passed parameters.
6467 DstReg = MI.getOperand(0).getReg();
6568 return true;
6669 case ARM::MOVr:
67 case ARM::tMOVr:
68 case ARM::tMOVhir2lor:
69 case ARM::tMOVlor2hir:
70 case ARM::tMOVhir2hir:
7170 assert(MI.getDesc().getNumOperands() >= 2 &&
7271 MI.getOperand(0).isReg() &&
7372 MI.getOperand(1).isReg() &&
101100 return MI->getOperand(0).getReg();
102101 }
103102 break;
104 case ARM::tRestore:
105 if (MI->getOperand(1).isFI() &&
106 MI->getOperand(2).isImm() &&
107 MI->getOperand(2).getImm() == 0) {
108 FrameIndex = MI->getOperand(1).getIndex();
109 return MI->getOperand(0).getReg();
110 }
111 break;
112103 }
113104 return 0;
114105 }
136127 return MI->getOperand(0).getReg();
137128 }
138129 break;
139 case ARM::tSpill:
140 if (MI->getOperand(1).isFI() &&
141 MI->getOperand(2).isImm() &&
142 MI->getOperand(2).getImm() == 0) {
143 FrameIndex = MI->getOperand(1).getIndex();
144 return MI->getOperand(0).getReg();
145 }
146 break;
147 }
130 }
131
148132 return 0;
149133 }
150134
151 void ARMInstrInfo::reMaterialize(MachineBasicBlock &MBB,
152 MachineBasicBlock::iterator I,
153 unsigned DestReg,
154 const MachineInstr *Orig) const {
135 void ARMBaseInstrInfo::reMaterialize(MachineBasicBlock &MBB,
136 MachineBasicBlock::iterator I,
137 unsigned DestReg,
138 const MachineInstr *Orig) const {
155139 DebugLoc dl = Orig->getDebugLoc();
156140 if (Orig->getOpcode() == ARM::MOVi2pieces) {
157141 RI.emitLoadConstPool(MBB, I, DestReg, Orig->getOperand(1).getImm(),
197181 }
198182
199183 MachineInstr *
200 ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
201 MachineBasicBlock::iterator &MBBI,
202 LiveVariables *LV) const {
184 ARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
185 MachineBasicBlock::iterator &MBBI,
186 LiveVariables *LV) const {
203187 if (!EnableARM3Addr)
204188 return NULL;
205189
260244 get(isSub ? ARM::SUBrs : ARM::ADDrs), WBReg)
261245 .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc)
262246 .addImm(Pred).addReg(0).addReg(0);
263 } else
247 } else
264248 UpdateMI = BuildMI(MF, MI->getDebugLoc(),
265249 get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
266250 .addReg(BaseReg).addReg(OffReg)
311295 NewMIs.push_back(UpdateMI);
312296 NewMIs.push_back(MemMI);
313297 }
314
298
315299 // Transfer LiveVariables states, kill / dead info.
316300 if (LV) {
317301 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
319303 if (MO.isReg() && MO.getReg() &&
320304 TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
321305 unsigned Reg = MO.getReg();
322
306
323307 LiveVariables::VarInfo &VI = LV->getVarInfo(Reg);
324308 if (MO.isDef()) {
325309 MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI;
348332 }
349333
350334 // Branch analysis.
351 bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
352 MachineBasicBlock *&FBB,
353 SmallVectorImpl &Cond,
354 bool AllowModify) const {
335 bool
336 ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
337 MachineBasicBlock *&FBB,
338 SmallVectorImpl &Cond,
339 bool AllowModify) const {
355340 // If the block has no terminators, it just falls into the block after it.
356341 MachineBasicBlock::iterator I = MBB.end();
357342 if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
358343 return false;
359
344
360345 // Get the last instruction in the block.
361346 MachineInstr *LastInst = I;
362
347
363348 // If there is only one terminator instruction, process it.
364349 unsigned LastOpc = LastInst->getOpcode();
365350 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
376361 }
377362 return true; // Can't handle indirect branch.
378363 }
379
364
380365 // Get the instruction before it if it is a terminator.
381366 MachineInstr *SecondLastInst = I;
382
367
383368 // If there are three terminators, we don't know what sort of block this is.
384369 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
385370 return true;
386
371
387372 // If the block ends with ARM::B/ARM::tB and a ARM::Bcc/ARM::tBcc, handle it.
388373 unsigned SecondLastOpc = SecondLastInst->getOpcode();
389374 if ((SecondLastOpc == ARM::Bcc && LastOpc == ARM::B) ||
394379 FBB = LastInst->getOperand(0).getMBB();
395380 return false;
396381 }
397
398 // If the block ends with two unconditional branches, handle it. The second
382
383 // If the block ends with two unconditional branches, handle it. The second
399384 // one is not executed, so remove it.
400385 if ((SecondLastOpc == ARM::B || SecondLastOpc==ARM::tB) &&
401386 (LastOpc == ARM::B || LastOpc == ARM::tB)) {
416401 if (AllowModify)
417402 I->eraseFromParent();
418403 return true;
419 }
404 }
420405
421406 // Otherwise, can't handle this.
422407 return true;
423408 }
424409
425410
426 unsigned ARMInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
411 unsigned ARMBaseInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
427412 MachineFunction &MF = *MBB.getParent();
428413 ARMFunctionInfo *AFI = MF.getInfo();
429414 int BOpc = AFI->isThumbFunction() ? ARM::tB : ARM::B;
434419 --I;
435420 if (I->getOpcode() != BOpc && I->getOpcode() != BccOpc)
436421 return 0;
437
422
438423 // Remove the branch.
439424 I->eraseFromParent();
440
425
441426 I = MBB.end();
442
427
443428 if (I == MBB.begin()) return 1;
444429 --I;
445430 if (I->getOpcode() != BccOpc)
446431 return 1;
447
432
448433 // Remove the branch.
449434 I->eraseFromParent();
450435 return 2;
451436 }
452437
453438 unsigned
454 ARMInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
455 MachineBasicBlock *FBB,
456 const SmallVectorImpl &Cond) const {
439 ARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
440 MachineBasicBlock *FBB,
441 const SmallVectorImpl &Cond) const {
457442 // FIXME this should probably have a DebugLoc argument
458443 DebugLoc dl = DebugLoc::getUnknownLoc();
459444 MachineFunction &MF = *MBB.getParent();
465450 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
466451 assert((Cond.size() == 2 || Cond.size() == 0) &&
467452 "ARM branch conditions have two components!");
468
453
469454 if (FBB == 0) {
470455 if (Cond.empty()) // Unconditional branch?
471456 BuildMI(&MBB, dl, get(BOpc)).addMBB(TBB);
474459 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
475460 return 1;
476461 }
477
462
478463 // Two-way conditional branch.
479464 BuildMI(&MBB, dl, get(BccOpc)).addMBB(TBB)
480465 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
487472 unsigned DestReg, unsigned SrcReg,
488473 const TargetRegisterClass *DestRC,
489474 const TargetRegisterClass *SrcRC) const {
490 MachineFunction &MF = *MBB.getParent();
491 ARMFunctionInfo *AFI = MF.getInfo();
492475 DebugLoc DL = DebugLoc::getUnknownLoc();
493476 if (I != MBB.end()) DL = I->getDebugLoc();
494477
495 if (!AFI->isThumbFunction()) {
496 if (DestRC == ARM::GPRRegisterClass) {
497 AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr), DestReg)
498 .addReg(SrcReg)));
499 return true;
500 }
501 } else {
502 if (DestRC == ARM::GPRRegisterClass) {
503 if (SrcRC == ARM::GPRRegisterClass) {
504 BuildMI(MBB, I, DL, get(ARM::tMOVhir2hir), DestReg).addReg(SrcReg);
505 return true;
506 } else if (SrcRC == ARM::tGPRRegisterClass) {
507 BuildMI(MBB, I, DL, get(ARM::tMOVlor2hir), DestReg).addReg(SrcReg);
508 return true;
509 }
510 } else if (DestRC == ARM::tGPRRegisterClass) {
511 if (SrcRC == ARM::GPRRegisterClass) {
512 BuildMI(MBB, I, DL, get(ARM::tMOVhir2lor), DestReg).addReg(SrcReg);
513 return true;
514 } else if (SrcRC == ARM::tGPRRegisterClass) {
515 BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg).addReg(SrcReg);
516 return true;
517 }
518 }
519 }
520478 if (DestRC != SrcRC) {
521479 // Not yet supported!
522480 return false;
523481 }
524482
525
526 if (DestRC == ARM::SPRRegisterClass)
483 if (DestRC == ARM::GPRRegisterClass)
484 AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr), DestReg)
485 .addReg(SrcReg)));
486 else if (DestRC == ARM::SPRRegisterClass)
527487 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYS), DestReg)
528488 .addReg(SrcReg));
529489 else if (DestRC == ARM::DPRRegisterClass)
533493 BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg);
534494 else
535495 return false;
536
496
537497 return true;
538498 }
539499
545505 if (I != MBB.end()) DL = I->getDebugLoc();
546506
547507 if (RC == ARM::GPRRegisterClass) {
548 MachineFunction &MF = *MBB.getParent();
549 ARMFunctionInfo *AFI = MF.getInfo();
550 assert (!AFI->isThumbFunction());
551508 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR))
552509 .addReg(SrcReg, getKillRegState(isKill))
553510 .addFrameIndex(FI).addReg(0).addImm(0));
554 } else if (RC == ARM::tGPRRegisterClass) {
555 MachineFunction &MF = *MBB.getParent();
556 ARMFunctionInfo *AFI = MF.getInfo();
557 assert (AFI->isThumbFunction());
558 BuildMI(MBB, I, DL, get(ARM::tSpill))
559 .addReg(SrcReg, getKillRegState(isKill))
560 .addFrameIndex(FI).addImm(0);
561511 } else if (RC == ARM::DPRRegisterClass) {
562512 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD))
563513 .addReg(SrcReg, getKillRegState(isKill))
578528 DebugLoc DL = DebugLoc::getUnknownLoc();
579529 unsigned Opc = 0;
580530 if (RC == ARM::GPRRegisterClass) {
581 ARMFunctionInfo *AFI = MF.getInfo();
582 if (AFI->isThumbFunction()) {
583 Opc = Addr[0].isFI() ? ARM::tSpill : ARM::tSTR;
584 MachineInstrBuilder MIB =
585 BuildMI(MF, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill));
586 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
587 MIB.addOperand(Addr[i]);
588 NewMIs.push_back(MIB);
589 return;
590 }
591531 Opc = ARM::STR;
592532 } else if (RC == ARM::DPRRegisterClass) {
593533 Opc = ARM::FSTD;
596536 Opc = ARM::FSTS;
597537 }
598538
599 MachineInstrBuilder MIB =
539 MachineInstrBuilder MIB =
600540 BuildMI(MF, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill));
601541 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
602542 MIB.addOperand(Addr[i]);
613553 if (I != MBB.end()) DL = I->getDebugLoc();
614554
615555 if (RC == ARM::GPRRegisterClass) {
616 MachineFunction &MF = *MBB.getParent();
617 ARMFunctionInfo *AFI = MF.getInfo();
618 assert (!AFI->isThumbFunction());
619556 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg)
620557 .addFrameIndex(FI).addReg(0).addImm(0));
621 } else if (RC == ARM::tGPRRegisterClass) {
622 MachineFunction &MF = *MBB.getParent();
623 ARMFunctionInfo *AFI = MF.getInfo();
624 assert (AFI->isThumbFunction());
625 BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg)
626 .addFrameIndex(FI).addImm(0);
627558 } else if (RC == ARM::DPRRegisterClass) {
628559 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg)
629560 .addFrameIndex(FI).addImm(0));
642573 DebugLoc DL = DebugLoc::getUnknownLoc();
643574 unsigned Opc = 0;
644575 if (RC == ARM::GPRRegisterClass) {
645 ARMFunctionInfo *AFI = MF.getInfo();
646 if (AFI->isThumbFunction()) {
647 Opc = Addr[0].isFI() ? ARM::tRestore : ARM::tLDR;
648 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg);
649 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
650 MIB.addOperand(Addr[i]);
651 NewMIs.push_back(MIB);
652 return;
653 }
654576 Opc = ARM::LDR;
655577 } else if (RC == ARM::DPRRegisterClass) {
656578 Opc = ARM::FLDD;
665587 AddDefaultPred(MIB);
666588 NewMIs.push_back(MIB);
667589 return;
668 }
669
670 bool ARMInstrInfo::
671 spillCalleeSavedRegisters(MachineBasicBlock &MBB,
672 MachineBasicBlock::iterator MI,
673 const std::vector &CSI) const {
674 MachineFunction &MF = *MBB.getParent();
675 ARMFunctionInfo *AFI = MF.getInfo();
676 if (!AFI->isThumbFunction() || CSI.empty())
677 return false;
678
679 DebugLoc DL = DebugLoc::getUnknownLoc();
680 if (MI != MBB.end()) DL = MI->getDebugLoc();
681
682 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, get(ARM::tPUSH));
683 for (unsigned i = CSI.size(); i != 0; --i) {
684 unsigned Reg = CSI[i-1].getReg();
685 // Add the callee-saved register as live-in. It's killed at the spill.
686 MBB.addLiveIn(Reg);
687 MIB.addReg(Reg, RegState::Kill);
688 }
689 return true;
690 }
691
692 bool ARMInstrInfo::
693 restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
694 MachineBasicBlock::iterator MI,
695 const std::vector &CSI) const {
696 MachineFunction &MF = *MBB.getParent();
697 ARMFunctionInfo *AFI = MF.getInfo();
698 if (!AFI->isThumbFunction() || CSI.empty())
699 return false;
700
701 bool isVarArg = AFI->getVarArgsRegSaveSize() > 0;
702 MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP),MI->getDebugLoc());
703 for (unsigned i = CSI.size(); i != 0; --i) {
704 unsigned Reg = CSI[i-1].getReg();
705 if (Reg == ARM::LR) {
706 // Special epilogue for vararg functions. See emitEpilogue
707 if (isVarArg)
708 continue;
709 Reg = ARM::PC;
710 PopMI->setDesc(get(ARM::tPOP_RET));
711 MI = MBB.erase(MI);
712 }
713 PopMI->addOperand(MachineOperand::CreateReg(Reg, true));
714 }
715
716 // It's illegal to emit pop instruction without operands.
717 if (PopMI->getNumOperands() > 0)
718 MBB.insert(MI, PopMI);
719
720 return true;
721590 }
722591
723592 MachineInstr *ARMInstrInfo::
751620 }
752621 break;
753622 }
754 case ARM::tMOVr:
755 case ARM::tMOVlor2hir:
756 case ARM::tMOVhir2lor:
757 case ARM::tMOVhir2hir: {
758 if (OpNum == 0) { // move -> store
759 unsigned SrcReg = MI->getOperand(1).getReg();
760 bool isKill = MI->getOperand(1).isKill();
761 if (RI.isPhysicalRegister(SrcReg) && !RI.isLowRegister(SrcReg))
762 // tSpill cannot take a high register operand.
763 break;
764 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::tSpill))
765 .addReg(SrcReg, getKillRegState(isKill))
766 .addFrameIndex(FI).addImm(0);
767 } else { // move -> load
768 unsigned DstReg = MI->getOperand(0).getReg();
769 if (RI.isPhysicalRegister(DstReg) && !RI.isLowRegister(DstReg))
770 // tRestore cannot target a high register operand.
771 break;
772 bool isDead = MI->getOperand(0).isDead();
773 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::tRestore))
774 .addReg(DstReg, RegState::Define | getDeadRegState(isDead))
775 .addFrameIndex(FI).addImm(0);
776 }
777 break;
778 }
779623 case ARM::FCPYS: {
780624 unsigned Pred = MI->getOperand(2).getImm();
781625 unsigned PredReg = MI->getOperand(3).getReg();
815659 return NewMI;
816660 }
817661
818 bool ARMInstrInfo::
662 bool ARMBaseInstrInfo::
819663 canFoldMemoryOperand(const MachineInstr *MI,
820664 const SmallVectorImpl &Ops) const {
821665 if (Ops.size() != 1) return false;
856700 return false;
857701 }
858702
859 bool ARMInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock &MBB) const {
703 bool
704 ARMBaseInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock &MBB) const {
860705 if (MBB.empty()) return false;
861
706
862707 switch (MBB.back().getOpcode()) {
863708 case ARM::BX_RET: // Return.
864709 case ARM::LDM_RET:
876721 }
877722 }
878723
879 bool ARMInstrInfo::
724 bool ARMBaseInstrInfo::
880725 ReverseBranchCondition(SmallVectorImpl &Cond) const {
881726 ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm();
882727 Cond[0].setImm(ARMCC::getOppositeCondition(CC));
883728 return false;
884729 }
885730
886 bool ARMInstrInfo::isPredicated(const MachineInstr *MI) const {
731 bool ARMBaseInstrInfo::isPredicated(const MachineInstr *MI) const {
887732 int PIdx = MI->findFirstPredOperandIdx();
888733 return PIdx != -1 && MI->getOperand(PIdx).getImm() != ARMCC::AL;
889734 }
890735
891 bool ARMInstrInfo::
736 bool ARMBaseInstrInfo::
892737 PredicateInstruction(MachineInstr *MI,
893738 const SmallVectorImpl &Pred) const {
894739 unsigned Opc = MI->getOpcode();
909754 return false;
910755 }
911756
912 bool ARMInstrInfo::
757 bool ARMBaseInstrInfo::
913758 SubsumesPredicate(const SmallVectorImpl &Pred1,
914759 const SmallVectorImpl &Pred2) const {
915760 if (Pred1.size() > 2 || Pred2.size() > 2)
936781 }
937782 }
938783
939 bool ARMInstrInfo::DefinesPredicate(MachineInstr *MI,
784 bool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI,
940785 std::vector &Pred) const {
941786 const TargetInstrDesc &TID = MI->getDesc();
942787 if (!TID.getImplicitDefs() && !TID.hasOptionalDef())
965810
966811 /// GetInstSize - Return the size of the specified MachineInstr.
967812 ///
968 unsigned ARMInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
813 unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
969814 const MachineBasicBlock &MBB = *MI->getParent();
970815 const MachineFunction *MF = MBB.getParent();
971816 const TargetAsmInfo *TAI = MF->getTarget().getTargetAsmInfo();
973818 // Basic size info comes from the TSFlags field.
974819 const TargetInstrDesc &TID = MI->getDesc();
975820 unsigned TSFlags = TID.TSFlags;
976
821
977822 switch ((TSFlags & ARMII::SizeMask) >> ARMII::SizeShift) {
978823 default: {
979824 // If this machine instr is an inline asm, measure it.
1023868 // FIXME: If we know the size of the function is less than (1 << 16) *2
1024869 // bytes, we can use 16-bit entries instead. Then there won't be an
1025870 // alignment issue.
1026 return getNumJTEntries(JT, JTI) * 4 +
871 return getNumJTEntries(JT, JTI) * 4 +
1027872 (MI->getOpcode()==ARM::tBR_JTr ? 2 : 4);
1028873 }
1029874 default:
5050 Size8Bytes = 2,
5151 Size4Bytes = 3,
5252 Size2Bytes = 4,
53
53
5454 // IndexMode - Unindex, pre-indexed, or post-indexed. Only valid for load
55 // and store ops
55 // and store ops
5656 IndexModeShift = 7,
5757 IndexModeMask = 3 << IndexModeShift,
5858 IndexModePre = 1,
5959 IndexModePost = 2,
60
60
6161 //===------------------------------------------------------------------===//
6262 // Misc flags.
6363
145145 };
146146 }
147147
148 class ARMInstrInfo : public TargetInstrInfoImpl {
148 class ARMBaseInstrInfo : public TargetInstrInfoImpl {
149149 const ARMRegisterInfo RI;
150 protected:
151 // Can be only subclassed.
152 explicit ARMBaseInstrInfo(const ARMSubtarget &STI);
150153 public:
151 explicit ARMInstrInfo(const ARMSubtarget &STI);
152154
153155 /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
154156 /// such, whenever a client has an instance of instruction info, it should
156158 ///
157159 virtual const ARMRegisterInfo &getRegisterInfo() const { return RI; }
158160
159 /// Return true if the instruction is a register to register move and return
160 /// the source and dest operands and their sub-register indices by reference.
161 virtual bool isMoveInstr(const MachineInstr &MI,
162 unsigned &SrcReg, unsigned &DstReg,
163 unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
164
165 virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
166 int &FrameIndex) const;
167 virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
168 int &FrameIndex) const;
169
170161 void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
171162 unsigned DestReg, const MachineInstr *Orig) const;
172163
183174 virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
184175 MachineBasicBlock *FBB,
185176 const SmallVectorImpl &Cond) const;
177
178 virtual bool canFoldMemoryOperand(const MachineInstr *MI,
179 const SmallVectorImpl &Ops) const;
180
181 virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const;
182 virtual
183 bool ReverseBranchCondition(SmallVectorImpl &Cond) const;
184
185 // Predication support.
186 virtual bool isPredicated(const MachineInstr *MI) const;
187
188 ARMCC::CondCodes getPredicate(const MachineInstr *MI) const {
189 int PIdx = MI->findFirstPredOperandIdx();
190 return PIdx != -1 ? (ARMCC::CondCodes)MI->getOperand(PIdx).getImm()
191 : ARMCC::AL;
192 }
193
194 virtual
195 bool PredicateInstruction(MachineInstr *MI,
196 const SmallVectorImpl &Pred) const;
197
198 virtual
199 bool SubsumesPredicate(const SmallVectorImpl &Pred1,
200 const SmallVectorImpl &Pred2) const;
201
202 virtual bool DefinesPredicate(MachineInstr *MI,
203 std::vector &Pred) const;
204
205 /// GetInstSize - Returns the size of the specified MachineInstr.
206 ///
207 virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const;
208 };
209
210 class ARMInstrInfo : public ARMBaseInstrInfo {
211 public:
212 explicit ARMInstrInfo(const ARMSubtarget &STI);
213
214 /// Return true if the instruction is a register to register move and return
215 /// the source and dest operands and their sub-register indices by reference.
216 virtual bool isMoveInstr(const MachineInstr &MI,
217 unsigned &SrcReg, unsigned &DstReg,
218 unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
219
220 virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
221 int &FrameIndex) const;
222 virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
223 int &FrameIndex) const;
224
186225 virtual bool copyRegToReg(MachineBasicBlock &MBB,
187226 MachineBasicBlock::iterator I,
188227 unsigned DestReg, unsigned SrcReg,
207246 SmallVectorImpl &Addr,
208247 const TargetRegisterClass *RC,
209248 SmallVectorImpl &NewMIs) const;
210 virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
211 MachineBasicBlock::iterator MI,
212 const std::vector &CSI) const;
213 virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
214 MachineBasicBlock::iterator MI,
215 const std::vector &CSI) const;
216
249
217250 virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
218251 MachineInstr* MI,
219252 const SmallVectorImpl &Ops,
225258 MachineInstr* LoadMI) const {
226259 return 0;
227260 }
228
229 virtual bool canFoldMemoryOperand(const MachineInstr *MI,
230 const SmallVectorImpl &Ops) const;
231
232 virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const;
233 virtual
234 bool ReverseBranchCondition(SmallVectorImpl &Cond) const;
235
236 // Predication support.
237 virtual bool isPredicated(const MachineInstr *MI) const;
238
239 ARMCC::CondCodes getPredicate(const MachineInstr *MI) const {
240 int PIdx = MI->findFirstPredOperandIdx();
241 return PIdx != -1 ? (ARMCC::CondCodes)MI->getOperand(PIdx).getImm()
242 : ARMCC::AL;
243 }
244
245 virtual
246 bool PredicateInstruction(MachineInstr *MI,
247 const SmallVectorImpl &Pred) const;
248
249 virtual
250 bool SubsumesPredicate(const SmallVectorImpl &Pred1,
251 const SmallVectorImpl &Pred2) const;
252
253 virtual bool DefinesPredicate(MachineInstr *MI,
254 std::vector &Pred) const;
255
256 /// GetInstSize - Returns the size of the specified MachineInstr.
257 ///
258 virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const;
259261 };
260262
261263 }
4242 0,0
4343 };
4444
45 ARMDarwinTargetAsmInfo::ARMDarwinTargetAsmInfo(const ARMTargetMachine &TM):
45 ARMDarwinTargetAsmInfo::ARMDarwinTargetAsmInfo(const ARMBaseTargetMachine &TM):
4646 ARMTargetAsmInfo(TM) {
4747 Subtarget = &TM.getSubtarget();
4848
5454 SupportsDebugInformation = true;
5555 }
5656
57 ARMELFTargetAsmInfo::ARMELFTargetAsmInfo(const ARMTargetMachine &TM):
57 ARMELFTargetAsmInfo::ARMELFTargetAsmInfo(const ARMBaseTargetMachine &TM):
5858 ARMTargetAsmInfo(TM) {
5959 Subtarget = &TM.getSubtarget();
6060
2525
2626 template
2727 struct ARMTargetAsmInfo : public BaseTAI {
28 explicit ARMTargetAsmInfo(const ARMTargetMachine &TM) : BaseTAI(TM) {
28 explicit ARMTargetAsmInfo(const ARMBaseTargetMachine &TM) : BaseTAI(TM) {
2929 BaseTAI::AsmTransCBE = arm_asm_table;
3030
3131 BaseTAI::AlignmentIsInBytes = false;
5050 EXTERN_TEMPLATE_INSTANTIATION(class ARMTargetAsmInfo);
5151
5252 struct ARMDarwinTargetAsmInfo : public ARMTargetAsmInfo {
53 explicit ARMDarwinTargetAsmInfo(const ARMTargetMachine &TM);
53 explicit ARMDarwinTargetAsmInfo(const ARMBaseTargetMachine &TM);
5454 };
5555
5656 struct ARMELFTargetAsmInfo : public ARMTargetAsmInfo {
57 explicit ARMELFTargetAsmInfo(const ARMTargetMachine &TM);
57 explicit ARMELFTargetAsmInfo(const ARMBaseTargetMachine &TM);
5858 };
5959
6060 } // namespace llvm
4242 extern "C" void LLVMInitializeARMTarget() { }
4343
4444 // No assembler printer by default
45 ARMTargetMachine::AsmPrinterCtorFn ARMTargetMachine::AsmPrinterCtor = 0;
45 ARMBaseTargetMachine::AsmPrinterCtorFn ARMBaseTargetMachine::AsmPrinterCtor = 0;
4646
4747 /// ThumbTargetMachine - Create an Thumb architecture model.
4848 ///
7373 return getJITMatchQuality()/2;
7474 }
7575
76 ThumbTargetMachine::ThumbTargetMachine(const Module &M, const std::string &FS)
77 : ARMTargetMachine(M, FS, true) {
78 }
79
8076 /// TargetMachine ctor - Create an ARM architecture model.
8177 ///
82 ARMTargetMachine::ARMTargetMachine(const Module &M, const std::string &FS,
83 bool isThumb)
78 ARMBaseTargetMachine::ARMBaseTargetMachine(const Module &M,
79 const std::string &FS,
80 bool isThumb)
8481 : Subtarget(M, FS, isThumb),
85 DataLayout(Subtarget.isAPCS_ABI() ?
86 // APCS ABI
87 (isThumb ?
88 std::string("e-p:32:32-f64:32:32-i64:32:32-"
89 "i16:16:32-i8:8:32-i1:8:32-a:0:32") :
90 std::string("e-p:32:32-f64:32:32-i64:32:32")) :
91 // AAPCS ABI
92 (isThumb ?
93 std::string("e-p:32:32-f64:64:64-i64:64:64-"
94 "i16:16:32-i8:8:32-i1:8:32-a:0:32") :
95 std::string("e-p:32:32-f64:64:64-i64:64:64"))),
96 InstrInfo(Subtarget),
9782 FrameInfo(Subtarget),
9883 JITInfo(),
99 TLInfo(*this),
10084 InstrItins(Subtarget.getInstrItineraryData()) {
10185 DefRelocModel = getRelocationModel();
86 }
87
88 ARMTargetMachine::ARMTargetMachine(const Module &M, const std::string &FS)
89 : ARMBaseTargetMachine(M, FS, false), InstrInfo(Subtarget),
90 DataLayout(Subtarget.isAPCS_ABI() ?
91 std::string("e-p:32:32-f64:32:32-i64:32:32") :
92 std::string("e-p:32:32-f64:64:64-i64:64:64")),
93 TLInfo(*this) {
94 }
95
96 ThumbTargetMachine::ThumbTargetMachine(const Module &M, const std::string &FS)
97 : ARMBaseTargetMachine(M, FS, true), InstrInfo(Subtarget),
98 DataLayout(Subtarget.isAPCS_ABI() ?
99 std::string("e-p:32:32-f64:32:32-i64:32:32-"
100 "i16:16:32-i8:8:32-i1:8:32-a:0:32") :
101 std::string("e-p:32:32-f64:64:64-i64:64:64-"
102 "i16:16:32-i8:8:32-i1:8:32-a:0:32")),
103 TLInfo(*this) {
102104 }
103105
104106 unsigned ARMTargetMachine::getJITMatchQuality() {
128130 }
129131
130132
131 const TargetAsmInfo *ARMTargetMachine::createTargetAsmInfo() const {
133 const TargetAsmInfo *ARMBaseTargetMachine::createTargetAsmInfo() const {
132134 switch (Subtarget.TargetType) {
133135 case ARMSubtarget::isDarwin:
134136 return new ARMDarwinTargetAsmInfo(*this);
141143
142144
143145 // Pass Pipeline Configuration
144 bool ARMTargetMachine::addInstSelector(PassManagerBase &PM,
145 CodeGenOpt::Level OptLevel) {
146 bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM,
147 CodeGenOpt::Level OptLevel) {
146148 PM.add(createARMISelDag(*this));
147149 return false;
148150 }
149151
150 bool ARMTargetMachine::addPreRegAlloc(PassManagerBase &PM,
151 CodeGenOpt::Level OptLevel) {
152 bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM,
153 CodeGenOpt::Level OptLevel) {
152154 // FIXME: temporarily disabling load / store optimization pass for Thumb mode.
153155 if (OptLevel != CodeGenOpt::None && !DisableLdStOpti && !Subtarget.isThumb())
154156 PM.add(createARMLoadStoreOptimizationPass(true));
155157 return true;
156158 }
157159
158 bool ARMTargetMachine::addPreEmitPass(PassManagerBase &PM,
159 CodeGenOpt::Level OptLevel) {
160 bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM,
161 CodeGenOpt::Level OptLevel) {
160162 // FIXME: temporarily disabling load / store optimization pass for Thumb mode.
161163 if (OptLevel != CodeGenOpt::None && !DisableLdStOpti && !Subtarget.isThumb())
162164 PM.add(createARMLoadStoreOptimizationPass());
169171 return true;
170172 }
171173
172 bool ARMTargetMachine::addAssemblyEmitter(PassManagerBase &PM,
173 CodeGenOpt::Level OptLevel,
174 bool Verbose,
175 raw_ostream &Out) {
174 bool ARMBaseTargetMachine::addAssemblyEmitter(PassManagerBase &PM,
175 CodeGenOpt::Level OptLevel,
176 bool Verbose,
177 raw_ostream &Out) {
176178 // Output assembly language.
177179 assert(AsmPrinterCtor && "AsmPrinter was not linked in");
178180 if (AsmPrinterCtor)
182184 }
183185
184186
185 bool ARMTargetMachine::addCodeEmitter(PassManagerBase &PM,
186 CodeGenOpt::Level OptLevel,
187 bool DumpAsm,
188 MachineCodeEmitter &MCE) {
187 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
188 CodeGenOpt::Level OptLevel,
189 bool DumpAsm,
190 MachineCodeEmitter &MCE) {
189191 // FIXME: Move this to TargetJITInfo!
190192 if (DefRelocModel == Reloc::Default)
191193 setRelocationModel(Reloc::Static);
201203 return false;
202204 }
203205
204 bool ARMTargetMachine::addCodeEmitter(PassManagerBase &PM,
205 CodeGenOpt::Level OptLevel,
206 bool DumpAsm,
207 JITCodeEmitter &JCE) {
206 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
207 CodeGenOpt::Level OptLevel,
208 bool DumpAsm,
209 JITCodeEmitter &JCE) {
208210 // FIXME: Move this to TargetJITInfo!
209211 if (DefRelocModel == Reloc::Default)
210212 setRelocationModel(Reloc::Static);
220222 return false;
221223 }
222224
223 bool ARMTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
224 CodeGenOpt::Level OptLevel,
225 bool DumpAsm,
226 MachineCodeEmitter &MCE) {
225 bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
226 CodeGenOpt::Level OptLevel,
227 bool DumpAsm,
228 MachineCodeEmitter &MCE) {
227229 // Machine code emitter pass for ARM.
228230 PM.add(createARMCodeEmitterPass(*this, MCE));
229231 if (DumpAsm) {
235237 return false;
236238 }
237239
238 bool ARMTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
239 CodeGenOpt::Level OptLevel,
240 bool DumpAsm,
241 JITCodeEmitter &JCE) {
240 bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
241 CodeGenOpt::Level OptLevel,
242 bool DumpAsm,
243 JITCodeEmitter &JCE) {
242244 // Machine code emitter pass for ARM.
243245 PM.add(createARMJITCodeEmitterPass(*this, JCE));
244246 if (DumpAsm) {
2121 #include "ARMJITInfo.h"
2222 #include "ARMSubtarget.h"
2323 #include "ARMISelLowering.h"
24 #include "ThumbInstrInfo.h"
2425
2526 namespace llvm {
2627
2728 class Module;
2829
29 class ARMTargetMachine : public LLVMTargetMachine {
30 class ARMBaseTargetMachine : public LLVMTargetMachine {
31 protected:
3032 ARMSubtarget Subtarget;
31 const TargetData DataLayout; // Calculates type size & alignment
32 ARMInstrInfo InstrInfo;
33
34 private:
3335 ARMFrameInfo FrameInfo;
3436 ARMJITInfo JITInfo;
35 ARMTargetLowering TLInfo;
3637 InstrItineraryData InstrItins;
3738 Reloc::Model DefRelocModel; // Reloc model before it's overridden.
3839
4041 // To avoid having target depend on the asmprinter stuff libraries, asmprinter
4142 // set this functions to ctor pointer at startup time if they are linked in.
4243 typedef FunctionPass *(*AsmPrinterCtorFn)(raw_ostream &o,
43 ARMTargetMachine &tm,
44 ARMBaseTargetMachine &tm,
4445 CodeGenOpt::Level OptLevel,
4546 bool verbose);
4647 static AsmPrinterCtorFn AsmPrinterCtor;
4748
4849 public:
49 ARMTargetMachine(const Module &M, const std::string &FS, bool isThumb = false);
50 ARMBaseTargetMachine(const Module &M, const std::string &FS, bool isThumb);
5051
51 virtual const ARMInstrInfo *getInstrInfo() const { return &InstrInfo; }
5252 virtual const ARMFrameInfo *getFrameInfo() const { return &FrameInfo; }
5353 virtual ARMJITInfo *getJITInfo() { return &JITInfo; }
54 virtual const ARMRegisterInfo *getRegisterInfo() const {
55 return &InstrInfo.getRegisterInfo();
56 }
57 virtual const TargetData *getTargetData() const { return &DataLayout; }
5854 virtual const ARMSubtarget *getSubtargetImpl() const { return &Subtarget; }
59 virtual ARMTargetLowering *getTargetLowering() const {
60 return const_cast(&TLInfo);
61 }
62 virtual const InstrItineraryData getInstrItineraryData() const {
55 virtual const InstrItineraryData getInstrItineraryData() const {
6356 return InstrItins;
6457 }
6558
9386 JITCodeEmitter &MCE);
9487 };
9588
89 /// ARMTargetMachine - ARM target machine.
90 ///
91 class ARMTargetMachine : public ARMBaseTargetMachine {
92 ARMInstrInfo InstrInfo;
93 const TargetData DataLayout; // Calculates type size & alignment
94 ARMTargetLowering TLInfo;
95 public:
96 ARMTargetMachine(const Module &M, const std::string &FS);
97
98 virtual const ARMRegisterInfo *getRegisterInfo() const {
99 return &InstrInfo.getRegisterInfo();
100 }
101
102 virtual ARMTargetLowering *getTargetLowering() const {
103 return const_cast(&TLInfo);
104 }
105
106 virtual const ARMInstrInfo *getInstrInfo() const { return &InstrInfo; }
107 virtual const TargetData *getTargetData() const { return &DataLayout; }
108
109 static unsigned getJITMatchQuality();
110 static unsigned getModuleMatchQuality(const Module &M);
111 };
112
96113 /// ThumbTargetMachine - Thumb target machine.
97114 ///
98 class ThumbTargetMachine : public ARMTargetMachine {
115 class ThumbTargetMachine : public ARMBaseTargetMachine {
116 ThumbInstrInfo InstrInfo;
117 const TargetData DataLayout; // Calculates type size & alignment
118 ARMTargetLowering TLInfo;
99119 public:
100120 ThumbTargetMachine(const Module &M, const std::string &FS);
121
122 virtual const ARMRegisterInfo *getRegisterInfo() const {
123 return &InstrInfo.getRegisterInfo();
124 }
125
126 virtual ARMTargetLowering *getTargetLowering() const {
127 return const_cast(&TLInfo);
128 }
129
130 virtual const ThumbInstrInfo *getInstrInfo() const { return &InstrInfo; }
131 virtual const TargetData *getTargetData() const { return &DataLayout; }
101132
102133 static unsigned getJITMatchQuality();
103134 static unsigned getModuleMatchQuality(const Module &M);
11371137 /// regardless of whether the function is in SSA form.
11381138 ///
11391139 FunctionPass *llvm::createARMCodePrinterPass(raw_ostream &o,
1140 ARMTargetMachine &tm,
1140 ARMBaseTargetMachine &tm,
11411141 CodeGenOpt::Level OptLevel,
11421142 bool verbose) {
11431143 return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo(), OptLevel, verbose);
11461146 namespace {
11471147 static struct Register {
11481148 Register() {
1149 ARMTargetMachine::registerAsmPrinter(createARMCodePrinterPass);
1149 ARMBaseTargetMachine::registerAsmPrinter(createARMCodePrinterPass);
11501150 }
11511151 } Registrator;
11521152 }
0 //===- ThumbInstrInfo.cpp - Thumb Instruction Information --------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "ARMInstrInfo.h"
14 #include "ARM.h"
15 #include "ARMGenInstrInfo.inc"
16 #include "ARMMachineFunctionInfo.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "ThumbInstrInfo.h"
21
22 using namespace llvm;
23
24 ThumbInstrInfo::ThumbInstrInfo(const ARMSubtarget &STI)
25 : ARMBaseInstrInfo(STI) {
26 }
27
28 bool ThumbInstrInfo::isMoveInstr(const MachineInstr &MI,
29 unsigned &SrcReg, unsigned &DstReg,
30 unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
31 SrcSubIdx = DstSubIdx = 0; // No sub-registers.
32
33 unsigned oc = MI.getOpcode();
34 switch (oc) {
35 default:
36 return false;
37 // FIXME: Thumb2
38 case ARM::tMOVr:
39 case ARM::tMOVhir2lor:
40 case ARM::tMOVlor2hir:
41 case ARM::tMOVhir2hir:
42 assert(MI.getDesc().getNumOperands() >= 2 &&
43 MI.getOperand(0).isReg() &&
44 MI.getOperand(1).isReg() &&
45 "Invalid Thumb MOV instruction");
46 SrcReg = MI.getOperand(1).getReg();
47 DstReg = MI.getOperand(0).getReg();
48 return true;
49 }
50 }
51
52 unsigned ThumbInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
53 int &FrameIndex) const {
54 switch (MI->getOpcode()) {
55 default: break;
56 // FIXME: Thumb2
57 case ARM::tRestore:
58 if (MI->getOperand(1).isFI() &&
59 MI->getOperand(2).isImm() &&
60 MI->getOperand(2).getImm() == 0) {
61 FrameIndex = MI->getOperand(1).getIndex();
62 return MI->getOperand(0).getReg();
63 }
64 break;
65 }
66 return 0;
67 }
68
69 unsigned ThumbInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
70 int &FrameIndex) const {
71 switch (MI->getOpcode()) {
72 default: break;
73 // FIXME: Thumb2
74 case ARM::tSpill:
75 if (MI->getOperand(1).isFI() &&
76 MI->getOperand(2).isImm() &&
77 MI->getOperand(2).getImm() == 0) {
78 FrameIndex = MI->getOperand(1).getIndex();
79 return MI->getOperand(0).getReg();
80 }
81 break;
82 }
83 return 0;
84 }
85
86 bool ThumbInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
87 MachineBasicBlock::iterator I,
88 unsigned DestReg, unsigned SrcReg,
89 const TargetRegisterClass *DestRC,
90 const TargetRegisterClass *SrcRC) const {
91 DebugLoc DL = DebugLoc::getUnknownLoc();
92 if (I != MBB.end()) DL = I->getDebugLoc();
93
94 // FIXME: Thumb2
95 if (DestRC == ARM::GPRRegisterClass) {
96 if (SrcRC == ARM::GPRRegisterClass) {
97 BuildMI(MBB, I, DL, get(ARM::tMOVhir2hir), DestReg).addReg(SrcReg);
98 return true;
99 } else if (SrcRC == ARM::tGPRRegisterClass) {
100 BuildMI(MBB, I, DL, get(ARM::tMOVlor2hir), DestReg).addReg(SrcReg);
101 return true;
102 }
103 } else if (DestRC == ARM::tGPRRegisterClass) {
104 if (SrcRC == ARM::GPRRegisterClass) {
105 BuildMI(MBB, I, DL, get(ARM::tMOVhir2lor), DestReg).addReg(SrcReg);
106 return true;
107 } else if (SrcRC == ARM::tGPRRegisterClass) {
108 BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg).addReg(SrcReg);
109 return true;
110 }
111 }
112
113 return false;
114 }
115
116 void ThumbInstrInfo::
117 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
118 unsigned SrcReg, bool isKill, int FI,
119 const TargetRegisterClass *RC) const {
120 DebugLoc DL = DebugLoc::getUnknownLoc();
121 if (I != MBB.end()) DL = I->getDebugLoc();
122
123 assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
124
125 // FIXME: Thumb2
126 if (RC == ARM::tGPRRegisterClass) {
127 BuildMI(MBB, I, DL, get(ARM::tSpill))
128 .addReg(SrcReg, getKillRegState(isKill))
129 .addFrameIndex(FI).addImm(0);
130 }
131 }
132
133 void ThumbInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
134 bool isKill,
135 SmallVectorImpl &Addr,
136 const TargetRegisterClass *RC,
137 SmallVectorImpl &NewMIs) const{
138 DebugLoc DL = DebugLoc::getUnknownLoc();
139 unsigned Opc = 0;
140
141 // FIXME: Thumb2. Is GPRRegClass here correct?
142 assert(RC == ARM::GPRRegisterClass && "Unknown regclass!");
143 if (RC == ARM::GPRRegisterClass) {
144 Opc = Addr[0].isFI() ? ARM::tSpill : ARM::tSTR;
145 }
146
147 MachineInstrBuilder MIB =
148 BuildMI(MF, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill));
149 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
150 MIB.addOperand(Addr[i]);
151 NewMIs.push_back(MIB);
152 return;
153 }
154
155 void ThumbInstrInfo::
156 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
157 unsigned DestReg, int FI,
158 const TargetRegisterClass *RC) const {
159 DebugLoc DL = DebugLoc::getUnknownLoc();
160 if (I != MBB.end()) DL = I->getDebugLoc();
161
162 // FIXME: Thumb2
163 assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
164
165 if (RC == ARM::tGPRRegisterClass) {
166 BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg)
167 .addFrameIndex(FI).addImm(0);
168 }
169 }
170
171 void ThumbInstrInfo::
172 loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
173 SmallVectorImpl &Addr,
174 const TargetRegisterClass *RC,
175 SmallVectorImpl &NewMIs) const {
176 DebugLoc DL = DebugLoc::getUnknownLoc();
177 unsigned Opc = 0;
178
179 // FIXME: Thumb2. Is GPRRegClass ok here?
180 if (RC == ARM::GPRRegisterClass) {
181 Opc = Addr[0].isFI() ? ARM::tRestore : ARM::tLDR;
182 }
183
184 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg);
185 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
186 MIB.addOperand(Addr[i]);
187 NewMIs.push_back(MIB);
188 return;
189 }
190
191 bool ThumbInstrInfo::
192 spillCalleeSavedRegisters(MachineBasicBlock &MBB,
193 MachineBasicBlock::iterator MI,
194 const std::vector &CSI) const {
195 if (CSI.empty())
196 return false;
197
198 DebugLoc DL = DebugLoc::getUnknownLoc();
199 if (MI != MBB.end()) DL = MI->getDebugLoc();
200
201 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, get(ARM::tPUSH));
202 for (unsigned i = CSI.size(); i != 0; --i) {
203 unsigned Reg = CSI[i-1].getReg();
204 // Add the callee-saved register as live-in. It's killed at the spill.
205 MBB.addLiveIn(Reg);
206 MIB.addReg(Reg, RegState::Kill);
207 }
208 return true;
209 }
210
211 bool ThumbInstrInfo::
212 restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
213 MachineBasicBlock::iterator MI,
214 const std::vector &CSI) const {
215 MachineFunction &MF = *MBB.getParent();
216 ARMFunctionInfo *AFI = MF.getInfo();
217 if (CSI.empty())
218 return false;
219
220 bool isVarArg = AFI->getVarArgsRegSaveSize() > 0;
221 MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP),MI->getDebugLoc());
222 for (unsigned i = CSI.size(); i != 0; --i) {
223 unsigned Reg = CSI[i-1].getReg();
224 if (Reg == ARM::LR) {
225 // Special epilogue for vararg functions. See emitEpilogue
226 if (isVarArg)
227 continue;
228 Reg = ARM::PC;
229 PopMI->setDesc(get(ARM::tPOP_RET));
230 MI = MBB.erase(MI);
231 }
232 PopMI->addOperand(MachineOperand::CreateReg(Reg, true));
233 }
234
235 // It's illegal to emit pop instruction without operands.
236 if (PopMI->getNumOperands() > 0)
237 MBB.insert(MI, PopMI);
238
239 return true;
240 }
241
242 MachineInstr *ThumbInstrInfo::
243 foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
244 const SmallVectorImpl &Ops, int FI) const {
245 if (Ops.size() != 1) return NULL;
246 const ARMRegisterInfo &RI = getRegisterInfo();
247
248 unsigned OpNum = Ops[0];
249 unsigned Opc = MI->getOpcode();
250 MachineInstr *NewMI = NULL;
251 switch (Opc) {
252 default: break;
253 case ARM::tMOVr:
254 case ARM::tMOVlor2hir:
255 case ARM::tMOVhir2lor:
256 case ARM::tMOVhir2hir: {
257 if (OpNum == 0) { // move -> store
258 unsigned SrcReg = MI->getOperand(1).getReg();
259 bool isKill = MI->getOperand(1).isKill();
260 if (RI.isPhysicalRegister(SrcReg) && !RI.isLowRegister(SrcReg))
261 // tSpill cannot take a high register operand.
262 break;
263 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::tSpill))
264 .addReg(SrcReg, getKillRegState(isKill))
265 .addFrameIndex(FI).addImm(0);
266 } else { // move -> load
267 unsigned DstReg = MI->getOperand(0).getReg();
268 if (RI.isPhysicalRegister(DstReg) && !RI.isLowRegister(DstReg))
269 // tRestore cannot target a high register operand.
270 break;
271 bool isDead = MI->getOperand(0).isDead();
272 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::tRestore))
273 .addReg(DstReg, RegState::Define | getDeadRegState(isDead))
274 .addFrameIndex(FI).addImm(0);
275 }
276 break;
277 }
278 }
279
280 return NewMI;
281 }
0 //===- ThumbInstrInfo.h - Thumb Instruction Information ----------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the ARM implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef THUMBINSTRUCTIONINFO_H
14 #define THUMBINSTRUCTIONINFO_H
15
16 #include "llvm/Target/TargetInstrInfo.h"
17 #include "ARMRegisterInfo.h"
18 #include "ARM.h"
19 #include "ARMInstrInfo.h"
20
21 namespace llvm {
22 class ARMSubtarget;
23
24 class ThumbInstrInfo : public ARMBaseInstrInfo {
25 public:
26 explicit ThumbInstrInfo(const ARMSubtarget &STI);
27
28 /// Return true if the instruction is a register to register move and return
29 /// the source and dest operands and their sub-register indices by reference.
30 virtual bool isMoveInstr(const MachineInstr &MI,
31 unsigned &SrcReg, unsigned &DstReg,
32 unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
33
34 virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
35 int &FrameIndex) const;
36 virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
37 int &FrameIndex) const;
38
39 virtual bool copyRegToReg(MachineBasicBlock &MBB,
40 MachineBasicBlock::iterator I,
41 unsigned DestReg, unsigned SrcReg,
42 const TargetRegisterClass *DestRC,
43 const TargetRegisterClass *SrcRC) const;
44 virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
45 MachineBasicBlock::iterator MBBI,
46 unsigned SrcReg, bool isKill, int FrameIndex,
47 const TargetRegisterClass *RC) const;
48
49 virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill,
50 SmallVectorImpl &Addr,
51 const TargetRegisterClass *RC,
52 SmallVectorImpl &NewMIs) const;
53
54 virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
55 MachineBasicBlock::iterator MBBI,
56 unsigned DestReg, int FrameIndex,
57 const TargetRegisterClass *RC) const;
58
59 virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
60 SmallVectorImpl &Addr,
61 const TargetRegisterClass *RC,
62 SmallVectorImpl &NewMIs) const;
63 virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
64 MachineBasicBlock::iterator MI,
65 const std::vector &CSI) const;
66 virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
67 MachineBasicBlock::iterator MI,
68 const std::vector &CSI) const;
69
70 virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
71 MachineInstr* MI,
72 const SmallVectorImpl &Ops,
73 MachineInstr* LoadMI) const {
74 return 0;
75 }
76
77 virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
78 MachineInstr* MI,
79 const SmallVectorImpl &Ops,
80 int FrameIndex) const;
81 };
82 }
83
84 #endif // THUMBINSTRUCTIONINFO_H