1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=i686-unknown-unknown < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=i686-unknown-unknown -O0 < %s | FileCheck %s -check-prefix=CHECK0 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker%struct.interrupt_frame = type { i32, i32, i32, i32, i32 } 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*, i32)* @test_isr_ecode to i8*), i8* bitcast (void (%struct.interrupt_frame*, i32)* @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 eax, putting original esp at +4. 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: pushl %eax 13*9880d681SAndroid Build Coastguard Worker ; CHECK: movl 12(%esp), %eax 14*9880d681SAndroid Build Coastguard Worker ; CHECK: popl %eax 15*9880d681SAndroid Build Coastguard Worker ; CHECK: iretl 16*9880d681SAndroid Build Coastguard Worker ; CHECK0-LABEL: test_isr_no_ecode: 17*9880d681SAndroid Build Coastguard Worker ; CHECK0: pushl %eax 18*9880d681SAndroid Build Coastguard Worker ; CHECK0: leal 4(%esp), %eax 19*9880d681SAndroid Build Coastguard Worker ; CHECK0: movl 8(%eax), %eax 20*9880d681SAndroid Build Coastguard Worker ; CHECK0: popl %eax 21*9880d681SAndroid Build Coastguard Worker ; CHECK0: iretl 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 i32, i32* %pflags, align 4 24*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "", "r"(i32 %flags) 25*9880d681SAndroid Build Coastguard Worker ret void 26*9880d681SAndroid Build Coastguard Worker} 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker; Spills eax and ecx, putting original esp at +8. Stack is adjusted up another 4 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, i32 %ecode) { 31*9880d681SAndroid Build Coastguard Worker ; CHECK-LABEL: test_isr_ecode 32*9880d681SAndroid Build Coastguard Worker ; CHECK: pushl %ecx 33*9880d681SAndroid Build Coastguard Worker ; CHECK: pushl %eax 34*9880d681SAndroid Build Coastguard Worker ; CHECK: movl 8(%esp), %eax 35*9880d681SAndroid Build Coastguard Worker ; CHECK: movl 20(%esp), %ecx 36*9880d681SAndroid Build Coastguard Worker ; CHECK: popl %eax 37*9880d681SAndroid Build Coastguard Worker ; CHECK: popl %ecx 38*9880d681SAndroid Build Coastguard Worker ; CHECK: addl $4, %esp 39*9880d681SAndroid Build Coastguard Worker ; CHECK: iretl 40*9880d681SAndroid Build Coastguard Worker ; CHECK0-LABEL: test_isr_ecode 41*9880d681SAndroid Build Coastguard Worker ; CHECK0: pushl %ecx 42*9880d681SAndroid Build Coastguard Worker ; CHECK0: pushl %eax 43*9880d681SAndroid Build Coastguard Worker ; CHECK0: movl 8(%esp), %eax 44*9880d681SAndroid Build Coastguard Worker ; CHECK0: leal 12(%esp), %ecx 45*9880d681SAndroid Build Coastguard Worker ; CHECK0: movl 8(%ecx), %ecx 46*9880d681SAndroid Build Coastguard Worker ; CHECK0: popl %eax 47*9880d681SAndroid Build Coastguard Worker ; CHECK0: popl %ecx 48*9880d681SAndroid Build Coastguard Worker ; CHECK0: addl $4, %esp 49*9880d681SAndroid Build Coastguard Worker ; CHECK0: iretl 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 i32, i32* %pflags, align 4 52*9880d681SAndroid Build Coastguard Worker call x86_fastcallcc void asm sideeffect "", "r,r"(i32 %flags, i32 %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, i32 %ecode) { 58*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "", "~{eax},~{ebx},~{ebp}"() 59*9880d681SAndroid Build Coastguard Worker ; CHECK-LABEL: test_isr_clobbers 60*9880d681SAndroid Build Coastguard Worker ; CHECK-SSE-NEXT: pushl %ebp 61*9880d681SAndroid Build Coastguard Worker ; CHECK-SSE-NEXT: pushl %ebx 62*9880d681SAndroid Build Coastguard Worker ; CHECK-SSE-NEXT; pushl %eax 63*9880d681SAndroid Build Coastguard Worker ; CHECK-SSE-NEXT: popl %eax 64*9880d681SAndroid Build Coastguard Worker ; CHECK-SSE-NEXT: popl %ebx 65*9880d681SAndroid Build Coastguard Worker ; CHECK-SSE-NEXT: popl %ebp 66*9880d681SAndroid Build Coastguard Worker ; CHECK-SSE-NEXT: addl $4, %esp 67*9880d681SAndroid Build Coastguard Worker ; CHECK-SSE-NEXT: iretl 68*9880d681SAndroid Build Coastguard Worker ; CHECK0-LABEL: test_isr_clobbers 69*9880d681SAndroid Build Coastguard Worker ; CHECK0-SSE-NEXT: pushl %ebp 70*9880d681SAndroid Build Coastguard Worker ; CHECK0-SSE-NEXT: pushl %ebx 71*9880d681SAndroid Build Coastguard Worker ; CHECK0-SSE-NEXT; pushl %eax 72*9880d681SAndroid Build Coastguard Worker ; CHECK0-SSE-NEXT: popl %eax 73*9880d681SAndroid Build Coastguard Worker ; CHECK0-SSE-NEXT: popl %ebx 74*9880d681SAndroid Build Coastguard Worker ; CHECK0-SSE-NEXT: popl %ebp 75*9880d681SAndroid Build Coastguard Worker ; CHECK0-SSE-NEXT: addl $4, %esp 76*9880d681SAndroid Build Coastguard Worker ; CHECK0-SSE-NEXT: iretl 77*9880d681SAndroid Build Coastguard Worker ret void 78*9880d681SAndroid Build Coastguard Worker} 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker@f80 = common global x86_fp80 0xK00000000000000000000, align 4 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Worker; Test that the presence of x87 does not crash the FP stackifier 83*9880d681SAndroid Build Coastguard Workerdefine x86_intrcc void @test_isr_x87(%struct.interrupt_frame* %frame) { 84*9880d681SAndroid Build Coastguard Worker ; CHECK-LABEL: test_isr_x87 85*9880d681SAndroid Build Coastguard Worker ; CHECK-DAG: fldt f80 86*9880d681SAndroid Build Coastguard Worker ; CHECK-DAG: fld1 87*9880d681SAndroid Build Coastguard Worker ; CHECK: faddp 88*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: fstpt f80 89*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: iretl 90*9880d681SAndroid Build Coastguard Workerentry: 91*9880d681SAndroid Build Coastguard Worker %ld = load x86_fp80, x86_fp80* @f80, align 4 92*9880d681SAndroid Build Coastguard Worker %add = fadd x86_fp80 %ld, 0xK3FFF8000000000000000 93*9880d681SAndroid Build Coastguard Worker store x86_fp80 %add, x86_fp80* @f80, align 4 94*9880d681SAndroid Build Coastguard Worker ret void 95*9880d681SAndroid Build Coastguard Worker} 96