diff options
| author | James Molloy <james.molloy@arm.com> | 2014-05-07 12:33:41 +0000 |
|---|---|---|
| committer | James Molloy <james.molloy@arm.com> | 2014-05-07 12:33:41 +0000 |
| commit | 4049e4fd771c5cf66b8733507dd91be23dc327dd (patch) | |
| tree | ac094f93d3c88f1ddd4eea03f3227a2388475fea /llvm/lib/Target | |
| parent | 4cd0782bf26d0c938a8ec5e043c0b4a4205f46aa (diff) | |
| download | bcm5719-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.td | 17 |
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], |

