summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2017-07-20 22:58:38 +0000
committerTim Northover <tnorthover@apple.com>2017-07-20 22:58:38 +0000
commit7b6d66c0c94f390105cc5f14d30330bc0eaf228d (patch)
tree035ab80c26607c3aff49cd612eaeb1e2f87700e9 /llvm/lib
parent071d77a51f333b084de7be38f37864ef5862b8c8 (diff)
downloadbcm5719-llvm-7b6d66c0c94f390105cc5f14d30330bc0eaf228d.tar.gz
bcm5719-llvm-7b6d66c0c94f390105cc5f14d30330bc0eaf228d.zip
Recommit: GlobalISel: select G_EXTRACT and G_INSERT instructions on AArch64.
It revealed a bug in the Localizer pass which has now been fixed. This includes the fix for SUBREG_TO_REG committed separately last time. llvm-svn: 308688
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp50
1 files changed, 49 insertions, 1 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
index 43f3daf8a03..d32a6bd7f81 100644
--- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
@@ -758,6 +758,55 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const {
constrainSelectedInstRegOperands(I, TII, TRI, RBI);
return true;
}
+ case TargetOpcode::G_EXTRACT: {
+ LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
+ // Larger extracts are vectors, same-size extracts should be something else
+ // by now (either split up or simplified to a COPY).
+ if (SrcTy.getSizeInBits() > 64 || Ty.getSizeInBits() > 32)
+ return false;
+
+ I.setDesc(TII.get(AArch64::UBFMXri));
+ MachineInstrBuilder(MF, I).addImm(I.getOperand(2).getImm() +
+ Ty.getSizeInBits() - 1);
+
+ unsigned DstReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
+ BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(),
+ TII.get(AArch64::COPY))
+ .addDef(I.getOperand(0).getReg())
+ .addUse(DstReg, 0, AArch64::sub_32);
+ RBI.constrainGenericRegister(I.getOperand(0).getReg(),
+ AArch64::GPR32RegClass, MRI);
+ I.getOperand(0).setReg(DstReg);
+
+ return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
+ }
+
+ case TargetOpcode::G_INSERT: {
+ LLT SrcTy = MRI.getType(I.getOperand(2).getReg());
+ // Larger inserts are vectors, same-size ones should be something else by
+ // now (split up or turned into COPYs).
+ if (Ty.getSizeInBits() > 64 || SrcTy.getSizeInBits() > 32)
+ return false;
+
+ I.setDesc(TII.get(AArch64::BFMXri));
+ unsigned LSB = I.getOperand(3).getImm();
+ unsigned Width = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
+ I.getOperand(3).setImm((64 - LSB) % 64);
+ MachineInstrBuilder(MF, I).addImm(Width - 1);
+
+ unsigned SrcReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
+ BuildMI(MBB, I.getIterator(), I.getDebugLoc(),
+ TII.get(AArch64::SUBREG_TO_REG))
+ .addDef(SrcReg)
+ .addImm(0)
+ .addUse(I.getOperand(2).getReg())
+ .addImm(AArch64::sub_32);
+ RBI.constrainGenericRegister(I.getOperand(2).getReg(),
+ AArch64::GPR32RegClass, MRI);
+ I.getOperand(2).setReg(SrcReg);
+
+ return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
+ }
case TargetOpcode::G_FRAME_INDEX: {
// allocas and G_FRAME_INDEX are only supported in addrspace(0).
if (Ty != LLT::pointer(0, 64)) {
@@ -765,7 +814,6 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const {
<< ", expected: " << LLT::pointer(0, 64) << '\n');
return false;
}
-
I.setDesc(TII.get(AArch64::ADDXri));
// MOs for a #0 shifted immediate.
OpenPOWER on IntegriCloud