LLVM  9.0.0svn
Thumb1InstrInfo.cpp
Go to the documentation of this file.
1 //===-- Thumb1InstrInfo.cpp - Thumb-1 Instruction Information -------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb-1 implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "Thumb1InstrInfo.h"
14 #include "ARMSubtarget.h"
18 #include "llvm/MC/MCInst.h"
19 
20 using namespace llvm;
21 
23  : ARMBaseInstrInfo(STI), RI() {}
24 
25 /// Return the noop instruction to use for a noop.
26 void Thumb1InstrInfo::getNoop(MCInst &NopInst) const {
27  NopInst.setOpcode(ARM::tMOVr);
28  NopInst.addOperand(MCOperand::createReg(ARM::R8));
29  NopInst.addOperand(MCOperand::createReg(ARM::R8));
31  NopInst.addOperand(MCOperand::createReg(0));
32 }
33 
34 unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc) const {
35  return 0;
36 }
37 
40  const DebugLoc &DL, unsigned DestReg,
41  unsigned SrcReg, bool KillSrc) const {
42  // Need to check the arch.
43  MachineFunction &MF = *MBB.getParent();
44  const ARMSubtarget &st = MF.getSubtarget<ARMSubtarget>();
45 
46  assert(ARM::GPRRegClass.contains(DestReg, SrcReg) &&
47  "Thumb1 can only copy GPR registers");
48 
49  if (st.hasV6Ops() || ARM::hGPRRegClass.contains(SrcReg)
50  || !ARM::tGPRRegClass.contains(DestReg))
51  BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg)
52  .addReg(SrcReg, getKillRegState(KillSrc))
54  else {
55  // FIXME: Can also use 'mov hi, $src; mov $dst, hi',
56  // with hi as either r10 or r11.
57 
58  const TargetRegisterInfo *RegInfo = st.getRegisterInfo();
59  if (MBB.computeRegisterLiveness(RegInfo, ARM::CPSR, I)
61  BuildMI(MBB, I, DL, get(ARM::tMOVSr), DestReg)
62  .addReg(SrcReg, getKillRegState(KillSrc))
63  ->addRegisterDead(ARM::CPSR, RegInfo);
64  return;
65  }
66 
67  // 'MOV lo, lo' is unpredictable on < v6, so use the stack to do it
68  BuildMI(MBB, I, DL, get(ARM::tPUSH))
70  .addReg(SrcReg, getKillRegState(KillSrc));
71  BuildMI(MBB, I, DL, get(ARM::tPOP))
73  .addReg(DestReg, getDefRegState(true));
74  }
75 }
76 
79  unsigned SrcReg, bool isKill, int FI,
80  const TargetRegisterClass *RC,
81  const TargetRegisterInfo *TRI) const {
82  assert((RC == &ARM::tGPRRegClass ||
84  isARMLowRegister(SrcReg))) && "Unknown regclass!");
85 
86  if (RC == &ARM::tGPRRegClass ||
88  isARMLowRegister(SrcReg))) {
89  DebugLoc DL;
90  if (I != MBB.end()) DL = I->getDebugLoc();
91 
92  MachineFunction &MF = *MBB.getParent();
93  MachineFrameInfo &MFI = MF.getFrameInfo();
96  MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
97  BuildMI(MBB, I, DL, get(ARM::tSTRspi))
98  .addReg(SrcReg, getKillRegState(isKill))
99  .addFrameIndex(FI)
100  .addImm(0)
101  .addMemOperand(MMO)
102  .add(predOps(ARMCC::AL));
103  }
104 }
105 
108  unsigned DestReg, int FI,
109  const TargetRegisterClass *RC,
110  const TargetRegisterInfo *TRI) const {
111  assert((RC->hasSuperClassEq(&ARM::tGPRRegClass) ||
113  isARMLowRegister(DestReg))) && "Unknown regclass!");
114 
115  if (RC->hasSuperClassEq(&ARM::tGPRRegClass) ||
117  isARMLowRegister(DestReg))) {
118  DebugLoc DL;
119  if (I != MBB.end()) DL = I->getDebugLoc();
120 
121  MachineFunction &MF = *MBB.getParent();
122  MachineFrameInfo &MFI = MF.getFrameInfo();
125  MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
126  BuildMI(MBB, I, DL, get(ARM::tLDRspi), DestReg)
127  .addFrameIndex(FI)
128  .addImm(0)
129  .addMemOperand(MMO)
130  .add(predOps(ARMCC::AL));
131  }
132 }
133 
134 void Thumb1InstrInfo::expandLoadStackGuard(
136  MachineFunction &MF = *MI->getParent()->getParent();
137  const TargetMachine &TM = MF.getTarget();
138  if (TM.isPositionIndependent())
139  expandLoadStackGuardBase(MI, ARM::tLDRLIT_ga_pcrel, ARM::tLDRi);
140  else
141  expandLoadStackGuardBase(MI, ARM::tLDRLIT_ga_abs, ARM::tLDRi);
142 }
143 
145  // In Thumb1 the scheduler may need to schedule a cross-copy between GPRS and CPSR
146  // but this is not always possible there, so allow the Scheduler to clone tADCS and tSBCS
147  // even if they have glue.
148  // FIXME. Actually implement the cross-copy where it is possible (post v6)
149  // because these copies entail more spilling.
150  unsigned Opcode = N->getMachineOpcode();
151  if (Opcode == ARM::tADCS || Opcode == ARM::tSBCS)
152  return true;
153 
154  return false;
155 }
const MachineInstrBuilder & add(const MachineOperand &MO) const
This class represents lattice values for constants.
Definition: AllocatorList.h:23
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.
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:33
bool hasV6Ops() const
Definition: ARMSubtarget.h:541
return AArch64::GPR64RegClass contains(Reg)
A description of a memory reference used in the backend.
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:115
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:158
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:170
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:160
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:508
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
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:65
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:183
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:122