LLVM  10.0.0svn
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 //===----------------------------------------------------------------------===//
13 #include "Thumb1InstrInfo.h"
14 #include "ARMSubtarget.h"
18 #include "llvm/MC/MCInst.h"
20 using namespace llvm;
23  : ARMBaseInstrInfo(STI), RI() {}
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 }
34 unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc) const {
35  return 0;
36 }
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>();
46  assert(ARM::GPRRegClass.contains(DestReg, SrcReg) &&
47  "Thumb1 can only copy GPR registers");
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.
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  }
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 }
79  unsigned SrcReg, bool isKill, int FI,
80  const TargetRegisterClass *RC,
81  const TargetRegisterInfo *TRI) const {
82  assert((RC == &ARM::tGPRRegClass ||
83  (Register::isPhysicalRegister(SrcReg) && isARMLowRegister(SrcReg))) &&
84  "Unknown regclass!");
86  if (RC == &ARM::tGPRRegClass ||
87  (Register::isPhysicalRegister(SrcReg) && isARMLowRegister(SrcReg))) {
88  DebugLoc DL;
89  if (I != MBB.end()) DL = I->getDebugLoc();
91  MachineFunction &MF = *MBB.getParent();
92  MachineFrameInfo &MFI = MF.getFrameInfo();
95  MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
96  BuildMI(MBB, I, DL, get(ARM::tSTRspi))
97  .addReg(SrcReg, getKillRegState(isKill))
98  .addFrameIndex(FI)
99  .addImm(0)
100  .addMemOperand(MMO)
101  .add(predOps(ARMCC::AL));
102  }
103 }
107  unsigned DestReg, int FI,
108  const TargetRegisterClass *RC,
109  const TargetRegisterInfo *TRI) const {
110  assert(
111  (RC->hasSuperClassEq(&ARM::tGPRRegClass) ||
112  (Register::isPhysicalRegister(DestReg) && isARMLowRegister(DestReg))) &&
113  "Unknown regclass!");
115  if (RC->hasSuperClassEq(&ARM::tGPRRegClass) ||
116  (Register::isPhysicalRegister(DestReg) && isARMLowRegister(DestReg))) {
117  DebugLoc DL;
118  if (I != MBB.end()) DL = I->getDebugLoc();
120  MachineFunction &MF = *MBB.getParent();
121  MachineFrameInfo &MFI = MF.getFrameInfo();
124  MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
125  BuildMI(MBB, I, DL, get(ARM::tLDRspi), DestReg)
126  .addFrameIndex(FI)
127  .addImm(0)
128  .addMemOperand(MMO)
129  .add(predOps(ARMCC::AL));
130  }
131 }
133 void Thumb1InstrInfo::expandLoadStackGuard(
135  MachineFunction &MF = *MI->getParent()->getParent();
136  const TargetMachine &TM = MF.getTarget();
137  if (TM.isPositionIndependent())
138  expandLoadStackGuardBase(MI, ARM::tLDRLIT_ga_pcrel, ARM::tLDRi);
139  else
140  expandLoadStackGuardBase(MI, ARM::tLDRLIT_ga_abs, ARM::tLDRi);
141 }
144  // In Thumb1 the scheduler may need to schedule a cross-copy between GPRS and CPSR
145  // but this is not always possible there, so allow the Scheduler to clone tADCS and tSBCS
146  // even if they have glue.
147  // FIXME. Actually implement the cross-copy where it is possible (post v6)
148  // because these copies entail more spilling.
149  unsigned Opcode = N->getMachineOpcode();
150  if (Opcode == ARM::tADCS || Opcode == ARM::tSBCS)
151  return true;
153  return false;
154 }
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
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:63
bool addRegisterDead(Register 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:572
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
static uint64_t add(uint64_t LeftOp, uint64_t RightOp)
Definition: FileCheck.cpp:243
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
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:539
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
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.