10b57cec5SDimitry Andric //===- NVPTXRegisterInfo.cpp - NVPTX Register Information -----------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains the NVPTX implementation of the TargetRegisterInfo class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "NVPTXRegisterInfo.h" 140b57cec5SDimitry Andric #include "NVPTX.h" 150b57cec5SDimitry Andric #include "NVPTXSubtarget.h" 16349cc55cSDimitry Andric #include "NVPTXTargetMachine.h" 170b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 220b57cec5SDimitry Andric #include "llvm/MC/MachineLocation.h" 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric using namespace llvm; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric #define DEBUG_TYPE "nvptx-reg-info" 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric namespace llvm { 290b57cec5SDimitry Andric std::string getNVPTXRegClassName(TargetRegisterClass const *RC) { 300b57cec5SDimitry Andric if (RC == &NVPTX::Float32RegsRegClass) 310b57cec5SDimitry Andric return ".f32"; 320b57cec5SDimitry Andric if (RC == &NVPTX::Float64RegsRegClass) 330b57cec5SDimitry Andric return ".f64"; 34*0fca6ea1SDimitry Andric if (RC == &NVPTX::Int128RegsRegClass) 35*0fca6ea1SDimitry Andric return ".b128"; 360b57cec5SDimitry Andric if (RC == &NVPTX::Int64RegsRegClass) 370b57cec5SDimitry Andric // We use untyped (.b) integer registers here as NVCC does. 380b57cec5SDimitry Andric // Correctness of generated code does not depend on register type, 390b57cec5SDimitry Andric // but using .s/.u registers runs into ptxas bug that prevents 400b57cec5SDimitry Andric // assembly of otherwise valid PTX into SASS. Despite PTX ISA 410b57cec5SDimitry Andric // specifying only argument size for fp16 instructions, ptxas does 420b57cec5SDimitry Andric // not allow using .s16 or .u16 arguments for .fp16 430b57cec5SDimitry Andric // instructions. At the same time it allows using .s32/.u32 440b57cec5SDimitry Andric // arguments for .fp16v2 instructions: 450b57cec5SDimitry Andric // 460b57cec5SDimitry Andric // .reg .b16 rb16 470b57cec5SDimitry Andric // .reg .s16 rs16 480b57cec5SDimitry Andric // add.f16 rb16,rb16,rb16; // OK 490b57cec5SDimitry Andric // add.f16 rs16,rs16,rs16; // Arguments mismatch for instruction 'add' 500b57cec5SDimitry Andric // but: 510b57cec5SDimitry Andric // .reg .b32 rb32 520b57cec5SDimitry Andric // .reg .s32 rs32 530b57cec5SDimitry Andric // add.f16v2 rb32,rb32,rb32; // OK 540b57cec5SDimitry Andric // add.f16v2 rs32,rs32,rs32; // OK 550b57cec5SDimitry Andric return ".b64"; 560b57cec5SDimitry Andric if (RC == &NVPTX::Int32RegsRegClass) 570b57cec5SDimitry Andric return ".b32"; 580b57cec5SDimitry Andric if (RC == &NVPTX::Int16RegsRegClass) 590b57cec5SDimitry Andric return ".b16"; 600b57cec5SDimitry Andric if (RC == &NVPTX::Int1RegsRegClass) 610b57cec5SDimitry Andric return ".pred"; 620b57cec5SDimitry Andric if (RC == &NVPTX::SpecialRegsRegClass) 630b57cec5SDimitry Andric return "!Special!"; 640b57cec5SDimitry Andric return "INTERNAL"; 650b57cec5SDimitry Andric } 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric std::string getNVPTXRegClassStr(TargetRegisterClass const *RC) { 680b57cec5SDimitry Andric if (RC == &NVPTX::Float32RegsRegClass) 690b57cec5SDimitry Andric return "%f"; 700b57cec5SDimitry Andric if (RC == &NVPTX::Float64RegsRegClass) 710b57cec5SDimitry Andric return "%fd"; 72*0fca6ea1SDimitry Andric if (RC == &NVPTX::Int128RegsRegClass) 73*0fca6ea1SDimitry Andric return "%rq"; 740b57cec5SDimitry Andric if (RC == &NVPTX::Int64RegsRegClass) 750b57cec5SDimitry Andric return "%rd"; 760b57cec5SDimitry Andric if (RC == &NVPTX::Int32RegsRegClass) 770b57cec5SDimitry Andric return "%r"; 780b57cec5SDimitry Andric if (RC == &NVPTX::Int16RegsRegClass) 790b57cec5SDimitry Andric return "%rs"; 800b57cec5SDimitry Andric if (RC == &NVPTX::Int1RegsRegClass) 810b57cec5SDimitry Andric return "%p"; 820b57cec5SDimitry Andric if (RC == &NVPTX::SpecialRegsRegClass) 830b57cec5SDimitry Andric return "!Special!"; 840b57cec5SDimitry Andric return "INTERNAL"; 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric } 870b57cec5SDimitry Andric 88bdd1243dSDimitry Andric NVPTXRegisterInfo::NVPTXRegisterInfo() 89bdd1243dSDimitry Andric : NVPTXGenRegisterInfo(0), StrPool(StrAlloc) {} 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric #define GET_REGINFO_TARGET_DESC 920b57cec5SDimitry Andric #include "NVPTXGenRegisterInfo.inc" 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric /// NVPTX Callee Saved Registers 950b57cec5SDimitry Andric const MCPhysReg * 960b57cec5SDimitry Andric NVPTXRegisterInfo::getCalleeSavedRegs(const MachineFunction *) const { 970b57cec5SDimitry Andric static const MCPhysReg CalleeSavedRegs[] = { 0 }; 980b57cec5SDimitry Andric return CalleeSavedRegs; 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric BitVector NVPTXRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 1020b57cec5SDimitry Andric BitVector Reserved(getNumRegs()); 103349cc55cSDimitry Andric for (unsigned Reg = NVPTX::ENVREG0; Reg <= NVPTX::ENVREG31; ++Reg) { 104349cc55cSDimitry Andric markSuperRegs(Reserved, Reg); 105349cc55cSDimitry Andric } 106349cc55cSDimitry Andric markSuperRegs(Reserved, NVPTX::VRFrame32); 107349cc55cSDimitry Andric markSuperRegs(Reserved, NVPTX::VRFrameLocal32); 108349cc55cSDimitry Andric markSuperRegs(Reserved, NVPTX::VRFrame64); 109349cc55cSDimitry Andric markSuperRegs(Reserved, NVPTX::VRFrameLocal64); 110349cc55cSDimitry Andric markSuperRegs(Reserved, NVPTX::VRDepot); 1110b57cec5SDimitry Andric return Reserved; 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric 114bdd1243dSDimitry Andric bool NVPTXRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 1150b57cec5SDimitry Andric int SPAdj, unsigned FIOperandNum, 1160b57cec5SDimitry Andric RegScavenger *RS) const { 1170b57cec5SDimitry Andric assert(SPAdj == 0 && "Unexpected"); 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric MachineInstr &MI = *II; 1200b57cec5SDimitry Andric int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric MachineFunction &MF = *MI.getParent()->getParent(); 1230b57cec5SDimitry Andric int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) + 1240b57cec5SDimitry Andric MI.getOperand(FIOperandNum + 1).getImm(); 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric // Using I0 as the frame pointer 127349cc55cSDimitry Andric MI.getOperand(FIOperandNum).ChangeToRegister(getFrameRegister(MF), false); 1280b57cec5SDimitry Andric MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 129bdd1243dSDimitry Andric return false; 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric Register NVPTXRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 133349cc55cSDimitry Andric const NVPTXTargetMachine &TM = 134349cc55cSDimitry Andric static_cast<const NVPTXTargetMachine &>(MF.getTarget()); 135349cc55cSDimitry Andric return TM.is64Bit() ? NVPTX::VRFrame64 : NVPTX::VRFrame32; 136349cc55cSDimitry Andric } 137349cc55cSDimitry Andric 138349cc55cSDimitry Andric Register 139349cc55cSDimitry Andric NVPTXRegisterInfo::getFrameLocalRegister(const MachineFunction &MF) const { 140349cc55cSDimitry Andric const NVPTXTargetMachine &TM = 141349cc55cSDimitry Andric static_cast<const NVPTXTargetMachine &>(MF.getTarget()); 142349cc55cSDimitry Andric return TM.is64Bit() ? NVPTX::VRFrameLocal64 : NVPTX::VRFrameLocal32; 1430b57cec5SDimitry Andric } 144