Home | History | Annotate | Download | only in X86
      1 ; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s
      2 ; RUN: llc -mtriple=x86_64-unknown-unknown -O0 < %s | FileCheck %s -check-prefix=CHECK0
      3 
      4 %struct.interrupt_frame = type { i64, i64, i64, i64, i64 }
      5 
      6 @llvm.used = appending global [4 x i8*] [i8* bitcast (void (%struct.interrupt_frame*)* @test_isr_no_ecode to i8*), i8* bitcast (void (%struct.interrupt_frame*, i64)* @test_isr_ecode to i8*), i8* bitcast (void (%struct.interrupt_frame*, i64)* @test_isr_clobbers to i8*), i8* bitcast (void (%struct.interrupt_frame*)* @test_isr_x87 to i8*)], section "llvm.metadata"
      7 
      8 ; Spills rax, putting original esp at +8.
      9 ; No stack adjustment if declared with no error code
     10 define x86_intrcc void @test_isr_no_ecode(%struct.interrupt_frame* %frame) {
     11   ; CHECK-LABEL: test_isr_no_ecode:
     12   ; CHECK: pushq %rax
     13   ; CHECK: movq 24(%rsp), %rax
     14   ; CHECK: popq %rax
     15   ; CHECK: iretq
     16   ; CHECK0-LABEL: test_isr_no_ecode:
     17   ; CHECK0: pushq %rax
     18   ; CHECK0: leaq 8(%rsp), %rax
     19   ; CHECK0: movq 16(%rax), %rax
     20   ; CHECK0: popq %rax
     21   ; CHECK0: iretq
     22   %pflags = getelementptr inbounds %struct.interrupt_frame, %struct.interrupt_frame* %frame, i32 0, i32 2
     23   %flags = load i64, i64* %pflags, align 4
     24   call void asm sideeffect "", "r"(i64 %flags)
     25   ret void
     26 }
     27 
     28 ; Spills rax and rcx, putting original rsp at +16. Stack is adjusted up another 8 bytes
     29 ; before return, popping the error code.
     30 define x86_intrcc void @test_isr_ecode(%struct.interrupt_frame* %frame, i64 %ecode) {
     31   ; CHECK-LABEL: test_isr_ecode
     32   ; CHECK: pushq %rax
     33   ; CHECK: pushq %rcx
     34   ; CHECK: movq 16(%rsp), %rax
     35   ; CHECK: movq 40(%rsp), %rcx
     36   ; CHECK: popq %rcx
     37   ; CHECK: popq %rax
     38   ; CHECK: addq $8, %rsp
     39   ; CHECK: iretq
     40   ; CHECK0-LABEL: test_isr_ecode
     41   ; CHECK0: pushq %rax
     42   ; CHECK0: pushq %rcx
     43   ; CHECK0: movq 16(%rsp), %rax
     44   ; CHECK0: leaq 24(%rsp), %rcx
     45   ; CHECK0: movq 16(%rcx), %rcx
     46   ; CHECK0: popq %rcx
     47   ; CHECK0: popq %rax
     48   ; CHECK0: addq $8, %rsp
     49   ; CHECK0: iretq
     50   %pflags = getelementptr inbounds %struct.interrupt_frame, %struct.interrupt_frame* %frame, i32 0, i32 2
     51   %flags = load i64, i64* %pflags, align 4
     52   call void asm sideeffect "", "r,r"(i64 %flags, i64 %ecode)
     53   ret void
     54 }
     55 
     56 ; All clobbered registers must be saved
     57 define x86_intrcc void @test_isr_clobbers(%struct.interrupt_frame* %frame, i64 %ecode) {
     58   call void asm sideeffect "", "~{rax},~{rbx},~{rbp},~{r11},~{xmm0}"()
     59   ; CHECK-LABEL: test_isr_clobbers
     60   ; CHECK-SSE-NEXT: pushq %rax
     61   ; CHECK-SSE-NEXT; pushq %r11
     62   ; CHECK-SSE-NEXT: pushq %rbp
     63   ; CHECK-SSE-NEXT: pushq %rbx
     64   ; CHECK-SSE-NEXT: movaps %xmm0
     65   ; CHECK-SSE-NEXT: movaps %xmm0
     66   ; CHECK-SSE-NEXT: popq %rbx
     67   ; CHECK-SSE-NEXT: popq %rbp
     68   ; CHECK-SSE-NEXT: popq %r11
     69   ; CHECK-SSE-NEXT: popq %rax
     70   ; CHECK-SSE-NEXT: addq $8, %rsp
     71   ; CHECK-SSE-NEXT: iretq
     72   ; CHECK0-LABEL: test_isr_clobbers
     73   ; CHECK0-SSE-NEXT: pushq %rax
     74   ; CHECK0-SSE-NEXT; pushq %r11
     75   ; CHECK0-SSE-NEXT: pushq %rbp
     76   ; CHECK0-SSE-NEXT: pushq %rbx
     77   ; CHECK0-SSE-NEXT: movaps %xmm0
     78   ; CHECK0-SSE-NEXT: movaps %xmm0
     79   ; CHECK0-SSE-NEXT: popq %rbx
     80   ; CHECK0-SSE-NEXT: popq %rbp
     81   ; CHECK0-SSE-NEXT: popq %r11
     82   ; CHECK0-SSE-NEXT: popq %rax
     83   ; CHECK0-SSE-NEXT: addq $8, %rsp
     84   ; CHECK0-SSE-NEXT: iretq
     85   ret void
     86 }
     87 
     88 @f80 = common global x86_fp80 0xK00000000000000000000, align 4
     89 
     90 ; Test that the presence of x87 does not crash the FP stackifier
     91 define x86_intrcc void @test_isr_x87(%struct.interrupt_frame* %frame) {
     92   ; CHECK-LABEL: test_isr_x87
     93   ; CHECK-DAG: fldt f80
     94   ; CHECK-DAG: fld1
     95   ; CHECK: faddp
     96   ; CHECK-NEXT: fstpt f80
     97   ; CHECK-NEXT: iretq
     98 entry:
     99   %ld = load x86_fp80, x86_fp80* @f80, align 4
    100   %add = fadd x86_fp80 %ld, 0xK3FFF8000000000000000
    101   store x86_fp80 %add, x86_fp80* @f80, align 4
    102   ret void
    103 }
    104