summary refs log tree commit diff
path: root/tests/codegen-llvm/naked-fn/generics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/codegen-llvm/naked-fn/generics.rs')
-rw-r--r--tests/codegen-llvm/naked-fn/generics.rs111
1 files changed, 111 insertions, 0 deletions
diff --git a/tests/codegen-llvm/naked-fn/generics.rs b/tests/codegen-llvm/naked-fn/generics.rs
new file mode 100644
index 00000000000..865be00d91e
--- /dev/null
+++ b/tests/codegen-llvm/naked-fn/generics.rs
@@ -0,0 +1,111 @@
+//@ 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");
+}