Statistics
| Branch: | Revision:

root / target-sh4 / op_helper.c @ f8ed7070

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