diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2013-05-27 21:48:25 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2013-05-27 21:48:25 +0000 |
commit | d28ab7e8022a5ccb399d0c54e186cb4f722c04bd (patch) | |
tree | 6c6ab529d3fc86865e5f41d7595f083dec8ff69e /clang/test/CodeGen/sparcv9-abi.c | |
parent | 9d9e1fc47953f6eac8855b17968322c63baed2d8 (diff) | |
download | bcm5719-llvm-d28ab7e8022a5ccb399d0c54e186cb4f722c04bd.tar.gz bcm5719-llvm-d28ab7e8022a5ccb399d0c54e186cb4f722c04bd.zip |
Add a SparcV9ABIInfo class for handling the standard SPARC v9 ABI.
- All integer arguments smaller than 64 bits are extended.
- Large structs are passed indirectly, not using 'byval'.
- Structs up to 32 bytes in size are returned in registers.
Some things are not implemented yet:
- EmitVAArg can be implemented in terms of the va_arg instruction.
- When structs are passed in registers, float members require special
handling because they are passed in the floating point registers.
- Structs are left-aligned when passed in registers. This may require
padding.
llvm-svn: 182745
Diffstat (limited to 'clang/test/CodeGen/sparcv9-abi.c')
-rw-r--r-- | clang/test/CodeGen/sparcv9-abi.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/clang/test/CodeGen/sparcv9-abi.c b/clang/test/CodeGen/sparcv9-abi.c new file mode 100644 index 00000000000..eb515e09e74 --- /dev/null +++ b/clang/test/CodeGen/sparcv9-abi.c @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -triple sparcv9-unknown-linux -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @f_void() +void f_void(void) {} + +// Arguments and return values smaller than the word size are extended. + +// CHECK: define signext i32 @f_int_1(i32 signext %x) +int f_int_1(int x) { return x; } + +// CHECK: define zeroext i32 @f_int_2(i32 zeroext %x) +unsigned f_int_2(unsigned x) { return x; } + +// CHECK: define i64 @f_int_3(i64 %x) +long long f_int_3(long long x) { return x; } + +// CHECK: define signext i8 @f_int_4(i8 signext %x) +char f_int_4(char x) { return x; } + +// Small structs are passed in registers. +struct small { + int *a, *b; +}; + +// CHECK: define %struct.small @f_small(i32* %x.coerce0, i32* %x.coerce1) +struct small f_small(struct small x) { + x.a += *x.b; + x.b = 0; + return x; +} + +// Medium-sized structs are passed indirectly, but can be returned in registers. +struct medium { + int *a, *b; + int *c, *d; +}; + +// CHECK: define %struct.medium @f_medium(%struct.medium* %x) +struct medium f_medium(struct medium x) { + x.a += *x.b; + x.b = 0; + return x; +} + +// Large structs are also returned indirectly. +struct large { + int *a, *b; + int *c, *d; + int x; +}; + +// CHECK: define void @f_large(%struct.large* noalias sret %agg.result, %struct.large* %x) +struct large f_large(struct large x) { + x.a += *x.b; + x.b = 0; + return x; +} + |