diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2013-04-06 18:32:12 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2013-04-06 18:32:12 +0000 |
commit | 1f25fe50236e5842b19198fbfe8a812be0b40cf5 (patch) | |
tree | 73be192b42959ea60b358384e53ac776af232705 /test/CodeGen | |
parent | 6e01dcbb7306514f11834f1e8d7d642013ea349b (diff) | |
download | external_llvm-1f25fe50236e5842b19198fbfe8a812be0b40cf5.zip external_llvm-1f25fe50236e5842b19198fbfe8a812be0b40cf5.tar.gz external_llvm-1f25fe50236e5842b19198fbfe8a812be0b40cf5.tar.bz2 |
Complete formal arguments for the SPARC v9 64-bit ABI.
All arguments are formally assigned to stack positions and then promoted
to floating point and integer registers. Since there are more floating
point registers than integer registers, this can cause situations where
floating point arguments are assigned to registers after integer
arguments that where assigned to the stack.
Use the inreg flag to indicate 32-bit fragments of structs containing
both float and int members.
The three-way shadowing between stack, integer, and floating point
registers requires custom argument lowering. The good news is that
return values are passed in the exact same way, and we can share the
code.
Still missing:
- Update LowerReturn to handle structs returned in registers.
- LowerCall.
- Variadic functions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178958 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen')
-rw-r--r-- | test/CodeGen/SPARC/64abi.ll | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/test/CodeGen/SPARC/64abi.ll b/test/CodeGen/SPARC/64abi.ll new file mode 100644 index 0000000..a9eb623 --- /dev/null +++ b/test/CodeGen/SPARC/64abi.ll @@ -0,0 +1,136 @@ +; RUN: llc < %s -march=sparcv9 | FileCheck %s + +; CHECK: intarg +; CHECK: stb %i0, [%i4] +; CHECK: stb %i1, [%i4] +; CHECK: sth %i2, [%i4] +; CHECK: st %i3, [%i4] +; CHECK: stx %i4, [%i4] +; CHECK: st %i5, [%i4] +; FIXME: Stack bias +; CHECK: ld [%fp+180], [[R:%[gilo][0-7]]] +; CHECK: st [[R]], [%i4] +; CHECK: ldx [%fp+184], [[R:%[gilo][0-7]]] +; CHECK: stx [[R]], [%i4] +define void @intarg(i8 %a0, ; %i0 + i8 %a1, ; %i1 + i16 %a2, ; %i2 + i32 %a3, ; %i3 + i8* %a4, ; %i4 + i32 %a5, ; %i5 + i32 %a6, ; [%fp+BIAS+176] + i8* %a7) { ; [%fp+BIAS+184] + store i8 %a0, i8* %a4 + store i8 %a1, i8* %a4 + %p16 = bitcast i8* %a4 to i16* + store i16 %a2, i16* %p16 + %p32 = bitcast i8* %a4 to i32* + store i32 %a3, i32* %p32 + %pp = bitcast i8* %a4 to i8** + store i8* %a4, i8** %pp + store i32 %a5, i32* %p32 + store i32 %a6, i32* %p32 + store i8* %a7, i8** %pp + ret void +} + +; CHECK: floatarg +; CHECK: fstod %f1, +; CHECK: faddd %f2, +; CHECK: faddd %f4, +; CHECK: faddd %f6, +; FIXME: Stack bias +; CHECK: ld [%fp+260], [[F:%f[0-9]+]] +; CHECK: fadds %f31, [[F]] +define double @floatarg(float %a0, ; %f1 + double %a1, ; %d2 + double %a2, ; %d4 + double %a3, ; %d6 + float %a4, ; %f9 + float %a5, ; %f11 + float %a6, ; %f13 + float %a7, ; %f15 + float %a8, ; %f17 + float %a9, ; %f19 + float %a10, ; %f21 + float %a11, ; %f23 + float %a12, ; %f25 + float %a13, ; %f27 + float %a14, ; %f29 + float %a15, ; %f31 + float %a16, ; [%fp+BIAS+256] (using 8 bytes) + float %a17) { ; [%fp+BIAS+264] (using 8 bytes) + %d0 = fpext float %a0 to double + %s1 = fadd double %a1, %d0 + %s2 = fadd double %a2, %s1 + %s3 = fadd double %a3, %s2 + %s16 = fadd float %a15, %a16 + %d16 = fpext float %s16 to double + %s17 = fadd double %d16, %s3 + ret double %s17 +} + +; CHECK: mixedarg +; CHECK: fstod %f3 +; CHECK: faddd %f6 +; CHECK: faddd %f16 +; CHECK: ldx [%fp+184] +; CHECK: ldx [%fp+200] +define void @mixedarg(i8 %a0, ; %i0 + float %a1, ; %f3 + i16 %a2, ; %i2 + double %a3, ; %d6 + i13 %a4, ; %i4 + float %a5, ; %f11 + i64 %a6, ; [%fp+BIAS+176] + double *%a7, ; [%fp+BIAS+184] + double %a8, ; %d16 + i16* %a9) { ; [%fp+BIAS+200] + %d1 = fpext float %a1 to double + %s3 = fadd double %a3, %d1 + %s8 = fadd double %a8, %s3 + store double %s8, double* %a7 + store i16 %a2, i16* %a9 + ret void +} + +; The inreg attribute is used to indicate 32-bit sized struct elements that +; share an 8-byte slot. +; CHECK: inreg_fi +; CHECK: fstoi %f1 +; CHECK: srlx %i0, 32, [[R:%[gilo][0-7]]] +; CHECK: sub [[R]], +define i32 @inreg_fi(i32 inreg %a0, ; high bits of %i0 + float inreg %a1) { ; %f1 + %b1 = fptosi float %a1 to i32 + %rv = sub i32 %a0, %b1 + ret i32 %rv +} + +; CHECK: inreg_ff +; CHECK: fsubs %f0, %f1, %f1 +define float @inreg_ff(float inreg %a0, ; %f0 + float inreg %a1) { ; %f1 + %rv = fsub float %a0, %a1 + ret float %rv +} + +; CHECK: inreg_if +; CHECK: fstoi %f0 +; CHECK: sub %i0 +define i32 @inreg_if(float inreg %a0, ; %f0 + i32 inreg %a1) { ; low bits of %i0 + %b0 = fptosi float %a0 to i32 + %rv = sub i32 %a1, %b0 + ret i32 %rv +} + +; The frontend shouldn't do this. Just pass i64 instead. +; CHECK: inreg_ii +; CHECK: srlx %i0, 32, [[R:%[gilo][0-7]]] +; CHECK: sub %i0, [[R]], %i0 +define i32 @inreg_ii(i32 inreg %a0, ; high bits of %i0 + i32 inreg %a1) { ; low bits of %i0 + %rv = sub i32 %a1, %a0 + ret i32 %rv +} |