Path: blob/main/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYRegisterInfo.cpp
96353 views
//===-- CSKYRegisterInfo.h - CSKY Register Information Impl ---*- 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 CSKY implementation of the TargetRegisterInfo class.9//10//===----------------------------------------------------------------------===//1112#include "CSKYRegisterInfo.h"13#include "CSKY.h"14#include "CSKYSubtarget.h"15#include "llvm/CodeGen/MachineFrameInfo.h"16#include "llvm/CodeGen/MachineFunction.h"17#include "llvm/CodeGen/RegisterScavenging.h"18#include "llvm/MC/MCContext.h"1920#define GET_REGINFO_TARGET_DESC21#include "CSKYGenRegisterInfo.inc"2223using namespace llvm;2425CSKYRegisterInfo::CSKYRegisterInfo()26: CSKYGenRegisterInfo(CSKY::R15, 0, 0, 0) {}2728const uint32_t *29CSKYRegisterInfo::getCallPreservedMask(const MachineFunction &MF,30CallingConv::ID Id) const {31const CSKYSubtarget &STI = MF.getSubtarget<CSKYSubtarget>();32if (STI.hasFPUv2DoubleFloat() || STI.hasFPUv3DoubleFloat())33return CSR_GPR_FPR64_RegMask;34if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat())35return CSR_GPR_FPR32_RegMask;36return CSR_I32_RegMask;37}3839Register CSKYRegisterInfo::getFrameRegister(const MachineFunction &MF) const {40const TargetFrameLowering *TFI = getFrameLowering(MF);41return TFI->hasFP(MF) ? CSKY::R8 : CSKY::R14;42}4344BitVector CSKYRegisterInfo::getReservedRegs(const MachineFunction &MF) const {45const CSKYFrameLowering *TFI = getFrameLowering(MF);46const CSKYSubtarget &STI = MF.getSubtarget<CSKYSubtarget>();47BitVector Reserved(getNumRegs());4849// Reserve the base register if we need to allocate50// variable-sized objects at runtime.51if (TFI->hasBP(MF))52markSuperRegs(Reserved, CSKY::R7); // bp5354if (TFI->hasFP(MF))55markSuperRegs(Reserved, CSKY::R8); // fp5657if (!STI.hasE2()) {58for (unsigned i = 0; i < 6; i++)59markSuperRegs(Reserved, CSKY::R8 + i); // R8 - R1360}6162markSuperRegs(Reserved, CSKY::R14); // sp63markSuperRegs(Reserved, CSKY::R15); // lr6465if (!STI.hasHighRegisters()) {66for (unsigned i = 0; i < 10; i++)67markSuperRegs(Reserved, CSKY::R16 + i); // R16 - R2568}6970markSuperRegs(Reserved, CSKY::R26);71markSuperRegs(Reserved, CSKY::R27);72markSuperRegs(Reserved, CSKY::R28); // gp73markSuperRegs(Reserved, CSKY::R29);74markSuperRegs(Reserved, CSKY::R30);75markSuperRegs(Reserved, CSKY::R31); // tp7677assert(checkAllSuperRegsMarked(Reserved));78return Reserved;79}8081const uint32_t *CSKYRegisterInfo::getNoPreservedMask() const {82return CSR_NoRegs_RegMask;83}8485const MCPhysReg *86CSKYRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {87const CSKYSubtarget &STI = MF->getSubtarget<CSKYSubtarget>();88if (MF->getFunction().hasFnAttribute("interrupt")) {89if (STI.hasFPUv3DoubleFloat())90return CSR_GPR_FPR64v3_ISR_SaveList;91if (STI.hasFPUv3SingleFloat())92return CSR_GPR_FPR32v3_ISR_SaveList;93if (STI.hasFPUv2DoubleFloat())94return CSR_GPR_FPR64_ISR_SaveList;95if (STI.hasFPUv2SingleFloat())96return CSR_GPR_FPR32_ISR_SaveList;97return CSR_GPR_ISR_SaveList;98}99100if (STI.hasFPUv2DoubleFloat() || STI.hasFPUv3DoubleFloat())101return CSR_GPR_FPR64_SaveList;102if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat())103return CSR_GPR_FPR32_SaveList;104return CSR_I32_SaveList;105}106107static bool IsLegalOffset(const CSKYInstrInfo *TII, MachineInstr *MI,108int &Offset) {109const MCInstrDesc &Desc = MI->getDesc();110unsigned AddrMode = (Desc.TSFlags & CSKYII::AddrModeMask);111unsigned i = 0;112for (; !MI->getOperand(i).isFI(); ++i) {113assert(i + 1 < MI->getNumOperands() &&114"Instr doesn't have FrameIndex operand!");115}116117if (MI->getOpcode() == CSKY::ADDI32) {118if (!isUInt<12>(std::abs(Offset) - 1))119return false;120if (Offset < 0) {121MI->setDesc(TII->get(CSKY::SUBI32));122Offset = -Offset;123}124125return true;126}127128if (MI->getOpcode() == CSKY::ADDI16XZ)129return false;130131if (Offset < 0)132return false;133134unsigned NumBits = 0;135unsigned Scale = 1;136switch (AddrMode) {137case CSKYII::AddrMode32B:138Scale = 1;139NumBits = 12;140break;141case CSKYII::AddrMode32H:142Scale = 2;143NumBits = 12;144break;145case CSKYII::AddrMode32WD:146Scale = 4;147NumBits = 12;148break;149case CSKYII::AddrMode16B:150Scale = 1;151NumBits = 5;152break;153case CSKYII::AddrMode16H:154Scale = 2;155NumBits = 5;156break;157case CSKYII::AddrMode16W:158Scale = 4;159NumBits = 5;160break;161case CSKYII::AddrMode32SDF:162Scale = 4;163NumBits = 8;164break;165default:166llvm_unreachable("Unsupported addressing mode!");167}168169// Cannot encode offset.170if ((Offset & (Scale - 1)) != 0)171return false;172173unsigned Mask = (1 << NumBits) - 1;174if ((unsigned)Offset <= Mask * Scale)175return true;176177// Offset out of range.178return false;179}180181bool CSKYRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,182int SPAdj, unsigned FIOperandNum,183RegScavenger *RS) const {184assert(SPAdj == 0 && "Unexpected non-zero SPAdj value");185186MachineInstr *MI = &*II;187MachineBasicBlock &MBB = *MI->getParent();188MachineFunction &MF = *MI->getParent()->getParent();189MachineRegisterInfo &MRI = MF.getRegInfo();190const CSKYInstrInfo *TII = MF.getSubtarget<CSKYSubtarget>().getInstrInfo();191DebugLoc DL = MI->getDebugLoc();192const CSKYSubtarget &STI = MF.getSubtarget<CSKYSubtarget>();193194switch (MI->getOpcode()) {195default:196break;197case CSKY::RESTORE_CARRY: {198Register NewReg = STI.hasE2()199? MRI.createVirtualRegister(&CSKY::GPRRegClass)200: MRI.createVirtualRegister(&CSKY::mGPRRegClass);201202auto *Temp = BuildMI(MBB, II, DL, TII->get(CSKY::LD32W), NewReg)203.add(MI->getOperand(1))204.add(MI->getOperand(2))205.getInstr();206207BuildMI(MBB, II, DL, TII->get(STI.hasE2() ? CSKY::BTSTI32 : CSKY::BTSTI16),208MI->getOperand(0).getReg())209.addReg(NewReg, getKillRegState(true))210.addImm(0);211212MI = Temp;213214MBB.erase(II);215break;216}217case CSKY::SPILL_CARRY: {218Register NewReg;219if (STI.hasE2()) {220NewReg = MRI.createVirtualRegister(&CSKY::GPRRegClass);221BuildMI(MBB, II, DL, TII->get(CSKY::MVC32), NewReg)222.add(MI->getOperand(0));223} else {224NewReg = MRI.createVirtualRegister(&CSKY::mGPRRegClass);225BuildMI(MBB, II, DL, TII->get(CSKY::MOVI16), NewReg).addImm(0);226BuildMI(MBB, II, DL, TII->get(CSKY::ADDC16))227.addReg(NewReg, RegState::Define)228.addReg(MI->getOperand(0).getReg(), RegState::Define)229.addReg(NewReg, getKillRegState(true))230.addReg(NewReg, getKillRegState(true))231.addReg(MI->getOperand(0).getReg());232233BuildMI(MBB, II, DL, TII->get(CSKY::BTSTI16), MI->getOperand(0).getReg())234.addReg(NewReg)235.addImm(0);236}237238MI = BuildMI(MBB, II, DL, TII->get(CSKY::ST32W))239.addReg(NewReg, getKillRegState(true))240.add(MI->getOperand(1))241.add(MI->getOperand(2))242.getInstr();243244MBB.erase(II);245246break;247}248}249250int FrameIndex = MI->getOperand(FIOperandNum).getIndex();251Register FrameReg;252int Offset = getFrameLowering(MF)253->getFrameIndexReference(MF, FrameIndex, FrameReg)254.getFixed() +255MI->getOperand(FIOperandNum + 1).getImm();256257if (!isInt<32>(Offset))258report_fatal_error(259"Frame offsets outside of the signed 32-bit range not supported");260261bool FrameRegIsKill = false;262MachineBasicBlock::iterator NewII(MI);263if (!IsLegalOffset(TII, MI, Offset)) {264assert(isInt<32>(Offset) && "Int32 expected");265// The offset won't fit in an immediate, so use a scratch register instead266// Modify Offset and FrameReg appropriately267Register ScratchReg = TII->movImm(MBB, NewII, DL, Offset);268BuildMI(MBB, NewII, DL,269TII->get(STI.hasE2() ? CSKY::ADDU32 : CSKY::ADDU16XZ), ScratchReg)270.addReg(ScratchReg, RegState::Kill)271.addReg(FrameReg);272273Offset = 0;274FrameReg = ScratchReg;275FrameRegIsKill = true;276}277278if (Offset == 0 &&279(MI->getOpcode() == CSKY::ADDI32 || MI->getOpcode() == CSKY::ADDI16XZ)) {280MI->setDesc(TII->get(TargetOpcode::COPY));281MI->getOperand(FIOperandNum)282.ChangeToRegister(FrameReg, false, false, FrameRegIsKill);283MI->removeOperand(FIOperandNum + 1);284} else {285MI->getOperand(FIOperandNum)286.ChangeToRegister(FrameReg, false, false, FrameRegIsKill);287MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);288}289return false;290}291292293