summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-05-26 17:21:53 +0000
committerTim Northover <tnorthover@apple.com>2014-05-26 17:21:53 +0000
commit4146695fb264a617a272f3dfd05b99b342e2b037 (patch)
tree3bd76fa7d4a3ea5cdf3f5ecd7eb38bbfbcaa7c82
parent90e79a50bb0d198edb226cccc338fe4333466b5e (diff)
downloadllvm-4146695fb264a617a272f3dfd05b99b342e2b037.tar.gz
llvm-4146695fb264a617a272f3dfd05b99b342e2b037.tar.bz2
llvm-4146695fb264a617a272f3dfd05b99b342e2b037.tar.xz
AArch64: simplify calling conventions slightly.
We can eliminate the custom C++ code in favour of some TableGen to check the same things. Functionality should be identical, except for a buffer overrun that was present in the C++ code and meant webkit failed if any small argument needed to be passed on the stack. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209636 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/AArch64/AArch64CallingConv.h94
-rw-r--r--lib/Target/AArch64/AArch64CallingConvention.td12
-rw-r--r--lib/Target/AArch64/AArch64FastISel.cpp1
-rw-r--r--lib/Target/AArch64/AArch64ISelLowering.cpp57
-rw-r--r--test/CodeGen/AArch64/arm64-patchpoint.ll8
5 files changed, 44 insertions, 128 deletions
diff --git a/lib/Target/AArch64/AArch64CallingConv.h b/lib/Target/AArch64/AArch64CallingConv.h
deleted file mode 100644
index 1fe426ed68..0000000000
--- a/lib/Target/AArch64/AArch64CallingConv.h
+++ /dev/null
@@ -1,94 +0,0 @@
-//=== AArch64CallingConv.h - Custom Calling Convention Routines -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the custom routines for the AArch64 Calling Convention that
-// aren't done by tablegen.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef AArch64CALLINGCONV_H
-#define AArch64CALLINGCONV_H
-
-#include "AArch64InstrInfo.h"
-#include "llvm/IR/CallingConv.h"
-#include "llvm/CodeGen/CallingConvLower.h"
-#include "llvm/Target/TargetInstrInfo.h"
-
-namespace llvm {
-
-/// CC_AArch64_Custom_i1i8i16_Reg - customized handling of passing i1/i8/i16 via
-/// register. Here, ValVT can be i1/i8/i16 or i32 depending on whether the
-/// argument is already promoted and LocVT is i1/i8/i16. We only promote the
-/// argument to i32 if we are sure this argument will be passed in register.
-static bool CC_AArch64_Custom_i1i8i16_Reg(unsigned ValNo, MVT ValVT, MVT LocVT,
- CCValAssign::LocInfo LocInfo,
- ISD::ArgFlagsTy ArgFlags,
- CCState &State,
- bool IsWebKitJS = false) {
- static const MCPhysReg RegList1[] = { AArch64::W0, AArch64::W1, AArch64::W2,
- AArch64::W3, AArch64::W4, AArch64::W5,
- AArch64::W6, AArch64::W7 };
- static const MCPhysReg RegList2[] = { AArch64::X0, AArch64::X1, AArch64::X2,
- AArch64::X3, AArch64::X4, AArch64::X5,
- AArch64::X6, AArch64::X7 };
- static const MCPhysReg WebKitRegList1[] = { AArch64::W0 };
- static const MCPhysReg WebKitRegList2[] = { AArch64::X0 };
-
- const MCPhysReg *List1 = IsWebKitJS ? WebKitRegList1 : RegList1;
- const MCPhysReg *List2 = IsWebKitJS ? WebKitRegList2 : RegList2;
-
- if (unsigned Reg = State.AllocateReg(List1, List2, 8)) {
- // Customized extra section for handling i1/i8/i16:
- // We need to promote the argument to i32 if it is not done already.
- if (ValVT != MVT::i32) {
- if (ArgFlags.isSExt())
- LocInfo = CCValAssign::SExt;
- else if (ArgFlags.isZExt())
- LocInfo = CCValAssign::ZExt;
- else
- LocInfo = CCValAssign::AExt;
- ValVT = MVT::i32;
- }
- // Set LocVT to i32 as well if passing via register.
- LocVT = MVT::i32;
- State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
- return true;
- }
- return false;
-}
-
-/// CC_AArch64_WebKit_JS_i1i8i16_Reg - customized handling of passing i1/i8/i16
-/// via register. This behaves the same as CC_AArch64_Custom_i1i8i16_Reg, but only
-/// uses the first register.
-static bool CC_AArch64_WebKit_JS_i1i8i16_Reg(unsigned ValNo, MVT ValVT, MVT LocVT,
- CCValAssign::LocInfo LocInfo,
- ISD::ArgFlagsTy ArgFlags,
- CCState &State) {
- return CC_AArch64_Custom_i1i8i16_Reg(ValNo, ValVT, LocVT, LocInfo, ArgFlags,
- State, true);
-}
-
-/// CC_AArch64_Custom_i1i8i16_Stack: customized handling of passing i1/i8/i16 on
-/// stack. Here, ValVT can be i1/i8/i16 or i32 depending on whether the argument
-/// is already promoted and LocVT is i1/i8/i16. If ValVT is already promoted,
-/// it will be truncated back to i1/i8/i16.
-static bool CC_AArch64_Custom_i1i8i16_Stack(unsigned ValNo, MVT ValVT, MVT LocVT,
- CCValAssign::LocInfo LocInfo,
- ISD::ArgFlagsTy ArgFlags,
- CCState &State) {
- unsigned Space = ((LocVT == MVT::i1 || LocVT == MVT::i8) ? 1 : 2);
- unsigned Offset12 = State.AllocateStack(Space, Space);
- ValVT = LocVT;
- State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset12, LocVT, LocInfo));
- return true;
-}
-
-} // End llvm namespace
-
-#endif
diff --git a/lib/Target/AArch64/AArch64CallingConvention.td b/lib/Target/AArch64/AArch64CallingConvention.td
index c263d14dcc..ded2e17c54 100644
--- a/lib/Target/AArch64/AArch64CallingConvention.td
+++ b/lib/Target/AArch64/AArch64CallingConvention.td
@@ -18,6 +18,9 @@ class CCIfAlign<string Align, CCAction A> :
class CCIfBigEndian<CCAction A> :
CCIf<"State.getTarget().getDataLayout()->isBigEndian()", A>;
+class CCIfUnallocated<string Reg, CCAction A> :
+ CCIf<"!State.isAllocated(AArch64::" # Reg # ")", A>;
+
//===----------------------------------------------------------------------===//
// ARM AAPCS64 Calling Convention
//===----------------------------------------------------------------------===//
@@ -42,7 +45,7 @@ def CC_AArch64_AAPCS : CallingConv<[
// Handle i1, i8, i16, i32, i64, f32, f64 and v2f64 by passing in registers,
// up to eight each of GPR and FPR.
- CCIfType<[i1, i8, i16], CCCustom<"CC_AArch64_Custom_i1i8i16_Reg">>,
+ CCIfType<[i1, i8, i16], CCIfUnallocated<"X7", CCPromoteToType<i32>>>,
CCIfType<[i32], CCAssignToRegWithShadow<[W0, W1, W2, W3, W4, W5, W6, W7],
[X0, X1, X2, X3, X4, X5, X6, X7]>>,
// i128 is split to two i64s, we can't fit half to register X7.
@@ -117,7 +120,7 @@ def CC_AArch64_DarwinPCS : CallingConv<[
// Handle i1, i8, i16, i32, i64, f32, f64 and v2f64 by passing in registers,
// up to eight each of GPR and FPR.
- CCIfType<[i1, i8, i16], CCCustom<"CC_AArch64_Custom_i1i8i16_Reg">>,
+ CCIfType<[i1, i8, i16], CCIfUnallocated<"X7", CCPromoteToType<i32>>>,
CCIfType<[i32], CCAssignToRegWithShadow<[W0, W1, W2, W3, W4, W5, W6, W7],
[X0, X1, X2, X3, X4, X5, X6, X7]>>,
// i128 is split to two i64s, we can't fit half to register X7.
@@ -140,7 +143,8 @@ def CC_AArch64_DarwinPCS : CallingConv<[
CCAssignToReg<[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
// If more than will fit in registers, pass them on the stack instead.
- CCIfType<[i1, i8, i16], CCCustom<"CC_AArch64_Custom_i1i8i16_Stack">>,
+ CCIfType<[i1, i8], CCAssignToStack<1, 1>>,
+ CCIfType<[i16], CCAssignToStack<2, 2>>,
CCIfType<[i32, f32], CCAssignToStack<4, 4>>,
CCIfType<[i64, f64, v1f64, v2f32, v1i64, v2i32, v4i16, v8i8],
CCAssignToStack<8, 8>>,
@@ -168,7 +172,7 @@ def CC_AArch64_DarwinPCS_VarArg : CallingConv<[
// 32bit quantity as undef.
def CC_AArch64_WebKit_JS : CallingConv<[
// Handle i1, i8, i16, i32, and i64 passing in register X0 (W0).
- CCIfType<[i1, i8, i16], CCCustom<"CC_AArch64_WebKit_JS_i1i8i16_Reg">>,
+ CCIfType<[i1, i8, i16], CCIfUnallocated<"X0", CCPromoteToType<i32>>>,
CCIfType<[i32], CCAssignToRegWithShadow<[W0], [X0]>>,
CCIfType<[i64], CCAssignToRegWithShadow<[X0], [W0]>>,
diff --git a/lib/Target/AArch64/AArch64FastISel.cpp b/lib/Target/AArch64/AArch64FastISel.cpp
index 8cc0f8a273..c3b53692fb 100644
--- a/lib/Target/AArch64/AArch64FastISel.cpp
+++ b/lib/Target/AArch64/AArch64FastISel.cpp
@@ -16,7 +16,6 @@
#include "AArch64.h"
#include "AArch64TargetMachine.h"
#include "AArch64Subtarget.h"
-#include "AArch64CallingConv.h"
#include "MCTargetDesc/AArch64AddressingModes.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/FastISel.h"
diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp
index 4ddba00733..5c504d1e6c 100644
--- a/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -14,7 +14,6 @@
#include "AArch64ISelLowering.h"
#include "AArch64PerfectShuffle.h"
#include "AArch64Subtarget.h"
-#include "AArch64CallingConv.h"
#include "AArch64MachineFunctionInfo.h"
#include "AArch64TargetMachine.h"
#include "AArch64TargetObjectFile.h"
@@ -1681,15 +1680,14 @@ SDValue AArch64TargetLowering::LowerFormalArguments(
EVT ActualVT = getValueType(CurOrigArg->getType(), /*AllowUnknown*/ true);
MVT ActualMVT = ActualVT.isSimple() ? ActualVT.getSimpleVT() : MVT::Other;
// If ActualMVT is i1/i8/i16, we should set LocVT to i8/i8/i16.
- MVT LocVT = ValVT;
if (ActualMVT == MVT::i1 || ActualMVT == MVT::i8)
- LocVT = MVT::i8;
+ ValVT = MVT::i8;
else if (ActualMVT == MVT::i16)
- LocVT = MVT::i16;
+ ValVT = MVT::i16;
CCAssignFn *AssignFn = CCAssignFnForCall(CallConv, /*IsVarArg=*/false);
bool Res =
- AssignFn(i, ValVT, LocVT, CCValAssign::Full, Ins[i].Flags, CCInfo);
+ AssignFn(i, ValVT, ValVT, CCValAssign::Full, Ins[i].Flags, CCInfo);
assert(!Res && "Call operand has unhandled type");
(void)Res;
}
@@ -1748,15 +1746,12 @@ SDValue AArch64TargetLowering::LowerFormalArguments(
case CCValAssign::BCvt:
ArgValue = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), ArgValue);
break;
+ case CCValAssign::AExt:
case CCValAssign::SExt:
- ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue,
- DAG.getValueType(VA.getValVT()));
- ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue);
- break;
case CCValAssign::ZExt:
- ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue,
- DAG.getValueType(VA.getValVT()));
- ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue);
+ // SelectionDAGBuilder will insert appropriate AssertZExt & AssertSExt
+ // nodes after our lowering.
+ assert(RegVT == Ins[i].VT && "incorrect register location selected");
break;
}
@@ -1777,21 +1772,26 @@ SDValue AArch64TargetLowering::LowerFormalArguments(
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
SDValue ArgValue;
- // If the loc type and val type are not the same, create an anyext load.
- if (VA.getLocVT().getSizeInBits() != VA.getValVT().getSizeInBits()) {
- // We should only get here if this is a pure integer.
- assert(!VA.getValVT().isVector() && VA.getValVT().isInteger() &&
- "Only integer extension supported!");
- ArgValue = DAG.getExtLoad(ISD::EXTLOAD, DL, VA.getValVT(), Chain, FIN,
- MachinePointerInfo::getFixedStack(FI),
- VA.getLocVT(),
- false, false, false, 0);
- } else {
- ArgValue = DAG.getLoad(VA.getValVT(), DL, Chain, FIN,
- MachinePointerInfo::getFixedStack(FI), false,
- false, false, 0);
+ ISD::LoadExtType ExtType = ISD::NON_EXTLOAD;
+ switch (VA.getLocInfo()) {
+ default:
+ break;
+ case CCValAssign::SExt:
+ ExtType = ISD::SEXTLOAD;
+ break;
+ case CCValAssign::ZExt:
+ ExtType = ISD::ZEXTLOAD;
+ break;
+ case CCValAssign::AExt:
+ ExtType = ISD::EXTLOAD;
+ break;
}
+ ArgValue = DAG.getExtLoad(ExtType, DL, VA.getValVT(), Chain, FIN,
+ MachinePointerInfo::getFixedStack(FI),
+ VA.getLocVT(),
+ false, false, false, 0);
+
InVals.push_back(ArgValue);
}
}
@@ -2184,14 +2184,13 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
MVT ActualMVT = ActualVT.isSimple() ? ActualVT.getSimpleVT() : ValVT;
ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
// If ActualMVT is i1/i8/i16, we should set LocVT to i8/i8/i16.
- MVT LocVT = ValVT;
if (ActualMVT == MVT::i1 || ActualMVT == MVT::i8)
- LocVT = MVT::i8;
+ ValVT = MVT::i8;
else if (ActualMVT == MVT::i16)
- LocVT = MVT::i16;
+ ValVT = MVT::i16;
CCAssignFn *AssignFn = CCAssignFnForCall(CallConv, /*IsVarArg=*/false);
- bool Res = AssignFn(i, ValVT, LocVT, CCValAssign::Full, ArgFlags, CCInfo);
+ bool Res = AssignFn(i, ValVT, ValVT, CCValAssign::Full, ArgFlags, CCInfo);
assert(!Res && "Call operand has unhandled type");
(void)Res;
}
diff --git a/test/CodeGen/AArch64/arm64-patchpoint.ll b/test/CodeGen/AArch64/arm64-patchpoint.ll
index 9ef1d778a3..039cdfcc38 100644
--- a/test/CodeGen/AArch64/arm64-patchpoint.ll
+++ b/test/CodeGen/AArch64/arm64-patchpoint.ll
@@ -161,3 +161,11 @@ define void @clobberScratch(i32* %p) {
declare void @llvm.experimental.stackmap(i64, i32, ...)
declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...)
+
+; CHECK-LABEL: test_i16:
+; CHECK: ldrh [[BREG:w[0-9]+]], [sp]
+; CHECK: add w0, w0, [[BREG]]
+define webkit_jscc i16 @test_i16(i16 zeroext %a, i16 zeroext %b) {
+ %sum = add i16 %a, %b
+ ret i16 %sum
+}