1*9880d681SAndroid Build Coastguard Worker; Test multiplication of two f64s, producing an f128 result. 2*9880d681SAndroid Build Coastguard Worker; 3*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Workerdeclare double @foo() 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; Check register multiplication. "mxdbr %f0, %f2" is not valid from LLVM's 8*9880d681SAndroid Build Coastguard Worker; point of view, because %f2 is the low register of the FP128 %f0. Pass the 9*9880d681SAndroid Build Coastguard Worker; multiplier in %f4 instead. 10*9880d681SAndroid Build Coastguard Workerdefine void @f1(double %f1, double %dummy, double %f2, fp128 *%dst) { 11*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1: 12*9880d681SAndroid Build Coastguard Worker; CHECK: mxdbr %f0, %f4 13*9880d681SAndroid Build Coastguard Worker; CHECK: std %f0, 0(%r2) 14*9880d681SAndroid Build Coastguard Worker; CHECK: std %f2, 8(%r2) 15*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 16*9880d681SAndroid Build Coastguard Worker %f1x = fpext double %f1 to fp128 17*9880d681SAndroid Build Coastguard Worker %f2x = fpext double %f2 to fp128 18*9880d681SAndroid Build Coastguard Worker %res = fmul fp128 %f1x, %f2x 19*9880d681SAndroid Build Coastguard Worker store fp128 %res, fp128 *%dst 20*9880d681SAndroid Build Coastguard Worker ret void 21*9880d681SAndroid Build Coastguard Worker} 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker; Check the low end of the MXDB range. 24*9880d681SAndroid Build Coastguard Workerdefine void @f2(double %f1, double *%ptr, fp128 *%dst) { 25*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2: 26*9880d681SAndroid Build Coastguard Worker; CHECK: mxdb %f0, 0(%r2) 27*9880d681SAndroid Build Coastguard Worker; CHECK: std %f0, 0(%r3) 28*9880d681SAndroid Build Coastguard Worker; CHECK: std %f2, 8(%r3) 29*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 30*9880d681SAndroid Build Coastguard Worker %f2 = load double , double *%ptr 31*9880d681SAndroid Build Coastguard Worker %f1x = fpext double %f1 to fp128 32*9880d681SAndroid Build Coastguard Worker %f2x = fpext double %f2 to fp128 33*9880d681SAndroid Build Coastguard Worker %res = fmul fp128 %f1x, %f2x 34*9880d681SAndroid Build Coastguard Worker store fp128 %res, fp128 *%dst 35*9880d681SAndroid Build Coastguard Worker ret void 36*9880d681SAndroid Build Coastguard Worker} 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker; Check the high end of the aligned MXDB range. 39*9880d681SAndroid Build Coastguard Workerdefine void @f3(double %f1, double *%base, fp128 *%dst) { 40*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 41*9880d681SAndroid Build Coastguard Worker; CHECK: mxdb %f0, 4088(%r2) 42*9880d681SAndroid Build Coastguard Worker; CHECK: std %f0, 0(%r3) 43*9880d681SAndroid Build Coastguard Worker; CHECK: std %f2, 8(%r3) 44*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 45*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr double, double *%base, i64 511 46*9880d681SAndroid Build Coastguard Worker %f2 = load double , double *%ptr 47*9880d681SAndroid Build Coastguard Worker %f1x = fpext double %f1 to fp128 48*9880d681SAndroid Build Coastguard Worker %f2x = fpext double %f2 to fp128 49*9880d681SAndroid Build Coastguard Worker %res = fmul fp128 %f1x, %f2x 50*9880d681SAndroid Build Coastguard Worker store fp128 %res, fp128 *%dst 51*9880d681SAndroid Build Coastguard Worker ret void 52*9880d681SAndroid Build Coastguard Worker} 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Worker; Check the next doubleword up, which needs separate address logic. 55*9880d681SAndroid Build Coastguard Worker; Other sequences besides this one would be OK. 56*9880d681SAndroid Build Coastguard Workerdefine void @f4(double %f1, double *%base, fp128 *%dst) { 57*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 58*9880d681SAndroid Build Coastguard Worker; CHECK: aghi %r2, 4096 59*9880d681SAndroid Build Coastguard Worker; CHECK: mxdb %f0, 0(%r2) 60*9880d681SAndroid Build Coastguard Worker; CHECK: std %f0, 0(%r3) 61*9880d681SAndroid Build Coastguard Worker; CHECK: std %f2, 8(%r3) 62*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 63*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr double, double *%base, i64 512 64*9880d681SAndroid Build Coastguard Worker %f2 = load double , double *%ptr 65*9880d681SAndroid Build Coastguard Worker %f1x = fpext double %f1 to fp128 66*9880d681SAndroid Build Coastguard Worker %f2x = fpext double %f2 to fp128 67*9880d681SAndroid Build Coastguard Worker %res = fmul fp128 %f1x, %f2x 68*9880d681SAndroid Build Coastguard Worker store fp128 %res, fp128 *%dst 69*9880d681SAndroid Build Coastguard Worker ret void 70*9880d681SAndroid Build Coastguard Worker} 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Worker; Check negative displacements, which also need separate address logic. 73*9880d681SAndroid Build Coastguard Workerdefine void @f5(double %f1, double *%base, fp128 *%dst) { 74*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5: 75*9880d681SAndroid Build Coastguard Worker; CHECK: aghi %r2, -8 76*9880d681SAndroid Build Coastguard Worker; CHECK: mxdb %f0, 0(%r2) 77*9880d681SAndroid Build Coastguard Worker; CHECK: std %f0, 0(%r3) 78*9880d681SAndroid Build Coastguard Worker; CHECK: std %f2, 8(%r3) 79*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 80*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr double, double *%base, i64 -1 81*9880d681SAndroid Build Coastguard Worker %f2 = load double , double *%ptr 82*9880d681SAndroid Build Coastguard Worker %f1x = fpext double %f1 to fp128 83*9880d681SAndroid Build Coastguard Worker %f2x = fpext double %f2 to fp128 84*9880d681SAndroid Build Coastguard Worker %res = fmul fp128 %f1x, %f2x 85*9880d681SAndroid Build Coastguard Worker store fp128 %res, fp128 *%dst 86*9880d681SAndroid Build Coastguard Worker ret void 87*9880d681SAndroid Build Coastguard Worker} 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker; Check that MXDB allows indices. 90*9880d681SAndroid Build Coastguard Workerdefine void @f6(double %f1, double *%base, i64 %index, fp128 *%dst) { 91*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6: 92*9880d681SAndroid Build Coastguard Worker; CHECK: sllg %r1, %r3, 3 93*9880d681SAndroid Build Coastguard Worker; CHECK: mxdb %f0, 800(%r1,%r2) 94*9880d681SAndroid Build Coastguard Worker; CHECK: std %f0, 0(%r4) 95*9880d681SAndroid Build Coastguard Worker; CHECK: std %f2, 8(%r4) 96*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 97*9880d681SAndroid Build Coastguard Worker %ptr1 = getelementptr double, double *%base, i64 %index 98*9880d681SAndroid Build Coastguard Worker %ptr2 = getelementptr double, double *%ptr1, i64 100 99*9880d681SAndroid Build Coastguard Worker %f2 = load double , double *%ptr2 100*9880d681SAndroid Build Coastguard Worker %f1x = fpext double %f1 to fp128 101*9880d681SAndroid Build Coastguard Worker %f2x = fpext double %f2 to fp128 102*9880d681SAndroid Build Coastguard Worker %res = fmul fp128 %f1x, %f2x 103*9880d681SAndroid Build Coastguard Worker store fp128 %res, fp128 *%dst 104*9880d681SAndroid Build Coastguard Worker ret void 105*9880d681SAndroid Build Coastguard Worker} 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Worker; Check that multiplications of spilled values can use MXDB rather than MXDBR. 108*9880d681SAndroid Build Coastguard Workerdefine double @f7(double *%ptr0) { 109*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7: 110*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, foo@PLT 111*9880d681SAndroid Build Coastguard Worker; CHECK: mxdb %f0, 160(%r15) 112*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 113*9880d681SAndroid Build Coastguard Worker %ptr1 = getelementptr double, double *%ptr0, i64 2 114*9880d681SAndroid Build Coastguard Worker %ptr2 = getelementptr double, double *%ptr0, i64 4 115*9880d681SAndroid Build Coastguard Worker %ptr3 = getelementptr double, double *%ptr0, i64 6 116*9880d681SAndroid Build Coastguard Worker %ptr4 = getelementptr double, double *%ptr0, i64 8 117*9880d681SAndroid Build Coastguard Worker %ptr5 = getelementptr double, double *%ptr0, i64 10 118*9880d681SAndroid Build Coastguard Worker %ptr6 = getelementptr double, double *%ptr0, i64 12 119*9880d681SAndroid Build Coastguard Worker %ptr7 = getelementptr double, double *%ptr0, i64 14 120*9880d681SAndroid Build Coastguard Worker %ptr8 = getelementptr double, double *%ptr0, i64 16 121*9880d681SAndroid Build Coastguard Worker %ptr9 = getelementptr double, double *%ptr0, i64 18 122*9880d681SAndroid Build Coastguard Worker %ptr10 = getelementptr double, double *%ptr0, i64 20 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Worker %val0 = load double , double *%ptr0 125*9880d681SAndroid Build Coastguard Worker %val1 = load double , double *%ptr1 126*9880d681SAndroid Build Coastguard Worker %val2 = load double , double *%ptr2 127*9880d681SAndroid Build Coastguard Worker %val3 = load double , double *%ptr3 128*9880d681SAndroid Build Coastguard Worker %val4 = load double , double *%ptr4 129*9880d681SAndroid Build Coastguard Worker %val5 = load double , double *%ptr5 130*9880d681SAndroid Build Coastguard Worker %val6 = load double , double *%ptr6 131*9880d681SAndroid Build Coastguard Worker %val7 = load double , double *%ptr7 132*9880d681SAndroid Build Coastguard Worker %val8 = load double , double *%ptr8 133*9880d681SAndroid Build Coastguard Worker %val9 = load double , double *%ptr9 134*9880d681SAndroid Build Coastguard Worker %val10 = load double , double *%ptr10 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Worker %frob0 = fadd double %val0, %val0 137*9880d681SAndroid Build Coastguard Worker %frob1 = fadd double %val1, %val1 138*9880d681SAndroid Build Coastguard Worker %frob2 = fadd double %val2, %val2 139*9880d681SAndroid Build Coastguard Worker %frob3 = fadd double %val3, %val3 140*9880d681SAndroid Build Coastguard Worker %frob4 = fadd double %val4, %val4 141*9880d681SAndroid Build Coastguard Worker %frob5 = fadd double %val5, %val5 142*9880d681SAndroid Build Coastguard Worker %frob6 = fadd double %val6, %val6 143*9880d681SAndroid Build Coastguard Worker %frob7 = fadd double %val7, %val7 144*9880d681SAndroid Build Coastguard Worker %frob8 = fadd double %val8, %val8 145*9880d681SAndroid Build Coastguard Worker %frob9 = fadd double %val9, %val9 146*9880d681SAndroid Build Coastguard Worker %frob10 = fadd double %val9, %val10 147*9880d681SAndroid Build Coastguard Worker 148*9880d681SAndroid Build Coastguard Worker store double %frob0, double *%ptr0 149*9880d681SAndroid Build Coastguard Worker store double %frob1, double *%ptr1 150*9880d681SAndroid Build Coastguard Worker store double %frob2, double *%ptr2 151*9880d681SAndroid Build Coastguard Worker store double %frob3, double *%ptr3 152*9880d681SAndroid Build Coastguard Worker store double %frob4, double *%ptr4 153*9880d681SAndroid Build Coastguard Worker store double %frob5, double *%ptr5 154*9880d681SAndroid Build Coastguard Worker store double %frob6, double *%ptr6 155*9880d681SAndroid Build Coastguard Worker store double %frob7, double *%ptr7 156*9880d681SAndroid Build Coastguard Worker store double %frob8, double *%ptr8 157*9880d681SAndroid Build Coastguard Worker store double %frob9, double *%ptr9 158*9880d681SAndroid Build Coastguard Worker store double %frob10, double *%ptr10 159*9880d681SAndroid Build Coastguard Worker 160*9880d681SAndroid Build Coastguard Worker %ret = call double @foo() 161*9880d681SAndroid Build Coastguard Worker 162*9880d681SAndroid Build Coastguard Worker %accext0 = fpext double %ret to fp128 163*9880d681SAndroid Build Coastguard Worker %ext0 = fpext double %frob0 to fp128 164*9880d681SAndroid Build Coastguard Worker %mul0 = fmul fp128 %accext0, %ext0 165*9880d681SAndroid Build Coastguard Worker %const0 = fpext double 1.01 to fp128 166*9880d681SAndroid Build Coastguard Worker %extra0 = fmul fp128 %mul0, %const0 167*9880d681SAndroid Build Coastguard Worker %trunc0 = fptrunc fp128 %extra0 to double 168*9880d681SAndroid Build Coastguard Worker 169*9880d681SAndroid Build Coastguard Worker %accext1 = fpext double %trunc0 to fp128 170*9880d681SAndroid Build Coastguard Worker %ext1 = fpext double %frob1 to fp128 171*9880d681SAndroid Build Coastguard Worker %mul1 = fmul fp128 %accext1, %ext1 172*9880d681SAndroid Build Coastguard Worker %const1 = fpext double 1.11 to fp128 173*9880d681SAndroid Build Coastguard Worker %extra1 = fmul fp128 %mul1, %const1 174*9880d681SAndroid Build Coastguard Worker %trunc1 = fptrunc fp128 %extra1 to double 175*9880d681SAndroid Build Coastguard Worker 176*9880d681SAndroid Build Coastguard Worker %accext2 = fpext double %trunc1 to fp128 177*9880d681SAndroid Build Coastguard Worker %ext2 = fpext double %frob2 to fp128 178*9880d681SAndroid Build Coastguard Worker %mul2 = fmul fp128 %accext2, %ext2 179*9880d681SAndroid Build Coastguard Worker %const2 = fpext double 1.21 to fp128 180*9880d681SAndroid Build Coastguard Worker %extra2 = fmul fp128 %mul2, %const2 181*9880d681SAndroid Build Coastguard Worker %trunc2 = fptrunc fp128 %extra2 to double 182*9880d681SAndroid Build Coastguard Worker 183*9880d681SAndroid Build Coastguard Worker %accext3 = fpext double %trunc2 to fp128 184*9880d681SAndroid Build Coastguard Worker %ext3 = fpext double %frob3 to fp128 185*9880d681SAndroid Build Coastguard Worker %mul3 = fmul fp128 %accext3, %ext3 186*9880d681SAndroid Build Coastguard Worker %const3 = fpext double 1.31 to fp128 187*9880d681SAndroid Build Coastguard Worker %extra3 = fmul fp128 %mul3, %const3 188*9880d681SAndroid Build Coastguard Worker %trunc3 = fptrunc fp128 %extra3 to double 189*9880d681SAndroid Build Coastguard Worker 190*9880d681SAndroid Build Coastguard Worker %accext4 = fpext double %trunc3 to fp128 191*9880d681SAndroid Build Coastguard Worker %ext4 = fpext double %frob4 to fp128 192*9880d681SAndroid Build Coastguard Worker %mul4 = fmul fp128 %accext4, %ext4 193*9880d681SAndroid Build Coastguard Worker %const4 = fpext double 1.41 to fp128 194*9880d681SAndroid Build Coastguard Worker %extra4 = fmul fp128 %mul4, %const4 195*9880d681SAndroid Build Coastguard Worker %trunc4 = fptrunc fp128 %extra4 to double 196*9880d681SAndroid Build Coastguard Worker 197*9880d681SAndroid Build Coastguard Worker %accext5 = fpext double %trunc4 to fp128 198*9880d681SAndroid Build Coastguard Worker %ext5 = fpext double %frob5 to fp128 199*9880d681SAndroid Build Coastguard Worker %mul5 = fmul fp128 %accext5, %ext5 200*9880d681SAndroid Build Coastguard Worker %const5 = fpext double 1.51 to fp128 201*9880d681SAndroid Build Coastguard Worker %extra5 = fmul fp128 %mul5, %const5 202*9880d681SAndroid Build Coastguard Worker %trunc5 = fptrunc fp128 %extra5 to double 203*9880d681SAndroid Build Coastguard Worker 204*9880d681SAndroid Build Coastguard Worker %accext6 = fpext double %trunc5 to fp128 205*9880d681SAndroid Build Coastguard Worker %ext6 = fpext double %frob6 to fp128 206*9880d681SAndroid Build Coastguard Worker %mul6 = fmul fp128 %accext6, %ext6 207*9880d681SAndroid Build Coastguard Worker %const6 = fpext double 1.61 to fp128 208*9880d681SAndroid Build Coastguard Worker %extra6 = fmul fp128 %mul6, %const6 209*9880d681SAndroid Build Coastguard Worker %trunc6 = fptrunc fp128 %extra6 to double 210*9880d681SAndroid Build Coastguard Worker 211*9880d681SAndroid Build Coastguard Worker %accext7 = fpext double %trunc6 to fp128 212*9880d681SAndroid Build Coastguard Worker %ext7 = fpext double %frob7 to fp128 213*9880d681SAndroid Build Coastguard Worker %mul7 = fmul fp128 %accext7, %ext7 214*9880d681SAndroid Build Coastguard Worker %const7 = fpext double 1.71 to fp128 215*9880d681SAndroid Build Coastguard Worker %extra7 = fmul fp128 %mul7, %const7 216*9880d681SAndroid Build Coastguard Worker %trunc7 = fptrunc fp128 %extra7 to double 217*9880d681SAndroid Build Coastguard Worker 218*9880d681SAndroid Build Coastguard Worker %accext8 = fpext double %trunc7 to fp128 219*9880d681SAndroid Build Coastguard Worker %ext8 = fpext double %frob8 to fp128 220*9880d681SAndroid Build Coastguard Worker %mul8 = fmul fp128 %accext8, %ext8 221*9880d681SAndroid Build Coastguard Worker %const8 = fpext double 1.81 to fp128 222*9880d681SAndroid Build Coastguard Worker %extra8 = fmul fp128 %mul8, %const8 223*9880d681SAndroid Build Coastguard Worker %trunc8 = fptrunc fp128 %extra8 to double 224*9880d681SAndroid Build Coastguard Worker 225*9880d681SAndroid Build Coastguard Worker %accext9 = fpext double %trunc8 to fp128 226*9880d681SAndroid Build Coastguard Worker %ext9 = fpext double %frob9 to fp128 227*9880d681SAndroid Build Coastguard Worker %mul9 = fmul fp128 %accext9, %ext9 228*9880d681SAndroid Build Coastguard Worker %const9 = fpext double 1.91 to fp128 229*9880d681SAndroid Build Coastguard Worker %extra9 = fmul fp128 %mul9, %const9 230*9880d681SAndroid Build Coastguard Worker %trunc9 = fptrunc fp128 %extra9 to double 231*9880d681SAndroid Build Coastguard Worker 232*9880d681SAndroid Build Coastguard Worker ret double %trunc9 233*9880d681SAndroid Build Coastguard Worker} 234