1*9880d681SAndroid Build Coastguard Worker; Test 16-bit atomic ANDs. 2*9880d681SAndroid Build Coastguard Worker; 3*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s -check-prefix=CHECK-SHIFT1 5*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s -check-prefix=CHECK-SHIFT2 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; Check AND of a variable. 8*9880d681SAndroid Build Coastguard Worker; - CHECK is for the main loop. 9*9880d681SAndroid Build Coastguard Worker; - CHECK-SHIFT1 makes sure that the negated shift count used by the second 10*9880d681SAndroid Build Coastguard Worker; RLL is set up correctly. The negation is independent of the NILL and L 11*9880d681SAndroid Build Coastguard Worker; tested in CHECK. 12*9880d681SAndroid Build Coastguard Worker; - CHECK-SHIFT2 makes sure that %b is shifted into the high part of the word 13*9880d681SAndroid Build Coastguard Worker; before being used, and that the low bits are set to 1. This sequence is 14*9880d681SAndroid Build Coastguard Worker; independent of the other loop prologue instructions. 15*9880d681SAndroid Build Coastguard Workerdefine i16 @f1(i16 *%src, i16 %b) { 16*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1: 17*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[RISBG:%r[1-9]+]], %r2, 0, 189, 0{{$}} 18*9880d681SAndroid Build Coastguard Worker; CHECK: sll %r2, 3 19*9880d681SAndroid Build Coastguard Worker; CHECK: l [[OLD:%r[0-9]+]], 0([[RISBG]]) 20*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL:\.[^:]*]]: 21*9880d681SAndroid Build Coastguard Worker; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0(%r2) 22*9880d681SAndroid Build Coastguard Worker; CHECK: nr [[ROT]], %r3 23*9880d681SAndroid Build Coastguard Worker; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}}) 24*9880d681SAndroid Build Coastguard Worker; CHECK: cs [[OLD]], [[NEW]], 0([[RISBG]]) 25*9880d681SAndroid Build Coastguard Worker; CHECK: jl [[LABEL]] 26*9880d681SAndroid Build Coastguard Worker; CHECK: rll %r2, [[OLD]], 16(%r2) 27*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 28*9880d681SAndroid Build Coastguard Worker; 29*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1-LABEL: f1: 30*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: sll %r2, 3 31*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: lcr [[NEGSHIFT:%r[1-9]+]], %r2 32*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll 33*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll {{%r[0-9]+}}, {{%r[0-9]+}}, 0([[NEGSHIFT]]) 34*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll 35*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: br %r14 36*9880d681SAndroid Build Coastguard Worker; 37*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2-LABEL: f1: 38*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: sll %r3, 16 39*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: oill %r3, 65535 40*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: rll 41*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: nr {{%r[0-9]+}}, %r3 42*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: rll 43*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: rll 44*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: br %r14 45*9880d681SAndroid Build Coastguard Worker %res = atomicrmw and i16 *%src, i16 %b seq_cst 46*9880d681SAndroid Build Coastguard Worker ret i16 %res 47*9880d681SAndroid Build Coastguard Worker} 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker; Check the minimum signed value. We AND the rotated word with 0x8000ffff. 50*9880d681SAndroid Build Coastguard Workerdefine i16 @f2(i16 *%src) { 51*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2: 52*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[RISBG:%r[1-9]+]], %r2, 0, 189, 0{{$}} 53*9880d681SAndroid Build Coastguard Worker; CHECK: sll %r2, 3 54*9880d681SAndroid Build Coastguard Worker; CHECK: l [[OLD:%r[0-9]+]], 0([[RISBG]]) 55*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL:\.[^:]*]]: 56*9880d681SAndroid Build Coastguard Worker; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0(%r2) 57*9880d681SAndroid Build Coastguard Worker; CHECK: nilh [[ROT]], 32768 58*9880d681SAndroid Build Coastguard Worker; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0([[NEGSHIFT:%r[1-9]+]]) 59*9880d681SAndroid Build Coastguard Worker; CHECK: cs [[OLD]], [[NEW]], 0([[RISBG]]) 60*9880d681SAndroid Build Coastguard Worker; CHECK: jl [[LABEL]] 61*9880d681SAndroid Build Coastguard Worker; CHECK: rll %r2, [[OLD]], 16(%r2) 62*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 63*9880d681SAndroid Build Coastguard Worker; 64*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1-LABEL: f2: 65*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: sll %r2, 3 66*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: lcr [[NEGSHIFT:%r[1-9]+]], %r2 67*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll 68*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll {{%r[0-9]+}}, {{%r[0-9]+}}, 0([[NEGSHIFT]]) 69*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll 70*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: br %r14 71*9880d681SAndroid Build Coastguard Worker; 72*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2-LABEL: f2: 73*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: br %r14 74*9880d681SAndroid Build Coastguard Worker %res = atomicrmw and i16 *%src, i16 -32768 seq_cst 75*9880d681SAndroid Build Coastguard Worker ret i16 %res 76*9880d681SAndroid Build Coastguard Worker} 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Worker; Check ANDs of -2 (-1 isn't useful). We AND the rotated word with 0xfffeffff. 79*9880d681SAndroid Build Coastguard Workerdefine i16 @f3(i16 *%src) { 80*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 81*9880d681SAndroid Build Coastguard Worker; CHECK: nilh [[ROT]], 65534 82*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 83*9880d681SAndroid Build Coastguard Worker; 84*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1-LABEL: f3: 85*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: br %r14 86*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2-LABEL: f3: 87*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: br %r14 88*9880d681SAndroid Build Coastguard Worker %res = atomicrmw and i16 *%src, i16 -2 seq_cst 89*9880d681SAndroid Build Coastguard Worker ret i16 %res 90*9880d681SAndroid Build Coastguard Worker} 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker; Check ANDs of 1. We AND the rotated word with 0x0001ffff. 93*9880d681SAndroid Build Coastguard Workerdefine i16 @f4(i16 *%src) { 94*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 95*9880d681SAndroid Build Coastguard Worker; CHECK: nilh [[ROT]], 1 96*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 97*9880d681SAndroid Build Coastguard Worker; 98*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1-LABEL: f4: 99*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: br %r14 100*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2-LABEL: f4: 101*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: br %r14 102*9880d681SAndroid Build Coastguard Worker %res = atomicrmw and i16 *%src, i16 1 seq_cst 103*9880d681SAndroid Build Coastguard Worker ret i16 %res 104*9880d681SAndroid Build Coastguard Worker} 105*9880d681SAndroid Build Coastguard Worker 106*9880d681SAndroid Build Coastguard Worker; Check the maximum signed value. We AND the rotated word with 0x7fffffff. 107*9880d681SAndroid Build Coastguard Workerdefine i16 @f5(i16 *%src) { 108*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5: 109*9880d681SAndroid Build Coastguard Worker; CHECK: nilh [[ROT]], 32767 110*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 111*9880d681SAndroid Build Coastguard Worker; 112*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1-LABEL: f5: 113*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: br %r14 114*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2-LABEL: f5: 115*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: br %r14 116*9880d681SAndroid Build Coastguard Worker %res = atomicrmw and i16 *%src, i16 32767 seq_cst 117*9880d681SAndroid Build Coastguard Worker ret i16 %res 118*9880d681SAndroid Build Coastguard Worker} 119*9880d681SAndroid Build Coastguard Worker 120*9880d681SAndroid Build Coastguard Worker; Check ANDs of a large unsigned value. We AND the rotated word with 121*9880d681SAndroid Build Coastguard Worker; 0xfffdffff. 122*9880d681SAndroid Build Coastguard Workerdefine i16 @f6(i16 *%src) { 123*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6: 124*9880d681SAndroid Build Coastguard Worker; CHECK: nilh [[ROT]], 65533 125*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 126*9880d681SAndroid Build Coastguard Worker; 127*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1-LABEL: f6: 128*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: br %r14 129*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2-LABEL: f6: 130*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: br %r14 131*9880d681SAndroid Build Coastguard Worker %res = atomicrmw and i16 *%src, i16 65533 seq_cst 132*9880d681SAndroid Build Coastguard Worker ret i16 %res 133*9880d681SAndroid Build Coastguard Worker} 134