summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Mips/MipsInstructionSelector.cpp')
-rw-r--r--llvm/lib/Target/Mips/MipsInstructionSelector.cpp148
1 files changed, 83 insertions, 65 deletions
diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
index f8fc7cb0898b..2f4c9d74262e 100644
--- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
+++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
@@ -18,6 +18,7 @@
#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/IR/IntrinsicsMips.h"
#define DEBUG_TYPE "mips-isel"
@@ -39,12 +40,13 @@ public:
private:
bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
+ bool isRegInGprb(Register Reg, MachineRegisterInfo &MRI) const;
+ bool isRegInFprb(Register Reg, MachineRegisterInfo &MRI) const;
bool materialize32BitImm(Register DestReg, APInt Imm,
MachineIRBuilder &B) const;
bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const;
const TargetRegisterClass *
- getRegClassForTypeOnBank(unsigned OpSize, const RegisterBank &RB,
- const RegisterBankInfo &RBI) const;
+ getRegClassForTypeOnBank(Register Reg, MachineRegisterInfo &MRI) const;
unsigned selectLoadStoreOpCode(MachineInstr &I,
MachineRegisterInfo &MRI) const;
@@ -84,24 +86,23 @@ MipsInstructionSelector::MipsInstructionSelector(
{
}
+bool MipsInstructionSelector::isRegInGprb(Register Reg,
+ MachineRegisterInfo &MRI) const {
+ return RBI.getRegBank(Reg, MRI, TRI)->getID() == Mips::GPRBRegBankID;
+}
+
+bool MipsInstructionSelector::isRegInFprb(Register Reg,
+ MachineRegisterInfo &MRI) const {
+ return RBI.getRegBank(Reg, MRI, TRI)->getID() == Mips::FPRBRegBankID;
+}
+
bool MipsInstructionSelector::selectCopy(MachineInstr &I,
MachineRegisterInfo &MRI) const {
Register DstReg = I.getOperand(0).getReg();
if (Register::isPhysicalRegister(DstReg))
return true;
- const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI);
- const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
-
- const TargetRegisterClass *RC = &Mips::GPR32RegClass;
- if (RegBank->getID() == Mips::FPRBRegBankID) {
- if (DstSize == 32)
- RC = &Mips::FGR32RegClass;
- else if (DstSize == 64)
- RC = STI.isFP64bit() ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
- else
- llvm_unreachable("Unsupported destination size");
- }
+ const TargetRegisterClass *RC = getRegClassForTypeOnBank(DstReg, MRI);
if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
<< " operand\n");
@@ -111,19 +112,27 @@ bool MipsInstructionSelector::selectCopy(MachineInstr &I,
}
const TargetRegisterClass *MipsInstructionSelector::getRegClassForTypeOnBank(
- unsigned OpSize, const RegisterBank &RB,
- const RegisterBankInfo &RBI) const {
- if (RB.getID() == Mips::GPRBRegBankID)
+ Register Reg, MachineRegisterInfo &MRI) const {
+ const LLT Ty = MRI.getType(Reg);
+ const unsigned TySize = Ty.getSizeInBits();
+
+ if (isRegInGprb(Reg, MRI)) {
+ assert((Ty.isScalar() || Ty.isPointer()) && TySize == 32 &&
+ "Register class not available for LLT, register bank combination");
return &Mips::GPR32RegClass;
+ }
- if (RB.getID() == Mips::FPRBRegBankID)
- return OpSize == 32
- ? &Mips::FGR32RegClass
- : STI.hasMips32r6() || STI.isFP64bit() ? &Mips::FGR64RegClass
- : &Mips::AFGR64RegClass;
+ if (isRegInFprb(Reg, MRI)) {
+ if (Ty.isScalar()) {
+ assert((TySize == 32 || TySize == 64) &&
+ "Register class not available for LLT, register bank combination");
+ if (TySize == 32)
+ return &Mips::FGR32RegClass;
+ return STI.isFP64bit() ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
+ }
+ }
- llvm_unreachable("getRegClassForTypeOnBank can't find register class.");
- return nullptr;
+ llvm_unreachable("Unsupported register bank.");
}
bool MipsInstructionSelector::materialize32BitImm(Register DestReg, APInt Imm,
@@ -131,8 +140,9 @@ bool MipsInstructionSelector::materialize32BitImm(Register DestReg, APInt Imm,
assert(Imm.getBitWidth() == 32 && "Unsupported immediate size.");
// Ori zero extends immediate. Used for values with zeros in high 16 bits.
if (Imm.getHiBits(16).isNullValue()) {
- MachineInstr *Inst = B.buildInstr(Mips::ORi, {DestReg}, {Register(Mips::ZERO)})
- .addImm(Imm.getLoBits(16).getLimitedValue());
+ MachineInstr *Inst =
+ B.buildInstr(Mips::ORi, {DestReg}, {Register(Mips::ZERO)})
+ .addImm(Imm.getLoBits(16).getLimitedValue());
return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
}
// Lui places immediate in high 16 bits and sets low 16 bits to zero.
@@ -143,8 +153,9 @@ bool MipsInstructionSelector::materialize32BitImm(Register DestReg, APInt Imm,
}
// ADDiu sign extends immediate. Used for values with 1s in high 17 bits.
if (Imm.isSignedIntN(16)) {
- MachineInstr *Inst = B.buildInstr(Mips::ADDiu, {DestReg}, {Register(Mips::ZERO)})
- .addImm(Imm.getLoBits(16).getLimitedValue());
+ MachineInstr *Inst =
+ B.buildInstr(Mips::ADDiu, {DestReg}, {Register(Mips::ZERO)})
+ .addImm(Imm.getLoBits(16).getLimitedValue());
return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
}
// Values that cannot be materialized with single immediate instruction.
@@ -160,17 +171,22 @@ bool MipsInstructionSelector::materialize32BitImm(Register DestReg, APInt Imm,
return true;
}
-/// Returning Opc indicates that we failed to select MIPS instruction opcode.
+/// When I.getOpcode() is returned, we failed to select MIPS instruction opcode.
unsigned
MipsInstructionSelector::selectLoadStoreOpCode(MachineInstr &I,
MachineRegisterInfo &MRI) const {
- STI.getRegisterInfo();
- const Register DestReg = I.getOperand(0).getReg();
- const unsigned RegBank = RBI.getRegBank(DestReg, MRI, TRI)->getID();
+ const Register ValueReg = I.getOperand(0).getReg();
+ const LLT Ty = MRI.getType(ValueReg);
+ const unsigned TySize = Ty.getSizeInBits();
const unsigned MemSizeInBytes = (*I.memoperands_begin())->getSize();
unsigned Opc = I.getOpcode();
const bool isStore = Opc == TargetOpcode::G_STORE;
- if (RegBank == Mips::GPRBRegBankID) {
+
+ if (isRegInGprb(ValueReg, MRI)) {
+ assert(((Ty.isScalar() && TySize == 32) ||
+ (Ty.isPointer() && TySize == 32 && MemSizeInBytes == 4)) &&
+ "Unsupported register bank, LLT, MemSizeInBytes combination");
+ (void)TySize;
if (isStore)
switch (MemSizeInBytes) {
case 4:
@@ -196,33 +212,39 @@ MipsInstructionSelector::selectLoadStoreOpCode(MachineInstr &I,
}
}
- if (RegBank == Mips::FPRBRegBankID) {
- switch (MemSizeInBytes) {
- case 4:
- return isStore ? Mips::SWC1 : Mips::LWC1;
- case 8:
+ if (isRegInFprb(ValueReg, MRI)) {
+ if (Ty.isScalar()) {
+ assert(((TySize == 32 && MemSizeInBytes == 4) ||
+ (TySize == 64 && MemSizeInBytes == 8)) &&
+ "Unsupported register bank, LLT, MemSizeInBytes combination");
+
+ if (MemSizeInBytes == 4)
+ return isStore ? Mips::SWC1 : Mips::LWC1;
+
if (STI.isFP64bit())
return isStore ? Mips::SDC164 : Mips::LDC164;
- else
- return isStore ? Mips::SDC1 : Mips::LDC1;
- case 16: {
+ return isStore ? Mips::SDC1 : Mips::LDC1;
+ }
+
+ if (Ty.isVector()) {
assert(STI.hasMSA() && "Vector instructions require target with MSA.");
- const unsigned VectorElementSizeInBytes =
- MRI.getType(DestReg).getElementType().getSizeInBytes();
- if (VectorElementSizeInBytes == 1)
+ assert((TySize == 128 && MemSizeInBytes == 16) &&
+ "Unsupported register bank, LLT, MemSizeInBytes combination");
+ switch (Ty.getElementType().getSizeInBits()) {
+ case 8:
return isStore ? Mips::ST_B : Mips::LD_B;
- if (VectorElementSizeInBytes == 2)
+ case 16:
return isStore ? Mips::ST_H : Mips::LD_H;
- if (VectorElementSizeInBytes == 4)
+ case 32:
return isStore ? Mips::ST_W : Mips::LD_W;
- if (VectorElementSizeInBytes == 8)
+ case 64:
return isStore ? Mips::ST_D : Mips::LD_D;
- return Opc;
- }
- default:
- return Opc;
+ default:
+ return Opc;
+ }
}
}
+
return Opc;
}
@@ -239,7 +261,8 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
return true;
}
- if (I.getOpcode() == Mips::G_MUL) {
+ if (I.getOpcode() == Mips::G_MUL &&
+ isRegInGprb(I.getOperand(0).getReg(), MRI)) {
MachineInstr *Mul = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MUL))
.add(I.getOperand(0))
.add(I.getOperand(1))
@@ -280,7 +303,7 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
I.eraseFromParent();
return true;
}
- case G_GEP: {
+ case G_PTR_ADD: {
MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu))
.add(I.getOperand(0))
.add(I.getOperand(1))
@@ -367,14 +390,12 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
}
case G_PHI: {
const Register DestReg = I.getOperand(0).getReg();
- const unsigned OpSize = MRI.getType(DestReg).getSizeInBits();
const TargetRegisterClass *DefRC = nullptr;
if (Register::isPhysicalRegister(DestReg))
DefRC = TRI.getRegClass(DestReg);
else
- DefRC = getRegClassForTypeOnBank(OpSize,
- *RBI.getRegBank(DestReg, MRI, TRI), RBI);
+ DefRC = getRegClassForTypeOnBank(DestReg, MRI);
I.setDesc(TII.get(TargetOpcode::PHI));
return RBI.constrainGenericRegister(DestReg, *DefRC, MRI);
@@ -389,15 +410,15 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
MachineOperand BaseAddr = I.getOperand(1);
int64_t SignedOffset = 0;
- // Try to fold load/store + G_GEP + G_CONSTANT
+ // Try to fold load/store + G_PTR_ADD + G_CONSTANT
// %SignedOffset:(s32) = G_CONSTANT i32 16_bit_signed_immediate
- // %Addr:(p0) = G_GEP %BaseAddr, %SignedOffset
+ // %Addr:(p0) = G_PTR_ADD %BaseAddr, %SignedOffset
// %LoadResult/%StoreSrc = load/store %Addr(p0)
// into:
// %LoadResult/%StoreSrc = NewOpc %BaseAddr(p0), 16_bit_signed_immediate
MachineInstr *Addr = MRI.getVRegDef(I.getOperand(1).getReg());
- if (Addr->getOpcode() == G_GEP) {
+ if (Addr->getOpcode() == G_PTR_ADD) {
MachineInstr *Offset = MRI.getVRegDef(Addr->getOperand(2).getReg());
if (Offset->getOpcode() == G_CONSTANT) {
APInt OffsetValue = Offset->getOperand(1).getCImm()->getValue();
@@ -452,15 +473,12 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
break;
}
case G_IMPLICIT_DEF: {
+ Register Dst = I.getOperand(0).getReg();
MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::IMPLICIT_DEF))
- .add(I.getOperand(0));
+ .addDef(Dst);
// Set class based on register bank, there can be fpr and gpr implicit def.
- MRI.setRegClass(MI->getOperand(0).getReg(),
- getRegClassForTypeOnBank(
- MRI.getType(I.getOperand(0).getReg()).getSizeInBits(),
- *RBI.getRegBank(I.getOperand(0).getReg(), MRI, TRI),
- RBI));
+ MRI.setRegClass(Dst, getRegClassForTypeOnBank(Dst, MRI));
break;
}
case G_CONSTANT: {