Path: blob/main/contrib/llvm-project/llvm/lib/Target/Lanai/LanaiRegisterInfo.cpp
96353 views
//===-- LanaiRegisterInfo.cpp - Lanai Register Information ------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains the Lanai implementation of the TargetRegisterInfo class.9//10//===----------------------------------------------------------------------===//1112#include "LanaiRegisterInfo.h"13#include "LanaiAluCode.h"14#include "LanaiCondCode.h"15#include "LanaiFrameLowering.h"16#include "LanaiInstrInfo.h"17#include "llvm/ADT/BitVector.h"18#include "llvm/ADT/STLExtras.h"19#include "llvm/CodeGen/MachineFrameInfo.h"20#include "llvm/CodeGen/MachineFunction.h"21#include "llvm/CodeGen/MachineInstrBuilder.h"22#include "llvm/CodeGen/RegisterScavenging.h"23#include "llvm/CodeGen/TargetFrameLowering.h"24#include "llvm/CodeGen/TargetInstrInfo.h"25#include "llvm/IR/Function.h"26#include "llvm/IR/Type.h"27#include "llvm/Support/ErrorHandling.h"2829#define GET_REGINFO_TARGET_DESC30#include "LanaiGenRegisterInfo.inc"3132using namespace llvm;3334LanaiRegisterInfo::LanaiRegisterInfo() : LanaiGenRegisterInfo(Lanai::RCA) {}3536const uint16_t *37LanaiRegisterInfo::getCalleeSavedRegs(const MachineFunction * /*MF*/) const {38return CSR_SaveList;39}4041BitVector LanaiRegisterInfo::getReservedRegs(const MachineFunction &MF) const {42BitVector Reserved(getNumRegs());4344Reserved.set(Lanai::R0);45Reserved.set(Lanai::R1);46Reserved.set(Lanai::PC);47Reserved.set(Lanai::R2);48Reserved.set(Lanai::SP);49Reserved.set(Lanai::R4);50Reserved.set(Lanai::FP);51Reserved.set(Lanai::R5);52Reserved.set(Lanai::RR1);53Reserved.set(Lanai::R10);54Reserved.set(Lanai::RR2);55Reserved.set(Lanai::R11);56Reserved.set(Lanai::RCA);57Reserved.set(Lanai::R15);58if (hasBasePointer(MF))59Reserved.set(getBaseRegister());60return Reserved;61}6263bool LanaiRegisterInfo::requiresRegisterScavenging(64const MachineFunction & /*MF*/) const {65return true;66}6768static bool isALUArithLoOpcode(unsigned Opcode) {69switch (Opcode) {70case Lanai::ADD_I_LO:71case Lanai::SUB_I_LO:72case Lanai::ADD_F_I_LO:73case Lanai::SUB_F_I_LO:74case Lanai::ADDC_I_LO:75case Lanai::SUBB_I_LO:76case Lanai::ADDC_F_I_LO:77case Lanai::SUBB_F_I_LO:78return true;79default:80return false;81}82}8384static unsigned getOppositeALULoOpcode(unsigned Opcode) {85switch (Opcode) {86case Lanai::ADD_I_LO:87return Lanai::SUB_I_LO;88case Lanai::SUB_I_LO:89return Lanai::ADD_I_LO;90case Lanai::ADD_F_I_LO:91return Lanai::SUB_F_I_LO;92case Lanai::SUB_F_I_LO:93return Lanai::ADD_F_I_LO;94case Lanai::ADDC_I_LO:95return Lanai::SUBB_I_LO;96case Lanai::SUBB_I_LO:97return Lanai::ADDC_I_LO;98case Lanai::ADDC_F_I_LO:99return Lanai::SUBB_F_I_LO;100case Lanai::SUBB_F_I_LO:101return Lanai::ADDC_F_I_LO;102default:103llvm_unreachable("Invalid ALU lo opcode");104}105}106107static unsigned getRRMOpcodeVariant(unsigned Opcode) {108switch (Opcode) {109case Lanai::LDBs_RI:110return Lanai::LDBs_RR;111case Lanai::LDBz_RI:112return Lanai::LDBz_RR;113case Lanai::LDHs_RI:114return Lanai::LDHs_RR;115case Lanai::LDHz_RI:116return Lanai::LDHz_RR;117case Lanai::LDW_RI:118return Lanai::LDW_RR;119case Lanai::STB_RI:120return Lanai::STB_RR;121case Lanai::STH_RI:122return Lanai::STH_RR;123case Lanai::SW_RI:124return Lanai::SW_RR;125default:126llvm_unreachable("Opcode has no RRM variant");127}128}129130bool LanaiRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,131int SPAdj, unsigned FIOperandNum,132RegScavenger *RS) const {133assert(SPAdj == 0 && "Unexpected");134135MachineInstr &MI = *II;136MachineFunction &MF = *MI.getParent()->getParent();137const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();138const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();139bool HasFP = TFI->hasFP(MF);140DebugLoc DL = MI.getDebugLoc();141142int FrameIndex = MI.getOperand(FIOperandNum).getIndex();143144int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) +145MI.getOperand(FIOperandNum + 1).getImm();146147// Addressable stack objects are addressed using neg. offsets from fp148// or pos. offsets from sp/basepointer149if (!HasFP || (hasStackRealignment(MF) && FrameIndex >= 0))150Offset += MF.getFrameInfo().getStackSize();151152Register FrameReg = getFrameRegister(MF);153if (FrameIndex >= 0) {154if (hasBasePointer(MF))155FrameReg = getBaseRegister();156else if (hasStackRealignment(MF))157FrameReg = Lanai::SP;158}159160// Replace frame index with a frame pointer reference.161// If the offset is small enough to fit in the immediate field, directly162// encode it.163// Otherwise scavenge a register and encode it into a MOVHI, OR_I_LO sequence.164if ((isSPLSOpcode(MI.getOpcode()) && !isInt<10>(Offset)) ||165!isInt<16>(Offset)) {166assert(RS && "Register scavenging must be on");167Register Reg = RS->FindUnusedReg(&Lanai::GPRRegClass);168if (!Reg)169Reg = RS->scavengeRegisterBackwards(Lanai::GPRRegClass, II, false, SPAdj);170assert(Reg && "Register scavenger failed");171172bool HasNegOffset = false;173// ALU ops have unsigned immediate values. If the Offset is negative, we174// negate it here and reverse the opcode later.175if (Offset < 0) {176HasNegOffset = true;177Offset = -Offset;178}179180if (!isInt<16>(Offset)) {181// Reg = hi(offset) | lo(offset)182BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::MOVHI), Reg)183.addImm(static_cast<uint32_t>(Offset) >> 16);184BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::OR_I_LO), Reg)185.addReg(Reg)186.addImm(Offset & 0xffffU);187} else {188// Reg = mov(offset)189BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::ADD_I_LO), Reg)190.addImm(0)191.addImm(Offset);192}193// Reg = FrameReg OP Reg194if (MI.getOpcode() == Lanai::ADD_I_LO) {195BuildMI(*MI.getParent(), II, DL,196HasNegOffset ? TII->get(Lanai::SUB_R) : TII->get(Lanai::ADD_R),197MI.getOperand(0).getReg())198.addReg(FrameReg)199.addReg(Reg)200.addImm(LPCC::ICC_T);201MI.eraseFromParent();202return true;203}204if (isSPLSOpcode(MI.getOpcode()) || isRMOpcode(MI.getOpcode())) {205MI.setDesc(TII->get(getRRMOpcodeVariant(MI.getOpcode())));206if (HasNegOffset) {207// Change the ALU op (operand 3) from LPAC::ADD (the default) to208// LPAC::SUB with the already negated offset.209assert((MI.getOperand(3).getImm() == LPAC::ADD) &&210"Unexpected ALU op in RRM instruction");211MI.getOperand(3).setImm(LPAC::SUB);212}213} else214llvm_unreachable("Unexpected opcode in frame index operation");215216MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false);217MI.getOperand(FIOperandNum + 1)218.ChangeToRegister(Reg, /*isDef=*/false, /*isImp=*/false,219/*isKill=*/true);220return false;221}222223// ALU arithmetic ops take unsigned immediates. If the offset is negative,224// we replace the instruction with one that inverts the opcode and negates225// the immediate.226if ((Offset < 0) && isALUArithLoOpcode(MI.getOpcode())) {227unsigned NewOpcode = getOppositeALULoOpcode(MI.getOpcode());228// We know this is an ALU op, so we know the operands are as follows:229// 0: destination register230// 1: source register (frame register)231// 2: immediate232BuildMI(*MI.getParent(), II, DL, TII->get(NewOpcode),233MI.getOperand(0).getReg())234.addReg(FrameReg)235.addImm(-Offset);236MI.eraseFromParent();237return true;238}239240MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false);241MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);242return false;243}244245bool LanaiRegisterInfo::hasBasePointer(const MachineFunction &MF) const {246const MachineFrameInfo &MFI = MF.getFrameInfo();247// When we need stack realignment and there are dynamic allocas, we can't248// reference off of the stack pointer, so we reserve a base pointer.249if (hasStackRealignment(MF) && MFI.hasVarSizedObjects())250return true;251252return false;253}254255unsigned LanaiRegisterInfo::getRARegister() const { return Lanai::RCA; }256257Register258LanaiRegisterInfo::getFrameRegister(const MachineFunction & /*MF*/) const {259return Lanai::FP;260}261262Register LanaiRegisterInfo::getBaseRegister() const { return Lanai::R14; }263264const uint32_t *265LanaiRegisterInfo::getCallPreservedMask(const MachineFunction & /*MF*/,266CallingConv::ID /*CC*/) const {267return CSR_RegMask;268}269270271