summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGen/sparcv9-abi.c
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2013-05-27 21:48:25 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2013-05-27 21:48:25 +0000
commitd28ab7e8022a5ccb399d0c54e186cb4f722c04bd (patch)
tree6c6ab529d3fc86865e5f41d7595f083dec8ff69e /clang/test/CodeGen/sparcv9-abi.c
parent9d9e1fc47953f6eac8855b17968322c63baed2d8 (diff)
downloadbcm5719-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.c58
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;
+}
+
OpenPOWER on IntegriCloud