Home | History | Annotate | Download | only in Mips
      1 ; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32   -relocation-model=pic < %s | \
      2 ; RUN:   FileCheck %s -check-prefixes=ALL,MIPS32-ANY,NO-SEB-SEH,CHECK-EL,NOT-MICROMIPS
      3 ; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32r2 -relocation-model=pic -verify-machineinstrs < %s | \
      4 ; RUN:   FileCheck %s -check-prefixes=ALL,MIPS32-ANY,HAS-SEB-SEH,CHECK-EL,NOT-MICROMIPS
      5 ; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32r6 -relocation-model=pic -verify-machineinstrs < %s | \
      6 ; RUN:   FileCheck %s -check-prefixes=ALL,MIPS32-ANY,HAS-SEB-SEH,CHECK-EL,MIPSR6
      7 ; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips4    -relocation-model=pic < %s | \
      8 ; RUN:   FileCheck %s -check-prefixes=ALL,MIPS64-ANY,NO-SEB-SEH,CHECK-EL,NOT-MICROMIPS
      9 ; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips64   -relocation-model=pic < %s | \
     10 ; RUN:   FileCheck %s -check-prefixes=ALL,MIPS64-ANY,NO-SEB-SEH,CHECK-EL,NOT-MICROMIPS
     11 ; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips64r2 -relocation-model=pic -verify-machineinstrs < %s | \
     12 ; RUN:   FileCheck %s -check-prefixes=ALL,MIPS64-ANY,HAS-SEB-SEH,CHECK-EL,NOT-MICROMIPS
     13 ; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips64r6 -relocation-model=pic < %s | \
     14 ; RUN:   FileCheck %s -check-prefixes=ALL,MIPS64-ANY,HAS-SEB-SEH,CHECK-EL,MIPSR6
     15 ; RUN: llc -march=mips64 -O0 -mcpu=mips64r6 -relocation-model=pic -verify-machineinstrs < %s | \
     16 ; RUN:   FileCheck %s -check-prefixes=ALL-LABEL,MIPS64-ANY,O0
     17 ; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32r2 -mattr=micromips -relocation-model=pic < %s | \
     18 ; RUN:   FileCheck %s -check-prefixes=ALL,MIPS32-ANY,HAS-SEB-SEH,CHECK-EL,MICROMIPS
     19 
     20 ; Keep one big-endian check so that we don't reduce testing, but don't add more
     21 ; since endianness doesn't affect the body of the atomic operations.
     22 ; RUN: llc -march=mips   --disable-machine-licm -mcpu=mips32 -relocation-model=pic < %s | \
     23 ; RUN:   FileCheck %s -check-prefixes=ALL,MIPS32-ANY,NO-SEB-SEH,CHECK-EB,NOT-MICROMIPS
     24 
     25 @x = common global i32 0, align 4
     26 
     27 define i32 @AtomicLoadAdd32(i32 signext %incr) nounwind {
     28 entry:
     29   %0 = atomicrmw add i32* @x, i32 %incr monotonic
     30   ret i32 %0
     31 
     32 ; ALL-LABEL: AtomicLoadAdd32:
     33 
     34 ; MIPS32-ANY:    lw      $[[R0:[0-9]+]], %got(x)
     35 ; MIPS64-ANY:    ld      $[[R0:[0-9]+]], %got_disp(x)(
     36 
     37 ; O0:        $[[BB0:[A-Z_0-9]+]]:
     38 ; O0:            ld      $[[R1:[0-9]+]]
     39 ; O0-NEXT:       ll      $[[R2:[0-9]+]], 0($[[R1]])
     40 
     41 ; ALL:       $[[BB0:[A-Z_0-9]+]]:
     42 ; ALL:           ll      $[[R3:[0-9]+]], 0($[[R0]])
     43 ; ALL:           addu    $[[R4:[0-9]+]], $[[R3]], $4
     44 ; ALL:           sc      $[[R4]], 0($[[R0]])
     45 ; NOT-MICROMIPS: beqz    $[[R4]], $[[BB0]]
     46 ; MICROMIPS:     beqzc   $[[R4]], $[[BB0]]
     47 ; MIPSR6:        beqzc   $[[R4]], $[[BB0]]
     48 }
     49 
     50 define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
     51 entry:
     52   %0 = atomicrmw nand i32* @x, i32 %incr monotonic
     53   ret i32 %0
     54 
     55 ; ALL-LABEL: AtomicLoadNand32:
     56 
     57 ; MIPS32-ANY:    lw      $[[R0:[0-9]+]], %got(x)
     58 ; MIPS64-ANY:    ld      $[[R0:[0-9]+]], %got_disp(x)(
     59 
     60 
     61 
     62 ; ALL:       $[[BB0:[A-Z_0-9]+]]:
     63 ; ALL:           ll      $[[R1:[0-9]+]], 0($[[R0]])
     64 ; ALL:           and     $[[R3:[0-9]+]], $[[R1]], $4
     65 ; ALL:           nor     $[[R2:[0-9]+]], $zero, $[[R3]]
     66 ; ALL:           sc      $[[R2]], 0($[[R0]])
     67 ; NOT-MICROMIPS: beqz    $[[R2]], $[[BB0]]
     68 ; MICROMIPS:     beqzc   $[[R2]], $[[BB0]]
     69 ; MIPSR6:        beqzc   $[[R2]], $[[BB0]]
     70 }
     71 
     72 define i32 @AtomicSwap32(i32 signext %newval) nounwind {
     73 entry:
     74   %newval.addr = alloca i32, align 4
     75   store i32 %newval, i32* %newval.addr, align 4
     76   %tmp = load i32, i32* %newval.addr, align 4
     77   %0 = atomicrmw xchg i32* @x, i32 %tmp monotonic
     78   ret i32 %0
     79 
     80 ; ALL-LABEL: AtomicSwap32:
     81 
     82 ; MIPS32-ANY:    lw      $[[R0:[0-9]+]], %got(x)
     83 ; MIPS64-ANY:    ld      $[[R0:[0-9]+]], %got_disp(x)
     84 
     85 ; ALL:       $[[BB0:[A-Z_0-9]+]]:
     86 ; ALL:           ll      ${{[0-9]+}}, 0($[[R0]])
     87 ; ALL:           sc      $[[R2:[0-9]+]], 0($[[R0]])
     88 ; NOT-MICROMIPS: beqz    $[[R2]], $[[BB0]]
     89 ; MICROMIPS:     beqzc   $[[R2]], $[[BB0]]
     90 ; MIPSR6:        beqzc   $[[R2]], $[[BB0]]
     91 }
     92 
     93 define i32 @AtomicCmpSwap32(i32 signext %oldval, i32 signext %newval) nounwind {
     94 entry:
     95   %newval.addr = alloca i32, align 4
     96   store i32 %newval, i32* %newval.addr, align 4
     97   %tmp = load i32, i32* %newval.addr, align 4
     98   %0 = cmpxchg i32* @x, i32 %oldval, i32 %tmp monotonic monotonic
     99   %1 = extractvalue { i32, i1 } %0, 0
    100   ret i32 %1
    101 
    102 ; ALL-LABEL: AtomicCmpSwap32:
    103 
    104 ; MIPS32-ANY:    lw      $[[R0:[0-9]+]], %got(x)
    105 ; MIPS64-ANY:    ld      $[[R0:[0-9]+]], %got_disp(x)(
    106 
    107 ; ALL:       $[[BB0:[A-Z_0-9]+]]:
    108 ; ALL:           ll      $2, 0($[[R0]])
    109 ; NOT-MICROMIPS: bne     $2, $4, $[[BB1:[A-Z_0-9]+]]
    110 ; MICROMIPS:     bne     $2, $4, $[[BB1:[A-Z_0-9]+]]
    111 ; MIPSR6:        bnec    $2, $4, $[[BB1:[A-Z_0-9]+]]
    112 ; ALL:           sc      $[[R2:[0-9]+]], 0($[[R0]])
    113 ; NOT-MICROMIPS: beqz    $[[R2]], $[[BB0]]
    114 ; MICROMIPS:     beqzc   $[[R2]], $[[BB0]]
    115 ; MIPSR6:        beqzc   $[[R2]], $[[BB0]]
    116 ; ALL:       $[[BB1]]:
    117 }
    118 
    119 
    120 
    121 @y = common global i8 0, align 1
    122 
    123 define signext i8 @AtomicLoadAdd8(i8 signext %incr) nounwind {
    124 entry:
    125   %0 = atomicrmw add i8* @y, i8 %incr monotonic
    126   ret i8 %0
    127 
    128 ; ALL-LABEL: AtomicLoadAdd8:
    129 
    130 ; MIPS32-ANY:    lw      $[[R0:[0-9]+]], %got(y)
    131 ; MIPS64-ANY:    ld      $[[R0:[0-9]+]], %got_disp(y)(
    132 
    133 ; ALL:           addiu   $[[R1:[0-9]+]], $zero, -4
    134 ; ALL:           and     $[[R2:[0-9]+]], $[[R0]], $[[R1]]
    135 ; ALL:           andi    $[[R3:[0-9]+]], $[[R0]], 3
    136 ; CHECK-EB:      xori    $[[R4:[0-9]+]], $[[R3]], 3
    137 ; CHECK-EB:      sll     $[[R5:[0-9]+]], $[[R4]], 3
    138 ; CHECK-EL:      sll     $[[R5:[0-9]+]], $[[R3]], 3
    139 ; ALL:           ori     $[[R6:[0-9]+]], $zero, 255
    140 ; ALL:           sllv    $[[R7:[0-9]+]], $[[R6]], $[[R5]]
    141 ; ALL:           nor     $[[R8:[0-9]+]], $zero, $[[R7]]
    142 ; ALL:           sllv    $[[R9:[0-9]+]], $4, $[[R5]]
    143 
    144 ; O0:        $[[BB0:[A-Z_0-9]+]]:
    145 ; O0:            ld      $[[R10:[0-9]+]]
    146 ; O0-NEXT:       ll      $[[R11:[0-9]+]], 0($[[R10]])
    147 
    148 ; ALL:       $[[BB0:[A-Z_0-9]+]]:
    149 ; ALL:           ll      $[[R12:[0-9]+]], 0($[[R2]])
    150 ; ALL:           addu    $[[R13:[0-9]+]], $[[R12]], $[[R9]]
    151 ; ALL:           and     $[[R14:[0-9]+]], $[[R13]], $[[R7]]
    152 ; ALL:           and     $[[R15:[0-9]+]], $[[R12]], $[[R8]]
    153 ; ALL:           or      $[[R16:[0-9]+]], $[[R15]], $[[R14]]
    154 ; ALL:           sc      $[[R16]], 0($[[R2]])
    155 ; NOT-MICROMIPS: beqz    $[[R16]], $[[BB0]]
    156 ; MICROMIPS:     beqzc   $[[R16]], $[[BB0]]
    157 ; MIPSR6:        beqzc   $[[R16]], $[[BB0]]
    158 
    159 ; ALL:           and     $[[R17:[0-9]+]], $[[R12]], $[[R7]]
    160 ; ALL:           srlv    $[[R18:[0-9]+]], $[[R17]], $[[R5]]
    161 
    162 ; NO-SEB-SEH:    sll     $[[R19:[0-9]+]], $[[R18]], 24
    163 ; NO-SEB-SEH:    sra     $2, $[[R19]], 24
    164 
    165 ; HAS-SEB-SEH:   seb     $2, $[[R18]]
    166 }
    167 
    168 define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind {
    169 entry:
    170   %0 = atomicrmw sub i8* @y, i8 %incr monotonic
    171   ret i8 %0
    172 
    173 ; ALL-LABEL: AtomicLoadSub8:
    174 
    175 ; MIPS32-ANY: lw      $[[R0:[0-9]+]], %got(y)
    176 ; MIPS64-ANY: ld      $[[R0:[0-9]+]], %got_disp(y)(
    177 
    178 ; ALL:        addiu   $[[R1:[0-9]+]], $zero, -4
    179 ; ALL:        and     $[[R2:[0-9]+]], $[[R0]], $[[R1]]
    180 ; ALL:        andi    $[[R3:[0-9]+]], $[[R0]], 3
    181 ; CHECK-EL:   sll     $[[R5:[0-9]+]], $[[R3]], 3
    182 ; CHECK-EB:   xori    $[[R4:[0-9]+]], $[[R3]], 3
    183 ; CHECK-EB:   sll     $[[R5:[0-9]+]], $[[R4]], 3
    184 ; ALL:        ori     $[[R6:[0-9]+]], $zero, 255
    185 ; ALL:        sllv    $[[R7:[0-9]+]], $[[R6]], $[[R5]]
    186 ; ALL:        nor     $[[R8:[0-9]+]], $zero, $[[R7]]
    187 ; ALL:        sllv    $[[R9:[0-9]+]], $4, $[[R5]]
    188 
    189 ; O0:        $[[BB0:[A-Z_0-9]+]]:
    190 ; O0:            ld      $[[R10:[0-9]+]]
    191 ; O0-NEXT:       ll      $[[R11:[0-9]+]], 0($[[R10]])
    192 
    193 ; ALL:    $[[BB0:[A-Z_0-9]+]]:
    194 ; ALL:        ll      $[[R12:[0-9]+]], 0($[[R2]])
    195 ; ALL:        subu    $[[R13:[0-9]+]], $[[R12]], $[[R9]]
    196 ; ALL:        and     $[[R14:[0-9]+]], $[[R13]], $[[R7]]
    197 ; ALL:        and     $[[R15:[0-9]+]], $[[R12]], $[[R8]]
    198 ; ALL:        or      $[[R16:[0-9]+]], $[[R15]], $[[R14]]
    199 ; ALL:        sc      $[[R16]], 0($[[R2]])
    200 ; NOT-MICROMIPS: beqz    $[[R16]], $[[BB0]]
    201 ; MICROMIPS:  beqzc   $[[R16]], $[[BB0]]
    202 ; MIPSR6:     beqzc   $[[R16]], $[[BB0]]
    203 
    204 ; ALL:        and     $[[R17:[0-9]+]], $[[R12]], $[[R7]]
    205 ; ALL:        srlv    $[[R18:[0-9]+]], $[[R17]], $[[R5]]
    206 
    207 ; NO-SEB-SEH: sll     $[[R19:[0-9]+]], $[[R18]], 24
    208 ; NO-SEB-SEH: sra     $2, $[[R19]], 24
    209 
    210 ; HAS-SEB-SEH:seb     $2, $[[R18]]
    211 }
    212 
    213 define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind {
    214 entry:
    215   %0 = atomicrmw nand i8* @y, i8 %incr monotonic
    216   ret i8 %0
    217 
    218 ; ALL-LABEL: AtomicLoadNand8:
    219 
    220 ; MIPS32-ANY:    lw      $[[R0:[0-9]+]], %got(y)
    221 ; MIPS64-ANY:    ld      $[[R0:[0-9]+]], %got_disp(y)(
    222 
    223 ; ALL:           addiu   $[[R1:[0-9]+]], $zero, -4
    224 ; ALL:           and     $[[R2:[0-9]+]], $[[R0]], $[[R1]]
    225 ; ALL:           andi    $[[R3:[0-9]+]], $[[R0]], 3
    226 ; CHECK-EL:      sll     $[[R5:[0-9]+]], $[[R3]], 3
    227 ; CHECK-EB:      xori    $[[R4:[0-9]+]], $[[R3]], 3
    228 ; CHECK-EB:      sll     $[[R5:[0-9]+]], $[[R4]], 3
    229 ; ALL:           ori     $[[R6:[0-9]+]], $zero, 255
    230 ; ALL:           sllv    $[[R7:[0-9]+]], $[[R6]], $[[R5]]
    231 ; ALL:           nor     $[[R8:[0-9]+]], $zero, $[[R7]]
    232 ; ALL:           sllv    $[[R9:[0-9]+]], $4, $[[R5]]
    233 
    234 ; O0:        $[[BB0:[A-Z_0-9]+]]:
    235 ; O0:            ld      $[[R10:[0-9]+]]
    236 ; O0-NEXT:       ll      $[[R11:[0-9]+]], 0($[[R10]])
    237 
    238 ; ALL:       $[[BB0:[A-Z_0-9]+]]:
    239 ; ALL:           ll      $[[R12:[0-9]+]], 0($[[R2]])
    240 ; ALL:           and     $[[R13:[0-9]+]], $[[R12]], $[[R9]]
    241 ; ALL:           nor     $[[R14:[0-9]+]], $zero, $[[R13]]
    242 ; ALL:           and     $[[R15:[0-9]+]], $[[R14]], $[[R7]]
    243 ; ALL:           and     $[[R16:[0-9]+]], $[[R12]], $[[R8]]
    244 ; ALL:           or      $[[R17:[0-9]+]], $[[R16]], $[[R15]]
    245 ; ALL:           sc      $[[R17]], 0($[[R2]])
    246 ; NOT-MICROMIPS: beqz    $[[R17]], $[[BB0]]
    247 ; MICROMIPS:     beqzc   $[[R17]], $[[BB0]]
    248 ; MIPSR6:        beqzc   $[[R17]], $[[BB0]]
    249 
    250 ; ALL:           and     $[[R18:[0-9]+]], $[[R12]], $[[R7]]
    251 ; ALL:           srlv    $[[R19:[0-9]+]], $[[R18]], $[[R5]]
    252 
    253 ; NO-SEB-SEH:    sll     $[[R20:[0-9]+]], $[[R19]], 24
    254 ; NO-SEB-SEH:    sra     $2, $[[R20]], 24
    255 
    256 ; HAS-SEB-SEH:   seb     $2, $[[R19]]
    257 }
    258 
    259 define signext i8 @AtomicSwap8(i8 signext %newval) nounwind {
    260 entry:
    261   %0 = atomicrmw xchg i8* @y, i8 %newval monotonic
    262   ret i8 %0
    263 
    264 ; ALL-LABEL: AtomicSwap8:
    265 
    266 ; MIPS32-ANY:    lw      $[[R0:[0-9]+]], %got(y)
    267 ; MIPS64-ANY:    ld      $[[R0:[0-9]+]], %got_disp(y)(
    268 
    269 ; ALL:           addiu   $[[R1:[0-9]+]], $zero, -4
    270 ; ALL:           and     $[[R2:[0-9]+]], $[[R0]], $[[R1]]
    271 ; ALL:           andi    $[[R3:[0-9]+]], $[[R0]], 3
    272 ; CHECK-EL:      sll     $[[R5:[0-9]+]], $[[R3]], 3
    273 ; CHECK-EB:      xori    $[[R4:[0-9]+]], $[[R3]], 3
    274 ; CHECK-EB:      sll     $[[R5:[0-9]+]], $[[R4]], 3
    275 ; ALL:           ori     $[[R6:[0-9]+]], $zero, 255
    276 ; ALL:           sllv    $[[R7:[0-9]+]], $[[R6]], $[[R5]]
    277 ; ALL:           nor     $[[R8:[0-9]+]], $zero, $[[R7]]
    278 ; ALL:           sllv    $[[R9:[0-9]+]], $4, $[[R5]]
    279 
    280 ; ALL:       $[[BB0:[A-Z_0-9]+]]:
    281 ; ALL:           ll      $[[R10:[0-9]+]], 0($[[R2]])
    282 ; ALL:           and     $[[R18:[0-9]+]], $[[R9]], $[[R7]]
    283 ; ALL:           and     $[[R13:[0-9]+]], $[[R10]], $[[R8]]
    284 ; ALL:           or      $[[R14:[0-9]+]], $[[R13]], $[[R18]]
    285 ; ALL:           sc      $[[R14]], 0($[[R2]])
    286 ; NOT-MICROMIPS: beqz    $[[R14]], $[[BB0]]
    287 ; MICROMIPS:     beqzc   $[[R14]], $[[BB0]]
    288 ; MIPSR6:        beqzc   $[[R14]], $[[BB0]]
    289 
    290 ; ALL:           and     $[[R15:[0-9]+]], $[[R10]], $[[R7]]
    291 ; ALL:           srlv    $[[R16:[0-9]+]], $[[R15]], $[[R5]]
    292 
    293 ; NO-SEB-SEH:    sll     $[[R17:[0-9]+]], $[[R16]], 24
    294 ; NO-SEB-SEH:    sra     $2, $[[R17]], 24
    295 
    296 ; HAS-SEB-SEH:   seb     $2, $[[R16]]
    297 
    298 }
    299 
    300 define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwind {
    301 entry:
    302   %pair0 = cmpxchg i8* @y, i8 %oldval, i8 %newval monotonic monotonic
    303   %0 = extractvalue { i8, i1 } %pair0, 0
    304   ret i8 %0
    305 
    306 ; ALL-LABEL: AtomicCmpSwap8:
    307 
    308 ; MIPS32-ANY:    lw      $[[R0:[0-9]+]], %got(y)
    309 ; MIPS64-ANY:    ld      $[[R0:[0-9]+]], %got_disp(y)(
    310 
    311 ; ALL:           addiu   $[[R1:[0-9]+]], $zero, -4
    312 ; ALL:           and     $[[R2:[0-9]+]], $[[R0]], $[[R1]]
    313 ; ALL:           andi    $[[R3:[0-9]+]], $[[R0]], 3
    314 ; CHECK-EL:      sll     $[[R5:[0-9]+]], $[[R3]], 3
    315 ; CHECK-EB:      xori    $[[R4:[0-9]+]], $[[R3]], 3
    316 ; CHECK-EB:      sll     $[[R5:[0-9]+]], $[[R4]], 3
    317 ; ALL:           ori     $[[R6:[0-9]+]], $zero, 255
    318 ; ALL:           sllv    $[[R7:[0-9]+]], $[[R6]], $[[R5]]
    319 ; ALL:           nor     $[[R8:[0-9]+]], $zero, $[[R7]]
    320 ; ALL:           andi    $[[R9:[0-9]+]], $4, 255
    321 ; ALL:           sllv    $[[R10:[0-9]+]], $[[R9]], $[[R5]]
    322 ; ALL:           andi    $[[R11:[0-9]+]], $5, 255
    323 ; ALL:           sllv    $[[R12:[0-9]+]], $[[R11]], $[[R5]]
    324 
    325 ; ALL:       $[[BB0:[A-Z_0-9]+]]:
    326 ; ALL:           ll      $[[R13:[0-9]+]], 0($[[R2]])
    327 ; ALL:           and     $[[R14:[0-9]+]], $[[R13]], $[[R7]]
    328 ; NOT-MICROMIPS: bne     $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]]
    329 ; MICROMIPS:     bne     $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]]
    330 ; MIPSR6:        bnec    $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]]
    331 
    332 ; ALL:           and     $[[R15:[0-9]+]], $[[R13]], $[[R8]]
    333 ; ALL:           or      $[[R16:[0-9]+]], $[[R15]], $[[R12]]
    334 ; ALL:           sc      $[[R16]], 0($[[R2]])
    335 ; NOT-MICROMIPS: beqz    $[[R16]], $[[BB0]]
    336 ; MICROMIPS:     beqzc   $[[R16]], $[[BB0]]
    337 ; MIPSR6:        beqzc   $[[R16]], $[[BB0]]
    338 
    339 ; ALL:       $[[BB1]]:
    340 ; ALL:           srlv    $[[R17:[0-9]+]], $[[R14]], $[[R5]]
    341 
    342 ; NO-SEB-SEH:    sll     $[[R18:[0-9]+]], $[[R17]], 24
    343 ; NO-SEB-SEH:    sra     $2, $[[R18]], 24
    344 
    345 ; HAS-SEB-SEH:   seb     $2, $[[R17]]
    346 }
    347 
    348 define i1 @AtomicCmpSwapRes8(i8* %ptr, i8 signext %oldval, i8 signext %newval) nounwind {
    349 entry:
    350   %0 = cmpxchg i8* %ptr, i8 %oldval, i8 %newval monotonic monotonic
    351   %1 = extractvalue { i8, i1 } %0, 1
    352   ret i1 %1
    353 ; ALL-LABEL: AtomicCmpSwapRes8
    354 
    355 ; ALL:           addiu   $[[R1:[0-9]+]], $zero, -4
    356 ; ALL:           and     $[[R2:[0-9]+]], $4, $[[R1]]
    357 ; ALL:           andi    $[[R3:[0-9]+]], $4, 3
    358 ; CHECK-EL:      sll     $[[R5:[0-9]+]], $[[R3]], 3
    359 ; CHECK-EB:      xori    $[[R4:[0-9]+]], $[[R3]], 3
    360 ; CHECK-EB:      sll     $[[R5:[0-9]+]], $[[R4]], 3
    361 ; ALL:           ori     $[[R6:[0-9]+]], $zero, 255
    362 ; ALL:           sllv    $[[R7:[0-9]+]], $[[R6]], $[[R5]]
    363 ; ALL:           nor     $[[R8:[0-9]+]], $zero, $[[R7]]
    364 ; ALL:           andi    $[[R9:[0-9]+]], $5, 255
    365 ; ALL:           sllv    $[[R10:[0-9]+]], $[[R9]], $[[R5]]
    366 ; ALL:           andi    $[[R11:[0-9]+]], $6, 255
    367 ; ALL:           sllv    $[[R12:[0-9]+]], $[[R11]], $[[R5]]
    368 
    369 ; ALL:       $[[BB0:[A-Z_0-9]+]]:
    370 ; ALL:           ll      $[[R13:[0-9]+]], 0($[[R2]])
    371 ; ALL:           and     $[[R14:[0-9]+]], $[[R13]], $[[R7]]
    372 ; NOT-MICROMIPS: bne     $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]]
    373 ; MICROMIPS:     bne     $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]]
    374 ; MIPSR6:        bnec    $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]]
    375 
    376 ; ALL:           and     $[[R15:[0-9]+]], $[[R13]], $[[R8]]
    377 ; ALL:           or      $[[R16:[0-9]+]], $[[R15]], $[[R12]]
    378 ; ALL:           sc      $[[R16]], 0($[[R2]])
    379 ; NOT-MICROMIPS: beqz    $[[R16]], $[[BB0]]
    380 ; MICROMIPS:     beqzc   $[[R16]], $[[BB0]]
    381 ; MIPSR6:        beqzc   $[[R16]], $[[BB0]]
    382 
    383 ; ALL:       $[[BB1]]:
    384 ; ALL:           srlv    $[[R17:[0-9]+]], $[[R14]], $[[R5]]
    385 
    386 ; NO-SEB-SEH:    sll     $[[R18:[0-9]+]], $[[R17]], 24
    387 ; NO-SEB-SEH:    sra     $[[R19:[0-9]+]], $[[R18]], 24
    388 
    389 ; FIXME: -march=mips produces a redundant sign extension here...
    390 ; NO-SEB-SEH:    sll     $[[R20:[0-9]+]], $5, 24
    391 ; NO-SEB-SEH:    sra     $[[R20]], $[[R20]], 24
    392 
    393 ; HAS-SEB-SEH:   seb     $[[R19:[0-9]+]], $[[R17]]
    394 
    395 ; FIXME: ...Leading to this split check.
    396 ; NO-SEB-SEH:    xor     $[[R21:[0-9]+]], $[[R19]], $[[R20]]
    397 ; HAS-SEB-SEH:   xor     $[[R21:[0-9]+]], $[[R19]], $5
    398 
    399 ; ALL: sltiu   $2, $[[R21]], 1
    400 }
    401 
    402 ; Check one i16 so that we cover the seh sign extend
    403 @z = common global i16 0, align 1
    404 
    405 define signext i16 @AtomicLoadAdd16(i16 signext %incr) nounwind {
    406 entry:
    407   %0 = atomicrmw add i16* @z, i16 %incr monotonic
    408   ret i16 %0
    409 
    410 ; ALL-LABEL: AtomicLoadAdd16:
    411 
    412 ; MIPS32-ANY:    lw      $[[R0:[0-9]+]], %got(z)
    413 ; MIPS64-ANY:    ld      $[[R0:[0-9]+]], %got_disp(z)(
    414 
    415 ; ALL:           addiu   $[[R1:[0-9]+]], $zero, -4
    416 ; ALL:           and     $[[R2:[0-9]+]], $[[R0]], $[[R1]]
    417 ; ALL:           andi    $[[R3:[0-9]+]], $[[R0]], 3
    418 ; CHECK-EB:      xori    $[[R4:[0-9]+]], $[[R3]], 2
    419 ; CHECK-EB:      sll     $[[R5:[0-9]+]], $[[R4]], 3
    420 ; CHECK-EL:      sll     $[[R5:[0-9]+]], $[[R3]], 3
    421 ; ALL:           ori     $[[R6:[0-9]+]], $zero, 65535
    422 ; ALL:           sllv    $[[R7:[0-9]+]], $[[R6]], $[[R5]]
    423 ; ALL:           nor     $[[R8:[0-9]+]], $zero, $[[R7]]
    424 ; ALL:           sllv    $[[R9:[0-9]+]], $4, $[[R5]]
    425 
    426 ; O0:        $[[BB0:[A-Z_0-9]+]]:
    427 ; O0:            ld      $[[R10:[0-9]+]]
    428 ; O0-NEXT:       ll      $[[R11:[0-9]+]], 0($[[R10]])
    429 
    430 ; ALL:       $[[BB0:[A-Z_0-9]+]]:
    431 ; ALL:           ll      $[[R12:[0-9]+]], 0($[[R2]])
    432 ; ALL:           addu    $[[R13:[0-9]+]], $[[R12]], $[[R9]]
    433 ; ALL:           and     $[[R14:[0-9]+]], $[[R13]], $[[R7]]
    434 ; ALL:           and     $[[R15:[0-9]+]], $[[R12]], $[[R8]]
    435 ; ALL:           or      $[[R16:[0-9]+]], $[[R15]], $[[R14]]
    436 ; ALL:           sc      $[[R16]], 0($[[R2]])
    437 ; NOT-MICROMIPS: beqz    $[[R16]], $[[BB0]]
    438 ; MICROMIPS:     beqzc   $[[R16]], $[[BB0]]
    439 ; MIPSR6:        beqzc   $[[R16]], $[[BB0]]
    440 
    441 ; ALL:           and     $[[R17:[0-9]+]], $[[R12]], $[[R7]]
    442 ; ALL:           srlv    $[[R18:[0-9]+]], $[[R17]], $[[R5]]
    443 
    444 ; NO-SEB-SEH:    sll     $[[R19:[0-9]+]], $[[R18]], 16
    445 ; NO-SEB-SEH:    sra     $2, $[[R19]], 16
    446 
    447 ; MIPS32R2:      seh     $2, $[[R18]]
    448 }
    449 
    450 ; Test that the i16 return value from cmpxchg is recognised as signed,
    451 ; so that setCC doesn't end up comparing an unsigned value to a signed
    452 ; value.
    453 ; The rest of the functions here are testing the atomic expansion, so
    454 ; we just match the end of the function.
    455 define {i16, i1} @foo(i16* %addr, i16 %l, i16 %r, i16 %new) {
    456   %desired = add i16 %l, %r
    457   %res = cmpxchg i16* %addr, i16 %desired, i16 %new seq_cst seq_cst
    458   ret {i16, i1} %res
    459 
    460 ; ALL-LABEL: foo
    461 ; MIPSR6:        addu    $[[R2:[0-9]+]], $[[R1:[0-9]+]], $[[R0:[0-9]+]]
    462 ; NOT-MICROMIPS: addu    $[[R2:[0-9]+]], $[[R1:[0-9]+]], $[[R0:[0-9]+]]
    463 ; MICROMIPS:     addu16  $[[R2:[0-9]+]], $[[R1:[0-9]+]], $[[R0:[0-9]+]]
    464 
    465 ; ALL:           sync
    466 
    467 ; ALL:           andi    $[[R3:[0-9]+]], $[[R2]], 65535
    468 ; ALL:       $[[BB0:[A-Z_0-9]+]]:
    469 ; ALL:           ll      $[[R4:[0-9]+]], 0($[[R5:[0-9]+]])
    470 ; ALL:           and     $[[R6:[0-9]+]], $[[R4]], $
    471 ; ALL:           and     $[[R7:[0-9]+]], $[[R4]], $
    472 ; ALL:           or      $[[R8:[0-9]+]], $[[R7]], $
    473 ; ALL:           sc      $[[R8]], 0($[[R5]])
    474 ; NOT-MICROMIPS: beqz    $[[R8]], $[[BB0]]
    475 ; MICROMIPS:     beqzc   $[[R8]], $[[BB0]]
    476 ; MIPSR6:        beqzc   $[[R8]], $[[BB0]]
    477 
    478 ; ALL:           srlv    $[[R9:[0-9]+]], $[[R6]], $
    479 
    480 ; NO-SEB-SEH:    sll     $[[R10:[0-9]+]], $[[R9]], 16
    481 ; NO-SEB-SEH:    sra     $[[R11:[0-9]+]], $[[R10]], 16
    482 
    483 ; NO-SEB-SEH:    sll     $[[R12:[0-9]+]], $[[R2]], 16
    484 ; NO-SEB-SEH:    sra     $[[R13:[0-9]+]], $[[R12]], 16
    485 
    486 ; HAS-SEB-SEH:   seh     $[[R11:[0-9]+]], $[[R9]]
    487 ; HAS-SEB-SEH:   seh     $[[R13:[0-9]+]], $[[R2]]
    488 
    489 ; ALL:           xor     $[[R12:[0-9]+]], $[[R11]], $[[R13]]
    490 ; ALL:           sltiu   $3, $[[R12]], 1
    491 ; ALL:           sync
    492 }
    493 
    494 @countsint = common global i32 0, align 4
    495 
    496 define i32 @CheckSync(i32 signext %v) nounwind noinline {
    497 entry:
    498   %0 = atomicrmw add i32* @countsint, i32 %v seq_cst
    499   ret i32 %0 
    500 
    501 ; ALL-LABEL: CheckSync:
    502 
    503 ; ALL:           sync
    504 ; ALL:           ll
    505 ; ALL:           sc
    506 ; ALL:           beq
    507 ; ALL:           sync
    508 }
    509 
    510 ; make sure that this assertion in
    511 ; TwoAddressInstructionPass::TryInstructionTransform does not fail:
    512 ;
    513 ; line 1203: assert(TargetRegisterInfo::isVirtualRegister(regB) &&
    514 ;
    515 ; it failed when MipsDAGToDAGISel::ReplaceUsesWithZeroReg replaced an
    516 ; operand of an atomic instruction with register $zero. 
    517 @a = external global i32
    518 
    519 define i32 @zeroreg() nounwind {
    520 entry:
    521   %pair0 = cmpxchg i32* @a, i32 1, i32 0 seq_cst seq_cst
    522   %0 = extractvalue { i32, i1 } %pair0, 0
    523   %1 = icmp eq i32 %0, 1
    524   %conv = zext i1 %1 to i32
    525   ret i32 %conv
    526 }
    527 
    528 ; Check that MIPS32R6 has the correct offset range.
    529 ; FIXME: At the moment, we don't seem to do addr+offset for any atomic load/store.
    530 define i32 @AtomicLoadAdd32_OffGt9Bit(i32 signext %incr) nounwind {
    531 entry:
    532   %0 = atomicrmw add i32* getelementptr(i32, i32* @x, i32 256), i32 %incr monotonic
    533   ret i32 %0
    534 
    535 ; ALL-LABEL: AtomicLoadAdd32_OffGt9Bit:
    536 
    537 ; MIPS32-ANY:    lw      $[[R0:[0-9]+]], %got(x)
    538 ; MIPS64-ANY:    ld      $[[R0:[0-9]+]], %got_disp(x)(
    539 
    540 ; ALL:           addiu   $[[PTR:[0-9]+]], $[[R0]], 1024
    541 ; ALL:       $[[BB0:[A-Z_0-9]+]]:
    542 ; ALL:           ll      $[[R1:[0-9]+]], 0($[[PTR]])
    543 ; ALL:           addu    $[[R2:[0-9]+]], $[[R1]], $4
    544 ; ALL:           sc      $[[R2]], 0($[[PTR]])
    545 ; NOT-MICROMIPS: beqz    $[[R2]], $[[BB0]]
    546 ; MICROMIPS:     beqzc   $[[R2]], $[[BB0]]
    547 ; MIPSR6:        beqzc   $[[R2]], $[[BB0]]
    548 }
    549