Mercurial > hg > CbC > CbC_llvm
diff test/CodeGen/X86/hhvm-cc.ll @ 95:afa8332a0e37 LLVM3.8
LLVM 3.8
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 13 Oct 2015 17:48:58 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/CodeGen/X86/hhvm-cc.ll Tue Oct 13 17:48:58 2015 +0900 @@ -0,0 +1,241 @@ +; RUN: llc < %s | FileCheck %s + +target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare hhvmcc i64 @bar(i64, i64, i64) nounwind + +; Simply check we can modify %rbx and %rbp before returning via call to bar. +define hhvmcc i64 @foo(i64 %a, i64 %b, i64 %c) nounwind { +entry: +; CHECK-LABEL: foo: +; CHECK-DAG: movl $1, %ebx +; CHECK-DAG: movl $3, %ebp +; CHECK: jmp bar + %ret = musttail call hhvmcc i64 @bar(i64 1, i64 %b, i64 3) + ret i64 %ret +} + +; Check that we can read and modify %rbx returned from PHP function. +define hhvmcc i64 @mod_return(i64 %a, i64 %b, i64 %c) nounwind { +entry: +; CHECK-LABEL: mod_return: +; CHECK-NEXT: {{^#.*}} +; CHECK-NEXT: callq bar +; CHECK-NEXT: incq %rbx + %tmp = call hhvmcc i64 @bar(i64 %a, i64 %b, i64 %c) + %retval = add i64 %tmp, 1 + ret i64 %retval +} + +%rettype = type { i64, i64, i64, i64, i64, i64, i64, + i64, i64, i64, i64, i64, i64, i64 +} + +; Check that we can return up to 14 64-bit args in registers. +define hhvmcc %rettype @return_all(i64 %a, i64 %b, i64 %c) nounwind { +entry: +; CHECK-LABEL: return_all: +; CHECK-DAG: movl $1, %ebx +; CHECK-DAG: movl $2, %ebp +; CHECK-DAG: movl $3, %edi +; CHECK-DAG: movl $4, %esi +; CHECK-DAG: movl $5, %edx +; CHECK-DAG: movl $6, %ecx +; CHECK-DAG: movl $7, %r8 +; CHECK-DAG: movl $8, %r9 +; CHECK-DAG: movl $9, %eax +; CHECK-DAG: movl $10, %r10 +; CHECK-DAG: movl $11, %r11 +; CHECK-DAG: movl $12, %r13 +; CHECK-DAG: movl $13, %r14 +; CHECK-DAG: movl $14, %r15 +; CHECK: retq + %r1 = insertvalue %rettype zeroinitializer, i64 1, 0 + %r2 = insertvalue %rettype %r1, i64 2, 1 + %r3 = insertvalue %rettype %r2, i64 3, 2 + %r4 = insertvalue %rettype %r3, i64 4, 3 + %r5 = insertvalue %rettype %r4, i64 5, 4 + %r6 = insertvalue %rettype %r5, i64 6, 5 + %r7 = insertvalue %rettype %r6, i64 7, 6 + %r8 = insertvalue %rettype %r7, i64 8, 7 + %r9 = insertvalue %rettype %r8, i64 9, 8 + %r10 = insertvalue %rettype %r9, i64 10, 9 + %r11 = insertvalue %rettype %r10, i64 11, 10 + %r12 = insertvalue %rettype %r11, i64 12, 11 + %r13 = insertvalue %rettype %r12, i64 13, 12 + %r14 = insertvalue %rettype %r13, i64 14, 13 + ret %rettype %r14 +} + +declare hhvmcc void @return_all_tc(i64, i64, i64, i64, i64, i64, i64, i64, + i64, i64, i64, i64, i64, i64, i64) + +; Check that we can return up to 14 64-bit args in registers via tail call. +define hhvmcc void @test_return_all_tc(i64 %a, i64 %b, i64 %c) nounwind { +entry: +; CHECK-LABEL: test_return_all_tc: +; CHECK-NEXT: {{^#.*}} +; CHECK-DAG: movl $1, %ebx +; CHECK-DAG: movl $3, %ebp +; CHECK-DAG: movl $4, %r15 +; CHECK-DAG: movl $5, %edi +; CHECK-DAG: movl $6, %esi +; CHECK-DAG: movl $7, %edx +; CHECK-DAG: movl $8, %ecx +; CHECK-DAG: movl $9, %r8 +; CHECK-DAG: movl $10, %r9 +; CHECK-DAG: movl $11, %eax +; CHECK-DAG: movl $12, %r10 +; CHECK-DAG: movl $13, %r11 +; CHECK-DAG: movl $14, %r13 +; CHECK-DAG: movl $15, %r14 +; CHECK: jmp return_all_tc + tail call hhvmcc void @return_all_tc( + i64 1, i64 %b, i64 3, i64 4, i64 5, i64 6, i64 7, + i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15) + ret void +} + +declare hhvmcc {i64, i64} @php_short(i64, i64, i64, i64) + +define hhvmcc i64 @test_php_short(i64 %a, i64 %b, i64 %c) nounwind { +entry: +; CHECK-LABEL: test_php_short: +; CHECK-NEXT: {{^#.*}} +; CHECK-NEXT: movl $42, %r15 +; CHECK-NEXT: callq php_short +; CHECK-NEXT: leaq (%rbp,%r12), %rbx +; CHECK-NEXT: retq + %pair = call hhvmcc {i64, i64} @php_short(i64 %a, i64 %b, i64 %c, i64 42) + %fp = extractvalue {i64, i64} %pair, 1 + %rv = add i64 %fp, %b + ret i64 %rv +} + +declare hhvmcc %rettype @php_all(i64, i64, i64, i64, i64, i64, i64, + i64, i64, i64, i64, i64, i64, i64, i64) + +; Check that we can pass 15 arguments in registers. +; Also check that %r12 (2nd arg) is not spilled. +define hhvmcc i64 @test_php_all(i64 %a, i64 %b, i64 %c) nounwind { +entry: +; CHECK-LABEL: test_php_all: +; CHECK-NEXT: {{^#.*}} +; CHECK-NOT: sub +; CHECK-NOT: sub +; CHECK-DAG: movl $1, %ebx +; CHECK-DAG: movl $3, %ebp +; CHECK-DAG: movl $4, %r15 +; CHECK-DAG: movl $5, %edi +; CHECK-DAG: movl $6, %esi +; CHECK-DAG: movl $7, %edx +; CHECK-DAG: movl $8, %ecx +; CHECK-DAG: movl $9, %r8 +; CHECK-DAG: movl $10, %r9 +; CHECK-DAG: movl $11, %eax +; CHECK-DAG: movl $12, %r10 +; CHECK-DAG: movl $13, %r11 +; CHECK-DAG: movl $14, %r13 +; CHECK-DAG: movl $15, %r14 +; CHECK: callq php_all + %pair = call hhvmcc %rettype @php_all( + i64 1, i64 %b, i64 3, i64 4, i64 5, i64 6, i64 7, + i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15) + %fp = extractvalue %rettype %pair, 1 + %rv = add i64 %fp, %b + ret i64 %rv +} + +declare hhvmcc void @svcreq(i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, + i64, i64) + +define hhvmcc void @test_svcreq(i64 %a, i64 %b, i64 %c) nounwind { +entry: +; CHECK-LABEL: test_svcreq: +; CHECK-DAG: movl $42, %r10 +; CHECK-DAG: movl $1, %edi +; CHECK-DAG: movl $2, %esi +; CHECK-DAG: movl $3, %edx +; CHECK-DAG: movl $4, %ecx +; CHECK-DAG: movl $5, %r8 +; CHECK-DAG: movl $6, %r9 +; CHECK: jmp svcreq + tail call hhvmcc void @svcreq(i64 %a, i64 %b, i64 %c, i64 undef, i64 1, + i64 2, i64 3, i64 4, i64 5, i64 6, i64 undef, + i64 42) + ret void +} + +declare hhvm_ccc void @helper_short(i64, i64, i64, i64, i64, i64, i64) + +; Pass all arguments in registers and check that we don't adjust stack +; for the call. +define hhvmcc void @test_helper_short(i64 %a, i64 %b, i64 %c) nounwind { +entry: +; CHECK-LABEL: test_helper_short: +; CHECK-NOT: push +; CHECK-NOT: sub +; CHECK-DAG: movl $1, %edi +; CHECK-DAG: movl $2, %esi +; CHECK-DAG: movl $3, %edx +; CHECK-DAG: movl $4, %ecx +; CHECK-DAG: movl $5, %r8 +; CHECK-DAG: movl $6, %r9 +; CHECK: callq helper_short + call hhvm_ccc void @helper_short(i64 %c, i64 1, i64 2, i64 3, i64 4, + i64 5, i64 6) + ret void +} + +declare hhvm_ccc void @helper(i64, i64, i64, i64, i64, i64, i64, i64, i64, i64) + +define hhvmcc void @test_helper(i64 %a, i64 %b, i64 %c) nounwind { +entry: +; CHECK-LABEL: test_helper: +; CHECK-DAG: movl $1, %edi +; CHECK-DAG: movl $2, %esi +; CHECK-DAG: movl $3, %edx +; CHECK-DAG: movl $4, %ecx +; CHECK-DAG: movl $5, %r8 +; CHECK-DAG: movl $6, %r9 +; CHECK: callq helper + call hhvm_ccc void @helper(i64 %c, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, + i64 7, i64 8, i64 9) + ret void +} + +; When we enter function with HHVM calling convention, the stack is aligned +; at 16 bytes. This means we align objects on the stack differently and +; adjust the stack differently for calls. +declare hhvm_ccc void @stack_helper(i64, i64, i64) +declare hhvm_ccc void @stack_helper2(<2 x double>, i64) + +define hhvmcc void @test_stack_helper(i64 %a, i64 %b, i64 %c) nounwind { +entry: +; CHECK-LABEL: test_stack_helper: +; CHECK-NOT: push +; CHECK: subq $32, %rsp +; CHECK: movaps 16(%rsp), %xmm0 +; CHECK: callq stack_helper2 + %t1 = alloca <2 x double>, align 16 + %t2 = alloca i64, align 8 + %t3 = alloca i64, align 8 + %load3 = load i64, i64 *%t3 + call hhvm_ccc void @stack_helper(i64 %c, i64 %load3, i64 42) + %load = load <2 x double>, <2 x double> *%t1 + %load2 = load i64, i64 *%t2 + call hhvm_ccc void @stack_helper2(<2 x double> %load, i64 %load2) + ret void +} + +; Check that we are not adjusting the stack before calling the helper. +define hhvmcc void @test_stack_helper2(i64 %a, i64 %b, i64 %c) nounwind { +entry: +; CHECK-LABEL: test_stack_helper2: +; CHECK-NOT: push +; CHECK-NOT: subq + call hhvm_ccc void @stack_helper(i64 %c, i64 7, i64 42) + ret void +} +