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