| Index: test/NaCl/X86/nacl-calls.ll
|
| diff --git a/test/NaCl/X86/nacl-calls.ll b/test/NaCl/X86/nacl-calls.ll
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..309e6298dac4a512060be35fcdee379efca4eb72
|
| --- /dev/null
|
| +++ b/test/NaCl/X86/nacl-calls.ll
|
| @@ -0,0 +1,149 @@
|
| +; RUN: pnacl-llc -mtriple=i686-unknown-nacl -filetype=asm %s -o - \
|
| +; RUN: | FileCheck %s --check-prefix=NACL32
|
| +; RUN: pnacl-llc -mtriple=i686-unknown-nacl -filetype=asm -O0 %s -o - \
|
| +; RUN: | FileCheck %s --check-prefix=NACL32O0
|
| +; RUN: pnacl-llc -mtriple=x86_64-unknown-nacl -filetype=asm %s -o - \
|
| +; RUN: | FileCheck %s --check-prefix=NACL64
|
| +; RUN: pnacl-llc -mtriple=x86_64-unknown-nacl -filetype=asm -O0 %s -o - \
|
| +; RUN: | FileCheck %s --check-prefix=NACL64
|
| +
|
| +;;;;
|
| +; Call to a NaCl trampoline (specific addresses).
|
| +define i32 @call_address() {
|
| +entry:
|
| + call void inttoptr (i32 66496 to void ()*)()
|
| + ret i32 0
|
| +}
|
| +; NACL32-LABEL: call_address
|
| +; NACL32: calll 66496
|
| +; NACL32O0-LABEL: call_address
|
| +; NACL32O0: movl $66496, [[REG:%[a-z0-9]+]]
|
| +; NACL32O0: naclcall {{.*}}[[REG]]
|
| +; NACL64-LABEL: call_address
|
| +; NACL64: movl $66496, %{{.*}}
|
| +; NACL64: naclcall %{{.*}},%r15
|
| +
|
| +define fastcc i32 @tail_call_address(i32 %arg) {
|
| +entry:
|
| + %call1 = tail call fastcc i32 inttoptr (i32 66496 to i32 (i32)*)(i32 %arg)
|
| + ret i32 %call1
|
| +}
|
| +; NACL32-LABEL: tail_call_address
|
| +; NACL32: movl $66496, [[REG:%[a-z0-9]+]]
|
| +; NACL32: nacljmp {{.*}}[[REG]]
|
| +; NACL32O0-LABEL: tail_call_address
|
| +; NACL32O0: movl $66496, [[REG:%[a-z0-9]+]]
|
| +; NACL32O0: nacljmp {{.*}}[[REG]]
|
| +; NACL64-LABEL: tail_call_address
|
| +; NACL64: movl $66496, %{{.*}}
|
| +; NACL64: nacljmp %{{.*}}, %r15
|
| +
|
| +
|
| +;;;;;
|
| +; Call to another function (external/internal), directly.
|
| +
|
| +declare void @other_function()
|
| +
|
| +define internal void @call_other_function() {
|
| + call void @other_function()
|
| + ret void
|
| +}
|
| +
|
| +define void @call_other_function2() {
|
| + call void @call_other_function()
|
| + ret void
|
| +}
|
| +; NACL32-LABEL: call_other_function
|
| +; NACL32: calll other_function
|
| +; NACL32-LABEL: call_other_function2
|
| +; NACL32: calll call_other_function
|
| +; NACL32O0-LABEL: call_other_function
|
| +; NACL32O0: calll other_function
|
| +; NACL64-LABEL: call_other_function
|
| +; NACL64: callq other_function
|
| +; NACL64-LABEL: call_other_function2
|
| +; NACL64: callq call_other_function
|
| +
|
| +
|
| +declare fastcc i32 @other_function_fast()
|
| +
|
| +define internal fastcc i32 @tail_call_other_function() {
|
| + %i = tail call fastcc i32 @other_function_fast()
|
| + ret i32 %i
|
| +}
|
| +
|
| +define fastcc i32 @tail_call_other_function2() {
|
| + %i = tail call fastcc i32 @tail_call_other_function()
|
| + ret i32 %i
|
| +}
|
| +; NACL32-LABEL: tail_call_other_function
|
| +; NACL32: jmp other_function_fast
|
| +; NACL32-LABEL: tail_call_other_function2
|
| +; NACL32: jmp tail_call_other_function
|
| +; NACL32O0-LABEL: tail_call_other_function
|
| +; NACL32O0: jmp other_function_fast
|
| +; NACL32O0-LABEL: tail_call_other_function2
|
| +; NACL32O0: jmp tail_call_other_function
|
| +; NACL64-LABEL: tail_call_other_function
|
| +; NACL64: jmp other_function_fast
|
| +; NACL64-LABEL: tail_call_other_function2
|
| +; NACL64: jmp tail_call_other_function
|
| +
|
| +;;;;;
|
| +; Indirect call, but not a specific address.
|
| +
|
| +@fp = external global i32 (i32)*
|
| +
|
| +; With a load.
|
| +define i32 @call_indirect() {
|
| + %1 = load i32 (i32)** @fp, align 4
|
| + %call1 = call i32 %1(i32 10)
|
| + ret i32 %call1
|
| +}
|
| +; NACL32-LABEL: call_indirect
|
| +; NACL32: movl fp, [[REG:%[a-z0-9]+]]
|
| +; NACL32: naclcall {{.*}}[[REG]]
|
| +; NACL32O0-LABEL: call_indirect
|
| +; NACL32O0: movl fp, [[REG:%[a-z0-9]+]]
|
| +; NACL32O0: naclcall {{.*}}[[REG]]
|
| +; NACL64-LABEL: call_indirect
|
| +; NACL64: movl fp({{.*}}), %{{.*}}
|
| +; NACL64: naclcall %{{.*}},%r15
|
| +
|
| +define fastcc i32 @tail_call_indirect() {
|
| + %1 = load i32 (i32)** @fp, align 4
|
| + %call1 = tail call fastcc i32 %1(i32 10)
|
| + ret i32 %call1
|
| +}
|
| +; NACL32-LABEL: tail_call_indirect
|
| +; NACL32: movl fp, [[REG:%[a-z0-9]+]]
|
| +; NACL32: nacljmp {{.*}}[[REG]]
|
| +; NACL32O0-LABEL: tail_call_indirect
|
| +; NACL32O0: movl fp, [[REG:%[a-z0-9]+]]
|
| +; NACL32O0: nacljmp {{.*}}[[REG]]
|
| +; NACL64-LABEL: tail_call_indirect
|
| +; NACL64: movl fp({{.*}}), %{{.*}}
|
| +; NACL64: nacljmp %{{.*}}, %r15
|
| +
|
| +; "Without" a load (may load from stack on x86-32 still).
|
| +define i32 @call_indirect_arg(i32 ()* %argfp) {
|
| + %call1 = call i32 %argfp()
|
| + ret i32 %call1
|
| +}
|
| +; NACL32-LABEL: call_indirect_arg
|
| +; NACL32: naclcall {{%[a-z0-9]+}}
|
| +; NACL32O0-LABEL: call_indirect_arg
|
| +; NACL32O0: naclcall {{%[a-z0-9]+}}
|
| +; NACL64-LABEL: call_indirect_arg
|
| +; NACL64: naclcall {{%[a-z0-9]+}},%r15
|
| +
|
| +define fastcc i32 @tail_call_indirect_arg(i32 ()* %argfp) {
|
| + %call1 = tail call fastcc i32 %argfp()
|
| + ret i32 %call1
|
| +}
|
| +; NACL32-LABEL: tail_call_indirect_arg
|
| +; NACL32: nacljmp {{%[a-z0-9]+}}
|
| +; NACL32O0-LABEL: tail_call_indirect_arg
|
| +; NACL32O0: nacljmp {{%[a-z0-9]+}}
|
| +; NACL64-LABEL: tail_call_indirect_arg
|
| +; NACL64: nacljmp {{%[a-z0-9]+}}, %r15
|
|
|