diff options
author | Tim Northover <tnorthover@apple.com> | 2016-10-11 22:29:23 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2016-10-11 22:29:23 +0000 |
commit | f8322a85c41875eb69f9fac139029ad9b013d1ea (patch) | |
tree | 28140b30300301074b34f08607055a17e92ad5ef /lib/Target/AArch64/AArch64InstructionSelector.cpp | |
parent | 426fd51c83edb6ff35904acdbfddbd11db62a5dd (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.cpp | 62 |
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; |