SH4: Convert remaining non-fp ops to TCG
[qemu] / target-sh4 / op.c
1 /*
2  *  SH4 emulation
3  *
4  *  Copyright (c) 2005 Samuel Tardieu
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #include "exec.h"
21
22 static inline void set_t(void)
23 {
24     env->sr |= SR_T;
25 }
26
27 static inline void clr_t(void)
28 {
29     env->sr &= ~SR_T;
30 }
31
32 static inline void cond_t(int cond)
33 {
34     if (cond)
35         set_t();
36     else
37         clr_t();
38 }
39
40 void OPPROTO op_fmov_frN_FT0(void)
41 {
42     FT0 = env->fregs[PARAM1];
43     RETURN();
44 }
45
46 void OPPROTO op_fmov_drN_DT0(void)
47 {
48     CPU_DoubleU d;
49
50     d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
51     d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
52     DT0 = d.d;
53     RETURN();
54 }
55
56 void OPPROTO op_fmov_frN_FT1(void)
57 {
58     FT1 = env->fregs[PARAM1];
59     RETURN();
60 }
61
62 void OPPROTO op_fmov_drN_DT1(void)
63 {
64     CPU_DoubleU d;
65
66     d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
67     d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
68     DT1 = d.d;
69     RETURN();
70 }
71
72 void OPPROTO op_fmov_FT0_frN(void)
73 {
74     env->fregs[PARAM1] = FT0;
75     RETURN();
76 }
77
78 void OPPROTO op_fmov_DT0_drN(void)
79 {
80     CPU_DoubleU d;
81
82     d.d = DT0;
83     *(uint32_t *)&env->fregs[PARAM1] = d.l.upper;
84     *(uint32_t *)&env->fregs[PARAM1 + 1] = d.l.lower;
85     RETURN();
86 }
87
88 void OPPROTO op_fadd_FT(void)
89 {
90     FT0 = float32_add(FT0, FT1, &env->fp_status);
91     RETURN();
92 }
93
94 void OPPROTO op_fadd_DT(void)
95 {
96     DT0 = float64_add(DT0, DT1, &env->fp_status);
97     RETURN();
98 }
99
100 void OPPROTO op_fsub_FT(void)
101 {
102     FT0 = float32_sub(FT0, FT1, &env->fp_status);
103     RETURN();
104 }
105
106 void OPPROTO op_fsub_DT(void)
107 {
108     DT0 = float64_sub(DT0, DT1, &env->fp_status);
109     RETURN();
110 }
111
112 void OPPROTO op_fmul_FT(void)
113 {
114     FT0 = float32_mul(FT0, FT1, &env->fp_status);
115     RETURN();
116 }
117
118 void OPPROTO op_fmul_DT(void)
119 {
120     DT0 = float64_mul(DT0, DT1, &env->fp_status);
121     RETURN();
122 }
123
124 void OPPROTO op_fdiv_FT(void)
125 {
126     FT0 = float32_div(FT0, FT1, &env->fp_status);
127     RETURN();
128 }
129
130 void OPPROTO op_fdiv_DT(void)
131 {
132     DT0 = float64_div(DT0, DT1, &env->fp_status);
133     RETURN();
134 }
135
136 void OPPROTO op_fcmp_eq_FT(void)
137 {
138     cond_t(float32_compare(FT0, FT1, &env->fp_status) == 0);
139     RETURN();
140 }
141
142 void OPPROTO op_fcmp_eq_DT(void)
143 {
144     cond_t(float64_compare(DT0, DT1, &env->fp_status) == 0);
145     RETURN();
146 }
147
148 void OPPROTO op_fcmp_gt_FT(void)
149 {
150     cond_t(float32_compare(FT0, FT1, &env->fp_status) == 1);
151     RETURN();
152 }
153
154 void OPPROTO op_fcmp_gt_DT(void)
155 {
156     cond_t(float64_compare(DT0, DT1, &env->fp_status) == 1);
157     RETURN();
158 }
159
160 void OPPROTO op_float_FT(void)
161 {
162     FT0 = int32_to_float32(env->fpul, &env->fp_status);
163     RETURN();
164 }
165
166 void OPPROTO op_float_DT(void)
167 {
168     DT0 = int32_to_float64(env->fpul, &env->fp_status);
169     RETURN();
170 }
171
172 void OPPROTO op_ftrc_FT(void)
173 {
174     env->fpul = float32_to_int32_round_to_zero(FT0, &env->fp_status);
175     RETURN();
176 }
177
178 void OPPROTO op_ftrc_DT(void)
179 {
180     env->fpul = float64_to_int32_round_to_zero(DT0, &env->fp_status);
181     RETURN();
182 }
183
184 void OPPROTO op_fneg_frN(void)
185 {
186     env->fregs[PARAM1] = float32_chs(env->fregs[PARAM1]);
187     RETURN();
188 }
189
190 void OPPROTO op_fabs_FT(void)
191 {
192     FT0 = float32_abs(FT0);
193     RETURN();
194 }
195
196 void OPPROTO op_fabs_DT(void)
197 {
198     DT0 = float64_abs(DT0);
199     RETURN();
200 }
201
202 void OPPROTO op_fcnvsd_FT_DT(void)
203 {
204     DT0 = float32_to_float64(FT0, &env->fp_status);
205     RETURN();
206 }
207
208 void OPPROTO op_fcnvds_DT_FT(void)
209 {
210     FT0 = float64_to_float32(DT0, &env->fp_status);
211     RETURN();
212 }
213
214 void OPPROTO op_fsqrt_FT(void)
215 {
216     FT0 = float32_sqrt(FT0, &env->fp_status);
217     RETURN();
218 }
219
220 void OPPROTO op_fsqrt_DT(void)
221 {
222     DT0 = float64_sqrt(DT0, &env->fp_status);
223     RETURN();
224 }
225
226 void OPPROTO op_fmov_T0_frN(void)
227 {
228     *(uint32_t *)&env->fregs[PARAM1] = T0;
229     RETURN();
230 }
231
232 void OPPROTO op_movl_fpul_FT0(void)
233 {
234     FT0 = *(float32 *)&env->fpul;
235     RETURN();
236 }
237
238 void OPPROTO op_movl_FT0_fpul(void)
239 {
240     *(float32 *)&env->fpul = FT0;
241     RETURN();
242 }
243
244 /* Load and store */
245 #define MEMSUFFIX _raw
246 #include "op_mem.c"
247 #undef MEMSUFFIX
248 #if !defined(CONFIG_USER_ONLY)
249 #define MEMSUFFIX _user
250 #include "op_mem.c"
251 #undef MEMSUFFIX
252
253 #define MEMSUFFIX _kernel
254 #include "op_mem.c"
255 #undef MEMSUFFIX
256 #endif