|  | //@ compile-flags: -Copt-level=3 | 
|  | //@ only-x86_64 | 
|  |  | 
|  | #![crate_type = "lib"] | 
|  |  | 
|  | use std::arch::naked_asm; | 
|  |  | 
|  | #[no_mangle] | 
|  | fn test(x: u64) { | 
|  | // just making sure these symbols get used | 
|  | using_const_generics::<1>(x); | 
|  | using_const_generics::<2>(x); | 
|  |  | 
|  | generic_function::<i64>(x as i64); | 
|  |  | 
|  | let foo = Foo(x); | 
|  |  | 
|  | foo.method(); | 
|  | foo.trait_method(); | 
|  | } | 
|  |  | 
|  | // CHECK: .balign 4 | 
|  | // CHECK: add rax, 2 | 
|  | // CHECK: add rax, 42 | 
|  |  | 
|  | // CHECK: .balign 4 | 
|  | // CHECK: add rax, 1 | 
|  | // CHECK: add rax, 42 | 
|  |  | 
|  | #[unsafe(naked)] | 
|  | pub extern "C" fn using_const_generics<const N: u64>(x: u64) -> u64 { | 
|  | const M: u64 = 42; | 
|  |  | 
|  | naked_asm!( | 
|  | "xor rax, rax", | 
|  | "add rax, rdi", | 
|  | "add rax, {}", | 
|  | "add rax, {}", | 
|  | "ret", | 
|  | const N, | 
|  | const M, | 
|  | ) | 
|  | } | 
|  |  | 
|  | trait Invert { | 
|  | fn invert(self) -> Self; | 
|  | } | 
|  |  | 
|  | impl Invert for i64 { | 
|  | fn invert(self) -> Self { | 
|  | -1 * self | 
|  | } | 
|  | } | 
|  |  | 
|  | // CHECK: .balign 4 | 
|  | // CHECK-LABEL: generic_function: | 
|  | // CHECK: call | 
|  | // CHECK: ret | 
|  |  | 
|  | #[unsafe(naked)] | 
|  | #[no_mangle] | 
|  | pub extern "C" fn generic_function<T: Invert>(x: i64) -> i64 { | 
|  | naked_asm!( | 
|  | "call {}", | 
|  | "ret", | 
|  | sym <T as Invert>::invert, | 
|  | ) | 
|  | } | 
|  |  | 
|  | #[derive(Copy, Clone)] | 
|  | #[repr(transparent)] | 
|  | struct Foo(u64); | 
|  |  | 
|  | // CHECK: .balign 4 | 
|  | // CHECK-LABEL: method: | 
|  | // CHECK: mov rax, rdi | 
|  |  | 
|  | impl Foo { | 
|  | #[unsafe(naked)] | 
|  | #[no_mangle] | 
|  | extern "C" fn method(self) -> u64 { | 
|  | naked_asm!("mov rax, rdi", "ret") | 
|  | } | 
|  | } | 
|  |  | 
|  | // CHECK: .balign 4 | 
|  | // CHECK-LABEL: trait_method: | 
|  | // CHECK: mov rax, rdi | 
|  |  | 
|  | trait Bar { | 
|  | extern "C" fn trait_method(self) -> u64; | 
|  | } | 
|  |  | 
|  | impl Bar for Foo { | 
|  | #[unsafe(naked)] | 
|  | #[no_mangle] | 
|  | extern "C" fn trait_method(self) -> u64 { | 
|  | naked_asm!("mov rax, rdi", "ret") | 
|  | } | 
|  | } | 
|  |  | 
|  | // CHECK: .balign 4 | 
|  | // CHECK-LABEL: naked_with_args_and_return: | 
|  | // CHECK: lea rax, [rdi + rsi] | 
|  |  | 
|  | // this previously ICE'd, see https://github.com/rust-lang/rust/issues/124375 | 
|  | #[unsafe(naked)] | 
|  | #[no_mangle] | 
|  | pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize { | 
|  | naked_asm!("lea rax, [rdi + rsi]", "ret"); | 
|  | } |