]> git.proxmox.com Git - qemu.git/blame - target-sh4/op.c
SH4: convert some more arithmetics ops to TCG
[qemu.git] / target-sh4 / op.c
CommitLineData
fdf9b3e8
FB
1/*
2 * SH4 emulation
5fafdf24 3 *
fdf9b3e8
FB
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
fdf9b3e8
FB
22static inline void set_t(void)
23{
24 env->sr |= SR_T;
25}
26
27static inline void clr_t(void)
28{
29 env->sr &= ~SR_T;
30}
31
32static inline void cond_t(int cond)
33{
34 if (cond)
35 set_t();
36 else
37 clr_t();
38}
39
fdf9b3e8
FB
40void OPPROTO op_cmp_str_T0_T1(void)
41{
42 cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) ||
43 (T0 & 0x0000ff00) == (T1 & 0x0000ff00) ||
44 (T0 & 0x00ff0000) == (T1 & 0x00ff0000) ||
45 (T0 & 0xff000000) == (T1 & 0xff000000));
46 RETURN();
47}
48
fdf9b3e8
FB
49void OPPROTO op_div0s_T0_T1(void)
50{
51 if (T1 & 0x80000000)
52 env->sr |= SR_Q;
53 else
54 env->sr &= ~SR_Q;
55 if (T0 & 0x80000000)
56 env->sr |= SR_M;
57 else
58 env->sr &= ~SR_M;
59 cond_t((T1 ^ T0) & 0x80000000);
60 RETURN();
61}
62
fdf9b3e8
FB
63void OPPROTO op_div1_T0_T1(void)
64{
65 helper_div1_T0_T1();
66 RETURN();
67}
68
fdf9b3e8
FB
69void OPPROTO op_shad_T0_T1(void)
70{
71 if ((T0 & 0x80000000) == 0)
72 T1 <<= (T0 & 0x1f);
73 else if ((T0 & 0x1f) == 0)
24988dc2 74 T1 = (T1 & 0x80000000)? 0xffffffff : 0;
fdf9b3e8
FB
75 else
76 T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1);
77 RETURN();
78}
79
80void OPPROTO op_shld_T0_T1(void)
81{
82 if ((T0 & 0x80000000) == 0)
83 T1 <<= (T0 & 0x1f);
84 else if ((T0 & 0x1f) == 0)
85 T1 = 0;
86 else
87 T1 = ((uint32_t) T1) >> ((~T0 & 0x1f) + 1);
88 RETURN();
89}
90
eda9b09b
FB
91void OPPROTO op_ldc_T0_sr(void)
92{
93 env->sr = T0 & 0x700083f3;
94 RETURN();
95}
96
97void OPPROTO op_stc_sr_T0(void)
98{
99 T0 = env->sr;
100 RETURN();
101}
102
fdf9b3e8
FB
103#define LDSTOPS(target,load,store) \
104void OPPROTO op_##load##_T0_##target (void) \
105{ env ->target = T0; RETURN(); \
106} \
107void OPPROTO op_##store##_##target##_T0 (void) \
108{ T0 = env->target; RETURN(); \
109} \
110
fdf9b3e8
FB
111 LDSTOPS(gbr, ldc, stc)
112 LDSTOPS(vbr, ldc, stc)
113 LDSTOPS(ssr, ldc, stc)
114 LDSTOPS(spc, ldc, stc)
115 LDSTOPS(sgr, ldc, stc)
116 LDSTOPS(dbr, ldc, stc)
117 LDSTOPS(mach, lds, sts)
118 LDSTOPS(macl, lds, sts)
119 LDSTOPS(pr, lds, sts)
eda9b09b
FB
120 LDSTOPS(fpul, lds, sts)
121
122void OPPROTO op_lds_T0_fpscr(void)
123{
124 env->fpscr = T0 & 0x003fffff;
ea6cf6be
TS
125 env->fp_status.float_rounding_mode = T0 & 0x01 ?
126 float_round_to_zero : float_round_nearest_even;
127
eda9b09b
FB
128 RETURN();
129}
130
131void OPPROTO op_sts_fpscr_T0(void)
132{
133 T0 = env->fpscr & 0x003fffff;
134 RETURN();
135}
fdf9b3e8 136
fdf9b3e8
FB
137void OPPROTO op_rotcl_Rn(void)
138{
139 helper_rotcl(&env->gregs[PARAM1]);
140 RETURN();
141}
142
143void OPPROTO op_rotcr_Rn(void)
144{
145 helper_rotcr(&env->gregs[PARAM1]);
146 RETURN();
147}
148
6f06939b 149void OPPROTO op_rotl_Rn(void)
fdf9b3e8
FB
150{
151 cond_t(env->gregs[PARAM1] & 0x80000000);
152 env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T);
153 RETURN();
154}
155
156void OPPROTO op_rotr_Rn(void)
157{
158 cond_t(env->gregs[PARAM1] & 1);
159 env->gregs[PARAM1] = (env->gregs[PARAM1] >> 1) |
160 ((env->sr & SR_T) ? 0x80000000 : 0);
161 RETURN();
162}
163
164void OPPROTO op_shal_Rn(void)
165{
166 cond_t(env->gregs[PARAM1] & 0x80000000);
167 env->gregs[PARAM1] <<= 1;
168 RETURN();
169}
170
171void OPPROTO op_shar_Rn(void)
172{
173 cond_t(env->gregs[PARAM1] & 1);
24988dc2 174 *(int32_t *)&env->gregs[PARAM1] >>= 1;
fdf9b3e8
FB
175 RETURN();
176}
177
178void OPPROTO op_shlr_Rn(void)
179{
180 cond_t(env->gregs[PARAM1] & 1);
a5d251bd 181 env->gregs[PARAM1] >>= 1;
fdf9b3e8
FB
182 RETURN();
183}
184
eda9b09b
FB
185void OPPROTO op_fmov_frN_FT0(void)
186{
e04ea3dc 187 FT0 = env->fregs[PARAM1];
eda9b09b
FB
188 RETURN();
189}
190
191void OPPROTO op_fmov_drN_DT0(void)
192{
e04ea3dc
TS
193 CPU_DoubleU d;
194
195 d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
196 d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
197 DT0 = d.d;
eda9b09b
FB
198 RETURN();
199}
200
ea6cf6be
TS
201void OPPROTO op_fmov_frN_FT1(void)
202{
e04ea3dc 203 FT1 = env->fregs[PARAM1];
ea6cf6be
TS
204 RETURN();
205}
206
207void OPPROTO op_fmov_drN_DT1(void)
208{
e04ea3dc
TS
209 CPU_DoubleU d;
210
211 d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
212 d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
213 DT1 = d.d;
ea6cf6be
TS
214 RETURN();
215}
216
eda9b09b
FB
217void OPPROTO op_fmov_FT0_frN(void)
218{
e04ea3dc 219 env->fregs[PARAM1] = FT0;
eda9b09b
FB
220 RETURN();
221}
222
223void OPPROTO op_fmov_DT0_drN(void)
224{
e04ea3dc
TS
225 CPU_DoubleU d;
226
227 d.d = DT0;
228 *(uint32_t *)&env->fregs[PARAM1] = d.l.upper;
229 *(uint32_t *)&env->fregs[PARAM1 + 1] = d.l.lower;
eda9b09b
FB
230 RETURN();
231}
232
ea6cf6be
TS
233void OPPROTO op_fadd_FT(void)
234{
235 FT0 = float32_add(FT0, FT1, &env->fp_status);
236 RETURN();
237}
238
239void OPPROTO op_fadd_DT(void)
240{
241 DT0 = float64_add(DT0, DT1, &env->fp_status);
242 RETURN();
243}
244
245void OPPROTO op_fsub_FT(void)
246{
247 FT0 = float32_sub(FT0, FT1, &env->fp_status);
248 RETURN();
249}
250
251void OPPROTO op_fsub_DT(void)
252{
253 DT0 = float64_sub(DT0, DT1, &env->fp_status);
254 RETURN();
255}
256
257void OPPROTO op_fmul_FT(void)
258{
259 FT0 = float32_mul(FT0, FT1, &env->fp_status);
260 RETURN();
261}
262
263void OPPROTO op_fmul_DT(void)
264{
265 DT0 = float64_mul(DT0, DT1, &env->fp_status);
266 RETURN();
267}
268
269void OPPROTO op_fdiv_FT(void)
270{
271 FT0 = float32_div(FT0, FT1, &env->fp_status);
272 RETURN();
273}
274
275void OPPROTO op_fdiv_DT(void)
276{
277 DT0 = float64_div(DT0, DT1, &env->fp_status);
278 RETURN();
279}
280
24988dc2
AJ
281void OPPROTO op_fcmp_eq_FT(void)
282{
283 cond_t(float32_compare(FT0, FT1, &env->fp_status) == 0);
284 RETURN();
285}
286
287void OPPROTO op_fcmp_eq_DT(void)
288{
289 cond_t(float64_compare(DT0, DT1, &env->fp_status) == 0);
290 RETURN();
291}
292
293void OPPROTO op_fcmp_gt_FT(void)
294{
295 cond_t(float32_compare(FT0, FT1, &env->fp_status) == 1);
296 RETURN();
297}
298
299void OPPROTO op_fcmp_gt_DT(void)
300{
301 cond_t(float64_compare(DT0, DT1, &env->fp_status) == 1);
302 RETURN();
303}
304
ea6cf6be
TS
305void OPPROTO op_float_FT(void)
306{
307 FT0 = int32_to_float32(env->fpul, &env->fp_status);
308 RETURN();
309}
310
311void OPPROTO op_float_DT(void)
312{
313 DT0 = int32_to_float64(env->fpul, &env->fp_status);
314 RETURN();
315}
316
317void OPPROTO op_ftrc_FT(void)
318{
319 env->fpul = float32_to_int32_round_to_zero(FT0, &env->fp_status);
320 RETURN();
321}
322
323void OPPROTO op_ftrc_DT(void)
324{
325 env->fpul = float64_to_int32_round_to_zero(DT0, &env->fp_status);
326 RETURN();
327}
328
24988dc2
AJ
329void OPPROTO op_fneg_frN(void)
330{
331 env->fregs[PARAM1] = float32_chs(env->fregs[PARAM1]);
332 RETURN();
333}
334
335void OPPROTO op_fabs_FT(void)
336{
337 FT0 = float32_abs(FT0);
338 RETURN();
339}
340
341void OPPROTO op_fabs_DT(void)
342{
343 DT0 = float64_abs(DT0);
344 RETURN();
345}
346
347void OPPROTO op_fcnvsd_FT_DT(void)
348{
349 DT0 = float32_to_float64(FT0, &env->fp_status);
350 RETURN();
351}
352
353void OPPROTO op_fcnvds_DT_FT(void)
354{
355 FT0 = float64_to_float32(DT0, &env->fp_status);
356 RETURN();
357}
358
359void OPPROTO op_fsqrt_FT(void)
360{
361 FT0 = float32_sqrt(FT0, &env->fp_status);
362 RETURN();
363}
364
365void OPPROTO op_fsqrt_DT(void)
366{
367 DT0 = float64_sqrt(DT0, &env->fp_status);
368 RETURN();
369}
370
ea6cf6be
TS
371void OPPROTO op_fmov_T0_frN(void)
372{
24988dc2 373 *(uint32_t *)&env->fregs[PARAM1] = T0;
ea6cf6be
TS
374 RETURN();
375}
376
eda9b09b
FB
377void OPPROTO op_movl_fpul_FT0(void)
378{
379 FT0 = *(float32 *)&env->fpul;
380 RETURN();
381}
382
383void OPPROTO op_movl_FT0_fpul(void)
384{
385 *(float32 *)&env->fpul = FT0;
386 RETURN();
387}
388
fdf9b3e8
FB
389/* Load and store */
390#define MEMSUFFIX _raw
391#include "op_mem.c"
392#undef MEMSUFFIX
393#if !defined(CONFIG_USER_ONLY)
394#define MEMSUFFIX _user
395#include "op_mem.c"
396#undef MEMSUFFIX
397
398#define MEMSUFFIX _kernel
399#include "op_mem.c"
400#undef MEMSUFFIX
401#endif