Statistics
| Branch: | Revision:

root / target-sh4 / op_helper.c @ 5fafdf24

History | View | Annotate | Download (6.5 kB)

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