Statistics
| Branch: | Revision:

root / target-cris / op_helper.c @ 8686c490

History | View | Annotate | Download (10.7 kB)

1 81fdc5f8 ths
/*
2 81fdc5f8 ths
 *  CRIS helper routines
3 81fdc5f8 ths
 *
4 81fdc5f8 ths
 *  Copyright (c) 2007 AXIS Communications
5 81fdc5f8 ths
 *  Written by Edgar E. Iglesias
6 81fdc5f8 ths
 *
7 81fdc5f8 ths
 * This library is free software; you can redistribute it and/or
8 81fdc5f8 ths
 * modify it under the terms of the GNU Lesser General Public
9 81fdc5f8 ths
 * License as published by the Free Software Foundation; either
10 81fdc5f8 ths
 * version 2 of the License, or (at your option) any later version.
11 81fdc5f8 ths
 *
12 81fdc5f8 ths
 * This library is distributed in the hope that it will be useful,
13 81fdc5f8 ths
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 81fdc5f8 ths
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 81fdc5f8 ths
 * Lesser General Public License for more details.
16 81fdc5f8 ths
 *
17 81fdc5f8 ths
 * You should have received a copy of the GNU Lesser General Public
18 81fdc5f8 ths
 * License along with this library; if not, write to the Free Software
19 81fdc5f8 ths
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 81fdc5f8 ths
 */
21 81fdc5f8 ths
22 81fdc5f8 ths
#include <assert.h>
23 81fdc5f8 ths
#include "exec.h"
24 786c02f1 edgar_igl
#include "mmu.h"
25 81fdc5f8 ths
26 81fdc5f8 ths
#define MMUSUFFIX _mmu
27 273af660 ths
#ifdef __s390__
28 273af660 ths
# define GETPC() ((void*)((unsigned long)__builtin_return_address(0) & 0x7fffffffUL))
29 273af660 ths
#else
30 273af660 ths
# define GETPC() (__builtin_return_address(0))
31 273af660 ths
#endif
32 81fdc5f8 ths
33 81fdc5f8 ths
#define SHIFT 0
34 81fdc5f8 ths
#include "softmmu_template.h"
35 81fdc5f8 ths
36 81fdc5f8 ths
#define SHIFT 1
37 81fdc5f8 ths
#include "softmmu_template.h"
38 81fdc5f8 ths
39 81fdc5f8 ths
#define SHIFT 2
40 81fdc5f8 ths
#include "softmmu_template.h"
41 81fdc5f8 ths
42 81fdc5f8 ths
#define SHIFT 3
43 81fdc5f8 ths
#include "softmmu_template.h"
44 81fdc5f8 ths
45 786c02f1 edgar_igl
#define D(x)
46 786c02f1 edgar_igl
47 81fdc5f8 ths
/* Try to fill the TLB and return an exception if error. If retaddr is
48 81fdc5f8 ths
   NULL, it means that the function was called in C code (i.e. not
49 81fdc5f8 ths
   from generated code or from helper.c) */
