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