LLVM  7.0.0svn
Go to the documentation of this file.
1 //===-- Thumb1InstrInfo.cpp - Thumb-1 Instruction Information -------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the Thumb-1 implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
14 #include "Thumb1InstrInfo.h"
15 #include "ARMSubtarget.h"
19 #include "llvm/MC/MCInst.h"
21 using namespace llvm;
24  : ARMBaseInstrInfo(STI), RI() {}
26 /// Return the noop instruction to use for a noop.
27 void Thumb1InstrInfo::getNoop(MCInst &NopInst) const {
28  NopInst.setOpcode(ARM::tMOVr);
29  NopInst.addOperand(MCOperand::createReg(ARM::R8));
30  NopInst.addOperand(MCOperand::createReg(ARM::R8));
32  NopInst.addOperand(MCOperand::createReg(0));
33 }
35 unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc) const {
36  return 0;
37 }
41  const DebugLoc &DL, unsigned DestReg,
42  unsigned SrcReg, bool KillSrc) const {
43  // Need to check the arch.
44  MachineFunction &MF = *MBB.getParent();
45  const ARMSubtarget &st = MF.getSubtarget<ARMSubtarget>();
47  assert(ARM::GPRRegClass.contains(DestReg, SrcReg) &&
48  "Thumb1 can only copy GPR registers");
50  if (st.hasV6Ops() || ARM::hGPRRegClass.contains(SrcReg)
51  || !ARM::tGPRRegClass.contains(DestReg))
52  BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg)
53  .addReg(SrcReg, getKillRegState(KillSrc))
55  else {
56  // FIXME: Can also use 'mov hi, $src; mov $dst, hi',
57  // with hi as either r10 or r11.
59  const TargetRegisterInfo *RegInfo = st.getRegisterInfo();
60  if (MBB.computeRegisterLiveness(RegInfo, ARM::CPSR, I)
62  BuildMI(MBB, I, DL, get(ARM::tMOVSr), DestReg)
63  .addReg(SrcReg, getKillRegState(KillSrc))
64  ->addRegisterDead(ARM::CPSR, RegInfo);
65  return;
66  }
68  // 'MOV lo, lo' is unpredictable on < v6, so use the stack to do it
69  BuildMI(MBB, I, DL, get(ARM::tPUSH))
71  .addReg(SrcReg, getKillRegState(KillSrc));
72  BuildMI(MBB, I, DL, get(ARM::tPOP))
74  .addReg(DestReg, getDefRegState(true));
75  }
76 }
80  unsigned SrcReg, bool isKill, int FI,
81  const TargetRegisterClass *RC,
82  const TargetRegisterInfo *TRI) const {
83  assert((RC == &ARM::tGPRRegClass ||
85  isARMLowRegister(SrcReg))) && "Unknown regclass!");
87  if (RC == &ARM::tGPRRegClass ||
89  isARMLowRegister(SrcReg))) {
90  DebugLoc DL;
91  if (I != MBB.end()) DL = I->getDebugLoc();
93  MachineFunction &MF = *MBB.getParent();
94  MachineFrameInfo &MFI = MF.getFrameInfo();
97  MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
98  BuildMI(MBB, I, DL, get(ARM::tSTRspi))
99  .addReg(SrcReg, getKillRegState(isKill))
100  .addFrameIndex(FI)
101  .addImm(0)
102  .addMemOperand(MMO)
103  .add(predOps(ARMCC::AL));
104  }
105 }
109  unsigned DestReg, int FI,
110  const TargetRegisterClass *RC,
111  const TargetRegisterInfo *TRI) const {
112  assert((RC->hasSuperClassEq(&ARM::tGPRRegClass) ||
114  isARMLowRegister(DestReg))) && "Unknown regclass!");
116  if (RC->hasSuperClassEq(&ARM::tGPRRegClass) ||
118  isARMLowRegister(DestReg))) {
119  DebugLoc DL;
120  if (I != MBB.end()) DL = I->getDebugLoc();
122  MachineFunction &MF = *MBB.getParent();
123  MachineFrameInfo &MFI = MF.getFrameInfo();
126  MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
127  BuildMI(MBB, I, DL, get(ARM::tLDRspi), DestReg)
128  .addFrameIndex(FI)
129  .addImm(0)
130  .addMemOperand(MMO)
131  .add(predOps(ARMCC::AL));
132  }
133 }
135 void Thumb1InstrInfo::expandLoadStackGuard(
137  MachineFunction &MF = *MI->getParent()->getParent();
138  const TargetMachine &TM = MF.getTarget();
139  if (TM.isPositionIndependent())
140  expandLoadStackGuardBase(MI, ARM::tLDRLIT_ga_pcrel, ARM::tLDRi);
141  else
142  expandLoadStackGuardBase(MI, ARM::tLDRLIT_ga_abs, ARM::tLDRi);
143 }
146  // In Thumb1 the scheduler may need to schedule a cross-copy between GPRS and CPSR
147  // but this is not always possible there, so allow the Scheduler to clone tADCS and tSBCS
148  // even if they have glue.
149  // FIXME. Actually implement the cross-copy where it is possible (post v6)
150  // because these copies entail more spilling.
151  unsigned Opcode = N->getMachineOpcode();
152  if (Opcode == ARM::tADCS || Opcode == ARM::tSBCS)
153  return true;
155  return false;
156 }
const MachineInstrBuilder & add(const MachineOperand &MO) const
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI, unsigned Reg, const_iterator Before, unsigned Neighborhood=10) const
Return whether (physical) register Reg has been defined and not killed as of just before Before...
unsigned getUnindexedOpcode(unsigned Opc) const override
bool addRegisterDead(unsigned Reg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI defined a register without a use.
A debug info location.
Definition: DebugLoc.h:34
bool hasV6Ops() const
Definition: ARMSubtarget.h:504
return AArch64::GPR64RegClass contains(Reg)
A description of a memory reference used in the backend.
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:116
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned 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.
bool canCopyGluedNodeDuringSchedule(SDNode *N) const override
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:159
unsigned getKillRegState(bool B)
unsigned getDefRegState(bool B)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
bool hasSuperClassEq(const TargetRegisterClass *RC) const
Returns true if RC is a super-class of or equal to this class.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void expandLoadStackGuardBase(MachineBasicBlock::iterator MI, unsigned LoadImmOpc, unsigned LoadOpc) const
Register is known to be fully dead.
const MachineInstrBuilder & addFrameIndex(int Idx) const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
The memory access writes data.
void setOpcode(unsigned Op)
Definition: MCInst.h:171
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Represents one node in the SelectionDAG.
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
void getNoop(MCInst &NopInst) const override
Return the noop instruction to use for a noop.
The memory access reads data.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
static bool isARMLowRegister(unsigned Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
Definition: ARMBaseInfo.h:147
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
bool isPositionIndependent() const
Thumb1InstrInfo(const ARMSubtarget &STI)
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
const ARMBaseRegisterInfo * getRegisterInfo() const override
Definition: ARMSubtarget.h:471
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:59
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:184
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:123