| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 1 | ; RUN: llc -mtriple=arm-none-none-eabi -mcpu=cortex-a15 -o - %s | FileCheck --check-prefix=CHECK-A %s | 
 | 2 | ; RUN: llc -mtriple=thumb-none-none-eabi -mcpu=cortex-a15 -o - %s | FileCheck --check-prefix=CHECK-A-THUMB %s | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 3 | ; RUN: llc -mtriple=thumb-apple-none-macho -mcpu=cortex-m3 -o - %s | FileCheck --check-prefix=CHECK-M %s | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 4 |  | 
 | 5 | declare arm_aapcscc void @bar() | 
 | 6 |  | 
 | 7 | @bigvar = global [16 x i32] zeroinitializer | 
 | 8 |  | 
 | 9 | define arm_aapcscc void @irq_fn() alignstack(8) "interrupt"="IRQ" { | 
 | 10 |   ; Must save all registers except banked sp and lr (we save lr anyway because | 
 | 11 |   ; we actually need it at the end to execute the return ourselves). | 
 | 12 |  | 
 | 13 |   ; Also need special function return setting pc and CPSR simultaneously. | 
 | 14 | ; CHECK-A-LABEL: irq_fn: | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 15 | ; CHECK-A: push {r0, r1, r2, r3, r11, r12, lr} | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 16 | ; CHECK-A: add r11, sp, #16 | 
 | 17 | ; CHECK-A: sub sp, sp, #{{[0-9]+}} | 
 | 18 | ; CHECK-A: bic sp, sp, #7 | 
 | 19 | ; CHECK-A: bl bar | 
 | 20 | ; CHECK-A: sub sp, r11, #16 | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 21 | ; CHECK-A: pop {r0, r1, r2, r3, r11, r12, lr} | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 22 | ; CHECK-A: subs pc, lr, #4 | 
 | 23 |  | 
 | 24 | ; CHECK-A-THUMB-LABEL: irq_fn: | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 25 | ; CHECK-A-THUMB: push.w {r0, r1, r2, r3, r4, r7, r12, lr} | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 26 | ; CHECK-A-THUMB: add r7, sp, #20 | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 27 | ; CHECK-A-THUMB: mov r4, sp | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 28 | ; CHECK-A-THUMB: bic r4, r4, #7 | 
 | 29 | ; CHECK-A-THUMB: bl bar | 
 | 30 | ; CHECK-A-THUMB: sub.w r4, r7,  #20 | 
 | 31 | ; CHECK-A-THUMB: mov sp, r4 | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 32 | ; CHECK-A-THUMB: pop.w {r0, r1, r2, r3, r4, r7, r12, lr} | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 33 | ; CHECK-A-THUMB: subs pc, lr, #4 | 
 | 34 |  | 
 | 35 |   ; Normal AAPCS function (r0-r3 pushed onto stack by hardware, lr set to | 
 | 36 |   ; appropriate sentinel so no special return needed). | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 37 | ; CHECK-M-LABEL: irq_fn: | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 38 | ; CHECK-M: push {r4, r7, lr} | 
 | 39 | ; CHECK-M: add r7, sp, #4 | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 40 | ; CHECK-M: mov r4, sp | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 41 | ; CHECK-M: bic r4, r4, #7 | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 42 | ; CHECK-M: mov sp, r4 | 
 | 43 | ; CHECK-M: blx _bar | 
 | 44 | ; CHECK-M: subs r4, r7, #4 | 
 | 45 | ; CHECK-M: mov sp, r4 | 
 | 46 | ; CHECK-M: pop {r4, r7, pc} | 
 | 47 |  | 
 | 48 |   call arm_aapcscc void @bar() | 
 | 49 |   ret void | 
 | 50 | } | 
 | 51 |  | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 52 | ; We don't push/pop r12, as it is banked for FIQ | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 53 | define arm_aapcscc void @fiq_fn() alignstack(8) "interrupt"="FIQ" { | 
 | 54 | ; CHECK-A-LABEL: fiq_fn: | 
 | 55 | ; CHECK-A: push {r0, r1, r2, r3, r4, r5, r6, r7, r11, lr} | 
 | 56 |   ; 32 to get past r0, r1, ..., r7 | 
 | 57 | ; CHECK-A: add r11, sp, #32 | 
 | 58 | ; CHECK-A: sub sp, sp, #{{[0-9]+}} | 
 | 59 | ; CHECK-A: bic sp, sp, #7 | 
 | 60 | ; [...] | 
 | 61 |   ; 32 must match above | 
 | 62 | ; CHECK-A: sub sp, r11, #32 | 
 | 63 | ; CHECK-A: pop {r0, r1, r2, r3, r4, r5, r6, r7, r11, lr} | 
 | 64 | ; CHECK-A: subs pc, lr, #4 | 
 | 65 |  | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 66 | ; CHECK-A-THUMB-LABEL: fiq_fn: | 
 | 67 | ; CHECK-M-LABEL: fiq_fn: | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 68 |   %val = load volatile [16 x i32]* @bigvar | 
 | 69 |   store volatile [16 x i32] %val, [16 x i32]* @bigvar | 
 | 70 |   ret void | 
 | 71 | } | 
 | 72 |  | 
 | 73 | define arm_aapcscc void @swi_fn() alignstack(8) "interrupt"="SWI" { | 
 | 74 | ; CHECK-A-LABEL: swi_fn: | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 75 | ; CHECK-A: push {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr} | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 76 | ; CHECK-A: add r11, sp, #44 | 
 | 77 | ; CHECK-A: sub sp, sp, #{{[0-9]+}} | 
 | 78 | ; CHECK-A: bic sp, sp, #7 | 
 | 79 | ; [...] | 
 | 80 | ; CHECK-A: sub sp, r11, #44 | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 81 | ; CHECK-A: pop {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr} | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 82 | ; CHECK-A: subs pc, lr, #0 | 
 | 83 |  | 
 | 84 |   %val = load volatile [16 x i32]* @bigvar | 
 | 85 |   store volatile [16 x i32] %val, [16 x i32]* @bigvar | 
 | 86 |   ret void | 
 | 87 | } | 
 | 88 |  | 
 | 89 | define arm_aapcscc void @undef_fn() alignstack(8) "interrupt"="UNDEF" { | 
 | 90 | ; CHECK-A-LABEL: undef_fn: | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 91 | ; CHECK-A: push {r0, r1, r2, r3, r11, r12, lr} | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 92 | ; CHECK-A: add r11, sp, #16 | 
 | 93 | ; CHECK-A: sub sp, sp, #{{[0-9]+}} | 
 | 94 | ; CHECK-A: bic sp, sp, #7 | 
 | 95 | ; [...] | 
 | 96 | ; CHECK-A: sub sp, r11, #16 | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 97 | ; CHECK-A: pop {r0, r1, r2, r3, r11, r12, lr} | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 98 | ; CHECK-A: subs pc, lr, #0 | 
 | 99 |  | 
 | 100 |   call void @bar() | 
 | 101 |   ret void | 
 | 102 | } | 
 | 103 |  | 
 | 104 | define arm_aapcscc void @abort_fn() alignstack(8) "interrupt"="ABORT" { | 
 | 105 | ; CHECK-A-LABEL: abort_fn: | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 106 | ; CHECK-A: push {r0, r1, r2, r3, r11, r12, lr} | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 107 | ; CHECK-A: add r11, sp, #16 | 
 | 108 | ; CHECK-A: sub sp, sp, #{{[0-9]+}} | 
 | 109 | ; CHECK-A: bic sp, sp, #7 | 
 | 110 | ; [...] | 
 | 111 | ; CHECK-A: sub sp, r11, #16 | 
| Stephen Hines | 36b5688 | 2014-04-23 16:57:46 -0700 | [diff] [blame] | 112 | ; CHECK-A: pop {r0, r1, r2, r3, r11, r12, lr} | 
| Tim Northover | bba9390 | 2013-10-01 14:33:28 +0000 | [diff] [blame] | 113 | ; CHECK-A: subs pc, lr, #4 | 
 | 114 |  | 
 | 115 |   call void @bar() | 
 | 116 |   ret void | 
 | 117 | } | 
 | 118 |  | 
 | 119 | @var = global double 0.0 | 
 | 120 |  | 
 | 121 | ; We don't save VFP regs, since it would be a massive overhead in the general | 
 | 122 | ; case. | 
 | 123 | define arm_aapcscc void @floating_fn() alignstack(8) "interrupt"="IRQ" { | 
 | 124 | ; CHECK-A-LABEL: floating_fn: | 
 | 125 | ; CHECK-A-NOT: vpush | 
 | 126 | ; CHECK-A-NOT: vstr | 
 | 127 | ; CHECK-A-NOT: vstm | 
 | 128 | ; CHECK-A: vadd.f64 {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} | 
 | 129 |   %lhs = load volatile double* @var | 
 | 130 |   %rhs = load volatile double* @var | 
 | 131 |   %sum = fadd double %lhs, %rhs | 
 | 132 |   store double %sum, double* @var | 
 | 133 |   ret void | 
 | 134 | } |