summaryrefslogtreecommitdiffstats
path: root/src/test/assembly/sparc-struct-abi.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/test/assembly/sparc-struct-abi.rs65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/test/assembly/sparc-struct-abi.rs b/src/test/assembly/sparc-struct-abi.rs
new file mode 100644
index 000000000..6a898b297
--- /dev/null
+++ b/src/test/assembly/sparc-struct-abi.rs
@@ -0,0 +1,65 @@
+// Test SPARC64 ABI
+// - float structure members are passes in floating point registers
+// (#86163)
+
+// assembly-output: emit-asm
+// needs-llvm-components: sparc
+// compile-flags: --target=sparcv9-sun-solaris -Copt-level=3
+#![crate_type = "lib"]
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
+#[lang = "copy"]
+pub trait Copy {}
+impl Copy for f32 {}
+
+#[repr(C)]
+pub struct Franta {
+ a: f32,
+ b: f32,
+ c: f32,
+ d: f32,
+}
+
+// NB: due to delay slots the `ld` following the call is actually executed before the call.
+#[no_mangle]
+pub unsafe extern "C" fn callee(arg: Franta) {
+ // CHECK-LABEL: callee:
+ // CHECK: st %f3, [[PLACE_D:.*]]
+ // CHECK: st %f2, [[PLACE_C:.*]]
+ // CHECK: st %f1, [[PLACE_B:.*]]
+ // CHECK: st %f0, [[PLACE_A:.*]]
+ // CHECK: call tst_use
+ // CHECK-NEXT: ld [[PLACE_A]], %f1
+ // CHECK: call tst_use
+ // CHECK-NEXT: ld [[PLACE_B]], %f1
+ // CHECK: call tst_use
+ // CHECK-NEXT: ld [[PLACE_C]], %f1
+ // CHECK: call tst_use
+ // CHECK-NEXT: ld [[PLACE_D]], %f1
+ clobber();
+ tst_use(arg.a);
+ tst_use(arg.b);
+ tst_use(arg.c);
+ tst_use(arg.d);
+}
+
+extern "C" {
+ fn opaque_callee(arg: Franta, intarg: i32);
+ fn tst_use(arg: f32);
+ fn clobber();
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn caller() {
+ // CHECK-LABEL: caller:
+ // CHECK: ld [{{.*}}], %f0
+ // CHECK: ld [{{.*}}], %f1
+ // CHECK: ld [{{.*}}], %f2
+ // CHECK: ld [{{.*}}], %f3
+ // CHECK: call opaque_callee
+ // CHECK: mov 3, %o2
+ opaque_callee(Franta { a: 1.0, b: 2.0, c: 3.0, d: 4.0 }, 3);
+}