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