1
//===- ARMBaseInstrInfo.h - ARM Base Instruction Information ----*- C++ -*-===//
3
// The LLVM Compiler Infrastructure
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
8
//===----------------------------------------------------------------------===//
10
// This file contains the Base ARM implementation of the TargetInstrInfo class.
12
//===----------------------------------------------------------------------===//
14
#ifndef ARMBASEINSTRUCTIONINFO_H
15
#define ARMBASEINSTRUCTIONINFO_H
18
#include "ARMRegisterInfo.h"
19
#include "llvm/CodeGen/MachineInstrBuilder.h"
20
#include "llvm/Target/TargetInstrInfo.h"
24
/// ARMII - This namespace holds all of the target specific flags that
25
/// instruction info tracks.
29
//===------------------------------------------------------------------===//
32
//===------------------------------------------------------------------===//
33
// This four-bit field describes the addressing mode used.
46
AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data
50
AddrModeT2_pc = 14, // +/- i12 for pc relative data
51
AddrModeT2_i8s4 = 15, // i8 * 4
53
// Size* - Flags to keep track of the size of an instruction.
55
SizeMask = 7 << SizeShift,
56
SizeSpecial = 1, // 0 byte pseudo or special case.
61
// IndexMode - Unindex, pre-indexed, or post-indexed. Only valid for load
64
IndexModeMask = 3 << IndexModeShift,
68
//===------------------------------------------------------------------===//
69
// Instruction encoding formats.
72
FormMask = 0x3f << FormShift,
74
// Pseudo instructions
75
Pseudo = 0 << FormShift,
77
// Multiply instructions
78
MulFrm = 1 << FormShift,
80
// Branch instructions
81
BrFrm = 2 << FormShift,
82
BrMiscFrm = 3 << FormShift,
84
// Data Processing instructions
85
DPFrm = 4 << FormShift,
86
DPSoRegFrm = 5 << FormShift,
89
LdFrm = 6 << FormShift,
90
StFrm = 7 << FormShift,
91
LdMiscFrm = 8 << FormShift,
92
StMiscFrm = 9 << FormShift,
93
LdStMulFrm = 10 << FormShift,
95
LdStExFrm = 28 << FormShift,
97
// Miscellaneous arithmetic instructions
98
ArithMiscFrm = 11 << FormShift,
100
// Extend instructions
101
ExtFrm = 12 << FormShift,
104
VFPUnaryFrm = 13 << FormShift,
105
VFPBinaryFrm = 14 << FormShift,
106
VFPConv1Frm = 15 << FormShift,
107
VFPConv2Frm = 16 << FormShift,
108
VFPConv3Frm = 17 << FormShift,
109
VFPConv4Frm = 18 << FormShift,
110
VFPConv5Frm = 19 << FormShift,
111
VFPLdStFrm = 20 << FormShift,
112
VFPLdStMulFrm = 21 << FormShift,
113
VFPMiscFrm = 22 << FormShift,
116
ThumbFrm = 23 << FormShift,
119
NEONFrm = 24 << FormShift,
120
NEONGetLnFrm = 25 << FormShift,
121
NEONSetLnFrm = 26 << FormShift,
122
NEONDupFrm = 27 << FormShift,
124
//===------------------------------------------------------------------===//
127
// UnaryDP - Indicates this is a unary data processing instruction, i.e.
128
// it doesn't have a Rn operand.
131
// Xform16Bit - Indicates this Thumb2 instruction may be transformed into
132
// a 16-bit Thumb instruction if certain conditions are met.
133
Xform16Bit = 1 << 16,
135
//===------------------------------------------------------------------===//
138
DomainMask = 3 << DomainShift,
139
DomainGeneral = 0 << DomainShift,
140
DomainVFP = 1 << DomainShift,
141
DomainNEON = 2 << DomainShift,
143
//===------------------------------------------------------------------===//
144
// Field shifts - such shifts are used to set field while generating
145
// machine instructions.
168
/// Target Operand Flag enum.
170
//===------------------------------------------------------------------===//
171
// ARM Specific MachineOperand flags.
175
/// MO_LO16 - On a symbol operand, this represents a relocation containing
176
/// lower 16 bit of the address. Used only via movw instruction.
179
/// MO_HI16 - On a symbol operand, this represents a relocation containing
180
/// higher 16 bit of the address. Used only via movt instruction.
185
class ARMBaseInstrInfo : public TargetInstrInfoImpl {
186
const ARMSubtarget& Subtarget;
188
// Can be only subclassed.
189
explicit ARMBaseInstrInfo(const ARMSubtarget &STI);
191
// Return the non-pre/post incrementing version of 'Opc'. Return 0
192
// if there is not such an opcode.
193
virtual unsigned getUnindexedOpcode(unsigned Opc) const =0;
195
virtual MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI,
196
MachineBasicBlock::iterator &MBBI,
197
LiveVariables *LV) const;
199
virtual const ARMBaseRegisterInfo &getRegisterInfo() const =0;
200
const ARMSubtarget &getSubtarget() const { return Subtarget; }
203
virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
204
MachineBasicBlock *&FBB,
205
SmallVectorImpl<MachineOperand> &Cond,
206
bool AllowModify) const;
207
virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const;
208
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
209
MachineBasicBlock *FBB,
210
const SmallVectorImpl<MachineOperand> &Cond) const;
213
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
215
// Predication support.
216
bool isPredicated(const MachineInstr *MI) const {
217
int PIdx = MI->findFirstPredOperandIdx();
218
return PIdx != -1 && MI->getOperand(PIdx).getImm() != ARMCC::AL;
221
ARMCC::CondCodes getPredicate(const MachineInstr *MI) const {
222
int PIdx = MI->findFirstPredOperandIdx();
223
return PIdx != -1 ? (ARMCC::CondCodes)MI->getOperand(PIdx).getImm()
228
bool PredicateInstruction(MachineInstr *MI,
229
const SmallVectorImpl<MachineOperand> &Pred) const;
232
bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
233
const SmallVectorImpl<MachineOperand> &Pred2) const;
235
virtual bool DefinesPredicate(MachineInstr *MI,
236
std::vector<MachineOperand> &Pred) const;
238
virtual bool isPredicable(MachineInstr *MI) const;
240
/// GetInstSize - Returns the size of the specified MachineInstr.
242
virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const;
244
/// Return true if the instruction is a register to register move and return
245
/// the source and dest operands and their sub-register indices by reference.
246
virtual bool isMoveInstr(const MachineInstr &MI,
247
unsigned &SrcReg, unsigned &DstReg,
248
unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
250
virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
251
int &FrameIndex) const;
252
virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
253
int &FrameIndex) const;
255
virtual bool copyRegToReg(MachineBasicBlock &MBB,
256
MachineBasicBlock::iterator I,
257
unsigned DestReg, unsigned SrcReg,
258
const TargetRegisterClass *DestRC,
259
const TargetRegisterClass *SrcRC) const;
261
virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
262
MachineBasicBlock::iterator MBBI,
263
unsigned SrcReg, bool isKill, int FrameIndex,
264
const TargetRegisterClass *RC) const;
266
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
267
MachineBasicBlock::iterator MBBI,
268
unsigned DestReg, int FrameIndex,
269
const TargetRegisterClass *RC) const;
271
virtual bool canFoldMemoryOperand(const MachineInstr *MI,
272
const SmallVectorImpl<unsigned> &Ops) const;
274
virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
276
const SmallVectorImpl<unsigned> &Ops,
277
int FrameIndex) const;
279
virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
281
const SmallVectorImpl<unsigned> &Ops,
282
MachineInstr* LoadMI) const;
284
virtual void reMaterialize(MachineBasicBlock &MBB,
285
MachineBasicBlock::iterator MI,
286
unsigned DestReg, unsigned SubIdx,
287
const MachineInstr *Orig,
288
const TargetRegisterInfo *TRI) const;
290
MachineInstr *duplicate(MachineInstr *Orig, MachineFunction &MF) const;
292
virtual bool produceSameValue(const MachineInstr *MI0,
293
const MachineInstr *MI1) const;
297
const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) {
298
return MIB.addImm((int64_t)ARMCC::AL).addReg(0);
302
const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) {
303
return MIB.addReg(0);
307
const MachineInstrBuilder &AddDefaultT1CC(const MachineInstrBuilder &MIB,
308
bool isDead = false) {
309
return MIB.addReg(ARM::CPSR, getDefRegState(true) | getDeadRegState(isDead));
313
const MachineInstrBuilder &AddNoT1CC(const MachineInstrBuilder &MIB) {
314
return MIB.addReg(0);
318
bool isUncondBranchOpcode(int Opc) {
319
return Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B;
323
bool isCondBranchOpcode(int Opc) {
324
return Opc == ARM::Bcc || Opc == ARM::tBcc || Opc == ARM::t2Bcc;
328
bool isJumpTableBranchOpcode(int Opc) {
329
return Opc == ARM::BR_JTr || Opc == ARM::BR_JTm || Opc == ARM::BR_JTadd ||
330
Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT;
334
bool isIndirectBranchOpcode(int Opc) {
335
return Opc == ARM::BRIND || Opc == ARM::tBRIND;
338
/// getInstrPredicate - If instruction is predicated, returns its predicate
339
/// condition, otherwise returns AL. It also returns the condition code
340
/// register by reference.
341
ARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg);
343
int getMatchingCondBranchOpcode(int Opc);
345
/// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of
346
/// instructions to materializea destreg = basereg + immediate in ARM / Thumb2
348
void emitARMRegPlusImmediate(MachineBasicBlock &MBB,
349
MachineBasicBlock::iterator &MBBI, DebugLoc dl,
350
unsigned DestReg, unsigned BaseReg, int NumBytes,
351
ARMCC::CondCodes Pred, unsigned PredReg,
352
const ARMBaseInstrInfo &TII);
354
void emitT2RegPlusImmediate(MachineBasicBlock &MBB,
355
MachineBasicBlock::iterator &MBBI, DebugLoc dl,
356
unsigned DestReg, unsigned BaseReg, int NumBytes,
357
ARMCC::CondCodes Pred, unsigned PredReg,
358
const ARMBaseInstrInfo &TII);
361
/// rewriteARMFrameIndex / rewriteT2FrameIndex -
362
/// Rewrite MI to access 'Offset' bytes from the FP. Return false if the
363
/// offset could not be handled directly in MI, and return the left-over
364
/// portion by reference.
365
bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
366
unsigned FrameReg, int &Offset,
367
const ARMBaseInstrInfo &TII);
369
bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
370
unsigned FrameReg, int &Offset,
371
const ARMBaseInstrInfo &TII);
373
} // End llvm namespace