summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorDiana Picus <diana.picus@linaro.org>2017-02-16 12:19:57 +0000
committerDiana Picus <diana.picus@linaro.org>2017-02-16 12:19:57 +0000
commitb1701e0b058113a0d1a9c624e480859b26f1345c (patch)
tree131b278d071b3e04615eec8a5aad5da74e55bfb4 /llvm/lib/Target
parent6beef3c087c35364f870b1204fb576ea6ff1843c (diff)
downloadbcm5719-llvm-b1701e0b058113a0d1a9c624e480859b26f1345c.tar.gz
bcm5719-llvm-b1701e0b058113a0d1a9c624e480859b26f1345c.zip
[ARM] GlobalISel: Select G_SEQUENCE and G_EXTRACT
Since they're only used for passing around double precision floating point values into the general purpose registers, we'll lower them to VMOVDRR and VMOVRRD. llvm-svn: 295310
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/ARM/ARMInstructionSelector.cpp78
1 files changed, 78 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
index 5201ddba781..e456534ddf9 100644
--- a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
+++ b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
@@ -102,6 +102,74 @@ static bool selectFAdd(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII,
return true;
}
+static bool selectSequence(MachineInstrBuilder &MIB,
+ const ARMBaseInstrInfo &TII,
+ MachineRegisterInfo &MRI,
+ const TargetRegisterInfo &TRI,
+ const RegisterBankInfo &RBI) {
+ assert(TII.getSubtarget().hasVFP2() && "Can't select sequence without VFP");
+
+ // We only support G_SEQUENCE as a way to stick together two scalar GPRs
+ // into one DPR.
+ unsigned VReg0 = MIB->getOperand(0).getReg();
+ (void)VReg0;
+ assert(MRI.getType(VReg0).getSizeInBits() == 64 &&
+ RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::FPRRegBankID &&
+ "Unsupported operand for G_SEQUENCE");
+ unsigned VReg1 = MIB->getOperand(1).getReg();
+ (void)VReg1;
+ assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
+ RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
+ "Unsupported operand for G_SEQUENCE");
+ unsigned VReg2 = MIB->getOperand(3).getReg();
+ (void)VReg2;
+ assert(MRI.getType(VReg2).getSizeInBits() == 32 &&
+ RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::GPRRegBankID &&
+ "Unsupported operand for G_SEQUENCE");
+
+ // Remove the operands corresponding to the offsets.
+ MIB->RemoveOperand(4);
+ MIB->RemoveOperand(2);
+
+ MIB->setDesc(TII.get(ARM::VMOVDRR));
+ MIB.add(predOps(ARMCC::AL));
+
+ return true;
+}
+
+static bool selectExtract(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII,
+ MachineRegisterInfo &MRI,
+ const TargetRegisterInfo &TRI,
+ const RegisterBankInfo &RBI) {
+ assert(TII.getSubtarget().hasVFP2() && "Can't select extract without VFP");
+
+ // We only support G_EXTRACT as a way to break up one DPR into two GPRs.
+ unsigned VReg0 = MIB->getOperand(0).getReg();
+ (void)VReg0;
+ assert(MRI.getType(VReg0).getSizeInBits() == 32 &&
+ RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::GPRRegBankID &&
+ "Unsupported operand for G_SEQUENCE");
+ unsigned VReg1 = MIB->getOperand(1).getReg();
+ (void)VReg1;
+ assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
+ RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
+ "Unsupported operand for G_SEQUENCE");
+ unsigned VReg2 = MIB->getOperand(2).getReg();
+ (void)VReg2;
+ assert(MRI.getType(VReg2).getSizeInBits() == 64 &&
+ RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::FPRRegBankID &&
+ "Unsupported operand for G_SEQUENCE");
+
+ // Remove the operands corresponding to the offsets.
+ MIB->RemoveOperand(4);
+ MIB->RemoveOperand(3);
+
+ MIB->setDesc(TII.get(ARM::VMOVRRD));
+ MIB.add(predOps(ARMCC::AL));
+
+ return true;
+}
+
/// Select the opcode for simple extensions (that translate to a single SXT/UXT
/// instruction). Extension operations more complicated than that should not
/// invoke this.
@@ -237,6 +305,16 @@ bool ARMInstructionSelector::select(MachineInstr &I) const {
MIB.addImm(0).add(predOps(ARMCC::AL));
break;
}
+ case G_SEQUENCE: {
+ if (!selectSequence(MIB, TII, MRI, TRI, RBI))
+ return false;
+ break;
+ }
+ case G_EXTRACT: {
+ if (!selectExtract(MIB, TII, MRI, TRI, RBI))
+ return false;
+ break;
+ }
default:
return false;
}
OpenPOWER on IntegriCloud