LLVM 19.0.0git
Go to the documentation of this file.
1//===- XtensaInstrInfo.cpp - Xtensa Instruction Information ---------------===//
3// The LLVM Compiler Infrastructure
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
11// This file contains the Xtensa implementation of the TargetInstrInfo class.
15#include "XtensaInstrInfo.h"
16#include "XtensaTargetMachine.h"
23#include "XtensaGenInstrInfo.inc"
25using namespace llvm;
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);
43 Flags, MFFrame.getObjectSize(FI), Alignment);
44 return MIB.addFrameIndex(FI).addImm(Offset).addMemOperand(MMO);
48 : XtensaGenInstrInfo(Xtensa::ADJCALLSTACKDOWN, Xtensa::ADJCALLSTACKUP),
49 RI(STI), STI(STI) {}
51/// Adjust SP by Amount bytes.
52void XtensaInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
55 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
57 if (Amount == 0)
58 return;
61 const TargetRegisterClass *RC = &Xtensa::ARRegClass;
63 // create virtual reg to store immediate
64 unsigned Reg = RegInfo.createVirtualRegister(RC);
66 if (isInt<8>(Amount)) { // addi sp, sp, amount
67 BuildMI(MBB, I, DL, get(Xtensa::ADDI), Reg).addReg(SP).addImm(Amount);
68 } else { // Expand immediate that doesn't fit in 8-bit.
69 unsigned Reg1;
70 loadImmediate(MBB, I, &Reg1, Amount);
71 BuildMI(MBB, I, DL, get(Xtensa::ADD), Reg)
72 .addReg(SP)
73 .addReg(Reg1, RegState::Kill);
74 }
76 BuildMI(MBB, I, DL, get(Xtensa::OR), SP)
83 const DebugLoc &DL, MCRegister DestReg,
84 MCRegister SrcReg, bool KillSrc) const {
85 // The MOV instruction is not present in core ISA,
86 // so use OR instruction.
87 if (Xtensa::ARRegClass.contains(DestReg, SrcReg))
88 BuildMI(MBB, MBBI, DL, get(Xtensa::OR), DestReg)
89 .addReg(SrcReg, getKillRegState(KillSrc))
90 .addReg(SrcReg, getKillRegState(KillSrc));
91 else
92 report_fatal_error("Impossible reg-to-reg copy");
97 bool isKill, int FrameIdx, const TargetRegisterClass *RC,
98 const TargetRegisterInfo *TRI, Register VReg) const {
99 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
100 unsigned LoadOpcode, StoreOpcode;
101 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);
102 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, get(StoreOpcode))
103 .addReg(SrcReg, getKillRegState(isKill));
104 addFrameReference(MIB, FrameIdx);
109 Register DestReg, int FrameIdx,
110 const TargetRegisterClass *RC,
111 const TargetRegisterInfo *TRI,
112 Register VReg) const {
113 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
114 unsigned LoadOpcode, StoreOpcode;
115 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);
116 addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg), FrameIdx);
120 unsigned &LoadOpcode,
121 unsigned &StoreOpcode,
122 int64_t offset) const {
123 assert((RC == &Xtensa::ARRegClass) &&
124 "Unsupported regclass to load or store");
126 LoadOpcode = Xtensa::L32I;
127 StoreOpcode = Xtensa::S32I;
132 unsigned *Reg, int64_t Value) const {
133 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
135 const TargetRegisterClass *RC = &Xtensa::ARRegClass;
137 // create virtual reg to store immediate
138 *Reg = RegInfo.createVirtualRegister(RC);
139 if (Value >= -2048 && Value <= 2047) {
140 BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Value);
141 } else if (Value >= -32768 && Value <= 32767) {
142 int Low = Value & 0xFF;
143 int High = Value & ~0xFF;
145 BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Low);
146 BuildMI(MBB, MBBI, DL, get(Xtensa::ADDMI), *Reg).addReg(*Reg).addImm(High);
147 } else if (Value >= -4294967296LL && Value <= 4294967295LL) {
148 // 32 bit arbirary constant
150 uint64_t UVal = ((uint64_t)Value) & 0xFFFFFFFFLL;
151 const Constant *CVal = ConstantInt::get(
153 false);
154 unsigned Idx = MCP->getConstantPoolIndex(CVal, Align(2U));
155 // MCSymbol MSym
156 BuildMI(MBB, MBBI, DL, get(Xtensa::L32R), *Reg).addConstantPoolIndex(Idx);
157 } else {
158 // use L32R to let assembler load immediate best
159 // TODO replace to L32R
160 report_fatal_error("Unsupported load immediate value");
161 }
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:41
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:356
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 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
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
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:456
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:159
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.