xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/VE/VERegisterInfo.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
1480093f4SDimitry Andric //===-- VERegisterInfo.cpp - VE Register Information ----------------------===//
2480093f4SDimitry Andric //
3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6480093f4SDimitry Andric //
7480093f4SDimitry Andric //===----------------------------------------------------------------------===//
8480093f4SDimitry Andric //
9480093f4SDimitry Andric // This file contains the VE implementation of the TargetRegisterInfo class.
10480093f4SDimitry Andric //
11480093f4SDimitry Andric //===----------------------------------------------------------------------===//
12480093f4SDimitry Andric 
13480093f4SDimitry Andric #include "VERegisterInfo.h"
14480093f4SDimitry Andric #include "VE.h"
15480093f4SDimitry Andric #include "VESubtarget.h"
16480093f4SDimitry Andric #include "llvm/ADT/BitVector.h"
17480093f4SDimitry Andric #include "llvm/ADT/STLExtras.h"
18480093f4SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
19480093f4SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
20480093f4SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
21480093f4SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
22480093f4SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
23480093f4SDimitry Andric #include "llvm/IR/Type.h"
24480093f4SDimitry Andric #include "llvm/Support/CommandLine.h"
25*e8d8bef9SDimitry Andric #include "llvm/Support/Debug.h"
26480093f4SDimitry Andric #include "llvm/Support/ErrorHandling.h"
27480093f4SDimitry Andric 
28480093f4SDimitry Andric using namespace llvm;
29480093f4SDimitry Andric 
30480093f4SDimitry Andric #define GET_REGINFO_TARGET_DESC
31480093f4SDimitry Andric #include "VEGenRegisterInfo.inc"
32480093f4SDimitry Andric 
33480093f4SDimitry Andric // VE uses %s10 == %lp to keep return address
34480093f4SDimitry Andric VERegisterInfo::VERegisterInfo() : VEGenRegisterInfo(VE::SX10) {}
35480093f4SDimitry Andric 
36480093f4SDimitry Andric const MCPhysReg *
37480093f4SDimitry Andric VERegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
385ffd83dbSDimitry Andric   switch (MF->getFunction().getCallingConv()) {
39*e8d8bef9SDimitry Andric   case CallingConv::Fast:
40*e8d8bef9SDimitry Andric     // Being explicit (same as standard CC).
415ffd83dbSDimitry Andric   default:
42480093f4SDimitry Andric     return CSR_SaveList;
435ffd83dbSDimitry Andric   case CallingConv::PreserveAll:
445ffd83dbSDimitry Andric     return CSR_preserve_all_SaveList;
455ffd83dbSDimitry Andric   }
46480093f4SDimitry Andric }
47480093f4SDimitry Andric 
48480093f4SDimitry Andric const uint32_t *VERegisterInfo::getCallPreservedMask(const MachineFunction &MF,
49480093f4SDimitry Andric                                                      CallingConv::ID CC) const {
505ffd83dbSDimitry Andric   switch (CC) {
51*e8d8bef9SDimitry Andric   case CallingConv::Fast:
52*e8d8bef9SDimitry Andric     // Being explicit (same as standard CC).
535ffd83dbSDimitry Andric   default:
54480093f4SDimitry Andric     return CSR_RegMask;
555ffd83dbSDimitry Andric   case CallingConv::PreserveAll:
565ffd83dbSDimitry Andric     return CSR_preserve_all_RegMask;
575ffd83dbSDimitry Andric   }
58480093f4SDimitry Andric }
59480093f4SDimitry Andric 
60480093f4SDimitry Andric const uint32_t *VERegisterInfo::getNoPreservedMask() const {
61480093f4SDimitry Andric   return CSR_NoRegs_RegMask;
62480093f4SDimitry Andric }
63480093f4SDimitry Andric 
64480093f4SDimitry Andric BitVector VERegisterInfo::getReservedRegs(const MachineFunction &MF) const {
65480093f4SDimitry Andric   BitVector Reserved(getNumRegs());
66480093f4SDimitry Andric 
675ffd83dbSDimitry Andric   const Register ReservedRegs[] = {
685ffd83dbSDimitry Andric       VE::SX8,  // Stack limit
695ffd83dbSDimitry Andric       VE::SX9,  // Frame pointer
705ffd83dbSDimitry Andric       VE::SX10, // Link register (return address)
715ffd83dbSDimitry Andric       VE::SX11, // Stack pointer
72480093f4SDimitry Andric 
735ffd83dbSDimitry Andric       // FIXME: maybe not need to be reserved
745ffd83dbSDimitry Andric       VE::SX12, // Outer register
755ffd83dbSDimitry Andric       VE::SX13, // Id register for dynamic linker
76480093f4SDimitry Andric 
775ffd83dbSDimitry Andric       VE::SX14, // Thread pointer
785ffd83dbSDimitry Andric       VE::SX15, // Global offset table register
795ffd83dbSDimitry Andric       VE::SX16, // Procedure linkage table register
805ffd83dbSDimitry Andric       VE::SX17, // Linkage-area register
81480093f4SDimitry Andric                 // sx18-sx33 are callee-saved registers
82480093f4SDimitry Andric                 // sx34-sx63 are temporary registers
835ffd83dbSDimitry Andric   };
845ffd83dbSDimitry Andric 
855ffd83dbSDimitry Andric   for (auto R : ReservedRegs)
865ffd83dbSDimitry Andric     for (MCRegAliasIterator ItAlias(R, this, true); ItAlias.isValid();
875ffd83dbSDimitry Andric          ++ItAlias)
885ffd83dbSDimitry Andric       Reserved.set(*ItAlias);
89480093f4SDimitry Andric 
90*e8d8bef9SDimitry Andric   // Reserve constant registers.
91*e8d8bef9SDimitry Andric   Reserved.set(VE::VM0);
92*e8d8bef9SDimitry Andric   Reserved.set(VE::VMP0);
93*e8d8bef9SDimitry Andric 
94480093f4SDimitry Andric   return Reserved;
95480093f4SDimitry Andric }
96480093f4SDimitry Andric 
97*e8d8bef9SDimitry Andric bool VERegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
98*e8d8bef9SDimitry Andric   switch (PhysReg) {
99*e8d8bef9SDimitry Andric   case VE::VM0:
100*e8d8bef9SDimitry Andric   case VE::VMP0:
101*e8d8bef9SDimitry Andric     return true;
102*e8d8bef9SDimitry Andric   default:
103*e8d8bef9SDimitry Andric     return false;
104*e8d8bef9SDimitry Andric   }
105*e8d8bef9SDimitry Andric }
106480093f4SDimitry Andric 
107480093f4SDimitry Andric const TargetRegisterClass *
108480093f4SDimitry Andric VERegisterInfo::getPointerRegClass(const MachineFunction &MF,
109480093f4SDimitry Andric                                    unsigned Kind) const {
110480093f4SDimitry Andric   return &VE::I64RegClass;
111480093f4SDimitry Andric }
112480093f4SDimitry Andric 
113*e8d8bef9SDimitry Andric static unsigned offsetToDisp(MachineInstr &MI) {
114*e8d8bef9SDimitry Andric   // Default offset in instruction's operands (reg+reg+imm).
115*e8d8bef9SDimitry Andric   unsigned OffDisp = 2;
116*e8d8bef9SDimitry Andric 
117*e8d8bef9SDimitry Andric #define RRCAS_multi_cases(NAME) NAME##rir : case NAME##rii
118*e8d8bef9SDimitry Andric 
119*e8d8bef9SDimitry Andric   {
120*e8d8bef9SDimitry Andric     using namespace llvm::VE;
121*e8d8bef9SDimitry Andric     switch (MI.getOpcode()) {
122*e8d8bef9SDimitry Andric     case RRCAS_multi_cases(TS1AML):
123*e8d8bef9SDimitry Andric     case RRCAS_multi_cases(TS1AMW):
124*e8d8bef9SDimitry Andric     case RRCAS_multi_cases(CASL):
125*e8d8bef9SDimitry Andric     case RRCAS_multi_cases(CASW):
126*e8d8bef9SDimitry Andric       // These instructions use AS format (reg+imm).
127*e8d8bef9SDimitry Andric       OffDisp = 1;
128*e8d8bef9SDimitry Andric       break;
129*e8d8bef9SDimitry Andric     }
130*e8d8bef9SDimitry Andric   }
131*e8d8bef9SDimitry Andric #undef RRCAS_multi_cases
132*e8d8bef9SDimitry Andric 
133*e8d8bef9SDimitry Andric   return OffDisp;
134*e8d8bef9SDimitry Andric }
135*e8d8bef9SDimitry Andric 
136480093f4SDimitry Andric static void replaceFI(MachineFunction &MF, MachineBasicBlock::iterator II,
137480093f4SDimitry Andric                       MachineInstr &MI, const DebugLoc &dl,
1385ffd83dbSDimitry Andric                       unsigned FIOperandNum, int Offset, Register FrameReg) {
139480093f4SDimitry Andric   // Replace frame index with a frame pointer reference directly.
140480093f4SDimitry Andric   // VE has 32 bit offset field, so no need to expand a target instruction.
141480093f4SDimitry Andric   // Directly encode it.
1425ffd83dbSDimitry Andric   MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false);
143*e8d8bef9SDimitry Andric   MI.getOperand(FIOperandNum + offsetToDisp(MI)).ChangeToImmediate(Offset);
144480093f4SDimitry Andric }
145480093f4SDimitry Andric 
146480093f4SDimitry Andric void VERegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
147480093f4SDimitry Andric                                          int SPAdj, unsigned FIOperandNum,
148480093f4SDimitry Andric                                          RegScavenger *RS) const {
149480093f4SDimitry Andric   assert(SPAdj == 0 && "Unexpected");
150480093f4SDimitry Andric 
151480093f4SDimitry Andric   MachineInstr &MI = *II;
152480093f4SDimitry Andric   DebugLoc dl = MI.getDebugLoc();
153480093f4SDimitry Andric   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
154480093f4SDimitry Andric   MachineFunction &MF = *MI.getParent()->getParent();
155480093f4SDimitry Andric   const VEFrameLowering *TFI = getFrameLowering(MF);
156480093f4SDimitry Andric 
1575ffd83dbSDimitry Andric   Register FrameReg;
158480093f4SDimitry Andric   int Offset;
159*e8d8bef9SDimitry Andric   Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg).getFixed();
160480093f4SDimitry Andric 
161*e8d8bef9SDimitry Andric   Offset += MI.getOperand(FIOperandNum + offsetToDisp(MI)).getImm();
162*e8d8bef9SDimitry Andric 
163*e8d8bef9SDimitry Andric   if (MI.getOpcode() == VE::STQrii) {
164*e8d8bef9SDimitry Andric     const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
165*e8d8bef9SDimitry Andric     Register SrcReg = MI.getOperand(3).getReg();
166*e8d8bef9SDimitry Andric     Register SrcHiReg = getSubReg(SrcReg, VE::sub_even);
167*e8d8bef9SDimitry Andric     Register SrcLoReg = getSubReg(SrcReg, VE::sub_odd);
168*e8d8bef9SDimitry Andric     // VE stores HiReg to 8(addr) and LoReg to 0(addr)
169*e8d8bef9SDimitry Andric     MachineInstr *StMI = BuildMI(*MI.getParent(), II, dl, TII.get(VE::STrii))
170*e8d8bef9SDimitry Andric                              .addReg(FrameReg)
171*e8d8bef9SDimitry Andric                              .addImm(0)
172*e8d8bef9SDimitry Andric                              .addImm(0)
173*e8d8bef9SDimitry Andric                              .addReg(SrcLoReg);
174*e8d8bef9SDimitry Andric     replaceFI(MF, II, *StMI, dl, 0, Offset, FrameReg);
175*e8d8bef9SDimitry Andric     MI.setDesc(TII.get(VE::STrii));
176*e8d8bef9SDimitry Andric     MI.getOperand(3).setReg(SrcHiReg);
177*e8d8bef9SDimitry Andric     Offset += 8;
178*e8d8bef9SDimitry Andric   } else if (MI.getOpcode() == VE::LDQrii) {
179*e8d8bef9SDimitry Andric     const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
180*e8d8bef9SDimitry Andric     Register DestReg = MI.getOperand(0).getReg();
181*e8d8bef9SDimitry Andric     Register DestHiReg = getSubReg(DestReg, VE::sub_even);
182*e8d8bef9SDimitry Andric     Register DestLoReg = getSubReg(DestReg, VE::sub_odd);
183*e8d8bef9SDimitry Andric     // VE loads HiReg from 8(addr) and LoReg from 0(addr)
184*e8d8bef9SDimitry Andric     MachineInstr *StMI =
185*e8d8bef9SDimitry Andric         BuildMI(*MI.getParent(), II, dl, TII.get(VE::LDrii), DestLoReg)
186*e8d8bef9SDimitry Andric             .addReg(FrameReg)
187*e8d8bef9SDimitry Andric             .addImm(0)
188*e8d8bef9SDimitry Andric             .addImm(0);
189*e8d8bef9SDimitry Andric     replaceFI(MF, II, *StMI, dl, 1, Offset, FrameReg);
190*e8d8bef9SDimitry Andric     MI.setDesc(TII.get(VE::LDrii));
191*e8d8bef9SDimitry Andric     MI.getOperand(0).setReg(DestHiReg);
192*e8d8bef9SDimitry Andric     Offset += 8;
193*e8d8bef9SDimitry Andric   }
194480093f4SDimitry Andric 
195480093f4SDimitry Andric   replaceFI(MF, II, MI, dl, FIOperandNum, Offset, FrameReg);
196480093f4SDimitry Andric }
197480093f4SDimitry Andric 
198480093f4SDimitry Andric Register VERegisterInfo::getFrameRegister(const MachineFunction &MF) const {
199480093f4SDimitry Andric   return VE::SX9;
200480093f4SDimitry Andric }
201