Statistics
| Branch: | Revision:

root / target-sh4 / op_helper.c @ 273af660

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