Path: blob/main/contrib/llvm-project/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
35271 views
//===- XtensaInstrInfo.cpp - Xtensa Instruction Information ---------------===//1//2// The LLVM Compiler Infrastructure3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9//10// This file contains the Xtensa implementation of the TargetInstrInfo class.11//12//===----------------------------------------------------------------------===//1314#include "XtensaInstrInfo.h"15#include "XtensaTargetMachine.h"16#include "llvm/CodeGen/MachineConstantPool.h"17#include "llvm/CodeGen/MachineFrameInfo.h"18#include "llvm/CodeGen/MachineInstrBuilder.h"19#include "llvm/CodeGen/MachineRegisterInfo.h"2021#define GET_INSTRINFO_CTOR_DTOR22#include "XtensaGenInstrInfo.inc"2324using namespace llvm;2526static const MachineInstrBuilder &27addFrameReference(const MachineInstrBuilder &MIB, int FI) {28MachineInstr *MI = MIB;29MachineFunction &MF = *MI->getParent()->getParent();30MachineFrameInfo &MFFrame = MF.getFrameInfo();31const MCInstrDesc &MCID = MI->getDesc();32MachineMemOperand::Flags Flags = MachineMemOperand::MONone;33if (MCID.mayLoad())34Flags |= MachineMemOperand::MOLoad;35if (MCID.mayStore())36Flags |= MachineMemOperand::MOStore;37int64_t Offset = 0;38Align Alignment = MFFrame.getObjectAlign(FI);3940MachineMemOperand *MMO =41MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(MF, FI, Offset),42Flags, MFFrame.getObjectSize(FI), Alignment);43return MIB.addFrameIndex(FI).addImm(Offset).addMemOperand(MMO);44}4546XtensaInstrInfo::XtensaInstrInfo(const XtensaSubtarget &STI)47: XtensaGenInstrInfo(Xtensa::ADJCALLSTACKDOWN, Xtensa::ADJCALLSTACKUP),48RI(STI), STI(STI) {}4950Register XtensaInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,51int &FrameIndex) const {52if (MI.getOpcode() == Xtensa::L32I) {53if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&54MI.getOperand(2).getImm() == 0) {55FrameIndex = MI.getOperand(1).getIndex();56return MI.getOperand(0).getReg();57}58}59return Register();60}6162Register XtensaInstrInfo::isStoreToStackSlot(const MachineInstr &MI,63int &FrameIndex) const {64if (MI.getOpcode() == Xtensa::S32I) {65if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&66MI.getOperand(2).getImm() == 0) {67FrameIndex = MI.getOperand(1).getIndex();68return MI.getOperand(0).getReg();69}70}71return Register();72}7374/// Adjust SP by Amount bytes.75void XtensaInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,76MachineBasicBlock &MBB,77MachineBasicBlock::iterator I) const {78DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();7980if (Amount == 0)81return;8283MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();84const TargetRegisterClass *RC = &Xtensa::ARRegClass;8586// create virtual reg to store immediate87unsigned Reg = RegInfo.createVirtualRegister(RC);8889if (isInt<8>(Amount)) { // addi sp, sp, amount90BuildMI(MBB, I, DL, get(Xtensa::ADDI), Reg).addReg(SP).addImm(Amount);91} else { // Expand immediate that doesn't fit in 8-bit.92unsigned Reg1;93loadImmediate(MBB, I, &Reg1, Amount);94BuildMI(MBB, I, DL, get(Xtensa::ADD), Reg)95.addReg(SP)96.addReg(Reg1, RegState::Kill);97}9899BuildMI(MBB, I, DL, get(Xtensa::OR), SP)100.addReg(Reg, RegState::Kill)101.addReg(Reg, RegState::Kill);102}103104void XtensaInstrInfo::copyPhysReg(MachineBasicBlock &MBB,105MachineBasicBlock::iterator MBBI,106const DebugLoc &DL, MCRegister DestReg,107MCRegister SrcReg, bool KillSrc) const {108// The MOV instruction is not present in core ISA,109// so use OR instruction.110if (Xtensa::ARRegClass.contains(DestReg, SrcReg))111BuildMI(MBB, MBBI, DL, get(Xtensa::OR), DestReg)112.addReg(SrcReg, getKillRegState(KillSrc))113.addReg(SrcReg, getKillRegState(KillSrc));114else115report_fatal_error("Impossible reg-to-reg copy");116}117118void XtensaInstrInfo::storeRegToStackSlot(119MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg,120bool isKill, int FrameIdx, const TargetRegisterClass *RC,121const TargetRegisterInfo *TRI, Register VReg) const {122DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();123unsigned LoadOpcode, StoreOpcode;124getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);125MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, get(StoreOpcode))126.addReg(SrcReg, getKillRegState(isKill));127addFrameReference(MIB, FrameIdx);128}129130void XtensaInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,131MachineBasicBlock::iterator MBBI,132Register DestReg, int FrameIdx,133const TargetRegisterClass *RC,134const TargetRegisterInfo *TRI,135Register VReg) const {136DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();137unsigned LoadOpcode, StoreOpcode;138getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);139addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg), FrameIdx);140}141142void XtensaInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC,143unsigned &LoadOpcode,144unsigned &StoreOpcode,145int64_t offset) const {146assert((RC == &Xtensa::ARRegClass) &&147"Unsupported regclass to load or store");148149LoadOpcode = Xtensa::L32I;150StoreOpcode = Xtensa::S32I;151}152153void XtensaInstrInfo::loadImmediate(MachineBasicBlock &MBB,154MachineBasicBlock::iterator MBBI,155unsigned *Reg, int64_t Value) const {156DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();157MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();158const TargetRegisterClass *RC = &Xtensa::ARRegClass;159160// create virtual reg to store immediate161*Reg = RegInfo.createVirtualRegister(RC);162if (Value >= -2048 && Value <= 2047) {163BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Value);164} else if (Value >= -32768 && Value <= 32767) {165int Low = Value & 0xFF;166int High = Value & ~0xFF;167168BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Low);169BuildMI(MBB, MBBI, DL, get(Xtensa::ADDMI), *Reg).addReg(*Reg).addImm(High);170} else if (Value >= -4294967296LL && Value <= 4294967295LL) {171// 32 bit arbitrary constant172MachineConstantPool *MCP = MBB.getParent()->getConstantPool();173uint64_t UVal = ((uint64_t)Value) & 0xFFFFFFFFLL;174const Constant *CVal = ConstantInt::get(175Type::getInt32Ty(MBB.getParent()->getFunction().getContext()), UVal,176false);177unsigned Idx = MCP->getConstantPoolIndex(CVal, Align(2U));178// MCSymbol MSym179BuildMI(MBB, MBBI, DL, get(Xtensa::L32R), *Reg).addConstantPoolIndex(Idx);180} else {181// use L32R to let assembler load immediate best182// TODO replace to L32R183report_fatal_error("Unsupported load immediate value");184}185}186187188