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