1; RUN: llc < %s -mtriple=ve | FileCheck %s
2
3;;; Test ‘frem’ Instruction
4;;;
5;;; Syntax:
6;;;   <result> = frem [fast-math flags]* <ty> <op1>, <op2> ; yields ty:result
7;;;
8;;; Overview:
9;;;   The ‘frem’ instruction returns the remainder from the division of its two
10;;;   operands.
11;;;
12;;; Arguments:
13;;;   The two arguments to the ‘frem’ instruction must be floating-point or
14;;;   vector of floating-point values. Both arguments must have identical types.
15;;;
16;;; Semantics:
17;;;   The value produced is the floating-point remainder of the two operands.
18;;;   This is the same output as a libm ‘fmod’ function, but without any
19;;;   possibility of setting errno. The remainder has the same sign as the
20;;;   dividend. This instruction is assumed to execute in the default
21;;;   floating-point environment. This instruction can also take any number
22;;;   of fast-math flags, which are optimization hints to enable otherwise
23;;;   unsafe floating-point optimizations:
24;;;
25;;; Example:
26;;;
27;;;   <result> = frem float 4.0, %var ; yields float:result = 4.0 % %var
28;;;
29;;; Note:
30;;;   We test only float/double/fp128.
31;;;   We have no way to generated frem from C source code, so convert fdiv
32;;;   to frem by using sed program.
33
34; Function Attrs: norecurse nounwind readnone
35define float @frem_float_var(float %0, float %1) {
36; CHECK-LABEL: frem_float_var:
37; CHECK:       .LBB{{[0-9]+}}_2:
38; CHECK-NEXT:    lea %s2, fmodf@lo
39; CHECK-NEXT:    and %s2, %s2, (32)0
40; CHECK-NEXT:    lea.sl %s12, fmodf@hi(, %s2)
41; CHECK-NEXT:    bsic %s10, (, %s12)
42; CHECK-NEXT:    or %s11, 0, %s9
43  %3 = frem float %0, %1
44  ret float %3
45}
46
47; Function Attrs: norecurse nounwind readnone
48define double @frem_double_var(double %0, double %1) {
49; CHECK-LABEL: frem_double_var:
50; CHECK:       .LBB{{[0-9]+}}_2:
51; CHECK-NEXT:    lea %s2, fmod@lo
52; CHECK-NEXT:    and %s2, %s2, (32)0
53; CHECK-NEXT:    lea.sl %s12, fmod@hi(, %s2)
54; CHECK-NEXT:    bsic %s10, (, %s12)
55; CHECK-NEXT:    or %s11, 0, %s9
56  %3 = frem double %0, %1
57  ret double %3
58}
59
60; Function Attrs: norecurse nounwind readnone
61define fp128 @frem_quad_var(fp128 %0, fp128 %1) {
62; CHECK-LABEL: frem_quad_var:
63; CHECK:       .LBB{{[0-9]+}}_2:
64; CHECK-NEXT:    lea %s4, fmodl@lo
65; CHECK-NEXT:    and %s4, %s4, (32)0
66; CHECK-NEXT:    lea.sl %s12, fmodl@hi(, %s4)
67; CHECK-NEXT:    bsic %s10, (, %s12)
68; CHECK-NEXT:    or %s11, 0, %s9
69  %3 = frem fp128 %0, %1
70  ret fp128 %3
71}
72
73; Function Attrs: norecurse nounwind readnone
74define float @frem_float_zero(float %0) {
75; CHECK-LABEL: frem_float_zero:
76; CHECK:       .LBB{{[0-9]+}}_2:
77; CHECK-NEXT:    or %s1, 0, %s0
78; CHECK-NEXT:    lea %s0, fmodf@lo
79; CHECK-NEXT:    and %s0, %s0, (32)0
80; CHECK-NEXT:    lea.sl %s12, fmodf@hi(, %s0)
81; CHECK-NEXT:    lea.sl %s0, 0
82; CHECK-NEXT:    bsic %s10, (, %s12)
83; CHECK-NEXT:    or %s11, 0, %s9
84  %2 = frem float 0.000000e+00, %0
85  ret float %2
86}
87
88; Function Attrs: norecurse nounwind readnone
89define double @frem_double_zero(double %0) {
90; CHECK-LABEL: frem_double_zero:
91; CHECK:       .LBB{{[0-9]+}}_2:
92; CHECK-NEXT:    or %s1, 0, %s0
93; CHECK-NEXT:    lea %s0, fmod@lo
94; CHECK-NEXT:    and %s0, %s0, (32)0
95; CHECK-NEXT:    lea.sl %s12, fmod@hi(, %s0)
96; CHECK-NEXT:    lea.sl %s0, 0
97; CHECK-NEXT:    bsic %s10, (, %s12)
98; CHECK-NEXT:    or %s11, 0, %s9
99  %2 = frem double 0.000000e+00, %0
100  ret double %2
101}
102
103; Function Attrs: norecurse nounwind readnone
104define fp128 @frem_quad_zero(fp128 %0) {
105; CHECK-LABEL: frem_quad_zero:
106; CHECK:       .LBB{{[0-9]+}}_2:
107; CHECK-NEXT:    or %s2, 0, %s0
108; CHECK-NEXT:    or %s3, 0, %s1
109; CHECK-NEXT:    lea %s0, .LCPI{{[0-9]+}}_0@lo
110; CHECK-NEXT:    and %s0, %s0, (32)0
111; CHECK-NEXT:    lea.sl %s4, .LCPI{{[0-9]+}}_0@hi(, %s0)
112; CHECK-NEXT:    ld %s0, 8(, %s4)
113; CHECK-NEXT:    ld %s1, (, %s4)
114; CHECK-NEXT:    lea %s4, fmodl@lo
115; CHECK-NEXT:    and %s4, %s4, (32)0
116; CHECK-NEXT:    lea.sl %s12, fmodl@hi(, %s4)
117; CHECK-NEXT:    bsic %s10, (, %s12)
118; CHECK-NEXT:    or %s11, 0, %s9
119  %2 = frem fp128 0xL00000000000000000000000000000000, %0
120  ret fp128 %2
121}
122
123; Function Attrs: norecurse nounwind readnone
124define float @frem_float_cont(float %0) {
125; CHECK-LABEL: frem_float_cont:
126; CHECK:       .LBB{{[0-9]+}}_2:
127; CHECK-NEXT:    or %s1, 0, %s0
128; CHECK-NEXT:    lea %s0, fmodf@lo
129; CHECK-NEXT:    and %s0, %s0, (32)0
130; CHECK-NEXT:    lea.sl %s12, fmodf@hi(, %s0)
131; CHECK-NEXT:    lea.sl %s0, -1073741824
132; CHECK-NEXT:    bsic %s10, (, %s12)
133; CHECK-NEXT:    or %s11, 0, %s9
134  %2 = frem float -2.000000e+00, %0
135  ret float %2
136}
137
138; Function Attrs: norecurse nounwind readnone
139define double @frem_double_cont(double %0) {
140; CHECK-LABEL: frem_double_cont:
141; CHECK:       .LBB{{[0-9]+}}_2:
142; CHECK-NEXT:    or %s1, 0, %s0
143; CHECK-NEXT:    lea %s0, fmod@lo
144; CHECK-NEXT:    and %s0, %s0, (32)0
145; CHECK-NEXT:    lea.sl %s12, fmod@hi(, %s0)
146; CHECK-NEXT:    lea.sl %s0, -1073741824
147; CHECK-NEXT:    bsic %s10, (, %s12)
148; CHECK-NEXT:    or %s11, 0, %s9
149  %2 = frem double -2.000000e+00, %0
150  ret double %2
151}
152
153; Function Attrs: norecurse nounwind readnone
154define fp128 @frem_quad_cont(fp128 %0) {
155; CHECK-LABEL: frem_quad_cont:
156; CHECK:       .LBB{{[0-9]+}}_2:
157; CHECK-NEXT:    or %s2, 0, %s0
158; CHECK-NEXT:    or %s3, 0, %s1
159; CHECK-NEXT:    lea %s0, .LCPI{{[0-9]+}}_0@lo
160; CHECK-NEXT:    and %s0, %s0, (32)0
161; CHECK-NEXT:    lea.sl %s4, .LCPI{{[0-9]+}}_0@hi(, %s0)
162; CHECK-NEXT:    ld %s0, 8(, %s4)
163; CHECK-NEXT:    ld %s1, (, %s4)
164; CHECK-NEXT:    lea %s4, fmodl@lo
165; CHECK-NEXT:    and %s4, %s4, (32)0
166; CHECK-NEXT:    lea.sl %s12, fmodl@hi(, %s4)
167; CHECK-NEXT:    bsic %s10, (, %s12)
168; CHECK-NEXT:    or %s11, 0, %s9
169  %2 = frem fp128 0xL0000000000000000C000000000000000, %0
170  ret fp128 %2
171}
172