Home | History | Annotate | Download | only in PowerPC
      1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
      2 ; RUN:   -mcpu=pwr8 < %s | FileCheck %s -check-prefix=CHECK-LE \
      3 ; RUN:   --implicit-check-not xxswapd
      4 
      5 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
      6 ; RUN:   -mcpu=pwr8 < %s | FileCheck %s -check-prefix=CHECK-BE
      7 
      8 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
      9 ; RUN:   -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-NOVSX
     10 
     11 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
     12 ; RUN:   -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-NOVSX \
     13 ; RUN:   --implicit-check-not xxswapd
     14 
     15 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
     16 ; RUN:   -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-BE-NOVSX
     17 
     18 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
     19 ; RUN:   -mcpu=pwr8 -mattr=-vsx < %s | \
     20 ; RUN:   FileCheck %s -check-prefix=CHECK-LE-NOVSX --implicit-check-not xxswapd
     21 
     22 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
     23 ; RUN:   -mcpu=pwr9 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
     24 ; RUN:   FileCheck %s -check-prefix=CHECK-P9 --implicit-check-not xxswapd
     25 
     26 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
     27 ; RUN:   -mcpu=pwr9 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-NOVSX \
     28 ; RUN:   --implicit-check-not xxswapd
     29 
     30 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
     31 ; RUN:   -mcpu=pwr9 -mattr=-power9-vector -mattr=-direct-move < %s | \
     32 ; RUN:   FileCheck %s -check-prefix=CHECK-LE --implicit-check-not xxswapd
     33 
     34 @x = common global <1 x i128> zeroinitializer, align 16
     35 @y = common global <1 x i128> zeroinitializer, align 16
     36 @a = common global i128 zeroinitializer, align 16
     37 @b = common global i128 zeroinitializer, align 16
     38 
     39 ; VSX:
     40 ;   %a is passed in register 34
     41 ;   The value of 1 is stored in the TOC.
     42 ;   On LE, ensure the value of 1 is swapped before being used (using xxswapd).
     43 ; VMX (no VSX): 
     44 ;   %a is passed in register 2
     45 ;   The value of 1 is stored in the TOC.
     46 ;   No swaps are necessary when using P8 Vector instructions on LE
     47 define <1 x i128> @v1i128_increment_by_one(<1 x i128> %a) nounwind {
     48        %tmp = add <1 x i128> %a, <i128 1>
     49        ret <1 x i128> %tmp  
     50 
     51 ; FIXME: Seems a 128-bit literal is materialized by loading from the TOC. There
     52 ;        should be a better way of doing this.
     53 
     54 ; CHECK-LE-LABEL: @v1i128_increment_by_one
     55 ; CHECK-LE: lxvd2x [[VAL:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
     56 ; CHECK-LE: xxswapd 35, [[VAL]]
     57 ; CHECK-LE: vadduqm 2, 2, 3
     58 ; CHECK-LE: blr
     59 
     60 ; CHECK-P9-LABEL: @v1i128_increment_by_one
     61 ; The below FIXME is due to the lowering for BUILD_VECTOR that will be fixed
     62 ; in a subsequent patch.
     63 ; FIXME: li [[R1:r[0-9]+]], 1
     64 ; FIXME: li [[R2:r[0-9]+]], 0
     65 ; FIXME: mtvsrdd [[V1:v[0-9]+]], [[R2]], [[R1]]
     66 ; CHECK-P9: lxvx [[V1:v[0-9]+]]
     67 ; CHECK-P9: vadduqm v2, v2, [[V1]]
     68 ; CHECK-P9: blr
     69 
     70 ; CHECK-BE-LABEL: @v1i128_increment_by_one
     71 ; CHECK-BE: lxvd2x 35, {{[0-9]+}}, {{[0-9]+}}
     72 ; CHECK-BE-NOT: xxswapd 
     73 ; CHECK-BE: vadduqm 2, 2, 3 
     74 ; CHECK-BE-NOT: xxswapd 34, {{[0-9]+}}
     75 ; CHECK-BE: blr
     76 
     77 ; CHECK-NOVSX-LABEL: @v1i128_increment_by_one
     78 ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}}
     79 ; CHECK-NOVSX-NOT: stxvd2x {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
     80 ; CHECK-NOVSX: lvx [[VAL:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
     81 ; CHECK-NOVSX-NOT: lxvd2x {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
     82 ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}}
     83 ; CHECK-NOVSX: vadduqm 2, 2, [[VAL]]
     84 ; CHECK-NOVSX: blr
     85 }
     86 
     87 ; VSX:
     88 ;   %a is passed in register 34
     89 ;   %b is passed in register 35
     90 ;   No swaps are necessary when using P8 Vector instructions on LE
     91 ; VMX (no VSX):
     92 ;   %a is passewd in register 2
     93 ;   %b is passed in register 3
     94 ;   On LE, do not need to swap contents of 2 and 3 because the lvx/stvx 
     95 ;   instructions no not swap elements
     96 define <1 x i128> @v1i128_increment_by_val(<1 x i128> %a, <1 x i128> %b) nounwind {
     97        %tmp = add <1 x i128> %a, %b
     98        ret <1 x i128> %tmp
     99 
    100 ; CHECK-LE-LABEL: @v1i128_increment_by_val
    101 ; CHECK-LE-NOT: xxswapd
    102 ; CHECK-LE: adduqm 2, 2, 3
    103 ; CHECK-LE: blr
    104 
    105 ; CHECK-BE-LABEL: @v1i128_increment_by_val
    106 ; CHECK-BE-NOT: xxswapd {{[0-9]+}}, 34
    107 ; CHECK-BE-NOT: xxswapd {{[0-9]+}}, 35
    108 ; CHECK-BE-NOT: xxswapd 34, [[RESULT]]
    109 ; CHECK-BE: adduqm 2, 2, 3
    110 ; CHECK-BE: blr
    111 
    112 ; CHECK-NOVSX-LABEL: @v1i128_increment_by_val
    113 ; CHECK-NOVSX-NOT: xxswapd 34, [[RESULT]]
    114 ; CHECK-NOVSX: adduqm 2, 2, 3
    115 ; CHECK-NOVSX: blr
    116 }
    117 
    118 ; Little Endian (VSX and VMX):
    119 ;   Lower 64-bits of %a are passed in register 3
    120 ;   Upper 64-bits of %a are passed in register 4
    121 ;   Increment lower 64-bits using addic (immediate value of 1)
    122 ;   Increment upper 64-bits using add zero extended
    123 ;   Results are placed in registers 3 and 4
    124 ; Big Endian (VSX and VMX)
    125 ;   Lower 64-bits of %a are passed in register 4
    126 ;   Upper 64-bits of %a are passed in register 3
    127 ;   Increment lower 64-bits using addic (immediate value of 1)
    128 ;   Increment upper 64-bits using add zero extended
    129 ;   Results are placed in registers 3 and 4
    130 define i128 @i128_increment_by_one(i128 %a) nounwind {
    131        %tmp =  add i128 %a,  1
    132        ret i128 %tmp
    133 ; CHECK-LE-LABEL: @i128_increment_by_one
    134 ; CHECK-LE: addic 3, 3, 1
    135 ; CHECK-LE-NEXT: addze 4, 4
    136 ; CHECK-LE: blr
    137 
    138 ; CHECK-BE-LABEL: @i128_increment_by_one
    139 ; CHECK-BE: addic 4, 4, 1
    140 ; CHECK-BE-NEXT: addze 3, 3
    141 ; CHECK-BE: blr
    142 
    143 ; CHECK-LE-NOVSX-LABEL: @i128_increment_by_one
    144 ; CHECK-LE-NOVSX: addic 3, 3, 1
    145 ; CHECK-LE-NOVSX-NEXT: addze 4, 4
    146 ; CHECK-LE-NOVSX: blr
    147 
    148 ; CHECK-BE-NOVSX-LABEL: @i128_increment_by_one
    149 ; CHECK-BE-NOVSX: addic 4, 4, 1
    150 ; CHECK-BE-NOVSX-NEXT: addze 3, 3
    151 ; CHECK-BE-NOVSX: blr
    152 }
    153 
    154 ; Little Endian (VSX and VMX):
    155 ;   Lower 64-bits of %a are passed in register 3
    156 ;   Upper 64-bits of %a are passed in register 4
    157 ;   Lower 64-bits of %b are passed in register 5
    158 ;   Upper 64-bits of %b are passed in register 6
    159 ;   Add the lower 64-bits using addc on registers 3 and 5
    160 ;   Add the upper 64-bits using adde on registers 4 and 6
    161 ;   Registers 3 and 4 should hold the result
    162 ; Big Endian (VSX and VMX):
    163 ;   Upper 64-bits of %a are passed in register 3
    164 ;   Lower 64-bits of %a are passed in register 4
    165 ;   Upper 64-bits of %b are passed in register 5
    166 ;   Lower 64-bits of %b are passed in register 6
    167 ;   Add the lower 64-bits using addc on registers 4 and 6
    168 ;   Add the upper 64-bits using adde on registers 3 and 5
    169 ;   Registers 3 and 4 should hold the result
    170 define i128 @i128_increment_by_val(i128 %a, i128 %b) nounwind {
    171        %tmp =  add i128 %a, %b
    172        ret i128 %tmp
    173 ; CHECK-LE-LABEL: @i128_increment_by_val
    174 ; CHECK-LE: addc 3, 3, 5
    175 ; CHECK-LE-NEXT: adde 4, 4, 6
    176 ; CHECK-LE: blr
    177 
    178 ; CHECK-BE-LABEL: @i128_increment_by_val
    179 ; CHECK-BE: addc 4, 4, 6
    180 ; CHECK-BE-NEXT: adde 3, 3, 5
    181 ; CHECK-BE: blr
    182 
    183 ; CHECK-LE-NOVSX-LABEL: @i128_increment_by_val
    184 ; CHECK-LE-NOVSX: addc 3, 3, 5
    185 ; CHECK-LE-NOVSX-NEXT: adde 4, 4, 6
    186 ; CHECK-LE-NOVSX: blr
    187 
    188 ; CHECK-BE-NOVSX-LABEL: @i128_increment_by_val
    189 ; CHECK-BE-NOVSX: addc 4, 4, 6
    190 ; CHECK-BE-NOVSX-NEXT: adde 3, 3, 5
    191 ; CHECK-BE-NOVSX: blr
    192 }
    193 
    194 
    195 ; Callsites for the routines defined above. 
    196 ; Ensure the parameters are loaded in the same order that is expected by the 
    197 ; callee. See comments for individual functions above for details on registers
    198 ; used for parameters.
    199 define <1 x i128> @call_v1i128_increment_by_one() nounwind {
    200        %tmp = load <1 x i128>, <1 x i128>* @x, align 16
    201        %ret = call <1 x i128> @v1i128_increment_by_one(<1 x i128> %tmp)
    202        ret <1 x i128> %ret
    203 
    204 ; CHECK-LE-LABEL: @call_v1i128_increment_by_one
    205 ; CHECK-LE: lvx 2, {{[0-9]+}}, {{[0-9]+}}
    206 ; CHECK-LE: bl v1i128_increment_by_one
    207 ; CHECK-LE: blr
    208 
    209 ; CHECK-P9-LABEL: @call_v1i128_increment_by_one
    210 ; CHECK-P9: lxv
    211 ; CHECK-P9: bl v1i128_increment_by_one
    212 ; CHECK-P9: blr
    213 
    214 ; CHECK-BE-LABEL: @call_v1i128_increment_by_one
    215 ; CHECK-BE: lxvw4x 34, {{[0-9]+}}, {{[0-9]+}}
    216 ; CHECK-BE-NOT: xxswapd 34, {{[0-9]+}}
    217 ; CHECK-BE: bl v1i128_increment_by_one
    218 ; CHECK-BE: blr
    219 
    220 ; CHECK-NOVSX-LABEL: @call_v1i128_increment_by_one
    221 ; CHECK-NOVSX: lvx 2, {{[0-9]+}}, {{[0-9]+}}
    222 ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}}
    223 ; CHECK-NOVSX: bl v1i128_increment_by_one
    224 ; CHECK-NOVSX: blr
    225 }
    226 
    227 define <1 x i128> @call_v1i128_increment_by_val() nounwind {
    228        %tmp = load <1 x i128>, <1 x i128>* @x, align 16
    229        %tmp2 = load <1 x i128>, <1 x i128>* @y, align 16
    230        %ret = call <1 x i128> @v1i128_increment_by_val(<1 x i128> %tmp, <1 x i128> %tmp2)
    231        ret <1 x i128> %ret
    232 
    233 ; CHECK-LE-LABEL: @call_v1i128_increment_by_val
    234 ; CHECK-LE: lvx 2, {{[0-9]+}}, {{[0-9]+}}
    235 ; CHECK-LE: lvx 3, {{[0-9]+}}, {{[0-9]+}}
    236 ; CHECK-LE: bl v1i128_increment_by_val
    237 ; CHECK-LE: blr
    238 
    239 ; CHECK-P9-LABEL: @call_v1i128_increment_by_val
    240 ; CHECK-P9-DAG: lxvx v2
    241 ; CHECK-P9-DAG: lxvx v3
    242 ; CHECK-P9: bl v1i128_increment_by_val
    243 ; CHECK-P9: blr
    244 
    245 ; CHECK-BE-LABEL: @call_v1i128_increment_by_val
    246 
    247 
    248 ; CHECK-BE-DAG: lxvw4x 35, {{[0-9]+}}, {{[0-9]+}}
    249 ; CHECK-BE-NOT: xxswapd 34, {{[0-9]+}}
    250 ; CHECK-BE-NOT: xxswapd 35, {{[0-9]+}}
    251 ; CHECK-BE: bl v1i128_increment_by_val
    252 ; CHECK-BE: blr
    253 
    254 ; CHECK-NOVSX-LABEL: @call_v1i128_increment_by_val
    255 ; CHECK-NOVSX-DAG: lvx 2, {{[0-9]+}}, {{[0-9]+}}
    256 ; CHECK-NOVSX-DAG: lvx 3, {{[0-9]+}}, {{[0-9]+}}
    257 ; CHECK-NOVSX-NOT: xxswapd 34, {{[0-9]+}}
    258 ; CHECK-NOVSX-NOT: xxswapd 35, {{[0-9]+}}
    259 ; CHECK-NOVSX: bl v1i128_increment_by_val
    260 ; CHECK-NOVSX: blr
    261 
    262 }
    263 
    264 define i128 @call_i128_increment_by_one() nounwind {
    265        %tmp = load i128, i128* @a, align 16
    266        %ret = call i128 @i128_increment_by_one(i128 %tmp)
    267        ret i128 %ret
    268 ;       %ret4 = call i128 @i128_increment_by_val(i128 %tmp2, i128 %tmp2)
    269 ; CHECK-LE-LABEL: @call_i128_increment_by_one
    270 ; CHECK-LE-DAG: ld 3, 0([[BASEREG:[0-9]+]])
    271 ; CHECK-LE-DAG: ld 4, 8([[BASEREG]])
    272 ; CHECK-LE: bl i128_increment_by_one
    273 ; CHECK-LE: blr
    274 
    275 ; CHECK-BE-LABEL: @call_i128_increment_by_one
    276 ; CHECK-BE-DAG: ld 3, 0([[BASEREG:[0-9]+]])
    277 ; CHECK-BE-DAG: ld 4, 8([[BASEREG]])
    278 ; CHECK-BE: bl i128_increment_by_one
    279 ; CHECK-BE: blr
    280 
    281 ; CHECK-NOVSX-LABEL: @call_i128_increment_by_one
    282 ; CHECK-NOVSX-DAG: ld 3, 0([[BASEREG:[0-9]+]])
    283 ; CHECK-NOVSX-DAG: ld 4, 8([[BASEREG]])
    284 ; CHECK-NOVSX: bl i128_increment_by_one
    285 ; CHECK-NOVSX: blr
    286 }
    287 
    288 define i128 @call_i128_increment_by_val() nounwind {
    289        %tmp = load i128, i128* @a, align 16
    290        %tmp2 = load i128, i128* @b, align 16
    291        %ret = call i128 @i128_increment_by_val(i128 %tmp, i128 %tmp2)
    292        ret i128 %ret
    293 ; CHECK-LE-LABEL: @call_i128_increment_by_val
    294 ; CHECK-LE-DAG: ld 3, 0([[P1BASEREG:[0-9]+]])
    295 ; CHECK-LE-DAG: ld 4, 8([[P1BASEREG]])
    296 ; CHECK-LE-DAG: ld 5, 0([[P2BASEREG:[0-9]+]])
    297 ; CHECK-LE-DAG: ld 6, 8([[P2BASEREG]])
    298 ; CHECK-LE: bl i128_increment_by_val
    299 ; CHECK-LE: blr
    300 
    301 ; CHECK-BE-LABEL: @call_i128_increment_by_val
    302 ; CHECK-BE-DAG: ld 3, 0([[P1BASEREG:[0-9]+]])
    303 ; CHECK-BE-DAG: ld 4, 8([[P1BASEREG]])
    304 ; CHECK-BE-DAG: ld 5, 0([[P2BASEREG:[0-9]+]])
    305 ; CHECK-BE-DAG: ld 6, 8([[P2BASEREG]])
    306 ; CHECK-BE: bl i128_increment_by_val
    307 ; CHECK-BE: blr
    308 
    309 ; CHECK-NOVSX-LABEL: @call_i128_increment_by_val
    310 ; CHECK-NOVSX-DAG: ld 3, 0([[P1BASEREG:[0-9]+]])
    311 ; CHECK-NOVSX-DAG: ld 4, 8([[P1BASEREG]])
    312 ; CHECK-NOVSX-DAG: ld 5, 0([[P2BASEREG:[0-9]+]])
    313 ; CHECK-NOVSX-DAG: ld 6, 8([[P2BASEREG]])
    314 ; CHECK-NOVSX: bl i128_increment_by_val
    315 ; CHECK-NOVSX: blr
    316 }
    317 
    318 
    319