50 81fdc5f8 ths
/* XXX: fix it to restore all registers */
51 6ebbf390 j_mayer
void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
52 81fdc5f8 ths
{
53 81fdc5f8 ths
    TranslationBlock *tb;
54 81fdc5f8 ths
    CPUState *saved_env;
55 44f8625d bellard
    unsigned long pc;
56 81fdc5f8 ths
    int ret;
57 81fdc5f8 ths
58 81fdc5f8 ths
    /* XXX: hack to restore env in all cases, even if not called from
59 81fdc5f8 ths
       generated code */
60 81fdc5f8 ths
    saved_env = env;
61 81fdc5f8 ths
    env = cpu_single_env;
62 b41f7df0 edgar_igl
63 ef29a70d edgar_igl
    D(fprintf(logfile, "%s pc=%x tpc=%x ra=%x\n", __func__, 
64 ef29a70d edgar_igl
             env->pc, env->debug1, retaddr));
65 6ebbf390 j_mayer
    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
66 81fdc5f8 ths
    if (__builtin_expect(ret, 0)) {
67 81fdc5f8 ths
        if (retaddr) {
68 81fdc5f8 ths
            /* now we have a real cpu fault */
69 44f8625d bellard
            pc = (unsigned long)retaddr;
70 81fdc5f8 ths
            tb = tb_find_pc(pc);
71 81fdc5f8 ths
            if (tb) {
72 81fdc5f8 ths
                /* the PC is inside the translated code. It means that we have
73 81fdc5f8 ths
                   a virtual CPU fault */
74 81fdc5f8 ths
                cpu_restore_state(tb, env, pc, NULL);
75 81fdc5f8 ths
            }
76 81fdc5f8 ths
        }
77 81fdc5f8 ths
        cpu_loop_exit();
78 81fdc5f8 ths
    }
79 81fdc5f8 ths
    env = saved_env;
80 81fdc5f8 ths
}
81 81fdc5f8 ths
82 dceaf394 edgar_igl
void helper_raise_exception(uint32_t index)
83 786c02f1 edgar_igl
{
84 dceaf394 edgar_igl
        env->exception_index = index;
85 dceaf394 edgar_igl
        cpu_loop_exit();
86 786c02f1 edgar_igl
}
87 786c02f1 edgar_igl
88 b41f7df0 edgar_igl
void helper_tlb_flush(void)
89 b41f7df0 edgar_igl
{
90 b41f7df0 edgar_igl
        tlb_flush(env, 1);
91 b41f7df0 edgar_igl
}
92 b41f7df0 edgar_igl
93 b41f7df0 edgar_igl
void helper_dump(uint32_t a0, uint32_t a1)
94 b41f7df0 edgar_igl
{
95 b41f7df0 edgar_igl
        (fprintf(logfile, "%s: a0=%x a1=%x\n", __func__, a0, a1)); 
96 b41f7df0 edgar_igl
}
97 b41f7df0 edgar_igl
98 b41f7df0 edgar_igl
void helper_dummy(void)
99 b41f7df0 edgar_igl
{
100 b41f7df0 edgar_igl
101 b41f7df0 edgar_igl
}
102 b41f7df0 edgar_igl
103 dceaf394 edgar_igl
void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg)
104 dceaf394 edgar_igl
{
105 dceaf394 edgar_igl
        uint32_t srs;
106 dceaf394 edgar_igl
        srs = env->pregs[PR_SRS];
107 dceaf394 edgar_igl
        srs &= 3;
108 dceaf394 edgar_igl
        env->sregs[srs][sreg] = env->regs[reg];
109 dceaf394 edgar_igl
110 dceaf394 edgar_igl
#if !defined(CONFIG_USER_ONLY)
111 dceaf394 edgar_igl
        if (srs == 1 || srs == 2) {
112 dceaf394 edgar_igl
                if (sreg == 6) {
113 dceaf394 edgar_igl
                        /* Writes to tlb-hi write to mm_cause as a side 
114 dceaf394 edgar_igl
                           effect.  */
115 dceaf394 edgar_igl
                        env->sregs[SFR_RW_MM_TLB_HI] = T0;
116 dceaf394 edgar_igl
                        env->sregs[SFR_R_MM_CAUSE] = T0;
117 dceaf394 edgar_igl
                }
118 dceaf394 edgar_igl
                else if (sreg == 5) {
119 dceaf394 edgar_igl
                        uint32_t set;
120 dceaf394 edgar_igl
                        uint32_t idx;
121 dceaf394 edgar_igl
                        uint32_t lo, hi;
122 dceaf394 edgar_igl
                        uint32_t vaddr;
123 dceaf394 edgar_igl
124 dceaf394 edgar_igl
                        vaddr = cris_mmu_tlb_latest_update(env);
125 dceaf394 edgar_igl
                        D(fprintf(logfile, "tlb flush vaddr=%x\n", vaddr));
126 dceaf394 edgar_igl
                        tlb_flush_page(env, vaddr);
127 dceaf394 edgar_igl
128 dceaf394 edgar_igl
                        idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
129 dceaf394 edgar_igl
                        set >>= 4;
130 dceaf394 edgar_igl
                        set &= 3;
131 dceaf394 edgar_igl
132 dceaf394 edgar_igl
                        idx &= 15;
133 dceaf394 edgar_igl
                        /* We've just made a write to tlb_lo.  */
134 dceaf394 edgar_igl
                        lo = env->sregs[SFR_RW_MM_TLB_LO];
135 dceaf394 edgar_igl
                        /* Writes are done via r_mm_cause.  */
136 dceaf394 edgar_igl
                        hi = env->sregs[SFR_R_MM_CAUSE];
137 dceaf394 edgar_igl
                        env->tlbsets[srs - 1][set][idx].lo = lo;
138 dceaf394 edgar_igl
                        env->tlbsets[srs - 1][set][idx].hi = hi;
139 dceaf394 edgar_igl
                }
140 dceaf394 edgar_igl
        }
141 dceaf394 edgar_igl
#endif
142 dceaf394 edgar_igl
}
143 dceaf394 edgar_igl
144 dceaf394 edgar_igl
void helper_movl_reg_sreg (uint32_t reg, uint32_t sreg)
145 dceaf394 edgar_igl
{
146 dceaf394 edgar_igl
        uint32_t srs;
147 dceaf394 edgar_igl
        env->pregs[PR_SRS] &= 3;
148 dceaf394 edgar_igl
        srs = env->pregs[PR_SRS];
149 dceaf394 edgar_igl
        
150 dceaf394 edgar_igl
#if !defined(CONFIG_USER_ONLY)
151 dceaf394 edgar_igl
        if (srs == 1 || srs == 2)
152 dceaf394 edgar_igl
        {
153 dceaf394 edgar_igl
                uint32_t set;
154 dceaf394 edgar_igl
                uint32_t idx;
155 dceaf394 edgar_igl
                uint32_t lo, hi;
156 dceaf394 edgar_igl
157 dceaf394 edgar_igl
                idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
158 dceaf394 edgar_igl
                set >>= 4;
159 dceaf394 edgar_igl
                set &= 3;
160 dceaf394 edgar_igl
                idx &= 15;
161 dceaf394 edgar_igl
162 dceaf394 edgar_igl
                /* Update the mirror regs.  */
163 dceaf394 edgar_igl
                hi = env->tlbsets[srs - 1][set][idx].hi;
164 dceaf394 edgar_igl
                lo = env->tlbsets[srs - 1][set][idx].lo;
165 dceaf394 edgar_igl
                env->sregs[SFR_RW_MM_TLB_HI] = hi;
166 dceaf394 edgar_igl
                env->sregs[SFR_RW_MM_TLB_LO] = lo;
167 dceaf394 edgar_igl
        }
168 dceaf394 edgar_igl
#endif
169 dceaf394 edgar_igl
        env->regs[reg] = env->sregs[srs][sreg];
170 dceaf394 edgar_igl
        RETURN();
171 dceaf394 edgar_igl
}
172 dceaf394 edgar_igl
173 dceaf394 edgar_igl
static void cris_ccs_rshift(CPUState *env)
174 dceaf394 edgar_igl
{
175 dceaf394 edgar_igl
        uint32_t ccs;
176 dceaf394 edgar_igl
177 dceaf394 edgar_igl
        /* Apply the ccs shift.  */
178 dceaf394 edgar_igl
        ccs = env->pregs[PR_CCS];
179 dceaf394 edgar_igl
        ccs = (ccs & 0xc0000000) | ((ccs & 0x0fffffff) >> 10);
180 dceaf394 edgar_igl
        if (ccs & U_FLAG)
181 dceaf394 edgar_igl
        {
182 dceaf394 edgar_igl
                /* Enter user mode.  */
183 dceaf394 edgar_igl
                env->ksp = env->regs[R_SP];
184 dceaf394 edgar_igl
                env->regs[R_SP] = env->pregs[PR_USP];
185 dceaf394 edgar_igl
        }
186 dceaf394 edgar_igl
187 dceaf394 edgar_igl
        env->pregs[PR_CCS] = ccs;
188 dceaf394 edgar_igl
}
189 dceaf394 edgar_igl
190 b41f7df0 edgar_igl
void helper_rfe(void)
191 b41f7df0 edgar_igl
{
192 b41f7df0 edgar_igl
        D(fprintf(logfile, "rfe: erp=%x pid=%x ccs=%x btarget=%x\n", 
193 b41f7df0 edgar_igl
                 env->pregs[PR_ERP], env->pregs[PR_PID],
194 b41f7df0 edgar_igl
                 env->pregs[PR_CCS],
195 b41f7df0 edgar_igl
                 env->btarget));
196 dceaf394 edgar_igl
197 dceaf394 edgar_igl
        cris_ccs_rshift(env);
198 dceaf394 edgar_igl
199 dceaf394 edgar_igl
        /* RFE sets the P_FLAG only if the R_FLAG is not set.  */
200 dceaf394 edgar_igl
        if (!(env->pregs[PR_CCS] & R_FLAG))
201 dceaf394 edgar_igl
                env->pregs[PR_CCS] |= P_FLAG;
202 b41f7df0 edgar_igl
}
203 b41f7df0 edgar_igl
204 b41f7df0 edgar_igl
void helper_store(uint32_t a0)
205 b41f7df0 edgar_igl
{
206 b41f7df0 edgar_igl
        if (env->pregs[PR_CCS] & P_FLAG )
207 b41f7df0 edgar_igl
        {
208 b41f7df0 edgar_igl
                cpu_abort(env, "cond_store_failed! pc=%x a0=%x\n",
209 b41f7df0 edgar_igl
                          env->pc, a0);
210 b41f7df0 edgar_igl
        }
211 b41f7df0 edgar_igl
}
212 b41f7df0 edgar_igl
213 81fdc5f8 ths
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
214 81fdc5f8 ths
                          int is_asi)
215 81fdc5f8 ths
{
216 786c02f1 edgar_igl
        D(printf("%s addr=%x w=%d ex=%d asi=%d\n", 
217 786c02f1 edgar_igl
                __func__, addr, is_write, is_exec, is_asi));
218 81fdc5f8 ths
}
219 b41f7df0 edgar_igl
220 b41f7df0 edgar_igl
static void evaluate_flags_writeback(uint32_t flags)
221 b41f7df0 edgar_igl
{
222 b41f7df0 edgar_igl
        int x;
223 b41f7df0 edgar_igl
224 b41f7df0 edgar_igl
        /* Extended arithmetics, leave the z flag alone.  */
225 b41f7df0 edgar_igl
        env->debug3 = env->pregs[PR_CCS];
226 b41f7df0 edgar_igl
227 b41f7df0 edgar_igl
        if (env->cc_x_live)
228 b41f7df0 edgar_igl
                x = env->cc_x;
229 b41f7df0 edgar_igl
        else
230 b41f7df0 edgar_igl
                x = env->pregs[PR_CCS] & X_FLAG;
231 b41f7df0 edgar_igl
232 b41f7df0 edgar_igl
        if ((x || env->cc_op == CC_OP_ADDC)
233 b41f7df0 edgar_igl
            && flags & Z_FLAG)
234 b41f7df0 edgar_igl
                env->cc_mask &= ~Z_FLAG;
235 b41f7df0 edgar_igl
236 b41f7df0 edgar_igl
        /* all insn clear the x-flag except setf or clrf.  */
237 b41f7df0 edgar_igl
        env->pregs[PR_CCS] &= ~(env->cc_mask | X_FLAG);
238 b41f7df0 edgar_igl
        flags &= env->cc_mask;
239 b41f7df0 edgar_igl
        env->pregs[PR_CCS] |= flags;
240 b41f7df0 edgar_igl
}
241 b41f7df0 edgar_igl
242 b41f7df0 edgar_igl
void helper_evaluate_flags_muls(void)
243 b41f7df0 edgar_igl
{
244 b41f7df0 edgar_igl
        uint32_t src;
245 b41f7df0 edgar_igl
        uint32_t dst;
246 b41f7df0 edgar_igl
        uint32_t res;
247 b41f7df0 edgar_igl
        uint32_t flags = 0;
248 dceaf394 edgar_igl
        int64_t tmp;
249 b41f7df0 edgar_igl
        int32_t mof;
250 b41f7df0 edgar_igl
        int dneg;
251 b41f7df0 edgar_igl
252 b41f7df0 edgar_igl
        src = env->cc_src;
253 b41f7df0 edgar_igl
        dst = env->cc_dest;
254 b41f7df0 edgar_igl
        res = env->cc_result;
255 b41f7df0 edgar_igl
256 b41f7df0 edgar_igl
        dneg = ((int32_t)res) < 0;
257 b41f7df0 edgar_igl
258 dceaf394 edgar_igl
        mof = env->pregs[PR_MOF];
259 dceaf394 edgar_igl
        tmp = mof;
260 dceaf394 edgar_igl
        tmp <<= 32;
261 dceaf394 edgar_igl
        tmp |= res;
262 b41f7df0 edgar_igl
        if (tmp == 0)
263 b41f7df0 edgar_igl
                flags |= Z_FLAG;
264 b41f7df0 edgar_igl
        else if (tmp < 0)
265 b41f7df0 edgar_igl
                flags |= N_FLAG;
266 b41f7df0 edgar_igl
        if ((dneg && mof != -1)
267 b41f7df0 edgar_igl
            || (!dneg && mof != 0))
268 b41f7df0 edgar_igl
                flags |= V_FLAG;
269 b41f7df0 edgar_igl
        evaluate_flags_writeback(flags);
270 b41f7df0 edgar_igl
}
271 b41f7df0 edgar_igl
272 b41f7df0 edgar_igl
void  helper_evaluate_flags_mulu(void)
273 b41f7df0 edgar_igl
{
274 b41f7df0 edgar_igl
        uint32_t src;
275 b41f7df0 edgar_igl
        uint32_t dst;
276 b41f7df0 edgar_igl
        uint32_t res;
277 b41f7df0 edgar_igl
        uint32_t flags = 0;
278 dceaf394 edgar_igl
        uint64_t tmp;
279 b41f7df0 edgar_igl
        uint32_t mof;
280 b41f7df0 edgar_igl
281 b41f7df0 edgar_igl
        src = env->cc_src;
282 b41f7df0 edgar_igl
        dst = env->cc_dest;
283 b41f7df0 edgar_igl
        res = env->cc_result;
284 b41f7df0 edgar_igl
285 dceaf394 edgar_igl
        mof = env->pregs[PR_MOF];
286 dceaf394 edgar_igl
        tmp = mof;
287 dceaf394 edgar_igl
        tmp <<= 32;
288 dceaf394 edgar_igl
        tmp |= res;
289 b41f7df0 edgar_igl
        if (tmp == 0)
290 b41f7df0 edgar_igl
                flags |= Z_FLAG;
291 b41f7df0 edgar_igl
        else if (tmp >> 63)
292 b41f7df0 edgar_igl
                flags |= N_FLAG;
293 b41f7df0 edgar_igl
        if (mof)
294 b41f7df0 edgar_igl
                flags |= V_FLAG;
295 b41f7df0 edgar_igl
296 b41f7df0 edgar_igl
        evaluate_flags_writeback(flags);
297 b41f7df0 edgar_igl
}
298 b41f7df0 edgar_igl
299 b41f7df0 edgar_igl
void  helper_evaluate_flags_mcp(void)
300 b41f7df0 edgar_igl
{
301 b41f7df0 edgar_igl
        uint32_t src;
302 b41f7df0 edgar_igl
        uint32_t dst;
303 b41f7df0 edgar_igl
        uint32_t res;
304 b41f7df0 edgar_igl
        uint32_t flags = 0;
305 b41f7df0 edgar_igl
306 b41f7df0 edgar_igl
        src = env->cc_src;
307 b41f7df0 edgar_igl
        dst = env->cc_dest;
308 b41f7df0 edgar_igl
        res = env->cc_result;
309 b41f7df0 edgar_igl
310 b41f7df0 edgar_igl
        if ((res & 0x80000000L) != 0L)
311 b41f7df0 edgar_igl
        {
312 b41f7df0 edgar_igl
                flags |= N_FLAG;
313 b41f7df0 edgar_igl
                if (((src & 0x80000000L) == 0L)
314 b41f7df0 edgar_igl
                    && ((dst & 0x80000000L) == 0L))
315 b41f7df0 edgar_igl
                {
316 b41f7df0 edgar_igl
                        flags |= V_FLAG;
317 b41f7df0 edgar_igl
                }
318 b41f7df0 edgar_igl
                else if (((src & 0x80000000L) != 0L) &&
319 b41f7df0 edgar_igl
                         ((dst & 0x80000000L) != 0L))
320 b41f7df0 edgar_igl
                {
321 b41f7df0 edgar_igl
                        flags |= R_FLAG;
322 b41f7df0 edgar_igl
                }
323 b41f7df0 edgar_igl
        }
324 b41f7df0 edgar_igl
        else
325 b41f7df0 edgar_igl
        {
326 b41f7df0 edgar_igl
                if (res == 0L)
327 b41f7df0 edgar_igl
                        flags |= Z_FLAG;
328 b41f7df0 edgar_igl
                if (((src & 0x80000000L) != 0L)
329 b41f7df0 edgar_igl
                    && ((dst & 0x80000000L) != 0L))
330 b41f7df0 edgar_igl
                        flags |= V_FLAG;
331 b41f7df0 edgar_igl
                if ((dst & 0x80000000L) != 0L
332 b41f7df0 edgar_igl
                    || (src & 0x80000000L) != 0L)
333 b41f7df0 edgar_igl
                        flags |= R_FLAG;
334 b41f7df0 edgar_igl
        }
335 b41f7df0 edgar_igl
336 b41f7df0 edgar_igl
        evaluate_flags_writeback(flags);
337 b41f7df0 edgar_igl
}
338 b41f7df0 edgar_igl
339 b41f7df0 edgar_igl
void  helper_evaluate_flags_alu_4(void)
340 b41f7df0 edgar_igl
{
341 b41f7df0 edgar_igl
        uint32_t src;
342 b41f7df0 edgar_igl
        uint32_t dst;
343 b41f7df0 edgar_igl
        uint32_t res;
344 b41f7df0 edgar_igl
        uint32_t flags = 0;
345 b41f7df0 edgar_igl
346 b41f7df0 edgar_igl
        src = env->cc_src;
347 b41f7df0 edgar_igl
        dst = env->cc_dest;
348 b41f7df0 edgar_igl
        res = env->cc_result;
349 b41f7df0 edgar_igl
350 b41f7df0 edgar_igl
        if ((res & 0x80000000L) != 0L)
351 b41f7df0 edgar_igl
        {
352 b41f7df0 edgar_igl
                flags |= N_FLAG;
353 b41f7df0 edgar_igl
                if (((src & 0x80000000L) == 0L)
354 b41f7df0 edgar_igl
                    && ((dst & 0x80000000L) == 0L))
355 b41f7df0 edgar_igl
                {
356 b41f7df0 edgar_igl
                        flags |= V_FLAG;
357 b41f7df0 edgar_igl
                }
358 b41f7df0 edgar_igl
                else if (((src & 0x80000000L) != 0L) &&
359 b41f7df0 edgar_igl
                         ((dst & 0x80000000L) != 0L))
360 b41f7df0 edgar_igl
                {
361 b41f7df0 edgar_igl
                        flags |= C_FLAG;
362 b41f7df0 edgar_igl
                }
363 b41f7df0 edgar_igl
        }
364 b41f7df0 edgar_igl
        else
365 b41f7df0 edgar_igl
        {
366 b41f7df0 edgar_igl
                if (res == 0L)
367 b41f7df0 edgar_igl
                        flags |= Z_FLAG;
368 b41f7df0 edgar_igl
                if (((src & 0x80000000L) != 0L)
369 b41f7df0 edgar_igl
                    && ((dst & 0x80000000L) != 0L))
370 b41f7df0 edgar_igl
                        flags |= V_FLAG;
371 b41f7df0 edgar_igl
                if ((dst & 0x80000000L) != 0L
372 b41f7df0 edgar_igl
                    || (src & 0x80000000L) != 0L)
373 b41f7df0 edgar_igl
                        flags |= C_FLAG;
374 b41f7df0 edgar_igl
        }
375 b41f7df0 edgar_igl
376 b41f7df0 edgar_igl
        if (env->cc_op == CC_OP_SUB
377 b41f7df0 edgar_igl
            || env->cc_op == CC_OP_CMP) {
378 b41f7df0 edgar_igl
                flags ^= C_FLAG;
379 b41f7df0 edgar_igl
        }
380 b41f7df0 edgar_igl
        evaluate_flags_writeback(flags);
381 b41f7df0 edgar_igl
}
382 b41f7df0 edgar_igl
383 b41f7df0 edgar_igl
void  helper_evaluate_flags_move_4 (void)
384 b41f7df0 edgar_igl
{
385 b41f7df0 edgar_igl
        uint32_t src;
386 b41f7df0 edgar_igl
        uint32_t res;
387 b41f7df0 edgar_igl
        uint32_t flags = 0;
388 b41f7df0 edgar_igl
389 b41f7df0 edgar_igl
        src = env->cc_src;
390 b41f7df0 edgar_igl
        res = env->cc_result;
391 b41f7df0 edgar_igl
392 b41f7df0 edgar_igl
        if ((int32_t)res < 0)
393 b41f7df0 edgar_igl
                flags |= N_FLAG;
394 b41f7df0 edgar_igl
        else if (res == 0L)
395 b41f7df0 edgar_igl
                flags |= Z_FLAG;
396 b41f7df0 edgar_igl
397 b41f7df0 edgar_igl
        evaluate_flags_writeback(flags);
398 b41f7df0 edgar_igl
}
399 b41f7df0 edgar_igl
void  helper_evaluate_flags_move_2 (void)
400 b41f7df0 edgar_igl
{
401 b41f7df0 edgar_igl
        uint32_t src;
402 b41f7df0 edgar_igl
        uint32_t flags = 0;
403 b41f7df0 edgar_igl
        uint16_t res;
404 b41f7df0 edgar_igl
405 b41f7df0 edgar_igl
        src = env->cc_src;
406 b41f7df0 edgar_igl
        res = env->cc_result;
407 b41f7df0 edgar_igl
408 b41f7df0 edgar_igl
        if ((int16_t)res < 0L)
409 b41f7df0 edgar_igl
                flags |= N_FLAG;
410 b41f7df0 edgar_igl
        else if (res == 0)
411 b41f7df0 edgar_igl
                flags |= Z_FLAG;
412 b41f7df0 edgar_igl
413 b41f7df0 edgar_igl
        evaluate_flags_writeback(flags);
414 b41f7df0 edgar_igl
}
415 b41f7df0 edgar_igl
416 b41f7df0 edgar_igl
/* TODO: This is expensive. We could split things up and only evaluate part of
417 b41f7df0 edgar_igl
   CCR on a need to know basis. For now, we simply re-evaluate everything.  */
