]> git.proxmox.com Git - mirror_qemu.git/blame - target-sh4/op_helper.c
Fix some warnings that would be generated by gcc -Wredundant-decls
[mirror_qemu.git] / target-sh4 / op_helper.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 <assert.h>
21#include "exec.h"
22
fdf9b3e8
FB
23#ifndef CONFIG_USER_ONLY
24
25#define MMUSUFFIX _mmu
fdf9b3e8
FB
26
27#define SHIFT 0
28#include "softmmu_template.h"
29
30#define SHIFT 1
31#include "softmmu_template.h"
32
33#define SHIFT 2
34#include "softmmu_template.h"
35
36#define SHIFT 3
37#include "softmmu_template.h"
38
6ebbf390 39void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
fdf9b3e8
FB
40{
41 TranslationBlock *tb;
42 CPUState *saved_env;
43 unsigned long pc;
44 int ret;
45
46 /* XXX: hack to restore env in all cases, even if not called from
47 generated code */
48 saved_env = env;
49 env = cpu_single_env;
6ebbf390 50 ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
fdf9b3e8
FB
51 if (ret) {
52 if (retaddr) {
53 /* now we have a real cpu fault */
54 pc = (unsigned long) retaddr;
55 tb = tb_find_pc(pc);
56 if (tb) {
57 /* the PC is inside the translated code. It means that we have
58 a virtual CPU fault */
59 cpu_restore_state(tb, env, pc, NULL);
60 }
61 }
e6afc2f4 62 cpu_loop_exit();
fdf9b3e8
FB
63 }
64 env = saved_env;
65}
66
67#endif
68
ea2b542a
AJ
69void helper_ldtlb(void)
70{
71#ifdef CONFIG_USER_ONLY
72 /* XXXXX */
73 assert(0);
74#else
75 cpu_load_tlb(env);
76#endif
77}
78
e6afc2f4
AJ
79void helper_raise_illegal_instruction(void)
80{
81 env->exception_index = 0x180;
82 cpu_loop_exit();
83}
84
85void helper_raise_slot_illegal_instruction(void)
86{
87 env->exception_index = 0x1a0;
88 cpu_loop_exit();
89}
90
91void helper_debug(void)
92{
93 env->exception_index = EXCP_DEBUG;
94 cpu_loop_exit();
95}
96
97void helper_sleep(void)
98{
99 env->halted = 1;
100 env->exception_index = EXCP_HLT;
101 cpu_loop_exit();
102}
103
104void helper_trapa(uint32_t tra)
105{
106 env->tra = tra << 2;
107 env->exception_index = 0x160;
108 cpu_loop_exit();
109}
110
fdf9b3e8
FB
111void helper_addc_T0_T1(void)
112{
113 uint32_t tmp0, tmp1;
114
115 tmp1 = T0 + T1;
116 tmp0 = T1;
117 T1 = tmp1 + (env->sr & 1);
118 if (tmp0 > tmp1)
119 env->sr |= SR_T;
120 else
121 env->sr &= ~SR_T;
122 if (tmp1 > T1)
123 env->sr |= SR_T;
124}
125
126void helper_addv_T0_T1(void)
127{
128 uint32_t dest, src, ans;
129
130 if ((int32_t) T1 >= 0)
131 dest = 0;
132 else
133 dest = 1;
134 if ((int32_t) T0 >= 0)
135 src = 0;
136 else
137 src = 1;
138 src += dest;
139 T1 += T0;
140 if ((int32_t) T1 >= 0)
141 ans = 0;
142 else
143 ans = 1;
144 ans += dest;
145 if (src == 0 || src == 2) {
146 if (ans == 1)
147 env->sr |= SR_T;
148 else
149 env->sr &= ~SR_T;
150 } else
151 env->sr &= ~SR_T;
152}
153
154#define T (env->sr & SR_T)
155#define Q (env->sr & SR_Q ? 1 : 0)
156#define M (env->sr & SR_M ? 1 : 0)
157#define SETT env->sr |= SR_T
158#define CLRT env->sr &= ~SR_T
159#define SETQ env->sr |= SR_Q
160#define CLRQ env->sr &= ~SR_Q
161#define SETM env->sr |= SR_M
162#define CLRM env->sr &= ~SR_M
163
164void helper_div1_T0_T1(void)
165{
166 uint32_t tmp0, tmp2;
167 uint8_t old_q, tmp1 = 0xff;
168
397e923f 169 //printf("div1 T0=0x%08x T1=0x%08x M=%d Q=%d T=%d\n", T0, T1, M, Q, T);
fdf9b3e8
FB
170 old_q = Q;
171 if ((0x80000000 & T1) != 0)
172 SETQ;
173 else
174 CLRQ;
175 tmp2 = T0;
176 T1 <<= 1;
177 T1 |= T;
178 switch (old_q) {
179 case 0:
180 switch (M) {
181 case 0:
182 tmp0 = T1;
183 T1 -= tmp2;
184 tmp1 = T1 > tmp0;
185 switch (Q) {
186 case 0:
187 if (tmp1)
188 SETQ;
189 else
190 CLRQ;
191 break;
192 case 1:
193 if (tmp1 == 0)
194 SETQ;
195 else
196 CLRQ;
197 break;
198 }
199 break;
200 case 1:
201 tmp0 = T1;
202 T1 += tmp2;
203 tmp1 = T1 < tmp0;
204 switch (Q) {
205 case 0:
206 if (tmp1 == 0)
207 SETQ;
208 else
209 CLRQ;
210 break;
211 case 1:
212 if (tmp1)
213 SETQ;
214 else
215 CLRQ;
216 break;
217 }
218 break;
219 }
220 break;
221 case 1:
222 switch (M) {
223 case 0:
224 tmp0 = T1;
225 T1 += tmp2;
226 tmp1 = T1 < tmp0;
227 switch (Q) {
228 case 0:
229 if (tmp1)
230 SETQ;
231 else
232 CLRQ;
233 break;
234 case 1:
235 if (tmp1 == 0)
236 SETQ;
237 else
238 CLRQ;
239 break;
240 }
241 break;
242 case 1:
243 tmp0 = T1;
244 T1 -= tmp2;
245 tmp1 = T1 > tmp0;
246 switch (Q) {
247 case 0:
248 if (tmp1 == 0)
249 SETQ;
250 else
251 CLRQ;
252 break;
253 case 1:
254 if (tmp1)
255 SETQ;
256 else
257 CLRQ;
258 break;
259 }
260 break;
261 }
262 break;
263 }
264 if (Q == M)
265 SETT;
266 else
267 CLRT;
397e923f 268 //printf("Output: T1=0x%08x M=%d Q=%d T=%d\n", T1, M, Q, T);
fdf9b3e8
FB
269}
270
271void helper_dmulsl_T0_T1()
272{
273 int64_t res;
274
275 res = (int64_t) (int32_t) T0 *(int64_t) (int32_t) T1;
276 env->mach = (res >> 32) & 0xffffffff;
277 env->macl = res & 0xffffffff;
278}
279
280void helper_dmulul_T0_T1()
281{
282 uint64_t res;
283
284 res = (uint64_t) (uint32_t) T0 *(uint64_t) (uint32_t) T1;
285 env->mach = (res >> 32) & 0xffffffff;
286 env->macl = res & 0xffffffff;
287}
288
289void helper_macl_T0_T1()
290{
291 int64_t res;
292
293 res = ((uint64_t) env->mach << 32) | env->macl;
294 res += (int64_t) (int32_t) T0 *(int64_t) (int32_t) T1;
295 env->mach = (res >> 32) & 0xffffffff;
296 env->macl = res & 0xffffffff;
297 if (env->sr & SR_S) {
298 if (res < 0)
299 env->mach |= 0xffff0000;
300 else
301 env->mach &= 0x00007fff;
302 }
303}
304
305void helper_macw_T0_T1()
306{
307 int64_t res;
308
309 res = ((uint64_t) env->mach << 32) | env->macl;
310 res += (int64_t) (int16_t) T0 *(int64_t) (int16_t) T1;
311 env->mach = (res >> 32) & 0xffffffff;
312 env->macl = res & 0xffffffff;
313 if (env->sr & SR_S) {
314 if (res < -0x80000000) {
315 env->mach = 1;
316 env->macl = 0x80000000;
317 } else if (res > 0x000000007fffffff) {
318 env->mach = 1;
319 env->macl = 0x7fffffff;
320 }
321 }
322}
323
324void helper_negc_T0()
325{
326 uint32_t temp;
327
328 temp = -T0;
329 T0 = temp - (env->sr & SR_T);
330 if (0 < temp)
331 env->sr |= SR_T;
332 else
333 env->sr &= ~SR_T;
334 if (temp < T0)
335 env->sr |= SR_T;
336}
337
338void helper_subc_T0_T1()
339{
340 uint32_t tmp0, tmp1;
341
342 tmp1 = T1 - T0;
343 tmp0 = T1;
344 T1 = tmp1 - (env->sr & SR_T);
345 if (tmp0 < tmp1)
346 env->sr |= SR_T;
347 else
348 env->sr &= ~SR_T;
349 if (tmp1 < T1)
350 env->sr |= SR_T;
351}
352
353void helper_subv_T0_T1()
354{
355 int32_t dest, src, ans;
356
357 if ((int32_t) T1 >= 0)
358 dest = 0;
359 else
360 dest = 1;
361 if ((int32_t) T0 >= 0)
362 src = 0;
363 else
364 src = 1;
365 src += dest;
366 T1 -= T0;
367 if ((int32_t) T1 >= 0)
368 ans = 0;
369 else
370 ans = 1;
371 ans += dest;
372 if (src == 1) {
373 if (ans == 1)
374 env->sr |= SR_T;
375 else
376 env->sr &= ~SR_T;
377 } else
378 env->sr &= ~SR_T;
379}
380
381void helper_rotcl(uint32_t * addr)
382{
383 uint32_t new;
384
385 new = (*addr << 1) | (env->sr & SR_T);
386 if (*addr & 0x80000000)
387 env->sr |= SR_T;
388 else
389 env->sr &= ~SR_T;
390 *addr = new;
391}
392
393void helper_rotcr(uint32_t * addr)
394{
395 uint32_t new;
396
397 new = (*addr >> 1) | ((env->sr & SR_T) ? 0x80000000 : 0);
398 if (*addr & 1)
399 env->sr |= SR_T;
400 else
401 env->sr &= ~SR_T;
402 *addr = new;
403}