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 27define i32 @AtomicLoadAdd32(i32 signext %incr) nounwind { 28entry: 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 50define i32 @AtomicLoadNand32(i32 signext %incr) nounwind { 51entry: 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 72define i32 @AtomicSwap32(i32 signext %newval) nounwind { 73entry: 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 93define i32 @AtomicCmpSwap32(i32 signext %oldval, i32 signext %newval) nounwind { 94entry: 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 123define signext i8 @AtomicLoadAdd8(i8 signext %incr) nounwind { 124entry: 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 168define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind { 169entry: 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 213define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind { 214entry: 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 259define signext i8 @AtomicSwap8(i8 signext %newval) nounwind { 260entry: 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 300define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwind { 301entry: 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 348define i1 @AtomicCmpSwapRes8(i8* %ptr, i8 signext %oldval, i8 signext %newval) nounwind { 349entry: 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 405define signext i16 @AtomicLoadAdd16(i16 signext %incr) nounwind { 406entry: 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. 455define {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 496define i32 @CheckSync(i32 signext %v) nounwind noinline { 497entry: 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 519define i32 @zeroreg() nounwind { 520entry: 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. 530define i32 @AtomicLoadAdd32_OffGt9Bit(i32 signext %incr) nounwind { 531entry: 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