xref: /qemu/target/hppa/fpu_helper.c (revision 5c39f954f5b8e32d22fa9fe5af7fb953a4258fee)
1*5c39f954SPhilippe Mathieu-Daudé /*
2*5c39f954SPhilippe Mathieu-Daudé  * Helpers for HPPA FPU instructions.
3*5c39f954SPhilippe Mathieu-Daudé  *
4*5c39f954SPhilippe Mathieu-Daudé  * Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
5*5c39f954SPhilippe Mathieu-Daudé  *
6*5c39f954SPhilippe Mathieu-Daudé  * This library is free software; you can redistribute it and/or
7*5c39f954SPhilippe Mathieu-Daudé  * modify it under the terms of the GNU Lesser General Public
8*5c39f954SPhilippe Mathieu-Daudé  * License as published by the Free Software Foundation; either
9*5c39f954SPhilippe Mathieu-Daudé  * version 2.1 of the License, or (at your option) any later version.
10*5c39f954SPhilippe Mathieu-Daudé  *
11*5c39f954SPhilippe Mathieu-Daudé  * This library is distributed in the hope that it will be useful,
12*5c39f954SPhilippe Mathieu-Daudé  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*5c39f954SPhilippe Mathieu-Daudé  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*5c39f954SPhilippe Mathieu-Daudé  * Lesser General Public License for more details.
15*5c39f954SPhilippe Mathieu-Daudé  *
16*5c39f954SPhilippe Mathieu-Daudé  * You should have received a copy of the GNU Lesser General Public
17*5c39f954SPhilippe Mathieu-Daudé  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18*5c39f954SPhilippe Mathieu-Daudé  */
19*5c39f954SPhilippe Mathieu-Daudé 
20*5c39f954SPhilippe Mathieu-Daudé #include "qemu/osdep.h"
21*5c39f954SPhilippe Mathieu-Daudé #include "cpu.h"
22*5c39f954SPhilippe Mathieu-Daudé #include "exec/exec-all.h"
23*5c39f954SPhilippe Mathieu-Daudé #include "exec/helper-proto.h"
24*5c39f954SPhilippe Mathieu-Daudé #include "fpu/softfloat.h"
25*5c39f954SPhilippe Mathieu-Daudé 
26*5c39f954SPhilippe Mathieu-Daudé void HELPER(loaded_fr0)(CPUHPPAState *env)
27*5c39f954SPhilippe Mathieu-Daudé {
28*5c39f954SPhilippe Mathieu-Daudé     uint32_t shadow = env->fr[0] >> 32;
29*5c39f954SPhilippe Mathieu-Daudé     int rm, d;
30*5c39f954SPhilippe Mathieu-Daudé 
31*5c39f954SPhilippe Mathieu-Daudé     env->fr0_shadow = shadow;
32*5c39f954SPhilippe Mathieu-Daudé 
33*5c39f954SPhilippe Mathieu-Daudé     switch (extract32(shadow, 9, 2)) {
34*5c39f954SPhilippe Mathieu-Daudé     default:
35*5c39f954SPhilippe Mathieu-Daudé         rm = float_round_nearest_even;
36*5c39f954SPhilippe Mathieu-Daudé         break;
37*5c39f954SPhilippe Mathieu-Daudé     case 1:
38*5c39f954SPhilippe Mathieu-Daudé         rm = float_round_to_zero;
39*5c39f954SPhilippe Mathieu-Daudé         break;
40*5c39f954SPhilippe Mathieu-Daudé     case 2:
41*5c39f954SPhilippe Mathieu-Daudé         rm = float_round_up;
42*5c39f954SPhilippe Mathieu-Daudé         break;
43*5c39f954SPhilippe Mathieu-Daudé     case 3:
44*5c39f954SPhilippe Mathieu-Daudé         rm = float_round_down;
45*5c39f954SPhilippe Mathieu-Daudé         break;
46*5c39f954SPhilippe Mathieu-Daudé     }
47*5c39f954SPhilippe Mathieu-Daudé     set_float_rounding_mode(rm, &env->fp_status);
48*5c39f954SPhilippe Mathieu-Daudé 
49*5c39f954SPhilippe Mathieu-Daudé     d = extract32(shadow, 5, 1);
50*5c39f954SPhilippe Mathieu-Daudé     set_flush_to_zero(d, &env->fp_status);
51*5c39f954SPhilippe Mathieu-Daudé     set_flush_inputs_to_zero(d, &env->fp_status);
52*5c39f954SPhilippe Mathieu-Daudé }
53*5c39f954SPhilippe Mathieu-Daudé 
54*5c39f954SPhilippe Mathieu-Daudé void cpu_hppa_loaded_fr0(CPUHPPAState *env)
55*5c39f954SPhilippe Mathieu-Daudé {
56*5c39f954SPhilippe Mathieu-Daudé     helper_loaded_fr0(env);
57*5c39f954SPhilippe Mathieu-Daudé }
58*5c39f954SPhilippe Mathieu-Daudé 
59*5c39f954SPhilippe Mathieu-Daudé #define CONVERT_BIT(X, SRC, DST)        \
60*5c39f954SPhilippe Mathieu-Daudé     ((SRC) > (DST)                      \
61*5c39f954SPhilippe Mathieu-Daudé      ? (X) / ((SRC) / (DST)) & (DST)    \
62*5c39f954SPhilippe Mathieu-Daudé      : ((X) & (SRC)) * ((DST) / (SRC)))
63*5c39f954SPhilippe Mathieu-Daudé 
64*5c39f954SPhilippe Mathieu-Daudé static void update_fr0_op(CPUHPPAState *env, uintptr_t ra)
65*5c39f954SPhilippe Mathieu-Daudé {
66*5c39f954SPhilippe Mathieu-Daudé     uint32_t soft_exp = get_float_exception_flags(&env->fp_status);
67*5c39f954SPhilippe Mathieu-Daudé     uint32_t hard_exp = 0;
68*5c39f954SPhilippe Mathieu-Daudé     uint32_t shadow = env->fr0_shadow;
69*5c39f954SPhilippe Mathieu-Daudé 
70*5c39f954SPhilippe Mathieu-Daudé     if (likely(soft_exp == 0)) {
71*5c39f954SPhilippe Mathieu-Daudé         env->fr[0] = (uint64_t)shadow << 32;
72*5c39f954SPhilippe Mathieu-Daudé         return;
73*5c39f954SPhilippe Mathieu-Daudé     }
74*5c39f954SPhilippe Mathieu-Daudé     set_float_exception_flags(0, &env->fp_status);
75*5c39f954SPhilippe Mathieu-Daudé 
76*5c39f954SPhilippe Mathieu-Daudé     hard_exp |= CONVERT_BIT(soft_exp, float_flag_inexact,   1u << 0);
77*5c39f954SPhilippe Mathieu-Daudé     hard_exp |= CONVERT_BIT(soft_exp, float_flag_underflow, 1u << 1);
78*5c39f954SPhilippe Mathieu-Daudé     hard_exp |= CONVERT_BIT(soft_exp, float_flag_overflow,  1u << 2);
79*5c39f954SPhilippe Mathieu-Daudé     hard_exp |= CONVERT_BIT(soft_exp, float_flag_divbyzero, 1u << 3);
80*5c39f954SPhilippe Mathieu-Daudé     hard_exp |= CONVERT_BIT(soft_exp, float_flag_invalid,   1u << 4);
81*5c39f954SPhilippe Mathieu-Daudé     shadow |= hard_exp << (32 - 5);
82*5c39f954SPhilippe Mathieu-Daudé     env->fr0_shadow = shadow;
83*5c39f954SPhilippe Mathieu-Daudé     env->fr[0] = (uint64_t)shadow << 32;
84*5c39f954SPhilippe Mathieu-Daudé 
85*5c39f954SPhilippe Mathieu-Daudé     if (hard_exp & shadow) {
86*5c39f954SPhilippe Mathieu-Daudé         hppa_dynamic_excp(env, EXCP_ASSIST, ra);
87*5c39f954SPhilippe Mathieu-Daudé     }
88*5c39f954SPhilippe Mathieu-Daudé }
89*5c39f954SPhilippe Mathieu-Daudé 
90*5c39f954SPhilippe Mathieu-Daudé float32 HELPER(fsqrt_s)(CPUHPPAState *env, float32 arg)
91*5c39f954SPhilippe Mathieu-Daudé {
92*5c39f954SPhilippe Mathieu-Daudé     float32 ret = float32_sqrt(arg, &env->fp_status);
93*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
94*5c39f954SPhilippe Mathieu-Daudé     return ret;
95*5c39f954SPhilippe Mathieu-Daudé }
96*5c39f954SPhilippe Mathieu-Daudé 
97*5c39f954SPhilippe Mathieu-Daudé float32 HELPER(frnd_s)(CPUHPPAState *env, float32 arg)
98*5c39f954SPhilippe Mathieu-Daudé {
99*5c39f954SPhilippe Mathieu-Daudé     float32 ret = float32_round_to_int(arg, &env->fp_status);
100*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
101*5c39f954SPhilippe Mathieu-Daudé     return ret;
102*5c39f954SPhilippe Mathieu-Daudé }
103*5c39f954SPhilippe Mathieu-Daudé 
104*5c39f954SPhilippe Mathieu-Daudé float32 HELPER(fadd_s)(CPUHPPAState *env, float32 a, float32 b)
105*5c39f954SPhilippe Mathieu-Daudé {
106*5c39f954SPhilippe Mathieu-Daudé     float32 ret = float32_add(a, b, &env->fp_status);
107*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
108*5c39f954SPhilippe Mathieu-Daudé     return ret;
109*5c39f954SPhilippe Mathieu-Daudé }
110*5c39f954SPhilippe Mathieu-Daudé 
111*5c39f954SPhilippe Mathieu-Daudé float32 HELPER(fsub_s)(CPUHPPAState *env, float32 a, float32 b)
112*5c39f954SPhilippe Mathieu-Daudé {
113*5c39f954SPhilippe Mathieu-Daudé     float32 ret = float32_sub(a, b, &env->fp_status);
114*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
115*5c39f954SPhilippe Mathieu-Daudé     return ret;
116*5c39f954SPhilippe Mathieu-Daudé }
117*5c39f954SPhilippe Mathieu-Daudé 
118*5c39f954SPhilippe Mathieu-Daudé float32 HELPER(fmpy_s)(CPUHPPAState *env, float32 a, float32 b)
119*5c39f954SPhilippe Mathieu-Daudé {
120*5c39f954SPhilippe Mathieu-Daudé     float32 ret = float32_mul(a, b, &env->fp_status);
121*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
122*5c39f954SPhilippe Mathieu-Daudé     return ret;
123*5c39f954SPhilippe Mathieu-Daudé }
124*5c39f954SPhilippe Mathieu-Daudé 
125*5c39f954SPhilippe Mathieu-Daudé float32 HELPER(fdiv_s)(CPUHPPAState *env, float32 a, float32 b)
126*5c39f954SPhilippe Mathieu-Daudé {
127*5c39f954SPhilippe Mathieu-Daudé     float32 ret = float32_div(a, b, &env->fp_status);
128*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
129*5c39f954SPhilippe Mathieu-Daudé     return ret;
130*5c39f954SPhilippe Mathieu-Daudé }
131*5c39f954SPhilippe Mathieu-Daudé 
132*5c39f954SPhilippe Mathieu-Daudé float64 HELPER(fsqrt_d)(CPUHPPAState *env, float64 arg)
133*5c39f954SPhilippe Mathieu-Daudé {
134*5c39f954SPhilippe Mathieu-Daudé     float64 ret = float64_sqrt(arg, &env->fp_status);
135*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
136*5c39f954SPhilippe Mathieu-Daudé     return ret;
137*5c39f954SPhilippe Mathieu-Daudé }
138*5c39f954SPhilippe Mathieu-Daudé 
139*5c39f954SPhilippe Mathieu-Daudé float64 HELPER(frnd_d)(CPUHPPAState *env, float64 arg)
140*5c39f954SPhilippe Mathieu-Daudé {
141*5c39f954SPhilippe Mathieu-Daudé     float64 ret = float64_round_to_int(arg, &env->fp_status);
142*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
143*5c39f954SPhilippe Mathieu-Daudé     return ret;
144*5c39f954SPhilippe Mathieu-Daudé }
145*5c39f954SPhilippe Mathieu-Daudé 
146*5c39f954SPhilippe Mathieu-Daudé float64 HELPER(fadd_d)(CPUHPPAState *env, float64 a, float64 b)
147*5c39f954SPhilippe Mathieu-Daudé {
148*5c39f954SPhilippe Mathieu-Daudé     float64 ret = float64_add(a, b, &env->fp_status);
149*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
150*5c39f954SPhilippe Mathieu-Daudé     return ret;
151*5c39f954SPhilippe Mathieu-Daudé }
152*5c39f954SPhilippe Mathieu-Daudé 
153*5c39f954SPhilippe Mathieu-Daudé float64 HELPER(fsub_d)(CPUHPPAState *env, float64 a, float64 b)
154*5c39f954SPhilippe Mathieu-Daudé {
155*5c39f954SPhilippe Mathieu-Daudé     float64 ret = float64_sub(a, b, &env->fp_status);
156*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
157*5c39f954SPhilippe Mathieu-Daudé     return ret;
158*5c39f954SPhilippe Mathieu-Daudé }
159*5c39f954SPhilippe Mathieu-Daudé 
160*5c39f954SPhilippe Mathieu-Daudé float64 HELPER(fmpy_d)(CPUHPPAState *env, float64 a, float64 b)
161*5c39f954SPhilippe Mathieu-Daudé {
162*5c39f954SPhilippe Mathieu-Daudé     float64 ret = float64_mul(a, b, &env->fp_status);
163*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
164*5c39f954SPhilippe Mathieu-Daudé     return ret;
165*5c39f954SPhilippe Mathieu-Daudé }
166*5c39f954SPhilippe Mathieu-Daudé 
167*5c39f954SPhilippe Mathieu-Daudé float64 HELPER(fdiv_d)(CPUHPPAState *env, float64 a, float64 b)
168*5c39f954SPhilippe Mathieu-Daudé {
169*5c39f954SPhilippe Mathieu-Daudé     float64 ret = float64_div(a, b, &env->fp_status);
170*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
171*5c39f954SPhilippe Mathieu-Daudé     return ret;
172*5c39f954SPhilippe Mathieu-Daudé }
173*5c39f954SPhilippe Mathieu-Daudé 
174*5c39f954SPhilippe Mathieu-Daudé float64 HELPER(fcnv_s_d)(CPUHPPAState *env, float32 arg)
175*5c39f954SPhilippe Mathieu-Daudé {
176*5c39f954SPhilippe Mathieu-Daudé     float64 ret = float32_to_float64(arg, &env->fp_status);
177*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
178*5c39f954SPhilippe Mathieu-Daudé     return ret;
179*5c39f954SPhilippe Mathieu-Daudé }
180*5c39f954SPhilippe Mathieu-Daudé 
181*5c39f954SPhilippe Mathieu-Daudé float32 HELPER(fcnv_d_s)(CPUHPPAState *env, float64 arg)
182*5c39f954SPhilippe Mathieu-Daudé {
183*5c39f954SPhilippe Mathieu-Daudé     float32 ret = float64_to_float32(arg, &env->fp_status);
184*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
185*5c39f954SPhilippe Mathieu-Daudé     return ret;
186*5c39f954SPhilippe Mathieu-Daudé }
187*5c39f954SPhilippe Mathieu-Daudé 
188*5c39f954SPhilippe Mathieu-Daudé float32 HELPER(fcnv_w_s)(CPUHPPAState *env, int32_t arg)
189*5c39f954SPhilippe Mathieu-Daudé {
190*5c39f954SPhilippe Mathieu-Daudé     float32 ret = int32_to_float32(arg, &env->fp_status);
191*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
192*5c39f954SPhilippe Mathieu-Daudé     return ret;
193*5c39f954SPhilippe Mathieu-Daudé }
194*5c39f954SPhilippe Mathieu-Daudé 
195*5c39f954SPhilippe Mathieu-Daudé float32 HELPER(fcnv_dw_s)(CPUHPPAState *env, int64_t arg)
196*5c39f954SPhilippe Mathieu-Daudé {
197*5c39f954SPhilippe Mathieu-Daudé     float32 ret = int64_to_float32(arg, &env->fp_status);
198*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
199*5c39f954SPhilippe Mathieu-Daudé     return ret;
200*5c39f954SPhilippe Mathieu-Daudé }
201*5c39f954SPhilippe Mathieu-Daudé 
202*5c39f954SPhilippe Mathieu-Daudé float64 HELPER(fcnv_w_d)(CPUHPPAState *env, int32_t arg)
203*5c39f954SPhilippe Mathieu-Daudé {
204*5c39f954SPhilippe Mathieu-Daudé     float64 ret = int32_to_float64(arg, &env->fp_status);
205*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
206*5c39f954SPhilippe Mathieu-Daudé     return ret;
207*5c39f954SPhilippe Mathieu-Daudé }
208*5c39f954SPhilippe Mathieu-Daudé 
209*5c39f954SPhilippe Mathieu-Daudé float64 HELPER(fcnv_dw_d)(CPUHPPAState *env, int64_t arg)
210*5c39f954SPhilippe Mathieu-Daudé {
211*5c39f954SPhilippe Mathieu-Daudé     float64 ret = int64_to_float64(arg, &env->fp_status);
212*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
213*5c39f954SPhilippe Mathieu-Daudé     return ret;
214*5c39f954SPhilippe Mathieu-Daudé }
215*5c39f954SPhilippe Mathieu-Daudé 
216*5c39f954SPhilippe Mathieu-Daudé int32_t HELPER(fcnv_s_w)(CPUHPPAState *env, float32 arg)
217*5c39f954SPhilippe Mathieu-Daudé {
218*5c39f954SPhilippe Mathieu-Daudé     int32_t ret = float32_to_int32(arg, &env->fp_status);
219*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
220*5c39f954SPhilippe Mathieu-Daudé     return ret;
221*5c39f954SPhilippe Mathieu-Daudé }
222*5c39f954SPhilippe Mathieu-Daudé 
223*5c39f954SPhilippe Mathieu-Daudé int32_t HELPER(fcnv_d_w)(CPUHPPAState *env, float64 arg)
224*5c39f954SPhilippe Mathieu-Daudé {
225*5c39f954SPhilippe Mathieu-Daudé     int32_t ret = float64_to_int32(arg, &env->fp_status);
226*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
227*5c39f954SPhilippe Mathieu-Daudé     return ret;
228*5c39f954SPhilippe Mathieu-Daudé }
229*5c39f954SPhilippe Mathieu-Daudé 
230*5c39f954SPhilippe Mathieu-Daudé int64_t HELPER(fcnv_s_dw)(CPUHPPAState *env, float32 arg)
231*5c39f954SPhilippe Mathieu-Daudé {
232*5c39f954SPhilippe Mathieu-Daudé     int64_t ret = float32_to_int64(arg, &env->fp_status);
233*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
234*5c39f954SPhilippe Mathieu-Daudé     return ret;
235*5c39f954SPhilippe Mathieu-Daudé }
236*5c39f954SPhilippe Mathieu-Daudé 
237*5c39f954SPhilippe Mathieu-Daudé int64_t HELPER(fcnv_d_dw)(CPUHPPAState *env, float64 arg)
238*5c39f954SPhilippe Mathieu-Daudé {
239*5c39f954SPhilippe Mathieu-Daudé     int64_t ret = float64_to_int64(arg, &env->fp_status);
240*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
241*5c39f954SPhilippe Mathieu-Daudé     return ret;
242*5c39f954SPhilippe Mathieu-Daudé }
243*5c39f954SPhilippe Mathieu-Daudé 
244*5c39f954SPhilippe Mathieu-Daudé int32_t HELPER(fcnv_t_s_w)(CPUHPPAState *env, float32 arg)
245*5c39f954SPhilippe Mathieu-Daudé {
246*5c39f954SPhilippe Mathieu-Daudé     int32_t ret = float32_to_int32_round_to_zero(arg, &env->fp_status);
247*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
248*5c39f954SPhilippe Mathieu-Daudé     return ret;
249*5c39f954SPhilippe Mathieu-Daudé }
250*5c39f954SPhilippe Mathieu-Daudé 
251*5c39f954SPhilippe Mathieu-Daudé int32_t HELPER(fcnv_t_d_w)(CPUHPPAState *env, float64 arg)
252*5c39f954SPhilippe Mathieu-Daudé {
253*5c39f954SPhilippe Mathieu-Daudé     int32_t ret = float64_to_int32_round_to_zero(arg, &env->fp_status);
254*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
255*5c39f954SPhilippe Mathieu-Daudé     return ret;
256*5c39f954SPhilippe Mathieu-Daudé }
257*5c39f954SPhilippe Mathieu-Daudé 
258*5c39f954SPhilippe Mathieu-Daudé int64_t HELPER(fcnv_t_s_dw)(CPUHPPAState *env, float32 arg)
259*5c39f954SPhilippe Mathieu-Daudé {
260*5c39f954SPhilippe Mathieu-Daudé     int64_t ret = float32_to_int64_round_to_zero(arg, &env->fp_status);
261*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
262*5c39f954SPhilippe Mathieu-Daudé     return ret;
263*5c39f954SPhilippe Mathieu-Daudé }
264*5c39f954SPhilippe Mathieu-Daudé 
265*5c39f954SPhilippe Mathieu-Daudé int64_t HELPER(fcnv_t_d_dw)(CPUHPPAState *env, float64 arg)
266*5c39f954SPhilippe Mathieu-Daudé {
267*5c39f954SPhilippe Mathieu-Daudé     int64_t ret = float64_to_int64_round_to_zero(arg, &env->fp_status);
268*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
269*5c39f954SPhilippe Mathieu-Daudé     return ret;
270*5c39f954SPhilippe Mathieu-Daudé }
271*5c39f954SPhilippe Mathieu-Daudé 
272*5c39f954SPhilippe Mathieu-Daudé float32 HELPER(fcnv_uw_s)(CPUHPPAState *env, uint32_t arg)
273*5c39f954SPhilippe Mathieu-Daudé {
274*5c39f954SPhilippe Mathieu-Daudé     float32 ret = uint32_to_float32(arg, &env->fp_status);
275*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
276*5c39f954SPhilippe Mathieu-Daudé     return ret;
277*5c39f954SPhilippe Mathieu-Daudé }
278*5c39f954SPhilippe Mathieu-Daudé 
279*5c39f954SPhilippe Mathieu-Daudé float32 HELPER(fcnv_udw_s)(CPUHPPAState *env, uint64_t arg)
280*5c39f954SPhilippe Mathieu-Daudé {
281*5c39f954SPhilippe Mathieu-Daudé     float32 ret = uint64_to_float32(arg, &env->fp_status);
282*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
283*5c39f954SPhilippe Mathieu-Daudé     return ret;
284*5c39f954SPhilippe Mathieu-Daudé }
285*5c39f954SPhilippe Mathieu-Daudé 
286*5c39f954SPhilippe Mathieu-Daudé float64 HELPER(fcnv_uw_d)(CPUHPPAState *env, uint32_t arg)
287*5c39f954SPhilippe Mathieu-Daudé {
288*5c39f954SPhilippe Mathieu-Daudé     float64 ret = uint32_to_float64(arg, &env->fp_status);
289*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
290*5c39f954SPhilippe Mathieu-Daudé     return ret;
291*5c39f954SPhilippe Mathieu-Daudé }
292*5c39f954SPhilippe Mathieu-Daudé 
293*5c39f954SPhilippe Mathieu-Daudé float64 HELPER(fcnv_udw_d)(CPUHPPAState *env, uint64_t arg)
294*5c39f954SPhilippe Mathieu-Daudé {
295*5c39f954SPhilippe Mathieu-Daudé     float64 ret = uint64_to_float64(arg, &env->fp_status);
296*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
297*5c39f954SPhilippe Mathieu-Daudé     return ret;
298*5c39f954SPhilippe Mathieu-Daudé }
299*5c39f954SPhilippe Mathieu-Daudé 
300*5c39f954SPhilippe Mathieu-Daudé uint32_t HELPER(fcnv_s_uw)(CPUHPPAState *env, float32 arg)
301*5c39f954SPhilippe Mathieu-Daudé {
302*5c39f954SPhilippe Mathieu-Daudé     uint32_t ret = float32_to_uint32(arg, &env->fp_status);
303*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
304*5c39f954SPhilippe Mathieu-Daudé     return ret;
305*5c39f954SPhilippe Mathieu-Daudé }
306*5c39f954SPhilippe Mathieu-Daudé 
307*5c39f954SPhilippe Mathieu-Daudé uint32_t HELPER(fcnv_d_uw)(CPUHPPAState *env, float64 arg)
308*5c39f954SPhilippe Mathieu-Daudé {
309*5c39f954SPhilippe Mathieu-Daudé     uint32_t ret = float64_to_uint32(arg, &env->fp_status);
310*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
311*5c39f954SPhilippe Mathieu-Daudé     return ret;
312*5c39f954SPhilippe Mathieu-Daudé }
313*5c39f954SPhilippe Mathieu-Daudé 
314*5c39f954SPhilippe Mathieu-Daudé uint64_t HELPER(fcnv_s_udw)(CPUHPPAState *env, float32 arg)
315*5c39f954SPhilippe Mathieu-Daudé {
316*5c39f954SPhilippe Mathieu-Daudé     uint64_t ret = float32_to_uint64(arg, &env->fp_status);
317*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
318*5c39f954SPhilippe Mathieu-Daudé     return ret;
319*5c39f954SPhilippe Mathieu-Daudé }
320*5c39f954SPhilippe Mathieu-Daudé 
321*5c39f954SPhilippe Mathieu-Daudé uint64_t HELPER(fcnv_d_udw)(CPUHPPAState *env, float64 arg)
322*5c39f954SPhilippe Mathieu-Daudé {
323*5c39f954SPhilippe Mathieu-Daudé     uint64_t ret = float64_to_uint64(arg, &env->fp_status);
324*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
325*5c39f954SPhilippe Mathieu-Daudé     return ret;
326*5c39f954SPhilippe Mathieu-Daudé }
327*5c39f954SPhilippe Mathieu-Daudé 
328*5c39f954SPhilippe Mathieu-Daudé uint32_t HELPER(fcnv_t_s_uw)(CPUHPPAState *env, float32 arg)
329*5c39f954SPhilippe Mathieu-Daudé {
330*5c39f954SPhilippe Mathieu-Daudé     uint32_t ret = float32_to_uint32_round_to_zero(arg, &env->fp_status);
331*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
332*5c39f954SPhilippe Mathieu-Daudé     return ret;
333*5c39f954SPhilippe Mathieu-Daudé }
334*5c39f954SPhilippe Mathieu-Daudé 
335*5c39f954SPhilippe Mathieu-Daudé uint32_t HELPER(fcnv_t_d_uw)(CPUHPPAState *env, float64 arg)
336*5c39f954SPhilippe Mathieu-Daudé {
337*5c39f954SPhilippe Mathieu-Daudé     uint32_t ret = float64_to_uint32_round_to_zero(arg, &env->fp_status);
338*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
339*5c39f954SPhilippe Mathieu-Daudé     return ret;
340*5c39f954SPhilippe Mathieu-Daudé }
341*5c39f954SPhilippe Mathieu-Daudé 
342*5c39f954SPhilippe Mathieu-Daudé uint64_t HELPER(fcnv_t_s_udw)(CPUHPPAState *env, float32 arg)
343*5c39f954SPhilippe Mathieu-Daudé {
344*5c39f954SPhilippe Mathieu-Daudé     uint64_t ret = float32_to_uint64_round_to_zero(arg, &env->fp_status);
345*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
346*5c39f954SPhilippe Mathieu-Daudé     return ret;
347*5c39f954SPhilippe Mathieu-Daudé }
348*5c39f954SPhilippe Mathieu-Daudé 
349*5c39f954SPhilippe Mathieu-Daudé uint64_t HELPER(fcnv_t_d_udw)(CPUHPPAState *env, float64 arg)
350*5c39f954SPhilippe Mathieu-Daudé {
351*5c39f954SPhilippe Mathieu-Daudé     uint64_t ret = float64_to_uint64_round_to_zero(arg, &env->fp_status);
352*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
353*5c39f954SPhilippe Mathieu-Daudé     return ret;
354*5c39f954SPhilippe Mathieu-Daudé }
355*5c39f954SPhilippe Mathieu-Daudé 
356*5c39f954SPhilippe Mathieu-Daudé static void update_fr0_cmp(CPUHPPAState *env, uint32_t y,
357*5c39f954SPhilippe Mathieu-Daudé                            uint32_t c, FloatRelation r)
358*5c39f954SPhilippe Mathieu-Daudé {
359*5c39f954SPhilippe Mathieu-Daudé     uint32_t shadow = env->fr0_shadow;
360*5c39f954SPhilippe Mathieu-Daudé 
361*5c39f954SPhilippe Mathieu-Daudé     switch (r) {
362*5c39f954SPhilippe Mathieu-Daudé     case float_relation_greater:
363*5c39f954SPhilippe Mathieu-Daudé         c = extract32(c, 4, 1);
364*5c39f954SPhilippe Mathieu-Daudé         break;
365*5c39f954SPhilippe Mathieu-Daudé     case float_relation_less:
366*5c39f954SPhilippe Mathieu-Daudé         c = extract32(c, 3, 1);
367*5c39f954SPhilippe Mathieu-Daudé         break;
368*5c39f954SPhilippe Mathieu-Daudé     case float_relation_equal:
369*5c39f954SPhilippe Mathieu-Daudé         c = extract32(c, 2, 1);
370*5c39f954SPhilippe Mathieu-Daudé         break;
371*5c39f954SPhilippe Mathieu-Daudé     case float_relation_unordered:
372*5c39f954SPhilippe Mathieu-Daudé         c = extract32(c, 1, 1);
373*5c39f954SPhilippe Mathieu-Daudé         break;
374*5c39f954SPhilippe Mathieu-Daudé     default:
375*5c39f954SPhilippe Mathieu-Daudé         g_assert_not_reached();
376*5c39f954SPhilippe Mathieu-Daudé     }
377*5c39f954SPhilippe Mathieu-Daudé 
378*5c39f954SPhilippe Mathieu-Daudé     if (y) {
379*5c39f954SPhilippe Mathieu-Daudé         /* targeted comparison */
380*5c39f954SPhilippe Mathieu-Daudé         /* set fpsr[ca[y - 1]] to current compare */
381*5c39f954SPhilippe Mathieu-Daudé         shadow = deposit32(shadow, 21 - (y - 1), 1, c);
382*5c39f954SPhilippe Mathieu-Daudé     } else {
383*5c39f954SPhilippe Mathieu-Daudé         /* queued comparison */
384*5c39f954SPhilippe Mathieu-Daudé         /* shift cq right by one place */
385*5c39f954SPhilippe Mathieu-Daudé         shadow = deposit32(shadow, 11, 10, extract32(shadow, 12, 10));
386*5c39f954SPhilippe Mathieu-Daudé         /* move fpsr[c] to fpsr[cq[0]] */
387*5c39f954SPhilippe Mathieu-Daudé         shadow = deposit32(shadow, 21, 1, extract32(shadow, 26, 1));
388*5c39f954SPhilippe Mathieu-Daudé         /* set fpsr[c] to current compare */
389*5c39f954SPhilippe Mathieu-Daudé         shadow = deposit32(shadow, 26, 1, c);
390*5c39f954SPhilippe Mathieu-Daudé     }
391*5c39f954SPhilippe Mathieu-Daudé 
392*5c39f954SPhilippe Mathieu-Daudé     env->fr0_shadow = shadow;
393*5c39f954SPhilippe Mathieu-Daudé     env->fr[0] = (uint64_t)shadow << 32;
394*5c39f954SPhilippe Mathieu-Daudé }
395*5c39f954SPhilippe Mathieu-Daudé 
396*5c39f954SPhilippe Mathieu-Daudé void HELPER(fcmp_s)(CPUHPPAState *env, float32 a, float32 b,
397*5c39f954SPhilippe Mathieu-Daudé                     uint32_t y, uint32_t c)
398*5c39f954SPhilippe Mathieu-Daudé {
399*5c39f954SPhilippe Mathieu-Daudé     FloatRelation r;
400*5c39f954SPhilippe Mathieu-Daudé     if (c & 1) {
401*5c39f954SPhilippe Mathieu-Daudé         r = float32_compare(a, b, &env->fp_status);
402*5c39f954SPhilippe Mathieu-Daudé     } else {
403*5c39f954SPhilippe Mathieu-Daudé         r = float32_compare_quiet(a, b, &env->fp_status);
404*5c39f954SPhilippe Mathieu-Daudé     }
405*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
406*5c39f954SPhilippe Mathieu-Daudé     update_fr0_cmp(env, y, c, r);
407*5c39f954SPhilippe Mathieu-Daudé }
408*5c39f954SPhilippe Mathieu-Daudé 
409*5c39f954SPhilippe Mathieu-Daudé void HELPER(fcmp_d)(CPUHPPAState *env, float64 a, float64 b,
410*5c39f954SPhilippe Mathieu-Daudé                     uint32_t y, uint32_t c)
411*5c39f954SPhilippe Mathieu-Daudé {
412*5c39f954SPhilippe Mathieu-Daudé     FloatRelation r;
413*5c39f954SPhilippe Mathieu-Daudé     if (c & 1) {
414*5c39f954SPhilippe Mathieu-Daudé         r = float64_compare(a, b, &env->fp_status);
415*5c39f954SPhilippe Mathieu-Daudé     } else {
416*5c39f954SPhilippe Mathieu-Daudé         r = float64_compare_quiet(a, b, &env->fp_status);
417*5c39f954SPhilippe Mathieu-Daudé     }
418*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
419*5c39f954SPhilippe Mathieu-Daudé     update_fr0_cmp(env, y, c, r);
420*5c39f954SPhilippe Mathieu-Daudé }
421*5c39f954SPhilippe Mathieu-Daudé 
422*5c39f954SPhilippe Mathieu-Daudé float32 HELPER(fmpyfadd_s)(CPUHPPAState *env, float32 a, float32 b, float32 c)
423*5c39f954SPhilippe Mathieu-Daudé {
424*5c39f954SPhilippe Mathieu-Daudé     float32 ret = float32_muladd(a, b, c, 0, &env->fp_status);
425*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
426*5c39f954SPhilippe Mathieu-Daudé     return ret;
427*5c39f954SPhilippe Mathieu-Daudé }
428*5c39f954SPhilippe Mathieu-Daudé 
429*5c39f954SPhilippe Mathieu-Daudé float32 HELPER(fmpynfadd_s)(CPUHPPAState *env, float32 a, float32 b, float32 c)
430*5c39f954SPhilippe Mathieu-Daudé {
431*5c39f954SPhilippe Mathieu-Daudé     float32 ret = float32_muladd(a, b, c, float_muladd_negate_product,
432*5c39f954SPhilippe Mathieu-Daudé                                  &env->fp_status);
433*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
434*5c39f954SPhilippe Mathieu-Daudé     return ret;
435*5c39f954SPhilippe Mathieu-Daudé }
436*5c39f954SPhilippe Mathieu-Daudé 
437*5c39f954SPhilippe Mathieu-Daudé float64 HELPER(fmpyfadd_d)(CPUHPPAState *env, float64 a, float64 b, float64 c)
438*5c39f954SPhilippe Mathieu-Daudé {
439*5c39f954SPhilippe Mathieu-Daudé     float64 ret = float64_muladd(a, b, c, 0, &env->fp_status);
440*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
441*5c39f954SPhilippe Mathieu-Daudé     return ret;
442*5c39f954SPhilippe Mathieu-Daudé }
443*5c39f954SPhilippe Mathieu-Daudé 
444*5c39f954SPhilippe Mathieu-Daudé float64 HELPER(fmpynfadd_d)(CPUHPPAState *env, float64 a, float64 b, float64 c)
445*5c39f954SPhilippe Mathieu-Daudé {
446*5c39f954SPhilippe Mathieu-Daudé     float64 ret = float64_muladd(a, b, c, float_muladd_negate_product,
447*5c39f954SPhilippe Mathieu-Daudé                                  &env->fp_status);
448*5c39f954SPhilippe Mathieu-Daudé     update_fr0_op(env, GETPC());
449*5c39f954SPhilippe Mathieu-Daudé     return ret;
450*5c39f954SPhilippe Mathieu-Daudé }
451