| // 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(); |
| } |