// 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); tail_call_avoidance_fn(); } extern "C" { fn opaque_callee(arg: Franta, intarg: i32); fn tst_use(arg: f32); fn clobber(); // This exists so that post-https://reviews.llvm.org/D138741 LLVM doesn't // tail-call away some of our assertions. fn tail_call_avoidance_fn(); } #[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); tail_call_avoidance_fn(); }