OLD | NEW |
(Empty) | |
| 1 ; RUN: llc -mtriple=x86_64-nacl %s -o - | FileCheck %s |
| 2 ; RUN: llc -mtriple=x86_64-nacl -fast-isel %s -o - | FileCheck %s |
| 3 |
| 4 ; Test calling with many parameters (such that some need to go on the stack), |
| 5 ; along with dynamic stack allocation and x86-64 NaCl stack/frame |
| 6 ; register sandboxing. |
| 7 |
| 8 declare i32 @callee(i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a
7, i32 %a8, i8* %ptr) |
| 9 |
| 10 define i32 @dyn_stack_alloc (i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a
6, i32 %a7, i32 %a8, i32 %amt) { |
| 11 %p = alloca i8, i32 %amt, align 1 |
| 12 %x = call i32 @callee(i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i3
2 %a7, i32 %a8, i8* %p) |
| 13 ret i32 %x |
| 14 } |
| 15 |
| 16 ; CHECK-LABEL: dyn_stack_alloc |
| 17 ; Set up frame pointer and save two registers. |
| 18 ; CHECK: movl %ebp, %eax |
| 19 ; CHECK-NEXT: pushq %rax |
| 20 ; CHECK: movq %rsp, %rbp |
| 21 ; CHECK-NEXT: .L |
| 22 ; CHECK-NEXT: .cfi_def_cfa_register %rbp |
| 23 ; CHECK-NEXT: pushq |
| 24 ; CHECK-NEXT: pushq |
| 25 ; CHECK-NOT: pushq |
| 26 |
| 27 ; The dynamic alloc (aligned): |
| 28 ; CHECK: movl 32(%rbp), [[AMT:%.*]] |
| 29 ; CHECK: movl %esp, [[TMP:%.*]] |
| 30 ; CHECK-NEXT: addl $15, [[AMT]] |
| 31 ; CHECK-NEXT: andl $-16, [[AMT]] |
| 32 ; CHECK-NEXT: subl [[AMT]], [[TMP]] |
| 33 ; Set the SP based on the final value of TMP. |
| 34 ; CHECK-NEXT: naclrestsp_noflags [[TMP]], %r15 |
| 35 |
| 36 ; Make more room for call arguments: |
| 37 ; CHECK: naclsspq $32, %r15 |
| 38 ; CHECK: callq callee |
| 39 |
| 40 ; Restore stack pointer from frame pointer - 16. It is -16 because |
| 41 ; the code still needs to pop the two pushed regs, before restoring |
| 42 ; the frame pointer from the stack. |
| 43 ; CHECK: naclspadj $-16, %r15 |
| 44 ; CHECK-NEXT: popq |
| 45 ; CHECK-NEXT: popq |
| 46 ; CHECK-NEXT: naclrestbp (%rsp), %r15 |
| 47 ; CHECK-NEXT: naclaspq $8, %r15 |
OLD | NEW |