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