1 ; Test multiplication of two f64s, producing an f128 result.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5 ; Check register multiplication. "mxdbr %f0, %f2" is not valid from LLVM's
6 ; point of view, because %f2 is the low register of the FP128 %f0. Pass the
7 ; multiplier in %f4 instead.
8 define void @f1(double %f1, double %dummy, double %f2, fp128 *%dst) {
10 ; CHECK: mxdbr %f0, %f4
11 ; CHECK: std %f0, 0(%r2)
12 ; CHECK: std %f2, 8(%r2)
14 %f1x = fpext double %f1 to fp128
15 %f2x = fpext double %f2 to fp128
16 %res = fmul fp128 %f1x, %f2x
17 store fp128 %res, fp128 *%dst
21 ; Check the low end of the MXDB range.
22 define void @f2(double %f1, double *%ptr, fp128 *%dst) {
24 ; CHECK: mxdb %f0, 0(%r2)
25 ; CHECK: std %f0, 0(%r3)
26 ; CHECK: std %f2, 8(%r3)
28 %f2 = load double *%ptr
29 %f1x = fpext double %f1 to fp128
30 %f2x = fpext double %f2 to fp128
31 %res = fmul fp128 %f1x, %f2x
32 store fp128 %res, fp128 *%dst
36 ; Check the high end of the aligned MXDB range.
37 define void @f3(double %f1, double *%base, fp128 *%dst) {
39 ; CHECK: mxdb %f0, 4088(%r2)
40 ; CHECK: std %f0, 0(%r3)
41 ; CHECK: std %f2, 8(%r3)
43 %ptr = getelementptr double *%base, i64 511
44 %f2 = load double *%ptr
45 %f1x = fpext double %f1 to fp128
46 %f2x = fpext double %f2 to fp128
47 %res = fmul fp128 %f1x, %f2x
48 store fp128 %res, fp128 *%dst
52 ; Check the next doubleword up, which needs separate address logic.
53 ; Other sequences besides this one would be OK.
54 define void @f4(double %f1, double *%base, fp128 *%dst) {
56 ; CHECK: aghi %r2, 4096
57 ; CHECK: mxdb %f0, 0(%r2)
58 ; CHECK: std %f0, 0(%r3)
59 ; CHECK: std %f2, 8(%r3)
61 %ptr = getelementptr double *%base, i64 512
62 %f2 = load double *%ptr
63 %f1x = fpext double %f1 to fp128
64 %f2x = fpext double %f2 to fp128
65 %res = fmul fp128 %f1x, %f2x
66 store fp128 %res, fp128 *%dst
70 ; Check negative displacements, which also need separate address logic.
71 define void @f5(double %f1, double *%base, fp128 *%dst) {
74 ; CHECK: mxdb %f0, 0(%r2)
75 ; CHECK: std %f0, 0(%r3)
76 ; CHECK: std %f2, 8(%r3)
78 %ptr = getelementptr double *%base, i64 -1
79 %f2 = load double *%ptr
80 %f1x = fpext double %f1 to fp128
81 %f2x = fpext double %f2 to fp128
82 %res = fmul fp128 %f1x, %f2x
83 store fp128 %res, fp128 *%dst
87 ; Check that MXDB allows indices.
88 define void @f6(double %f1, double *%base, i64 %index, fp128 *%dst) {
90 ; CHECK: sllg %r1, %r3, 3
91 ; CHECK: mxdb %f0, 800(%r1,%r2)
92 ; CHECK: std %f0, 0(%r4)
93 ; CHECK: std %f2, 8(%r4)
95 %ptr1 = getelementptr double *%base, i64 %index
96 %ptr2 = getelementptr double *%ptr1, i64 100
97 %f2 = load double *%ptr2
98 %f1x = fpext double %f1 to fp128
99 %f2x = fpext double %f2 to fp128
100 %res = fmul fp128 %f1x, %f2x
101 store fp128 %res, fp128 *%dst