summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM
diff options
context:
space:
mode:
authorDiana Picus <diana.picus@linaro.org>2017-02-28 14:17:53 +0000
committerDiana Picus <diana.picus@linaro.org>2017-02-28 14:17:53 +0000
commit1ffca2aeafa86aa90f824f0cee249306cb22ea55 (patch)
tree34d2ef88098783b60eef0e2eea3732cec64d00b7 /llvm/lib/Target/ARM
parent6414ab726d85189d91c8fb6f7125a33f1c1a84e0 (diff)
downloadbcm5719-llvm-1ffca2aeafa86aa90f824f0cee249306cb22ea55.tar.gz
bcm5719-llvm-1ffca2aeafa86aa90f824f0cee249306cb22ea55.zip
[ARM] GlobalISel: Lower i32 and fp call parameters on the stack
Lower i32, float and double parameters that need to live on the stack. This boils down to creating some G_GEPs starting from the stack pointer and storing the values there. During the process we also keep track of the stack size and use the final value in the ADJCALLSTACKDOWN/UP instructions. We currently assert for smaller types, since they usually require extensions. They will be handled in a separate patch. llvm-svn: 296473
Diffstat (limited to 'llvm/lib/Target/ARM')
-rw-r--r--llvm/lib/Target/ARM/ARMCallLowering.cpp38
1 files changed, 31 insertions, 7 deletions
diff --git a/llvm/lib/Target/ARM/ARMCallLowering.cpp b/llvm/lib/Target/ARM/ARMCallLowering.cpp
index f4f3b261bf5..a827fd9de19 100644
--- a/llvm/lib/Target/ARM/ARMCallLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMCallLowering.cpp
@@ -53,11 +53,27 @@ namespace {
struct OutgoingValueHandler : public CallLowering::ValueHandler {
OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
MachineInstrBuilder &MIB, CCAssignFn *AssignFn)
- : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
+ : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB), StackSize(0) {}
unsigned getStackAddress(uint64_t Size, int64_t Offset,
MachinePointerInfo &MPO) override {
- llvm_unreachable("Don't know how to get a stack address yet");
+ // FIXME: Support smaller sizes (which may require extensions).
+ assert((Size == 4 || Size == 8) && "Unsupported size");
+
+ LLT p0 = LLT::pointer(0, 32);
+ LLT s32 = LLT::scalar(32);
+ unsigned SPReg = MRI.createGenericVirtualRegister(p0);
+ MIRBuilder.buildCopy(SPReg, ARM::SP);
+
+ unsigned OffsetReg = MRI.createGenericVirtualRegister(s32);
+ MIRBuilder.buildConstant(OffsetReg, Offset);
+
+ unsigned AddrReg = MRI.createGenericVirtualRegister(p0);
+ MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
+
+ MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
+ StackSize = std::max(StackSize, Size + Offset);
+ return AddrReg;
}
void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
@@ -75,7 +91,12 @@ struct OutgoingValueHandler : public CallLowering::ValueHandler {
void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
MachinePointerInfo &MPO, CCValAssign &VA) override {
- llvm_unreachable("Don't know how to assign a value to an address yet");
+ // FIXME: Support smaller sizes (which may require extensions).
+ assert((Size == 4 || Size == 8) && "Unsupported size");
+
+ auto MMO = MIRBuilder.getMF().getMachineMemOperand(
+ MPO, MachineMemOperand::MOStore, Size, /* Alignment */ 0);
+ MIRBuilder.buildStore(ValVReg, Addr, *MMO);
}
unsigned assignCustomValue(const CallLowering::ArgInfo &Arg,
@@ -110,6 +131,7 @@ struct OutgoingValueHandler : public CallLowering::ValueHandler {
}
MachineInstrBuilder &MIB;
+ uint64_t StackSize;
};
} // End anonymous namespace.
@@ -352,9 +374,7 @@ bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
if (MF.getSubtarget<ARMSubtarget>().genLongCalls())
return false;
- MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN)
- .addImm(0)
- .add(predOps(ARMCC::AL));
+ auto CallSeqStart = MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN);
// FIXME: This is the calling convention of the caller - we should use the
// calling convention of the callee instead.
@@ -397,8 +417,12 @@ bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
return false;
}
+ // We now know the size of the stack - update the ADJCALLSTACKDOWN
+ // accordingly.
+ CallSeqStart.addImm(ArgHandler.StackSize).add(predOps(ARMCC::AL));
+
MIRBuilder.buildInstr(ARM::ADJCALLSTACKUP)
- .addImm(0)
+ .addImm(ArgHandler.StackSize)
.addImm(0)
.add(predOps(ARMCC::AL));
OpenPOWER on IntegriCloud