Home | History | Annotate | Download | only in SystemZ
      1 ; Test saving and restoring of call-saved GPRs.
      2 ;
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
      4 
      5 ; This function should require all GPRs, but no other spill slots.  The caller
      6 ; allocates room for the GPR save slots, so we shouldn't need to allocate any
      7 ; extra space.
      8 ;
      9 ; The function only modifies the low 32 bits of each register, which in
     10 ; itself would allow STM and LM to be used instead of STMG and LMG.
     11 ; However, the ABI defines the offset of each register, so we always
     12 ; use the 64-bit form.
     13 ;
     14 ; Use a different address for the final store, so that we can check that
     15 ; %r15 isn't referenced again until after that.
     16 define void @f1(i32 *%ptr) {
     17 ; CHECK-LABEL: f1:
     18 ; CHECK: stmg %r6, %r15, 48(%r15)
     19 ; CHECK-NOT: %r15
     20 ; CHECK: .cfi_offset %r6, -112
     21 ; CHECK: .cfi_offset %r7, -104
     22 ; CHECK: .cfi_offset %r8, -96
     23 ; CHECK: .cfi_offset %r9, -88
     24 ; CHECK: .cfi_offset %r10, -80
     25 ; CHECK: .cfi_offset %r11, -72
     26 ; CHECK: .cfi_offset %r12, -64
     27 ; CHECK: .cfi_offset %r13, -56
     28 ; CHECK: .cfi_offset %r14, -48
     29 ; CHECK: .cfi_offset %r15, -40
     30 ; ...main function body...
     31 ; CHECK-NOT: %r15
     32 ; CHECK: st {{.*}}, 4(%r2)
     33 ; CHECK: lmg %r6, %r15, 48(%r15)
     34 ; CHECK: br %r14
     35   %l0 = load volatile i32 , i32 *%ptr
     36   %l1 = load volatile i32 , i32 *%ptr
     37   %l3 = load volatile i32 , i32 *%ptr
     38   %l4 = load volatile i32 , i32 *%ptr
     39   %l5 = load volatile i32 , i32 *%ptr
     40   %l6 = load volatile i32 , i32 *%ptr
     41   %l7 = load volatile i32 , i32 *%ptr
     42   %l8 = load volatile i32 , i32 *%ptr
     43   %l9 = load volatile i32 , i32 *%ptr
     44   %l10 = load volatile i32 , i32 *%ptr
     45   %l11 = load volatile i32 , i32 *%ptr
     46   %l12 = load volatile i32 , i32 *%ptr
     47   %l13 = load volatile i32 , i32 *%ptr
     48   %l14 = load volatile i32 , i32 *%ptr
     49   %add0 = add i32 %l0, %l0
     50   %add1 = add i32 %l1, %add0
     51   %add3 = add i32 %l3, %add1
     52   %add4 = add i32 %l4, %add3
     53   %add5 = add i32 %l5, %add4
     54   %add6 = add i32 %l6, %add5
     55   %add7 = add i32 %l7, %add6
     56   %add8 = add i32 %l8, %add7
     57   %add9 = add i32 %l9, %add8
     58   %add10 = add i32 %l10, %add9
     59   %add11 = add i32 %l11, %add10
     60   %add12 = add i32 %l12, %add11
     61   %add13 = add i32 %l13, %add12
     62   %add14 = add i32 %l14, %add13
     63   store volatile i32 %add0, i32 *%ptr
     64   store volatile i32 %add1, i32 *%ptr
     65   store volatile i32 %add3, i32 *%ptr
     66   store volatile i32 %add4, i32 *%ptr
     67   store volatile i32 %add5, i32 *%ptr
     68   store volatile i32 %add6, i32 *%ptr
     69   store volatile i32 %add7, i32 *%ptr
     70   store volatile i32 %add8, i32 *%ptr
     71   store volatile i32 %add9, i32 *%ptr
     72   store volatile i32 %add10, i32 *%ptr
     73   store volatile i32 %add11, i32 *%ptr
     74   store volatile i32 %add12, i32 *%ptr
     75   store volatile i32 %add13, i32 *%ptr
     76   %final = getelementptr i32, i32 *%ptr, i32 1
     77   store volatile i32 %add14, i32 *%final
     78   ret void
     79 }
     80 
     81 ; Like f1, but requires one fewer GPR.  We allocate the call-saved GPRs
     82 ; from %r14 down, so that the STMG/LMG sequences aren't any longer than
     83 ; they need to be.
     84 define void @f2(i32 *%ptr) {
     85 ; CHECK-LABEL: f2:
     86 ; CHECK: stmg %r7, %r15, 56(%r15)
     87 ; CHECK-NOT: %r15
     88 ; CHECK: .cfi_offset %r7, -104
     89 ; CHECK: .cfi_offset %r8, -96
     90 ; CHECK: .cfi_offset %r9, -88
     91 ; CHECK: .cfi_offset %r10, -80
     92 ; CHECK: .cfi_offset %r11, -72
     93 ; CHECK: .cfi_offset %r12, -64
     94 ; CHECK: .cfi_offset %r13, -56
     95 ; CHECK: .cfi_offset %r14, -48
     96 ; CHECK: .cfi_offset %r15, -40
     97 ; ...main function body...
     98 ; CHECK-NOT: %r15
     99 ; CHECK-NOT: %r6
    100 ; CHECK: st {{.*}}, 4(%r2)
    101 ; CHECK: lmg %r7, %r15, 56(%r15)
    102 ; CHECK: br %r14
    103   %l0 = load volatile i32 , i32 *%ptr
    104   %l1 = load volatile i32 , i32 *%ptr
    105   %l3 = load volatile i32 , i32 *%ptr
    106   %l4 = load volatile i32 , i32 *%ptr
    107   %l5 = load volatile i32 , i32 *%ptr
    108   %l7 = load volatile i32 , i32 *%ptr
    109   %l8 = load volatile i32 , i32 *%ptr
    110   %l9 = load volatile i32 , i32 *%ptr
    111   %l10 = load volatile i32 , i32 *%ptr
    112   %l11 = load volatile i32 , i32 *%ptr
    113   %l12 = load volatile i32 , i32 *%ptr
    114   %l13 = load volatile i32 , i32 *%ptr
    115   %l14 = load volatile i32 , i32 *%ptr
    116   %add0 = add i32 %l0, %l0
    117   %add1 = add i32 %l1, %add0
    118   %add3 = add i32 %l3, %add1
    119   %add4 = add i32 %l4, %add3
    120   %add5 = add i32 %l5, %add4
    121   %add7 = add i32 %l7, %add5
    122   %add8 = add i32 %l8, %add7
    123   %add9 = add i32 %l9, %add8
    124   %add10 = add i32 %l10, %add9
    125   %add11 = add i32 %l11, %add10
    126   %add12 = add i32 %l12, %add11
    127   %add13 = add i32 %l13, %add12
    128   %add14 = add i32 %l14, %add13
    129   store volatile i32 %add0, i32 *%ptr
    130   store volatile i32 %add1, i32 *%ptr
    131   store volatile i32 %add3, i32 *%ptr
    132   store volatile i32 %add4, i32 *%ptr
    133   store volatile i32 %add5, i32 *%ptr
    134   store volatile i32 %add7, i32 *%ptr
    135   store volatile i32 %add8, i32 *%ptr
    136   store volatile i32 %add9, i32 *%ptr
    137   store volatile i32 %add10, i32 *%ptr
    138   store volatile i32 %add11, i32 *%ptr
    139   store volatile i32 %add12, i32 *%ptr
    140   store volatile i32 %add13, i32 *%ptr
    141   %final = getelementptr i32, i32 *%ptr, i32 1
    142   store volatile i32 %add14, i32 *%final
    143   ret void
    144 }
    145 
    146 ; Like f1, but only needs one call-saved GPR, which ought to be %r14.
    147 define void @f3(i32 *%ptr) {
    148 ; CHECK-LABEL: f3:
    149 ; CHECK: stmg %r14, %r15, 112(%r15)
    150 ; CHECK-NOT: %r15
    151 ; CHECK: .cfi_offset %r14, -48
    152 ; CHECK: .cfi_offset %r15, -40
    153 ; ...main function body...
    154 ; CHECK-NOT: %r15
    155 ; CHECK-NOT: %r6
    156 ; CHECK-NOT: %r7
    157 ; CHECK-NOT: %r8
    158 ; CHECK-NOT: %r9
    159 ; CHECK-NOT: %r10
    160 ; CHECK-NOT: %r11
    161 ; CHECK-NOT: %r12
    162 ; CHECK-NOT: %r13
    163 ; CHECK: st {{.*}}, 4(%r2)
    164 ; CHECK: lmg %r14, %r15, 112(%r15)
    165 ; CHECK: br %r14
    166   %l0 = load volatile i32 , i32 *%ptr
    167   %l1 = load volatile i32 , i32 *%ptr
    168   %l3 = load volatile i32 , i32 *%ptr
    169   %l4 = load volatile i32 , i32 *%ptr
    170   %l5 = load volatile i32 , i32 *%ptr
    171   %l14 = load volatile i32 , i32 *%ptr
    172   %add0 = add i32 %l0, %l0
    173   %add1 = add i32 %l1, %add0
    174   %add3 = add i32 %l3, %add1
    175   %add4 = add i32 %l4, %add3
    176   %add5 = add i32 %l5, %add4
    177   %add14 = add i32 %l14, %add5
    178   store volatile i32 %add0, i32 *%ptr
    179   store volatile i32 %add1, i32 *%ptr
    180   store volatile i32 %add3, i32 *%ptr
    181   store volatile i32 %add4, i32 *%ptr
    182   store volatile i32 %add5, i32 *%ptr
    183   %final = getelementptr i32, i32 *%ptr, i32 1
    184   store volatile i32 %add14, i32 *%final
    185   ret void
    186 }
    187 
    188 ; This function should use all call-clobbered GPRs but no call-saved ones.
    189 ; It shouldn't need to touch the stack at all.
    190 define void @f4(i32 *%ptr) {
    191 ; CHECK-LABEL: f4:
    192 ; CHECK-NOT: %r15
    193 ; CHECK-NOT: %r6
    194 ; CHECK-NOT: %r7
    195 ; CHECK-NOT: %r8
    196 ; CHECK-NOT: %r9
    197 ; CHECK-NOT: %r10
    198 ; CHECK-NOT: %r11
    199 ; CHECK-NOT: %r12
    200 ; CHECK-NOT: %r13
    201 ; CHECK: br %r14
    202   %l0 = load volatile i32 , i32 *%ptr
    203   %l1 = load volatile i32 , i32 *%ptr
    204   %l3 = load volatile i32 , i32 *%ptr
    205   %l4 = load volatile i32 , i32 *%ptr
    206   %l5 = load volatile i32 , i32 *%ptr
    207   %add0 = add i32 %l0, %l0
    208   %add1 = add i32 %l1, %add0
    209   %add3 = add i32 %l3, %add1
    210   %add4 = add i32 %l4, %add3
    211   %add5 = add i32 %l5, %add4
    212   store volatile i32 %add0, i32 *%ptr
    213   store volatile i32 %add1, i32 *%ptr
    214   store volatile i32 %add3, i32 *%ptr
    215   store volatile i32 %add4, i32 *%ptr
    216   %final = getelementptr i32, i32 *%ptr, i32 1
    217   store volatile i32 %add5, i32 *%final
    218   ret void
    219 }
    220