LLVM  12.0.0git
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, MCRegister DestReg,
41  MCRegister 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  Register 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.getObjectAlign(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  Register 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.getObjectAlign(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
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:22
This class represents lattice values for constants.
Definition: AllocatorList.h:23
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:65
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:585
return AArch64::GPR64RegClass contains(Reg)
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
MachineBasicBlock & MBB
LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI, MCRegister Reg, const_iterator Before, unsigned Neighborhood=10) const
Return whether (physical) register Reg has been defined and not killed as of just before Before...
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...
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.
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.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
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
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const override
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Represents one node in the SelectionDAG.
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:59
#define N
const ARMBaseRegisterInfo * getRegisterInfo() const override
Definition: ARMSubtarget.h:551
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, 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.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
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:184
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.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL