OSDN Git Service

[ARM] GlobalISel: Lower calls to void() functions
authorDiana Picus <diana.picus@linaro.org>
Tue, 21 Feb 2017 11:33:59 +0000 (11:33 +0000)
committerDiana Picus <diana.picus@linaro.org>
Tue, 21 Feb 2017 11:33:59 +0000 (11:33 +0000)
For now, we hardcode a BLX instruction, and generate an ADJCALLSTACKDOWN/UP pair
with amount 0.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@295716 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMCallLowering.cpp
lib/Target/ARM/ARMCallLowering.h
test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll

index d79d917..64e870c 100644 (file)
@@ -304,3 +304,38 @@ bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
                               AssignFn);
   return handleAssignments(MIRBuilder, ArgInfos, ArgHandler);
 }
+
+bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
+                                const MachineOperand &Callee,
+                                const ArgInfo &OrigRet,
+                                ArrayRef<ArgInfo> OrigArgs) const {
+  const MachineFunction &MF = MIRBuilder.getMF();
+  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
+
+  if (MF.getSubtarget<ARMSubtarget>().genLongCalls())
+    return false;
+
+  // FIXME: Support calling functions with arguments.
+  if (OrigArgs.size() > 0)
+    return false;
+
+  // FIXME: Support calling functions with return types.
+  if (!OrigRet.Ty->isVoidTy())
+    return false;
+
+  MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN)
+      .addImm(0)
+      .add(predOps(ARMCC::AL));
+
+  MIRBuilder.buildInstr(ARM::BLX)
+      .add(Callee)
+      // FIXME: Don't hardcode the calling conv here...
+      .addRegMask(TRI->getCallPreservedMask(MF, CallingConv::ARM_AAPCS));
+
+  MIRBuilder.buildInstr(ARM::ADJCALLSTACKUP)
+      .addImm(0)
+      .addImm(0)
+      .add(predOps(ARMCC::AL));
+
+  return true;
+}
index 7c3b3dd..a712561 100644 (file)
@@ -34,6 +34,10 @@ public:
   bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
                             ArrayRef<unsigned> VRegs) const override;
 
+  bool lowerCall(MachineIRBuilder &MIRBuilder, const MachineOperand &Callee,
+                 const ArgInfo &OrigRet,
+                 ArrayRef<ArgInfo> OrigArgs) const override;
+
 private:
   bool lowerReturnVal(MachineIRBuilder &MIRBuilder, const Value *Val,
                       unsigned VReg, MachineInstrBuilder &Ret) const;
index ead9950..28bbda4 100644 (file)
@@ -335,3 +335,26 @@ entry:
   %v = fadd double %p0, %p1
   ret double %v
 }
+
+define arm_aapcscc void @test_indirect_call(void() *%fptr) {
+; CHECK-LABEL: name: test_indirect_call
+; CHECK: [[FPTR:%[0-9]+]](p0) = COPY %r0
+; CHECK: ADJCALLSTACKDOWN 0, 14, _, implicit-def %sp, implicit %sp
+; CHECK: BLX [[FPTR]](p0), csr_aapcs, implicit-def %lr, implicit %sp
+; CHECK: ADJCALLSTACKUP 0, 0, 14, _, implicit-def %sp, implicit %sp
+entry:
+  notail call arm_aapcscc void %fptr()
+  ret void
+}
+
+declare arm_aapcscc void @call_target()
+
+define arm_aapcscc void @test_direct_call() {
+; CHECK-LABEL: name: test_direct_call
+; CHECK: ADJCALLSTACKDOWN 0, 14, _, implicit-def %sp, implicit %sp
+; CHECK: BLX @call_target, csr_aapcs, implicit-def %lr, implicit %sp
+; CHECK: ADJCALLSTACKUP 0, 0, 14, _, implicit-def %sp, implicit %sp
+entry:
+  notail call arm_aapcscc void @call_target()
+  ret void
+}