21#include "llvm/IR/IntrinsicsRISCV.h"
23#define GET_TARGET_REGBANK_IMPL
24#include "RISCVGenRegisterBank.inc"
119 switch (RC.
getID()) {
121 case RISCV::VCSRRegClassID:
148bool RISCVRegisterBankInfo::hasFPConstraints(
156 if (
MI.getOpcode() != TargetOpcode::COPY)
159 return getRegBank(
MI.getOperand(0).getReg(), MRI,
TRI) == &RISCV::FPRBRegBank;
165 switch (
MI.getOpcode()) {
166 case RISCV::G_FCVT_W_RV64:
167 case RISCV::G_FCVT_WU_RV64:
168 case RISCV::G_FCLASS:
169 case TargetOpcode::G_FPTOSI:
170 case TargetOpcode::G_FPTOUI:
171 case TargetOpcode::G_FCMP:
177 return hasFPConstraints(
MI, MRI,
TRI);
183 switch (
MI.getOpcode()) {
184 case TargetOpcode::G_SITOFP:
185 case TargetOpcode::G_UITOFP:
191 return hasFPConstraints(
MI, MRI,
TRI);
194bool RISCVRegisterBankInfo::anyUseOnlyUseFP(
199 [&](
const MachineInstr &
UseMI) { return onlyUsesFP(UseMI, MRI, TRI); });
207 else if (
Size == 128)
209 else if (
Size == 256)
211 else if (
Size == 512)
221 const unsigned Opc =
MI.getOpcode();
237 assert((GPRSize == 32 || GPRSize == 64) &&
"Unexpected GPR size");
239 unsigned NumOperands =
MI.getNumOperands();
245 case TargetOpcode::G_ADD:
246 case TargetOpcode::G_SUB:
247 case TargetOpcode::G_SHL:
248 case TargetOpcode::G_ASHR:
249 case TargetOpcode::G_LSHR:
250 case TargetOpcode::G_AND:
251 case TargetOpcode::G_OR:
252 case TargetOpcode::G_XOR:
253 case TargetOpcode::G_MUL:
254 case TargetOpcode::G_SDIV:
255 case TargetOpcode::G_SREM:
256 case TargetOpcode::G_SMULH:
257 case TargetOpcode::G_SMAX:
258 case TargetOpcode::G_SMIN:
259 case TargetOpcode::G_UDIV:
260 case TargetOpcode::G_UREM:
261 case TargetOpcode::G_UMULH:
262 case TargetOpcode::G_UMAX:
263 case TargetOpcode::G_UMIN:
264 case TargetOpcode::G_PTR_ADD:
265 case TargetOpcode::G_PTRTOINT:
266 case TargetOpcode::G_INTTOPTR:
267 case TargetOpcode::G_FADD:
268 case TargetOpcode::G_FSUB:
269 case TargetOpcode::G_FMUL:
270 case TargetOpcode::G_FDIV:
271 case TargetOpcode::G_FABS:
272 case TargetOpcode::G_FNEG:
273 case TargetOpcode::G_FSQRT:
274 case TargetOpcode::G_FMAXNUM:
275 case TargetOpcode::G_FMINNUM: {
285 Mapping = GPRValueMapping;
289 for (
unsigned Idx = 1; Idx != NumOperands; ++Idx) {
292 "Operand has incompatible type");
301 case TargetOpcode::G_SEXTLOAD:
302 case TargetOpcode::G_ZEXTLOAD:
305 case TargetOpcode::G_IMPLICIT_DEF: {
309 auto Mapping = GPRValueMapping;
317 else if (anyUseOnlyUseFP(Dst, MRI,
TRI))
328 case TargetOpcode::G_LOAD: {
332 OpdsMapping[1] = GPRValueMapping;
339 OpdsMapping[0] = GPRValueMapping;
346 if (GPRSize == 32 &&
Size.getFixedValue() == 64) {
355 if (anyUseOnlyUseFP(
MI.getOperand(0).getReg(), MRI,
TRI)) {
366 case TargetOpcode::G_STORE: {
370 OpdsMapping[1] = GPRValueMapping;
377 OpdsMapping[0] = GPRValueMapping;
384 if (GPRSize == 32 &&
Size.getFixedValue() == 64) {
391 if (onlyDefinesFP(*
DefMI, MRI,
TRI))
395 case TargetOpcode::G_SELECT: {
401 assert(TestTy.
isVector() &&
"Unexpected condition argument type");
402 OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] =
415 if (GPRSize == 32 && Ty.getSizeInBits() == 64) {
426 return onlyUsesFP(UseMI, MRI, TRI);
443 for (
unsigned Idx = 2; Idx < 4; ++Idx) {
453 OpdsMapping[1] = GPRValueMapping;
459 OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] = Mapping;
462 case RISCV::G_FCVT_W_RV64:
463 case RISCV::G_FCVT_WU_RV64:
464 case TargetOpcode::G_FPTOSI:
465 case TargetOpcode::G_FPTOUI:
466 case RISCV::G_FCLASS: {
468 OpdsMapping[0] = GPRValueMapping;
472 case TargetOpcode::G_SITOFP:
473 case TargetOpcode::G_UITOFP: {
476 OpdsMapping[1] = GPRValueMapping;
479 case TargetOpcode::G_FCMP: {
482 unsigned Size = Ty.getSizeInBits();
484 OpdsMapping[0] = GPRValueMapping;
488 case TargetOpcode::G_MERGE_VALUES: {
491 if (GPRSize == 32 && Ty.getSizeInBits() == 64) {
494 OpdsMapping[1] = GPRValueMapping;
495 OpdsMapping[2] = GPRValueMapping;
499 case TargetOpcode::G_UNMERGE_VALUES: {
502 if (GPRSize == 32 && Ty.getSizeInBits() == 64) {
504 OpdsMapping[0] = GPRValueMapping;
505 OpdsMapping[1] = GPRValueMapping;
510 case TargetOpcode::G_SPLAT_VECTOR: {
522 OpdsMapping[1] = GPRValueMapping;
525 case TargetOpcode::G_INTRINSIC: {
529 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntrinsicID)) {
530 unsigned ScalarIdx = -1;
531 if (
II->hasScalarOperand()) {
532 ScalarIdx =
II->ScalarOperand + 2;
534 for (
unsigned Idx = 0; Idx < NumOperands; ++Idx) {
542 }
else if (
II->IsFPIntrinsic && ScalarIdx == Idx) {
546 OpdsMapping[Idx] = GPRValueMapping;
551 if (IntrinsicID == Intrinsic::riscv_vsetvli ||
552 IntrinsicID == Intrinsic::riscv_vsetvlimax) {
553 for (
unsigned Idx = 0; Idx < NumOperands; ++Idx) {
557 OpdsMapping[Idx] = GPRValueMapping;
564 for (
unsigned Idx = 0; Idx < NumOperands; ++Idx) {
565 auto &MO =
MI.getOperand(Idx);
566 if (!MO.isReg() || !MO.getReg())
578 OpdsMapping[Idx] = GPRValueMapping;
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
Register const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
static const RegisterBankInfo::ValueMapping * getFPValueMapping(unsigned Size)
static const RegisterBankInfo::ValueMapping * getVRBValueMapping(unsigned Size)
This file declares the targeting of the RegisterBankInfo class for RISC-V.
constexpr bool isVector() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
RISCVRegisterBankInfo(unsigned HwMode)
const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC, LLT Ty) const override
Get a register bank that covers RC.
const InstructionMapping & getInstrMapping(const MachineInstr &MI) const override
Get the mapping of the different operands of MI on the register bank.
Helper class that represents how the value of an instruction may be mapped and what is the related co...
bool isValid() const
Check whether this object is valid.
const InstructionMapping & getInstructionMapping(unsigned ID, unsigned Cost, const ValueMapping *OperandsMapping, unsigned NumOperands) const
Method to get a uniquely generated InstructionMapping.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
unsigned getMaximumSize(unsigned RegBankID) const
Get the maximum size in bits that fits in the given register bank.
virtual const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC, LLT Ty) const
Get a register bank that covers RC.
const ValueMapping * getOperandsMapping(Iterator Begin, Iterator End) const
Get the uniquely generated array of ValueMapping for the elements of between Begin and End.
static const unsigned DefaultMappingID
Identifier used when the related instruction mapping instance is generated by target independent code...
unsigned HwMode
Current HwMode for the target.
const InstructionMapping & getInstrMappingImpl(const MachineInstr &MI) const
Try to get the mapping of MI.
This class implements the register bank concept.
Wrapper class representing virtual and physical registers.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
unsigned getID() const
Return the register class ID number.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const RegisterBankInfo::PartialMapping PartMappings[]
const RegisterBankInfo::ValueMapping ValueMappings[]
This is an optimization pass for GlobalISel generic memory operations.
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isPreISelGenericFloatingPointOpcode(unsigned Opc)
Returns whether opcode Opc is a pre-isel generic floating-point opcode, having only floating-point op...
Helper struct that represents how a value is partially mapped into a register.
Helper struct that represents how a value is mapped through different register banks.