summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorJames Molloy <james.molloy@arm.com>2014-05-07 12:33:41 +0000
committerJames Molloy <james.molloy@arm.com>2014-05-07 12:33:41 +0000
commit4049e4fd771c5cf66b8733507dd91be23dc327dd (patch)
treeac094f93d3c88f1ddd4eea03f3227a2388475fea /llvm/lib/Target
parent4cd0782bf26d0c938a8ec5e043c0b4a4205f46aa (diff)
downloadbcm5719-llvm-4049e4fd771c5cf66b8733507dd91be23dc327dd.tar.gz
bcm5719-llvm-4049e4fd771c5cf66b8733507dd91be23dc327dd.zip
[ARM64-BE] Implement the lane-twiddling logic at AAPCS boundaries for big endian.
The AAPCS states that values passed in registers must have a value as though they had been loaded with "LDR". LDR is equivalent to "LD1.64 vX.1D" - that is, loading scalars to vector registers and loading 1-element vectors is equivalent. The logic implemented here is to ensure that at all call boundaries and during formal argument lowering all vectors are treated as their bitwidth-based floating point scalar counterpart, which is always one of f64 or f128 (v2i32 -> f64, v4i32 -> f128 etc). A BITCAST is inserted so that the appropriate REV will be generated during code generation. llvm-svn: 208198
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/ARM64/ARM64CallingConvention.td17
1 files changed, 17 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM64/ARM64CallingConvention.td b/llvm/lib/Target/ARM64/ARM64CallingConvention.td
index 40324953c02..0ef5601718d 100644
--- a/llvm/lib/Target/ARM64/ARM64CallingConvention.td
+++ b/llvm/lib/Target/ARM64/ARM64CallingConvention.td
@@ -14,6 +14,9 @@
/// CCIfAlign - Match of the original alignment of the arg
class CCIfAlign<string Align, CCAction A> :
CCIf<!strconcat("ArgFlags.getOrigAlign() == ", Align), A>;
+/// CCIfBigEndian - Match only if we're in big endian mode.
+class CCIfBigEndian<CCAction A> :
+ CCIf<"State.getTarget().getDataLayout()->isBigEndian()", A>;
//===----------------------------------------------------------------------===//
// ARM AAPCS64 Calling Convention
@@ -23,6 +26,13 @@ def CC_ARM64_AAPCS : CallingConv<[
CCIfType<[v2f32], CCBitConvertToType<v2i32>>,
CCIfType<[v2f64, v4f32], CCBitConvertToType<v2i64>>,
+ // Big endian vectors must be passed as if they were 1-element vectors so that
+ // their lanes are in a consistent order.
+ CCIfBigEndian<CCIfType<[v2i32, v2f32, v4i16, v4f16, v8i8],
+ CCBitConvertToType<f64>>>,
+ CCIfBigEndian<CCIfType<[v2i64, v2f64, v4i32, v4f32, v8i16, v8f16, v16i8],
+ CCBitConvertToType<f128>>>,
+
// An SRet is passed in X8, not X0 like a normal pointer parameter.
CCIfSRet<CCIfType<[i64], CCAssignToRegWithShadow<[X8], [W8]>>>,
@@ -67,6 +77,13 @@ def RetCC_ARM64_AAPCS : CallingConv<[
CCIfType<[v2f32], CCBitConvertToType<v2i32>>,
CCIfType<[v2f64, v4f32], CCBitConvertToType<v2i64>>,
+ // Big endian vectors must be passed as if they were 1-element vectors so that
+ // their lanes are in a consistent order.
+ CCIfBigEndian<CCIfType<[v2i32, v2f32, v4i16, v4f16, v8i8],
+ CCBitConvertToType<f64>>>,
+ CCIfBigEndian<CCIfType<[v2i64, v2f64, v4i32, v4f32, v8i16, v8f16, v16i8],
+ CCBitConvertToType<f128>>>,
+
CCIfType<[i32], CCAssignToRegWithShadow<[W0, W1, W2, W3, W4, W5, W6, W7],
[X0, X1, X2, X3, X4, X5, X6, X7]>>,
CCIfType<[i64], CCAssignToRegWithShadow<[X0, X1, X2, X3, X4, X5, X6, X7],
OpenPOWER on IntegriCloud