1; RUN: llc -mcpu=pwr9 -mtriple=powerpc64le-unknown-unknown \ 2; RUN: -enable-ppc-quad-precision -ppc-vsr-nums-as-vr \ 3; RUN: -verify-machineinstrs -ppc-asm-full-reg-names < %s | FileCheck %s 4 5; Function Attrs: norecurse nounwind readnone 6define fp128 @loadConstant() { 7; CHECK-LABEL: loadConstant: 8; CHECK: # %bb.0: # %entry 9; CHECK-NEXT: addis r[[REG0:[0-9]+]], r2, .LCPI0_0@toc@ha 10; CHECK-NEXT: addi r[[REG0]], r[[REG0]], .LCPI0_0@toc@l 11; CHECK-NEXT: lxvx v2, 0, r[[REG0]] 12; CHECK-NEXT: blr 13 entry: 14 ret fp128 0xL00000000000000004001400000000000 15} 16 17; Function Attrs: norecurse nounwind readnone 18define fp128 @loadConstant2(fp128 %a, fp128 %b) { 19; CHECK-LABEL: loadConstant2: 20; CHECK: # %bb.0: # %entry 21; CHECK-NEXT: xsaddqp v2, v2, v3 22; CHECK-NEXT: addis r[[REG0:[0-9]+]], r2, .LCPI1_0@toc@ha 23; CHECK-NEXT: addi r[[REG0]], r[[REG0]], .LCPI1_0@toc@l 24; CHECK-NEXT: lxvx v[[REG1:[0-9]+]], 0, r[[REG0]] 25; CHECK-NEXT: xsaddqp v2, v2, v[[REG1]] 26; CHECK-NEXT: blr 27 entry: 28 %add = fadd fp128 %a, %b 29 %add1 = fadd fp128 %add, 0xL00000000000000004001400000000000 30 ret fp128 %add1 31} 32 33; Test passing float128 by value. 34; Function Attrs: norecurse nounwind readnone 35define signext i32 @fp128Param(fp128 %a) { 36; CHECK-LABEL: fp128Param: 37; CHECK: # %bb.0: # %entry 38; CHECK-NEXT: xscvqpswz v2, v2 39; CHECK-NEXT: mfvsrwz r3, v2 40; CHECK-NEXT: extsw r3, r3 41; CHECK-NEXT: blr 42entry: 43 %conv = fptosi fp128 %a to i32 44 ret i32 %conv 45} 46 47; Test float128 as return value. 48; Function Attrs: norecurse nounwind readnone 49define fp128 @fp128Return(fp128 %a, fp128 %b) { 50; CHECK-LABEL: fp128Return: 51; CHECK: # %bb.0: # %entry 52; CHECK-NEXT: xsaddqp v2, v2, v3 53; CHECK-NEXT: blr 54entry: 55 %add = fadd fp128 %a, %b 56 ret fp128 %add 57} 58 59; array of float128 types 60; Function Attrs: norecurse nounwind readonly 61define fp128 @fp128Array(fp128* nocapture readonly %farray, 62; CHECK-LABEL: fp128Array: 63; CHECK: # %bb.0: # %entry 64; CHECK-NEXT: sldi r4, r4, 4 65; CHECK-NEXT: lxv v2, 0(r3) 66; CHECK-NEXT: add r4, r3, r4 67; CHECK-NEXT: lxv v3, -16(r4) 68; CHECK-NEXT: xsaddqp v2, v2, v3 69; CHECK-NEXT: blr 70 i32 signext %loopcnt, fp128* nocapture readnone %sum) { 71entry: 72 %0 = load fp128, fp128* %farray, align 16 73 %sub = add nsw i32 %loopcnt, -1 74 %idxprom = sext i32 %sub to i64 75 %arrayidx1 = getelementptr inbounds fp128, fp128* %farray, i64 %idxprom 76 %1 = load fp128, fp128* %arrayidx1, align 16 77 %add = fadd fp128 %0, %1 78 ret fp128 %add 79} 80 81; Up to 12 qualified floating-point arguments can be passed in v2-v13. 82; Function to test passing 13 float128 parameters. 83; Function Attrs: norecurse nounwind readnone 84define fp128 @maxVecParam(fp128 %p1, fp128 %p2, fp128 %p3, fp128 %p4, fp128 %p5, 85; CHECK-LABEL: maxVecParam: 86; CHECK: # %bb.0: # %entry 87; CHECK-NEXT: xsaddqp v2, v2, v3 88; CHECK-NEXT: lxv v[[REG0:[0-9]+]], 224(r1) 89; CHECK-NEXT: xsaddqp v2, v2, v4 90; CHECK-NEXT: xsaddqp v2, v2, v5 91; CHECK-NEXT: xsaddqp v2, v2, v6 92; CHECK-NEXT: xsaddqp v2, v2, v7 93; CHECK-NEXT: xsaddqp v2, v2, v8 94; CHECK-NEXT: xsaddqp v2, v2, v9 95; CHECK-NEXT: xsaddqp v2, v2, v10 96; CHECK-NEXT: xsaddqp v2, v2, v11 97; CHECK-NEXT: xsaddqp v2, v2, v12 98; CHECK-NEXT: xsaddqp v2, v2, v13 99; CHECK-NEXT: xssubqp v2, v2, v[[REG0]] 100; CHECK-NEXT: blr 101 fp128 %p6, fp128 %p7, fp128 %p8, fp128 %p9, fp128 %p10, 102 fp128 %p11, fp128 %p12, fp128 %p13) { 103entry: 104 %add = fadd fp128 %p1, %p2 105 %add1 = fadd fp128 %add, %p3 106 %add2 = fadd fp128 %add1, %p4 107 %add3 = fadd fp128 %add2, %p5 108 %add4 = fadd fp128 %add3, %p6 109 %add5 = fadd fp128 %add4, %p7 110 %add6 = fadd fp128 %add5, %p8 111 %add7 = fadd fp128 %add6, %p9 112 %add8 = fadd fp128 %add7, %p10 113 %add9 = fadd fp128 %add8, %p11 114 %add10 = fadd fp128 %add9, %p12 115 %sub = fsub fp128 %add10, %p13 116 ret fp128 %sub 117} 118 119; Passing a mix of float128 and other type parameters. 120; Function Attrs: norecurse nounwind readnone 121define fp128 @mixParam_01(fp128 %a, i32 signext %i, fp128 %b) { 122; CHECK-LABEL: mixParam_01: 123; CHECK: # %bb.0: # %entry 124; CHECK-NEXT: mtvsrwa v4, r5 125; CHECK-NEXT: xsaddqp v2, v2, v3 126; CHECK-NEXT: xscvsdqp v[[REG0:[0-9]+]], v4 127; CHECK-NEXT: xsaddqp v2, v2, v[[REG0]] 128; CHECK-NEXT: blr 129entry: 130 %add = fadd fp128 %a, %b 131 %conv = sitofp i32 %i to fp128 132 %add1 = fadd fp128 %add, %conv 133 ret fp128 %add1 134} 135; Function Attrs: norecurse nounwind readnone 136define fastcc fp128 @mixParam_01f(fp128 %a, i32 signext %i, fp128 %b) { 137; CHECK-LABEL: mixParam_01f: 138; CHECK: # %bb.0: # %entry 139; CHECK-NEXT: mtvsrwa v[[REG0:[0-9]+]], r3 140; CHECK-NEXT: xsaddqp v2, v2, v3 141; CHECK-NEXT: xscvsdqp v[[REG1:[0-9]+]], v[[REG0]] 142; CHECK-NEXT: xsaddqp v2, v2, v[[REG1]] 143; CHECK-NEXT: blr 144entry: 145 %add = fadd fp128 %a, %b 146 %conv = sitofp i32 %i to fp128 147 %add1 = fadd fp128 %add, %conv 148 ret fp128 %add1 149} 150 151; Function Attrs: norecurse nounwind 152define fp128 @mixParam_02(fp128 %p1, double %p2, i64* nocapture %p3, 153; CHECK-LABEL: mixParam_02: 154; CHECK: # %bb.0: # %entry 155; CHECK-DAG: lwz r3, 96(r1) 156; CHECK: add r4, r7, r9 157; CHECK-NEXT: xxlor v[[REG0:[0-9]+]], f1, f1 158; CHECK-DAG: add r4, r4, r10 159; CHECK: xscvdpqp v[[REG0]], v[[REG0]] 160; CHECK-NEXT: add r3, r4, r3 161; CHECK-NEXT: clrldi r3, r3, 32 162; CHECK-NEXT: std r3, 0(r6) 163; CHECK-NEXT: lxv v[[REG1:[0-9]+]], 0(r8) 164; CHECK-NEXT: xsaddqp v2, v[[REG1]], v2 165; CHECK-NEXT: xsaddqp v2, v2, v3 166; CHECK-NEXT: blr 167 i16 signext %p4, fp128* nocapture readonly %p5, 168 i32 signext %p6, i8 zeroext %p7, i32 zeroext %p8) { 169entry: 170 %conv = sext i16 %p4 to i32 171 %add = add nsw i32 %conv, %p6 172 %conv1 = zext i8 %p7 to i32 173 %add2 = add nsw i32 %add, %conv1 174 %add3 = add i32 %add2, %p8 175 %conv4 = zext i32 %add3 to i64 176 store i64 %conv4, i64* %p3, align 8 177 %0 = load fp128, fp128* %p5, align 16 178 %add5 = fadd fp128 %0, %p1 179 %conv6 = fpext double %p2 to fp128 180 %add7 = fadd fp128 %add5, %conv6 181 ret fp128 %add7 182} 183 184; Function Attrs: norecurse nounwind 185define fastcc fp128 @mixParam_02f(fp128 %p1, double %p2, i64* nocapture %p3, 186; CHECK-LABEL: mixParam_02f: 187; CHECK: # %bb.0: # %entry 188; CHECK-NEXT: add r4, r4, r6 189; CHECK-NEXT: xxlor v[[REG0:[0-9]+]], f1, f1 190; CHECK-NEXT: add r4, r4, r7 191; CHECK-NEXT: xscvdpqp v[[REG0]], v[[REG0]] 192; CHECK-NEXT: add r4, r4, r8 193; CHECK-NEXT: clrldi r4, r4, 32 194; CHECK-NEXT: std r4, 0(r3) 195; CHECK-NEXT: lxv v[[REG1:[0-9]+]], 0(r5) 196; CHECK-NEXT: xsaddqp v2, v[[REG1]], v2 197; CHECK-NEXT: xsaddqp v2, v2, v[[REG0]] 198; CHECK-NEXT: blr 199 i16 signext %p4, fp128* nocapture readonly %p5, 200 i32 signext %p6, i8 zeroext %p7, i32 zeroext %p8) { 201entry: 202 %conv = sext i16 %p4 to i32 203 %add = add nsw i32 %conv, %p6 204 %conv1 = zext i8 %p7 to i32 205 %add2 = add nsw i32 %add, %conv1 206 %add3 = add i32 %add2, %p8 207 %conv4 = zext i32 %add3 to i64 208 store i64 %conv4, i64* %p3, align 8 209 %0 = load fp128, fp128* %p5, align 16 210 %add5 = fadd fp128 %0, %p1 211 %conv6 = fpext double %p2 to fp128 212 %add7 = fadd fp128 %add5, %conv6 213 ret fp128 %add7 214} 215 216; Passing a mix of float128 and vector parameters. 217; Function Attrs: norecurse nounwind 218define void @mixParam_03(fp128 %f1, double* nocapture %d1, <4 x i32> %vec1, 219; CHECK-LABEL: mixParam_03: 220; CHECK: # %bb.0: # %entry 221; CHECK-DAG: ld r3, 104(r1) 222; CHECK-DAG: mtvsrwa v[[REG2:[0-9]+]], r10 223; CHECK-DAG: stxv v2, 0(r9) 224; CHECK-DAG: xscvsdqp v[[REG1:[0-9]+]], v[[REG2]] 225; CHECK: stxvx v3, 0, r3 226; CHECK-NEXT: lxv v2, 0(r9) 227; CHECK-NEXT: xsaddqp v2, v2, v[[REG1]] 228; CHECK-NEXT: xscvqpdp v2, v2 229; CHECK-NEXT: stxsd v2, 0(r5) 230; CHECK-NEXT: blr 231 fp128* nocapture %f2, i32 signext %i1, i8 zeroext %c1, 232 <4 x i32>* nocapture %vec2) { 233entry: 234 store fp128 %f1, fp128* %f2, align 16 235 store <4 x i32> %vec1, <4 x i32>* %vec2, align 16 236 %0 = load fp128, fp128* %f2, align 16 237 %conv = sitofp i32 %i1 to fp128 238 %add = fadd fp128 %0, %conv 239 %conv1 = fptrunc fp128 %add to double 240 store double %conv1, double* %d1, align 8 241 ret void 242} 243 244; Function Attrs: norecurse nounwind 245define fastcc void @mixParam_03f(fp128 %f1, double* nocapture %d1, <4 x i32> %vec1, 246; CHECK-LABEL: mixParam_03f: 247; CHECK: # %bb.0: # %entry 248; CHECK-NEXT: mtvsrwa v[[REG0:[0-9]+]], r5 249; CHECK-NEXT: stxv v[[REG1:[0-9]+]], 0(r4) 250; CHECK-NEXT: stxv v[[REG2:[0-9]+]], 0(r7) 251; CHECK-NEXT: lxv v[[REG1]], 0(r4) 252; CHECK-NEXT: xscvsdqp v[[REG3:[0-9]+]], v[[REG0]] 253; CHECK-NEXT: xsaddqp v[[REG4:[0-9]+]], v[[REG1]], v[[REG3]] 254; CHECK-NEXT: xscvqpdp v2, v[[REG4]] 255; CHECK-NEXT: stxsd v2, 0(r3) 256; CHECK-NEXT: blr 257 fp128* nocapture %f2, i32 signext %i1, i8 zeroext %c1, 258 <4 x i32>* nocapture %vec2) { 259entry: 260 store fp128 %f1, fp128* %f2, align 16 261 store <4 x i32> %vec1, <4 x i32>* %vec2, align 16 262 %0 = load fp128, fp128* %f2, align 16 263 %conv = sitofp i32 %i1 to fp128 264 %add = fadd fp128 %0, %conv 265 %conv1 = fptrunc fp128 %add to double 266 store double %conv1, double* %d1, align 8 267 ret void 268} 269