| //@ add-minicore |
| //@ assembly-output: emit-asm |
| //@ compile-flags: -Copt-level=3 |
| // |
| //@ revisions: AMDGPU NVPTX |
| //@ [AMDGPU] compile-flags: --crate-type=rlib --target=amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 |
| //@ [AMDGPU] needs-llvm-components: amdgpu |
| //@ [NVPTX] compile-flags: --crate-type=rlib --target=nvptx64-nvidia-cuda |
| //@ [NVPTX] needs-llvm-components: nvptx |
| #![feature(no_core, lang_items, intrinsics, rustc_attrs)] |
| #![no_core] |
| #![crate_type = "lib"] |
| |
| extern crate minicore; |
| use minicore::*; |
| |
| #[lang = "va_arg_safe"] |
| pub unsafe trait VaArgSafe {} |
| |
| unsafe impl VaArgSafe for i32 {} |
| unsafe impl VaArgSafe for i64 {} |
| unsafe impl VaArgSafe for i128 {} |
| unsafe impl VaArgSafe for f64 {} |
| unsafe impl<T> VaArgSafe for *const T {} |
| |
| #[repr(transparent)] |
| struct VaListInner { |
| ptr: *const c_void, |
| } |
| |
| #[repr(transparent)] |
| #[lang = "va_list"] |
| pub struct VaList<'a> { |
| inner: VaListInner, |
| _marker: PhantomData<&'a mut ()>, |
| } |
| |
| #[rustc_intrinsic] |
| #[rustc_nounwind] |
| pub const unsafe fn va_arg<T: VaArgSafe>(ap: &mut VaList<'_>) -> T; |
| |
| #[unsafe(no_mangle)] |
| unsafe extern "C" fn read_f64(ap: &mut VaList<'_>) -> f64 { |
| // CHECK-LABEL: read_f64 |
| // |
| // AMDGPU: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| // AMDGPU-NEXT: flat_load_dwordx2 v[4:5], v[0:1] |
| // AMDGPU-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0) |
| // AMDGPU-NEXT: flat_load_dwordx2 v[2:3], v[4:5] |
| // AMDGPU-NEXT: v_add_co_u32_e32 v4, vcc, 8, v4 |
| // AMDGPU-NEXT: v_addc_co_u32_e32 v5, vcc, 0, v5, vcc |
| // AMDGPU-NEXT: flat_store_dwordx2 v[0:1], v[4:5] |
| // AMDGPU-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0) |
| // AMDGPU-NEXT: v_mov_b32_e32 v0, v2 |
| // AMDGPU-NEXT: v_mov_b32_e32 v1, v3 |
| // AMDGPU-NEXT: s_setpc_b64 s[30:31] |
| // |
| // NVPTX: ld.param.b64 %rd1, [read_f64_param_0]; |
| // NVPTX-NEXT: ld.b64 %rd2, [%rd1]; |
| // NVPTX-NEXT: add.s64 %rd3, %rd2, 7; |
| // NVPTX-NEXT: and.b64 %rd4, %rd3, -8; |
| // NVPTX-NEXT: add.s64 %rd5, %rd4, 8; |
| // NVPTX-NEXT: st.b64 [%rd1], %rd5; |
| // NVPTX-NEXT: ld.b64 %rd6, [%rd4]; |
| // NVPTX-NEXT: st.param.b64 [func_retval0], %rd6; |
| // NVPTX-NEXT: ret; |
| va_arg(ap) |
| } |
| |
| #[unsafe(no_mangle)] |
| unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 { |
| // CHECK-LABEL: read_i32 |
| // |
| // AMDGPU: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| // AMDGPU-NEXT: flat_load_dwordx2 v[3:4], v[0:1] |
| // AMDGPU-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0) |
| // AMDGPU-NEXT: flat_load_dword v2, v[3:4] |
| // AMDGPU-NEXT: v_add_co_u32_e32 v3, vcc, 4, v3 |
| // AMDGPU-NEXT: v_addc_co_u32_e32 v4, vcc, 0, v4, vcc |
| // AMDGPU-NEXT: flat_store_dwordx2 v[0:1], v[3:4] |
| // AMDGPU-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0) |
| // AMDGPU-NEXT: v_mov_b32_e32 v0, v2 |
| // AMDGPU-NEXT: s_setpc_b64 s[30:31] |
| // |
| // NVPTX: ld.param.b64 %rd1, [read_i32_param_0]; |
| // NVPTX-NEXT: ld.b64 %rd2, [%rd1]; |
| // NVPTX-NEXT: add.s64 %rd3, %rd2, 3; |
| // NVPTX-NEXT: and.b64 %rd4, %rd3, -4; |
| // NVPTX-NEXT: add.s64 %rd5, %rd4, 4; |
| // NVPTX-NEXT: st.b64 [%rd1], %rd5; |
| // NVPTX-NEXT: ld.b32 %r1, [%rd4]; |
| // NVPTX-NEXT: st.param.b32 [func_retval0], %r1; |
| // NVPTX-NEXT: ret; |
| va_arg(ap) |
| } |
| |
| #[unsafe(no_mangle)] |
| unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 { |
| // CHECK-LABEL: read_i64 |
| // |
| // AMDGPU: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| // AMDGPU-NEXT: flat_load_dwordx2 v[4:5], v[0:1] |
| // AMDGPU-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0) |
| // AMDGPU-NEXT: flat_load_dwordx2 v[2:3], v[4:5] |
| // AMDGPU-NEXT: v_add_co_u32_e32 v4, vcc, 8, v4 |
| // AMDGPU-NEXT: v_addc_co_u32_e32 v5, vcc, 0, v5, vcc |
| // AMDGPU-NEXT: flat_store_dwordx2 v[0:1], v[4:5] |
| // AMDGPU-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0) |
| // AMDGPU-NEXT: v_mov_b32_e32 v0, v2 |
| // AMDGPU-NEXT: v_mov_b32_e32 v1, v3 |
| // AMDGPU-NEXT: s_setpc_b64 s[30:31] |
| // |
| // NVPTX: ld.param.b64 %rd1, [read_i64_param_0]; |
| // NVPTX-NEXT: ld.b64 %rd2, [%rd1]; |
| // NVPTX-NEXT: add.s64 %rd3, %rd2, 7; |
| // NVPTX-NEXT: and.b64 %rd4, %rd3, -8; |
| // NVPTX-NEXT: add.s64 %rd5, %rd4, 8; |
| // NVPTX-NEXT: st.b64 [%rd1], %rd5; |
| // NVPTX-NEXT: ld.b64 %rd6, [%rd4]; |
| // NVPTX-NEXT: st.param.b64 [func_retval0], %rd6; |
| // NVPTX-NEXT: ret; |
| va_arg(ap) |
| } |
| |
| #[unsafe(no_mangle)] |
| unsafe extern "C" fn read_i128(ap: &mut VaList<'_>) -> i128 { |
| // CHECK-LABEL: read_i128 |
| // |
| // AMDGPU: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| // AMDGPU-NEXT: v_mov_b32_e32 v5, v1 |
| // AMDGPU-NEXT: v_mov_b32_e32 v4, v0 |
| // AMDGPU-NEXT: flat_load_dwordx2 v[6:7], v[4:5] |
| // AMDGPU-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0) |
| // AMDGPU-NEXT: flat_load_dwordx4 v[0:3], v[6:7] |
| // AMDGPU-NEXT: v_add_co_u32_e32 v6, vcc, 16, v6 |
| // AMDGPU-NEXT: v_addc_co_u32_e32 v7, vcc, 0, v7, vcc |
| // AMDGPU-NEXT: flat_store_dwordx2 v[4:5], v[6:7] |
| // AMDGPU-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0) |
| // AMDGPU-NEXT: s_setpc_b64 s[30:31] |
| // |
| // NVPTX: ld.param.b64 %rd1, [read_i128_param_0]; |
| // NVPTX-NEXT: ld.b64 %rd2, [%rd1]; |
| // NVPTX-NEXT: add.s64 %rd3, %rd2, 15; |
| // NVPTX-NEXT: and.b64 %rd4, %rd3, -16; |
| // NVPTX-NEXT: add.s64 %rd5, %rd4, 16; |
| // NVPTX-NEXT: st.b64 [%rd1], %rd5; |
| // NVPTX-NEXT: ld.v2.b64 {%rd6, %rd7}, [%rd4]; |
| // NVPTX-NEXT: st.param.v2.b64 [func_retval0], {%rd6, %rd7}; |
| // NVPTX-NEXT: ret; |
| va_arg(ap) |
| } |
| |
| #[unsafe(no_mangle)] |
| unsafe extern "C" fn read_ptr(ap: &mut VaList<'_>) -> *const u8 { |
| // CHECK-LABEL: read_ptr |
| // |
| // AMDGPU: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| // AMDGPU-NEXT: flat_load_dwordx2 v[4:5], v[0:1] |
| // AMDGPU-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0) |
| // AMDGPU-NEXT: flat_load_dwordx2 v[2:3], v[4:5] |
| // AMDGPU-NEXT: v_add_co_u32_e32 v4, vcc, 8, v4 |
| // AMDGPU-NEXT: v_addc_co_u32_e32 v5, vcc, 0, v5, vcc |
| // AMDGPU-NEXT: flat_store_dwordx2 v[0:1], v[4:5] |
| // AMDGPU-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0) |
| // AMDGPU-NEXT: v_mov_b32_e32 v0, v2 |
| // AMDGPU-NEXT: v_mov_b32_e32 v1, v3 |
| // AMDGPU-NEXT: s_setpc_b64 s[30:31] |
| // |
| // NVPTX: ld.param.b64 %rd1, [read_ptr_param_0]; |
| // NVPTX-NEXT: ld.b64 %rd2, [%rd1]; |
| // NVPTX-NEXT: add.s64 %rd3, %rd2, 7; |
| // NVPTX-NEXT: and.b64 %rd4, %rd3, -8; |
| // NVPTX-NEXT: add.s64 %rd5, %rd4, 8; |
| // NVPTX-NEXT: st.b64 [%rd1], %rd5; |
| // NVPTX-NEXT: ld.b64 %rd6, [%rd4]; |
| // NVPTX-NEXT: st.param.b64 [func_retval0], %rd6; |
| // NVPTX-NEXT: ret; |
| va_arg(ap) |
| } |