summaryrefslogtreecommitdiff
path: root/lib/Target/AArch64/AArch64InstructionSelector.cpp
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2016-10-11 22:29:23 +0000
committerTim Northover <tnorthover@apple.com>2016-10-11 22:29:23 +0000
commitf8322a85c41875eb69f9fac139029ad9b013d1ea (patch)
tree28140b30300301074b34f08607055a17e92ad5ef /lib/Target/AArch64/AArch64InstructionSelector.cpp
parent426fd51c83edb6ff35904acdbfddbd11db62a5dd (diff)
GlobalISel: support same-size casts on AArch64.
Mostly Ahmed's work again, I'm just sprucing things up slightly before committing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283952 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/AArch64/AArch64InstructionSelector.cpp')
-rw-r--r--lib/Target/AArch64/AArch64InstructionSelector.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/Target/AArch64/AArch64InstructionSelector.cpp b/lib/Target/AArch64/AArch64InstructionSelector.cpp
index 164beacea0d..04e74b01d80 100644
--- a/lib/Target/AArch64/AArch64InstructionSelector.cpp
+++ b/lib/Target/AArch64/AArch64InstructionSelector.cpp
@@ -41,6 +41,32 @@ AArch64InstructionSelector::AArch64InstructionSelector(
: InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()), RBI(RBI) {}
+// FIXME: This should be target-independent, inferred from the types declared
+// for each class in the bank.
+static const TargetRegisterClass *
+getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB,
+ const RegisterBankInfo &RBI) {
+ if (RB.getID() == AArch64::GPRRegBankID) {
+ if (Ty.getSizeInBits() <= 32)
+ return &AArch64::GPR32RegClass;
+ if (Ty.getSizeInBits() == 64)
+ return &AArch64::GPR64RegClass;
+ return nullptr;
+ }
+
+ if (RB.getID() == AArch64::FPRRegBankID) {
+ if (Ty.getSizeInBits() == 32)
+ return &AArch64::FPR32RegClass;
+ if (Ty.getSizeInBits() == 64)
+ return &AArch64::FPR64RegClass;
+ if (Ty.getSizeInBits() == 128)
+ return &AArch64::FPR128RegClass;
+ return nullptr;
+ }
+
+ return nullptr;
+}
+
/// Check whether \p I is a currently unsupported binary operation:
/// - it has an unsized type
/// - an operand is not a vreg
@@ -493,6 +519,42 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const {
I.eraseFromParent();
return true;
}
+
+ case TargetOpcode::G_INTTOPTR:
+ case TargetOpcode::G_PTRTOINT:
+ case TargetOpcode::G_BITCAST: {
+ const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
+ const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
+
+ const unsigned DstReg = I.getOperand(0).getReg();
+ const unsigned SrcReg = I.getOperand(1).getReg();
+
+ const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
+ const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
+
+ const TargetRegisterClass *DstRC =
+ getRegClassForTypeOnBank(DstTy, DstRB, RBI);
+ if (!DstRC)
+ return false;
+
+ const TargetRegisterClass *SrcRC =
+ getRegClassForTypeOnBank(SrcTy, SrcRB, RBI);
+ if (!SrcRC)
+ return false;
+
+ if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
+ !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
+ DEBUG(dbgs() << "Failed to constrain G_BITCAST\n");
+ return false;
+ }
+
+ BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::COPY))
+ .addDef(DstReg)
+ .addUse(SrcReg);
+
+ I.eraseFromParent();
+ return true;
+ }
}
return false;