418 b41f7df0 edgar_igl
void helper_evaluate_flags (void)
419 b41f7df0 edgar_igl
{
420 b41f7df0 edgar_igl
        uint32_t src;
421 b41f7df0 edgar_igl
        uint32_t dst;
422 b41f7df0 edgar_igl
        uint32_t res;
423 b41f7df0 edgar_igl
        uint32_t flags = 0;
424 b41f7df0 edgar_igl
425 b41f7df0 edgar_igl
        src = env->cc_src;
426 b41f7df0 edgar_igl
        dst = env->cc_dest;
427 b41f7df0 edgar_igl
        res = env->cc_result;
428 b41f7df0 edgar_igl
429 b41f7df0 edgar_igl
430 b41f7df0 edgar_igl
        /* Now, evaluate the flags. This stuff is based on
431 b41f7df0 edgar_igl
           Per Zander's CRISv10 simulator.  */
432 b41f7df0 edgar_igl
        switch (env->cc_size)
433 b41f7df0 edgar_igl
        {
434 b41f7df0 edgar_igl
                case 1:
435 b41f7df0 edgar_igl
                        if ((res & 0x80L) != 0L)
436 b41f7df0 edgar_igl
                        {
437 b41f7df0 edgar_igl
                                flags |= N_FLAG;
438 b41f7df0 edgar_igl
                                if (((src & 0x80L) == 0L)
439 b41f7df0 edgar_igl
                                    && ((dst & 0x80L) == 0L))
440 b41f7df0 edgar_igl
                                {
441 b41f7df0 edgar_igl
                                        flags |= V_FLAG;
442 b41f7df0 edgar_igl
                                }
443 b41f7df0 edgar_igl
                                else if (((src & 0x80L) != 0L)
444 b41f7df0 edgar_igl
                                         && ((dst & 0x80L) != 0L))
445 b41f7df0 edgar_igl
                                {
446 b41f7df0 edgar_igl
                                        flags |= C_FLAG;
447 b41f7df0 edgar_igl
                                }
448 b41f7df0 edgar_igl
                        }
449 b41f7df0 edgar_igl
                        else
450 b41f7df0 edgar_igl
                        {
451 b41f7df0 edgar_igl
                                if ((res & 0xFFL) == 0L)
452 b41f7df0 edgar_igl
                                {
453 b41f7df0 edgar_igl
                                        flags |= Z_FLAG;
454 b41f7df0 edgar_igl
                                }
455 b41f7df0 edgar_igl
                                if (((src & 0x80L) != 0L)
456 b41f7df0 edgar_igl
                                    && ((dst & 0x80L) != 0L))
457 b41f7df0 edgar_igl
                                {
458 b41f7df0 edgar_igl
                                        flags |= V_FLAG;
459 b41f7df0 edgar_igl
                                }
460 b41f7df0 edgar_igl
                                if ((dst & 0x80L) != 0L
461 b41f7df0 edgar_igl
                                    || (src & 0x80L) != 0L)
462 b41f7df0 edgar_igl
                                {
463 b41f7df0 edgar_igl
                                        flags |= C_FLAG;
464 b41f7df0 edgar_igl
                                }
465 b41f7df0 edgar_igl
                        }
466 b41f7df0 edgar_igl
                        break;
467 b41f7df0 edgar_igl
                case 2:
468 b41f7df0 edgar_igl
                        if ((res & 0x8000L) != 0L)
469 b41f7df0 edgar_igl
                        {
470 b41f7df0 edgar_igl
                                flags |= N_FLAG;
471 b41f7df0 edgar_igl
                                if (((src & 0x8000L) == 0L)
472 b41f7df0 edgar_igl
                                    && ((dst & 0x8000L) == 0L))
473 b41f7df0 edgar_igl
                                {
474 b41f7df0 edgar_igl
                                        flags |= V_FLAG;
475 b41f7df0 edgar_igl
                                }
476 b41f7df0 edgar_igl
                                else if (((src & 0x8000L) != 0L)
477 b41f7df0 edgar_igl
                                         && ((dst & 0x8000L) != 0L))
478 b41f7df0 edgar_igl
                                {
479 b41f7df0 edgar_igl
                                        flags |= C_FLAG;
480 b41f7df0 edgar_igl
                                }
481 b41f7df0 edgar_igl
                        }
482 b41f7df0 edgar_igl
                        else
483 b41f7df0 edgar_igl
                        {
484 b41f7df0 edgar_igl
                                if ((res & 0xFFFFL) == 0L)
485 b41f7df0 edgar_igl
                                {
486 b41f7df0 edgar_igl
                                        flags |= Z_FLAG;
487 b41f7df0 edgar_igl
                                }
488 b41f7df0 edgar_igl
                                if (((src & 0x8000L) != 0L)
489 b41f7df0 edgar_igl
                                    && ((dst & 0x8000L) != 0L))
490 b41f7df0 edgar_igl
                                {
491 b41f7df0 edgar_igl
                                        flags |= V_FLAG;
492 b41f7df0 edgar_igl
                                }
493 b41f7df0 edgar_igl
                                if ((dst & 0x8000L) != 0L
494 b41f7df0 edgar_igl
                                    || (src & 0x8000L) != 0L)
495 b41f7df0 edgar_igl
                                {
496 b41f7df0 edgar_igl
                                        flags |= C_FLAG;
497 b41f7df0 edgar_igl
                                }
498 b41f7df0 edgar_igl
                        }
499 b41f7df0 edgar_igl
                        break;
500 b41f7df0 edgar_igl
                case 4:
501 b41f7df0 edgar_igl
                        if ((res & 0x80000000L) != 0L)
502 b41f7df0 edgar_igl
                        {
503 b41f7df0 edgar_igl
                                flags |= N_FLAG;
504 b41f7df0 edgar_igl
                                if (((src & 0x80000000L) == 0L)
505 b41f7df0 edgar_igl
                                    && ((dst & 0x80000000L) == 0L))
506 b41f7df0 edgar_igl
                                {
507 b41f7df0 edgar_igl
                                        flags |= V_FLAG;
508 b41f7df0 edgar_igl
                                }
509 b41f7df0 edgar_igl
                                else if (((src & 0x80000000L) != 0L) &&
510 b41f7df0 edgar_igl
                                         ((dst & 0x80000000L) != 0L))
511 b41f7df0 edgar_igl
                                {
512 b41f7df0 edgar_igl
                                        flags |= C_FLAG;
513 b41f7df0 edgar_igl
                                }
514 b41f7df0 edgar_igl
                        }
515 b41f7df0 edgar_igl
                        else
516 b41f7df0 edgar_igl
                        {
517 b41f7df0 edgar_igl
                                if (res == 0L)
518 b41f7df0 edgar_igl
                                        flags |= Z_FLAG;
519 b41f7df0 edgar_igl
                                if (((src & 0x80000000L) != 0L)
520 b41f7df0 edgar_igl
                                    && ((dst & 0x80000000L) != 0L))
521 b41f7df0 edgar_igl
                                        flags |= V_FLAG;
522 b41f7df0 edgar_igl
                                if ((dst & 0x80000000L) != 0L
523 b41f7df0 edgar_igl
                                    || (src & 0x80000000L) != 0L)
524 b41f7df0 edgar_igl
                                        flags |= C_FLAG;
525 b41f7df0 edgar_igl
                        }
526 b41f7df0 edgar_igl
                        break;
527 b41f7df0 edgar_igl
                default:
528 b41f7df0 edgar_igl
                        break;
529 b41f7df0 edgar_igl
        }
530 b41f7df0 edgar_igl
531 b41f7df0 edgar_igl
        if (env->cc_op == CC_OP_SUB
532 b41f7df0 edgar_igl
            || env->cc_op == CC_OP_CMP) {
533 b41f7df0 edgar_igl
                flags ^= C_FLAG;
534 b41f7df0 edgar_igl
        }
535 b41f7df0 edgar_igl
        evaluate_flags_writeback(flags);
536 b41f7df0 edgar_igl
}