1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
|
//===-- VERegisterInfo.cpp - VE Register Information ----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the VE implementation of the TargetRegisterInfo class.
//
//===----------------------------------------------------------------------===//
#include "VERegisterInfo.h"
#include "VE.h"
#include "VESubtarget.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
#define GET_REGINFO_TARGET_DESC
#include "VEGenRegisterInfo.inc"
// VE uses %s10 == %lp to keep return address
VERegisterInfo::VERegisterInfo() : VEGenRegisterInfo(VE::SX10) {}
const MCPhysReg *
VERegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
switch (MF->getFunction().getCallingConv()) {
case CallingConv::Fast:
// Being explicit (same as standard CC).
default:
return CSR_SaveList;
case CallingConv::PreserveAll:
return CSR_preserve_all_SaveList;
}
}
const uint32_t *VERegisterInfo::getCallPreservedMask(const MachineFunction &MF,
CallingConv::ID CC) const {
switch (CC) {
case CallingConv::Fast:
// Being explicit (same as standard CC).
default:
return CSR_RegMask;
case CallingConv::PreserveAll:
return CSR_preserve_all_RegMask;
}
}
const uint32_t *VERegisterInfo::getNoPreservedMask() const {
return CSR_NoRegs_RegMask;
}
BitVector VERegisterInfo::getReservedRegs(const MachineFunction &MF) const {
BitVector Reserved(getNumRegs());
const Register ReservedRegs[] = {
VE::SX8, // Stack limit
VE::SX9, // Frame pointer
VE::SX10, // Link register (return address)
VE::SX11, // Stack pointer
// FIXME: maybe not need to be reserved
VE::SX12, // Outer register
VE::SX13, // Id register for dynamic linker
VE::SX14, // Thread pointer
VE::SX15, // Global offset table register
VE::SX16, // Procedure linkage table register
VE::SX17, // Linkage-area register
// sx18-sx33 are callee-saved registers
// sx34-sx63 are temporary registers
};
for (auto R : ReservedRegs)
for (MCRegAliasIterator ItAlias(R, this, true); ItAlias.isValid();
++ItAlias)
Reserved.set(*ItAlias);
// Reserve constant registers.
Reserved.set(VE::VM0);
Reserved.set(VE::VMP0);
return Reserved;
}
bool VERegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
switch (PhysReg) {
case VE::VM0:
case VE::VMP0:
return true;
default:
return false;
}
}
const TargetRegisterClass *
VERegisterInfo::getPointerRegClass(const MachineFunction &MF,
unsigned Kind) const {
return &VE::I64RegClass;
}
static unsigned offsetToDisp(MachineInstr &MI) {
// Default offset in instruction's operands (reg+reg+imm).
unsigned OffDisp = 2;
#define RRCAS_multi_cases(NAME) NAME##rir : case NAME##rii
{
using namespace llvm::VE;
switch (MI.getOpcode()) {
case RRCAS_multi_cases(TS1AML):
case RRCAS_multi_cases(TS1AMW):
case RRCAS_multi_cases(CASL):
case RRCAS_multi_cases(CASW):
// These instructions use AS format (reg+imm).
OffDisp = 1;
break;
}
}
#undef RRCAS_multi_cases
return OffDisp;
}
static void replaceFI(MachineFunction &MF, MachineBasicBlock::iterator II,
MachineInstr &MI, const DebugLoc &dl,
unsigned FIOperandNum, int Offset, Register FrameReg) {
// Replace frame index with a frame pointer reference directly.
// VE has 32 bit offset field, so no need to expand a target instruction.
// Directly encode it.
MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false);
MI.getOperand(FIOperandNum + offsetToDisp(MI)).ChangeToImmediate(Offset);
}
void VERegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS) const {
assert(SPAdj == 0 && "Unexpected");
MachineInstr &MI = *II;
DebugLoc dl = MI.getDebugLoc();
int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
MachineFunction &MF = *MI.getParent()->getParent();
const VEFrameLowering *TFI = getFrameLowering(MF);
Register FrameReg;
int Offset;
Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg).getFixed();
Offset += MI.getOperand(FIOperandNum + offsetToDisp(MI)).getImm();
if (MI.getOpcode() == VE::STQrii) {
const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
Register SrcReg = MI.getOperand(3).getReg();
Register SrcHiReg = getSubReg(SrcReg, VE::sub_even);
Register SrcLoReg = getSubReg(SrcReg, VE::sub_odd);
// VE stores HiReg to 8(addr) and LoReg to 0(addr)
MachineInstr *StMI = BuildMI(*MI.getParent(), II, dl, TII.get(VE::STrii))
.addReg(FrameReg)
.addImm(0)
.addImm(0)
.addReg(SrcLoReg);
replaceFI(MF, II, *StMI, dl, 0, Offset, FrameReg);
MI.setDesc(TII.get(VE::STrii));
MI.getOperand(3).setReg(SrcHiReg);
Offset += 8;
} else if (MI.getOpcode() == VE::LDQrii) {
const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
Register DestReg = MI.getOperand(0).getReg();
Register DestHiReg = getSubReg(DestReg, VE::sub_even);
Register DestLoReg = getSubReg(DestReg, VE::sub_odd);
// VE loads HiReg from 8(addr) and LoReg from 0(addr)
MachineInstr *StMI =
BuildMI(*MI.getParent(), II, dl, TII.get(VE::LDrii), DestLoReg)
.addReg(FrameReg)
.addImm(0)
.addImm(0);
replaceFI(MF, II, *StMI, dl, 1, Offset, FrameReg);
MI.setDesc(TII.get(VE::LDrii));
MI.getOperand(0).setReg(DestHiReg);
Offset += 8;
}
replaceFI(MF, II, MI, dl, FIOperandNum, Offset, FrameReg);
}
Register VERegisterInfo::getFrameRegister(const MachineFunction &MF) const {
return VE::SX9;
}
|