Home | History | Annotate | Download | only in XCore
      1 ; RUN: llc < %s -march=xcore | FileCheck %s
      2 ; RUN: llc < %s -march=xcore -disable-fp-elim | FileCheck %s -check-prefix=CHECKFP
      3 
      4 ; When using SP for small frames, we don't need any scratch registers (SR).
      5 ; When using SP for large frames, we may need two scratch registers.
      6 ; When using FP, for large or small frames, we may need one scratch register.
      7 
      8 ; FP + small frame: spill FP+SR = entsp 2
      9 ; CHECKFP-LABEL: f1
     10 ; CHECKFP: entsp 2
     11 ; CHECKFP-NEXT: stw r10, sp[1]
     12 ; CHECKFP-NEXT: ldaw r10, sp[0]
     13 ; CHECKFP: set sp, r10
     14 ; CHECKFP-NEXT: ldw r10, sp[1]
     15 ; CHECKFP-NEXT: retsp 2
     16 ;
     17 ; !FP + small frame: no spills = no stack adjustment needed
     18 ; CHECK-LABEL: f1
     19 ; CHECK: stw lr, sp[0]
     20 ; CHECK: ldw lr, sp[0]
     21 ; CHECK-NEXT: retsp 0
     22 define void @f1() nounwind {
     23 entry:
     24   tail call void asm sideeffect "", "~{lr}"() nounwind
     25   ret void
     26 }
     27 
     28 
     29 ; FP + small frame: spill FP+SR+R0+LR = entsp 3 + extsp 1
     30 ; CHECKFP-LABEL:f3
     31 ; CHECKFP: entsp 3
     32 ; CHECKFP-NEXT: stw r10, sp[1]
     33 ; CHECKFP-NEXT: ldaw r10, sp[0]
     34 ; CHECKFP-NEXT: stw [[REG:r[4-9]+]], r10[2]
     35 ; CHECKFP-NEXT: mov [[REG]], r0
     36 ; CHECKFP-NEXT: extsp 1
     37 ; CHECKFP-NEXT: bl f2
     38 ; CHECKFP-NEXT: ldaw sp, sp[1]
     39 ; CHECKFP-NEXT: mov r0, [[REG]]
     40 ; CHECKFP-NEXT: ldw [[REG]], r10[2]
     41 ; CHECKFP-NEXT: set sp, r10
     42 ; CHECKFP-NEXT: ldw r10, sp[1]
     43 ; CHECKFP-NEXT: retsp 3
     44 ;
     45 ; !FP + small frame: spill R0+LR = entsp 2
     46 ; CHECK-LABEL: f3
     47 ; CHECK: entsp 2
     48 ; CHECK-NEXT: stw [[REG:r[4-9]+]], sp[1]
     49 ; CHECK-NEXT: mov [[REG]], r0
     50 ; CHECK-NEXT: bl f2
     51 ; CHECK-NEXT: mov r0, [[REG]]
     52 ; CHECK-NEXT: ldw [[REG]], sp[1]
     53 ; CHECK-NEXT: retsp 2
     54 declare void @f2()
     55 define i32 @f3(i32 %i) nounwind {
     56 entry:
     57   call void @f2()
     58   ret i32 %i
     59 }
     60 
     61 
     62 ; FP + large frame: spill FP+SR = entsp 2 + 100000
     63 ; CHECKFP-LABEL: f4
     64 ; CHECKFP: entsp 65535
     65 ; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
     66 ; CHECKFP-NEXT: .cfi_def_cfa_offset 262140
     67 ; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
     68 ; CHECKFP-NEXT: .cfi_offset 15, 0
     69 ; CHECKFP-NEXT: extsp 34467
     70 ; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
     71 ; CHECKFP-NEXT: .cfi_def_cfa_offset 400008
     72 ; CHECKFP-NEXT: stw r10, sp[1]
     73 ; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
     74 ; CHECKFP-NEXT: .cfi_offset 10, -400004
     75 ; CHECKFP-NEXT: ldaw r10, sp[0]
     76 ; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
     77 ; CHECKFP-NEXT: .cfi_def_cfa_register 10
     78 ; CHECKFP-NEXT: set sp, r10
     79 ; CHECKFP-NEXT: ldw r10, sp[1]
     80 ; CHECKFP-NEXT: ldaw sp, sp[65535]
     81 ; CHECKFP-NEXT: retsp 34467
     82 ;
     83 ; !FP + large frame: spill SR+SR = entsp 2 + 100000
     84 ; CHECK-LABEL: f4
     85 ; CHECK: entsp 65535
     86 ; CHECK-NEXT: .Ltmp{{[0-9]+}}
     87 ; CHECK-NEXT: .cfi_def_cfa_offset 262140
     88 ; CHECK-NEXT: .Ltmp{{[0-9]+}}
     89 ; CHECK-NEXT: .cfi_offset 15, 0
     90 ; CHECK-NEXT: extsp 34467
     91 ; CHECK-NEXT: .Ltmp{{[0-9]+}}
     92 ; CHECK-NEXT: .cfi_def_cfa_offset 400008
     93 ; CHECK-NEXT: ldaw sp, sp[65535]
     94 ; CHECK-NEXT: retsp 34467
     95 define void @f4() {
     96 entry:
     97   %0 = alloca [100000 x i32]
     98   ret void
     99 }
    100 
    101 
    102 ; FP + large frame: spill FP+SR+R4+LR = entsp 3 + 200000  + extsp 1
    103 ; CHECKFP: .section .cp.rodata.cst4,"aMc",@progbits,4
    104 ; CHECKFP-NEXT: .p2align 2
    105 ; CHECKFP-NEXT: .LCPI[[CNST0:[0-9_]+]]:
    106 ; CHECKFP-NEXT: .long 200002
    107 ; CHECKFP-NEXT: .LCPI[[CNST1:[0-9_]+]]:
    108 ; CHECKFP-NEXT: .long 200001
    109 ; CHECKFP-NEXT: .text
    110 ; CHECKFP-LABEL: f6
    111 ; CHECKFP: entsp 65535
    112 ; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
    113 ; CHECKFP-NEXT: .cfi_def_cfa_offset 262140
    114 ; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
    115 ; CHECKFP-NEXT: .cfi_offset 15, 0
    116 ; CHECKFP-NEXT: extsp 65535
    117 ; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
    118 ; CHECKFP-NEXT: .cfi_def_cfa_offset 524280
    119 ; CHECKFP-NEXT: extsp 65535
    120 ; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
    121 ; CHECKFP-NEXT: .cfi_def_cfa_offset 786420
    122 ; CHECKFP-NEXT: extsp 3398
    123 ; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
    124 ; CHECKFP-NEXT: .cfi_def_cfa_offset 800012
    125 ; CHECKFP-NEXT: stw r10, sp[1]
    126 ; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
    127 ; CHECKFP-NEXT: .cfi_offset 10, -800008
    128 ; CHECKFP-NEXT: ldaw r10, sp[0]
    129 ; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
    130 ; CHECKFP-NEXT: .cfi_def_cfa_register 10
    131 ; CHECKFP-NEXT: ldw r1, cp[.LCPI[[CNST0]]]
    132 ; CHECKFP-NEXT: stw [[REG:r[4-9]+]], r10[r1]
    133 ; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
    134 ; CHECKFP-NEXT: .cfi_offset 4, -4
    135 ; CHECKFP-NEXT: mov [[REG]], r0
    136 ; CHECKFP-NEXT: extsp 1
    137 ; CHECKFP-NEXT: ldaw r0, r10[2]
    138 ; CHECKFP-NEXT: bl f5
    139 ; CHECKFP-NEXT: ldaw sp, sp[1]
    140 ; CHECKFP-NEXT: ldw r1, cp[.LCPI3_1]
    141 ; CHECKFP-NEXT: ldaw r0, r10[r1]
    142 ; CHECKFP-NEXT: extsp 1
    143 ; CHECKFP-NEXT: bl f5
    144 ; CHECKFP-NEXT: ldaw sp, sp[1]
    145 ; CHECKFP-NEXT: mov r0, [[REG]]
    146 ; CHECKFP-NEXT: ldw r1, cp[.LCPI[[CNST0]]]
    147 ; CHECKFP-NEXT: ldw [[REG]], r10[r1]
    148 ; CHECKFP-NEXT: set sp, r10
    149 ; CHECKFP-NEXT: ldw r10, sp[1]
    150 ; CHECKFP-NEXT: ldaw sp, sp[65535]
    151 ; CHECKFP-NEXT: ldaw sp, sp[65535]
    152 ; CHECKFP-NEXT: ldaw sp, sp[65535]
    153 ; CHECKFP-NEXT: retsp 3398
    154 ;
    155 ; !FP + large frame: spill SR+SR+R4+LR = entsp 4 + 200000
    156 ; CHECK: .section .cp.rodata.cst4,"aMc",@progbits,4
    157 ; CHECK-NEXT: .p2align 2
    158 ; CHECK-NEXT: .LCPI[[CNST0:[0-9_]+]]:
    159 ; CHECK-NEXT: .long 200003
    160 ; CHECK-NEXT: .LCPI[[CNST1:[0-9_]+]]:
    161 ; CHECK-NEXT: .long 200002
    162 ; CHECK-NEXT: .text
    163 ; CHECK-LABEL: f6
    164 ; CHECK: entsp 65535
    165 ; CHECK-NEXT: .Ltmp{{[0-9]+}}
    166 ; CHECK-NEXT: .cfi_def_cfa_offset 262140
    167 ; CHECK-NEXT: .Ltmp{{[0-9]+}}
    168 ; CHECK-NEXT: .cfi_offset 15, 0
    169 ; CHECK-NEXT: extsp 65535
    170 ; CHECK-NEXT: .Ltmp{{[0-9]+}}
    171 ; CHECK-NEXT: .cfi_def_cfa_offset 524280
    172 ; CHECK-NEXT: extsp 65535
    173 ; CHECK-NEXT: .Ltmp{{[0-9]+}}
    174 ; CHECK-NEXT: .cfi_def_cfa_offset 786420
    175 ; CHECK-NEXT: extsp 3399
    176 ; CHECK-NEXT: .Ltmp{{[0-9]+}}
    177 ; CHECK-NEXT: .cfi_def_cfa_offset 800016
    178 ; CHECK-NEXT: ldaw r1, sp[0]
    179 ; CHECK-NEXT: ldw r2, cp[.LCPI[[CNST0]]]
    180 ; CHECK-NEXT: stw [[REG:r[4-9]+]], r1[r2]
    181 ; CHECK-NEXT: .Ltmp{{[0-9]+}}
    182 ; CHECK-NEXT: .cfi_offset 4, -4
    183 ; CHECK-NEXT: mov [[REG]], r0
    184 ; CHECK-NEXT: ldaw r0, sp[3]
    185 ; CHECK-NEXT: bl f5
    186 ; CHECK-NEXT: ldaw r0, sp[0]
    187 ; CHECK-NEXT: ldw r1, cp[.LCPI[[CNST1]]]
    188 ; CHECK-NEXT: ldaw r0, r0[r1]
    189 ; CHECK-NEXT: bl f5
    190 ; CHECK-NEXT: mov r0, [[REG]]
    191 ; CHECK-NEXT: ldaw [[REG]], sp[0]
    192 ; CHECK-NEXT: ldw r1, cp[.LCPI[[CNST0]]]
    193 ; CHECK-NEXT: ldw [[REG]], [[REG]][r1]
    194 ; CHECK-NEXT: ldaw sp, sp[65535]
    195 ; CHECK-NEXT: ldaw sp, sp[65535]
    196 ; CHECK-NEXT: ldaw sp, sp[65535]
    197 ; CHECK-NEXT: retsp 3399
    198 declare void @f5(i32*)
    199 define i32 @f6(i32 %i) {
    200 entry:
    201   %0 = alloca [200000 x i32]
    202   %1 = getelementptr inbounds [200000 x i32], [200000 x i32]* %0, i32 0, i32 0
    203   call void @f5(i32* %1)
    204   %2 = getelementptr inbounds [200000 x i32], [200000 x i32]* %0, i32 0, i32 199999
    205   call void @f5(i32* %2)
    206   ret i32 %i
    207 }
    208 
    209 ; FP + large frame: spill FP+SR+LR = entsp 2 + 256  + extsp 1
    210 ; CHECKFP-LABEL:f8
    211 ; CHECKFP: entsp 258
    212 ; CHECKFP-NEXT: stw r10, sp[1]
    213 ; CHECKFP-NEXT: ldaw r10, sp[0]
    214 ; CHECKFP-NEXT: mkmsk [[REG:r[0-9]+]], 8
    215 ; CHECKFP-NEXT: ldaw r0, r10{{\[}}[[REG]]{{\]}}
    216 ; CHECKFP-NEXT: extsp 1
    217 ; CHECKFP-NEXT: bl f5
    218 ; CHECKFP-NEXT: ldaw sp, sp[1]
    219 ; CHECKFP-NEXT: set sp, r10
    220 ; CHECKFP-NEXT: ldw r10, sp[1]
    221 ; CHECKFP-NEXT: retsp 258
    222 ;
    223 ; !FP + large frame: spill SR+SR+LR = entsp 3 + 256
    224 ; CHECK-LABEL:f8
    225 ; CHECK: entsp 257
    226 ; CHECK-NEXT: ldaw r0, sp[254]
    227 ; CHECK-NEXT: bl f5
    228 ; CHECK-NEXT: retsp 257
    229 define void @f8() nounwind {
    230 entry:
    231   %0 = alloca [256 x i32]
    232   %1 = getelementptr inbounds [256 x i32], [256 x i32]* %0, i32 0, i32 253
    233   call void @f5(i32* %1)
    234   ret void
    235 }
    236 
    237 ; FP + large frame: spill FP+SR+LR = entsp 2 + 32768  + extsp 1
    238 ; CHECKFP-LABEL:f9
    239 ; CHECKFP: entsp 32770
    240 ; CHECKFP-NEXT: stw r10, sp[1]
    241 ; CHECKFP-NEXT: ldaw r10, sp[0]
    242 ; CHECKFP-NEXT: ldc [[REG:r[0-9]+]], 32767
    243 ; CHECKFP-NEXT: ldaw r0, r10{{\[}}[[REG]]{{\]}}
    244 ; CHECKFP-NEXT: extsp 1
    245 ; CHECKFP-NEXT: bl f5
    246 ; CHECKFP-NEXT: ldaw sp, sp[1]
    247 ; CHECKFP-NEXT: set sp, r10
    248 ; CHECKFP-NEXT: ldw r10, sp[1]
    249 ; CHECKFP-NEXT: retsp 32770
    250 ;
    251 ; !FP + large frame: spill SR+SR+LR = entsp 3 + 32768
    252 ; CHECK-LABEL:f9
    253 ; CHECK: entsp 32771
    254 ; CHECK-NEXT: ldaw r0, sp[32768]
    255 ; CHECK-NEXT: bl f5
    256 ; CHECK-NEXT: retsp 32771
    257 define void @f9() nounwind {
    258 entry:
    259   %0 = alloca [32768 x i32]
    260   %1 = getelementptr inbounds [32768 x i32], [32768 x i32]* %0, i32 0, i32 32765
    261   call void @f5(i32* %1)
    262   ret void
    263 }
    264