LLVM 19.0.0git
XtensaInstrInfo.cpp
Go to the documentation of this file.
1//===- XtensaInstrInfo.cpp - Xtensa Instruction Information ---------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6// See https://llvm.org/LICENSE.txt for license information.
7// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8//
9//===----------------------------------------------------------------------===//
10//
11// This file contains the Xtensa implementation of the TargetInstrInfo class.
12//
13//===----------------------------------------------------------------------===//
14
15#include "XtensaInstrInfo.h"
16#include "XtensaTargetMachine.h"
21
22#define GET_INSTRINFO_CTOR_DTOR
23#include "XtensaGenInstrInfo.inc"
24
25using namespace llvm;
26
27static const MachineInstrBuilder &
29 MachineInstr *MI = MIB;
30 MachineFunction &MF = *MI->getParent()->getParent();
31 MachineFrameInfo &MFFrame = MF.getFrameInfo();
32 const MCInstrDesc &MCID = MI->getDesc();
34 if (MCID.mayLoad())
36 if (MCID.mayStore())
38 int64_t Offset = 0;
39 Align Alignment = MFFrame.getObjectAlign(FI);
40
43 Flags, MFFrame.getObjectSize(FI), Alignment);
44 return MIB.addFrameIndex(FI).addImm(Offset).addMemOperand(MMO);
45}
46
48 : XtensaGenInstrInfo(Xtensa::ADJCALLSTACKDOWN, Xtensa::ADJCALLSTACKUP),
49 RI(STI), STI(STI) {}
50
52 int &FrameIndex) const {
53 if (MI.getOpcode() == Xtensa::L32I) {
54 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
55 MI.getOperand(2).getImm() == 0) {
56 FrameIndex = MI.getOperand(1).getIndex();
57 return MI.getOperand(0).getReg();
58 }
59 }
60 return Register();
61}
62
64 int &FrameIndex) const {
65 if (MI.getOpcode() == Xtensa::S32I) {
66 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
67 MI.getOperand(2).getImm() == 0) {
68 FrameIndex = MI.getOperand(1).getIndex();
69 return MI.getOperand(0).getReg();
70 }
71 }
72 return Register();
73}
74
75/// Adjust SP by Amount bytes.
76void XtensaInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
79 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
80
81 if (Amount == 0)
82 return;
83
85 const TargetRegisterClass *RC = &Xtensa::ARRegClass;
86
87 // create virtual reg to store immediate
88 unsigned Reg = RegInfo.createVirtualRegister(RC);
89
90 if (isInt<8>(Amount)) { // addi sp, sp, amount
91 BuildMI(MBB, I, DL, get(Xtensa::ADDI), Reg).addReg(SP).addImm(Amount);
92 } else { // Expand immediate that doesn't fit in 8-bit.
93 unsigned Reg1;
94 loadImmediate(MBB, I, &Reg1, Amount);
95 BuildMI(MBB, I, DL, get(Xtensa::ADD), Reg)
96 .addReg(SP)
97 .addReg(Reg1, RegState::Kill);
98 }
99
100 BuildMI(MBB, I, DL, get(Xtensa::OR), SP)
102 .addReg(Reg, RegState::Kill);
103}
104
107 const DebugLoc &DL, MCRegister DestReg,
108 MCRegister SrcReg, bool KillSrc) const {
109 // The MOV instruction is not present in core ISA,
110 // so use OR instruction.
111 if (Xtensa::ARRegClass.contains(DestReg, SrcReg))
112 BuildMI(MBB, MBBI, DL, get(Xtensa::OR), DestReg)
113 .addReg(SrcReg, getKillRegState(KillSrc))
114 .addReg(SrcReg, getKillRegState(KillSrc));
115 else
116 report_fatal_error("Impossible reg-to-reg copy");
117}
118
121 bool isKill, int FrameIdx, const TargetRegisterClass *RC,
122 const TargetRegisterInfo *TRI, Register VReg) const {
123 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
124 unsigned LoadOpcode, StoreOpcode;
125 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);
126 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, get(StoreOpcode))
127 .addReg(SrcReg, getKillRegState(isKill));
128 addFrameReference(MIB, FrameIdx);
129}
130
133 Register DestReg, int FrameIdx,
134 const TargetRegisterClass *RC,
135 const TargetRegisterInfo *TRI,
136 Register VReg) const {
137 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
138 unsigned LoadOpcode, StoreOpcode;
139 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);
140 addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg), FrameIdx);
141}
142
144 unsigned &LoadOpcode,
145 unsigned &StoreOpcode,
146 int64_t offset) const {
147 assert((RC == &Xtensa::ARRegClass) &&
148 "Unsupported regclass to load or store");
149
150 LoadOpcode = Xtensa::L32I;
151 StoreOpcode = Xtensa::S32I;
152}
153
156 unsigned *Reg, int64_t Value) const {
157 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
159 const TargetRegisterClass *RC = &Xtensa::ARRegClass;
160
161 // create virtual reg to store immediate
162 *Reg = RegInfo.createVirtualRegister(RC);
163 if (Value >= -2048 && Value <= 2047) {
164 BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Value);
165 } else if (Value >= -32768 && Value <= 32767) {
166 int Low = Value & 0xFF;
167 int High = Value & ~0xFF;
168
169 BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Low);
170 BuildMI(MBB, MBBI, DL, get(Xtensa::ADDMI), *Reg).addReg(*Reg).addImm(High);
171 } else if (Value >= -4294967296LL && Value <= 4294967295LL) {
172 // 32 bit arbirary constant
174 uint64_t UVal = ((uint64_t)Value) & 0xFFFFFFFFLL;
175 const Constant *CVal = ConstantInt::get(
177 false);
178 unsigned Idx = MCP->getConstantPoolIndex(CVal, Align(2U));
179 // MCSymbol MSym
180 BuildMI(MBB, MBBI, DL, get(Xtensa::L32R), *Reg).addConstantPoolIndex(Idx);
181 } else {
182 // use L32R to let assembler load immediate best
183 // TODO replace to L32R
184 report_fatal_error("Unsupported load immediate value");
185 }
186}
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
unsigned const TargetRegisterInfo * TRI
uint64_t High
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:469
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI)
This is an important base class in LLVM.
Definition: Constant.h:42
A debug info location.
Definition: DebugLoc.h:33
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:358
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
bool mayStore() const
Return true if this instruction could possibly modify memory.
Definition: MCInstrDesc.h:444
bool mayLoad() const
Return true if this instruction could possibly read memory.
Definition: MCInstrDesc.h:438
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, 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.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
Definition: MachineInstr.h:69
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static IntegerType * getInt32Ty(LLVMContext &C)
LLVM Value Representation.
Definition: Value.h:74
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const override
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
void loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned *Reg, int64_t Value) const
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
Adjust SP by Amount bytes.
XtensaInstrInfo(const XtensaSubtarget &STI)
void getLoadStoreOpcodes(const TargetRegisterClass *RC, unsigned &LoadOpcode, unsigned &StoreOpcode, int64_t offset) const
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
@ Offset
Definition: DWP.cpp:480
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
unsigned getKillRegState(bool B)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.