Statistics
| Branch: | Revision:

root / target-cris / translate.c @ 211ecdc0

History | View | Annotate | Download (81.7 kB)

1 8170028d ths
/*
2 8170028d ths
 *  CRIS emulation for qemu: main translation routines.
3 8170028d ths
 *
4 05ba7d5f edgar_igl
 *  Copyright (c) 2008 AXIS Communications AB
5 8170028d ths
 *  Written by Edgar E. Iglesias.
6 8170028d ths
 *
7 8170028d ths
 * This library is free software; you can redistribute it and/or
8 8170028d ths
 * modify it under the terms of the GNU Lesser General Public
9 8170028d ths
 * License as published by the Free Software Foundation; either
10 8170028d ths
 * version 2 of the License, or (at your option) any later version.
11 8170028d ths
 *
12 8170028d ths
 * This library is distributed in the hope that it will be useful,
13 8170028d ths
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 8170028d ths
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 8170028d ths
 * Lesser General Public License for more details.
16 8170028d ths
 *
17 8170028d ths
 * You should have received a copy of the GNU Lesser General Public
18 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 8170028d ths
 */
20 8170028d ths
21 b41f7df0 edgar_igl
/*
22 b41f7df0 edgar_igl
 * FIXME:
23 cf1d97f0 edgar_igl
 * The condition code translation is in need of attention.
24 b41f7df0 edgar_igl
 */
25 b41f7df0 edgar_igl
26 8170028d ths
#include <stdarg.h>
27 8170028d ths
#include <stdlib.h>
28 8170028d ths
#include <stdio.h>
29 8170028d ths
#include <string.h>
30 8170028d ths
#include <inttypes.h>
31 8170028d ths
32 8170028d ths
#include "cpu.h"
33 8170028d ths
#include "exec-all.h"
34 8170028d ths
#include "disas.h"
35 57fec1fe bellard
#include "tcg-op.h"
36 05ba7d5f edgar_igl
#include "helper.h"
37 52819664 edgar_igl
#include "mmu.h"
38 8170028d ths
#include "crisv32-decode.h"
39 ca10f867 aurel32
#include "qemu-common.h"
40 8170028d ths
41 a7812ae4 pbrook
#define GEN_HELPER 1
42 a7812ae4 pbrook
#include "helper.h"
43 a7812ae4 pbrook
44 8170028d ths
#define DISAS_CRIS 0
45 8170028d ths
#if DISAS_CRIS
46 93fcfe39 aliguori
#  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
47 8170028d ths
#else
48 d12d51d5 aliguori
#  define LOG_DIS(...) do { } while (0)
49 8170028d ths
#endif
50 8170028d ths
51 b41f7df0 edgar_igl
#define D(x)
52 8170028d ths
#define BUG() (gen_BUG(dc, __FILE__, __LINE__))
53 8170028d ths
#define BUG_ON(x) ({if (x) BUG();})
54 8170028d ths
55 4f400ab5 edgar_igl
#define DISAS_SWI 5
56 4f400ab5 edgar_igl
57 8170028d ths
/* Used by the decoder.  */
58 8170028d ths
#define EXTRACT_FIELD(src, start, end) \
59 8170028d ths
            (((src) >> start) & ((1 << (end - start + 1)) - 1))
60 8170028d ths
61 8170028d ths
#define CC_MASK_NZ 0xc
62 8170028d ths
#define CC_MASK_NZV 0xe
63 8170028d ths
#define CC_MASK_NZVC 0xf
64 8170028d ths
#define CC_MASK_RNZV 0x10e
65 8170028d ths
66 a7812ae4 pbrook
static TCGv_ptr cpu_env;
67 9b32fbf8 edgar_igl
static TCGv cpu_R[16];
68 9b32fbf8 edgar_igl
static TCGv cpu_PR[16];
69 9b32fbf8 edgar_igl
static TCGv cc_x;
70 9b32fbf8 edgar_igl
static TCGv cc_src;
71 9b32fbf8 edgar_igl
static TCGv cc_dest;
72 9b32fbf8 edgar_igl
static TCGv cc_result;
73 9b32fbf8 edgar_igl
static TCGv cc_op;
74 9b32fbf8 edgar_igl
static TCGv cc_size;
75 9b32fbf8 edgar_igl
static TCGv cc_mask;
76 9b32fbf8 edgar_igl
77 9b32fbf8 edgar_igl
static TCGv env_btaken;
78 9b32fbf8 edgar_igl
static TCGv env_btarget;
79 9b32fbf8 edgar_igl
static TCGv env_pc;
80 b41f7df0 edgar_igl
81 2e70f6ef pbrook
#include "gen-icount.h"
82 2e70f6ef pbrook
83 8170028d ths
/* This is the state at translation time.  */
84 8170028d ths
typedef struct DisasContext {
85 8170028d ths
        CPUState *env;
86 b41f7df0 edgar_igl
        target_ulong pc, ppc;
87 8170028d ths
88 8170028d ths
        /* Decoder.  */
89 40e9eddd Edgar E. Iglesias
        unsigned int (*decoder)(struct DisasContext *dc);
90 8170028d ths
        uint32_t ir;
91 8170028d ths
        uint32_t opcode;
92 8170028d ths
        unsigned int op1;
93 8170028d ths
        unsigned int op2;
94 8170028d ths
        unsigned int zsize, zzsize;
95 8170028d ths
        unsigned int mode;
96 8170028d ths
        unsigned int postinc;
97 8170028d ths
98 40e9eddd Edgar E. Iglesias
        unsigned int size;
99 40e9eddd Edgar E. Iglesias
        unsigned int src;
100 40e9eddd Edgar E. Iglesias
        unsigned int dst;
101 40e9eddd Edgar E. Iglesias
        unsigned int cond;
102 40e9eddd Edgar E. Iglesias
103 8170028d ths
        int update_cc;
104 8170028d ths
        int cc_op;
105 8170028d ths
        int cc_size;
106 8170028d ths
        uint32_t cc_mask;
107 30abcfc7 edgar_igl
108 30abcfc7 edgar_igl
        int cc_size_uptodate; /* -1 invalid or last written value.  */
109 30abcfc7 edgar_igl
110 30abcfc7 edgar_igl
        int cc_x_uptodate;  /* 1 - ccs, 2 - known | X_FLAG. 0 not uptodate.  */
111 30abcfc7 edgar_igl
        int flags_uptodate; /* Wether or not $ccs is uptodate.  */
112 30abcfc7 edgar_igl
        int flagx_known; /* Wether or not flags_x has the x flag known at
113 30abcfc7 edgar_igl
                            translation time.  */
114 8170028d ths
        int flags_x;
115 8170028d ths
116 30abcfc7 edgar_igl
        int clear_x; /* Clear x after this insn?  */
117 40e9eddd Edgar E. Iglesias
        int clear_prefix; /* Clear prefix after this insn?  */
118 40e9eddd Edgar E. Iglesias
        int clear_locked_irq; /* Clear the irq lockout.  */
119 2a44f7f1 edgar_igl
        int cpustate_changed;
120 2a44f7f1 edgar_igl
        unsigned int tb_flags; /* tb dependent flags.  */
121 8170028d ths
        int is_jmp;
122 8170028d ths
123 2a44f7f1 edgar_igl
#define JMP_NOJMP    0
124 2a44f7f1 edgar_igl
#define JMP_DIRECT   1
125 2a44f7f1 edgar_igl
#define JMP_INDIRECT 2
126 2a44f7f1 edgar_igl
        int jmp; /* 0=nojmp, 1=direct, 2=indirect.  */ 
127 2a44f7f1 edgar_igl
        uint32_t jmp_pc;
128 2a44f7f1 edgar_igl
129 8170028d ths
        int delayed_branch;
130 8170028d ths
131 8170028d ths
        struct TranslationBlock *tb;
132 8170028d ths
        int singlestep_enabled;
133 8170028d ths
} DisasContext;
134 8170028d ths
135 7ccfb2eb blueswir1
static void gen_BUG(DisasContext *dc, const char *file, int line)
136 8170028d ths
{
137 8170028d ths
        printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
138 93fcfe39 aliguori
        qemu_log("BUG: pc=%x %s %d\n", dc->pc, file, line);
139 cf1d97f0 edgar_igl
        cpu_abort(dc->env, "%s:%d\n", file, line);
140 8170028d ths
}
141 8170028d ths
142 9b32fbf8 edgar_igl
static const char *regnames[] =
143 a825e703 edgar_igl
{
144 a825e703 edgar_igl
        "$r0", "$r1", "$r2", "$r3",
145 a825e703 edgar_igl
        "$r4", "$r5", "$r6", "$r7",
146 a825e703 edgar_igl
        "$r8", "$r9", "$r10", "$r11",
147 a825e703 edgar_igl
        "$r12", "$r13", "$sp", "$acr",
148 a825e703 edgar_igl
};
149 9b32fbf8 edgar_igl
static const char *pregnames[] =
150 a825e703 edgar_igl
{
151 a825e703 edgar_igl
        "$bz", "$vr", "$pid", "$srs",
152 a825e703 edgar_igl
        "$wz", "$exs", "$eda", "$mof",
153 a825e703 edgar_igl
        "$dz", "$ebp", "$erp", "$srp",
154 a825e703 edgar_igl
        "$nrp", "$ccs", "$usp", "$spc",
155 a825e703 edgar_igl
};
156 a825e703 edgar_igl
157 05ba7d5f edgar_igl
/* We need this table to handle preg-moves with implicit width.  */
158 9b32fbf8 edgar_igl
static int preg_sizes[] = {
159 05ba7d5f edgar_igl
        1, /* bz.  */
160 05ba7d5f edgar_igl
        1, /* vr.  */
161 05ba7d5f edgar_igl
        4, /* pid.  */
162 05ba7d5f edgar_igl
        1, /* srs.  */
163 05ba7d5f edgar_igl
        2, /* wz.  */
164 05ba7d5f edgar_igl
        4, 4, 4,
165 05ba7d5f edgar_igl
        4, 4, 4, 4,
166 05ba7d5f edgar_igl
        4, 4, 4, 4,
167 05ba7d5f edgar_igl
};
168 05ba7d5f edgar_igl
169 05ba7d5f edgar_igl
#define t_gen_mov_TN_env(tn, member) \
170 3157a0a9 edgar_igl
 _t_gen_mov_TN_env((tn), offsetof(CPUState, member))
171 05ba7d5f edgar_igl
#define t_gen_mov_env_TN(member, tn) \
172 3157a0a9 edgar_igl
 _t_gen_mov_env_TN(offsetof(CPUState, member), (tn))
173 05ba7d5f edgar_igl
174 b41f7df0 edgar_igl
static inline void t_gen_mov_TN_reg(TCGv tn, int r)
175 b41f7df0 edgar_igl
{
176 b41f7df0 edgar_igl
        if (r < 0 || r > 15)
177 b41f7df0 edgar_igl
                fprintf(stderr, "wrong register read $r%d\n", r);
178 b41f7df0 edgar_igl
        tcg_gen_mov_tl(tn, cpu_R[r]);
179 b41f7df0 edgar_igl
}
180 b41f7df0 edgar_igl
static inline void t_gen_mov_reg_TN(int r, TCGv tn)
181 b41f7df0 edgar_igl
{
182 b41f7df0 edgar_igl
        if (r < 0 || r > 15)
183 b41f7df0 edgar_igl
                fprintf(stderr, "wrong register write $r%d\n", r);
184 b41f7df0 edgar_igl
        tcg_gen_mov_tl(cpu_R[r], tn);
185 b41f7df0 edgar_igl
}
186 05ba7d5f edgar_igl
187 05ba7d5f edgar_igl
static inline void _t_gen_mov_TN_env(TCGv tn, int offset)
188 05ba7d5f edgar_igl
{
189 b41f7df0 edgar_igl
        if (offset > sizeof (CPUState))
190 b41f7df0 edgar_igl
                fprintf(stderr, "wrong load from env from off=%d\n", offset);
191 05ba7d5f edgar_igl
        tcg_gen_ld_tl(tn, cpu_env, offset);
192 05ba7d5f edgar_igl
}
193 05ba7d5f edgar_igl
static inline void _t_gen_mov_env_TN(int offset, TCGv tn)
194 05ba7d5f edgar_igl
{
195 b41f7df0 edgar_igl
        if (offset > sizeof (CPUState))
196 b41f7df0 edgar_igl
                fprintf(stderr, "wrong store to env at off=%d\n", offset);
197 05ba7d5f edgar_igl
        tcg_gen_st_tl(tn, cpu_env, offset);
198 05ba7d5f edgar_igl
}
199 05ba7d5f edgar_igl
200 05ba7d5f edgar_igl
static inline void t_gen_mov_TN_preg(TCGv tn, int r)
201 05ba7d5f edgar_igl
{
202 b41f7df0 edgar_igl
        if (r < 0 || r > 15)
203 b41f7df0 edgar_igl
                fprintf(stderr, "wrong register read $p%d\n", r);
204 05ba7d5f edgar_igl
        if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
205 3157a0a9 edgar_igl
                tcg_gen_mov_tl(tn, tcg_const_tl(0));
206 05ba7d5f edgar_igl
        else if (r == PR_VR)
207 3157a0a9 edgar_igl
                tcg_gen_mov_tl(tn, tcg_const_tl(32));
208 05ba7d5f edgar_igl
        else
209 a825e703 edgar_igl
                tcg_gen_mov_tl(tn, cpu_PR[r]);
210 05ba7d5f edgar_igl
}
211 cf1d97f0 edgar_igl
static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
212 05ba7d5f edgar_igl
{
213 b41f7df0 edgar_igl
        if (r < 0 || r > 15)
214 b41f7df0 edgar_igl
                fprintf(stderr, "wrong register write $p%d\n", r);
215 05ba7d5f edgar_igl
        if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
216 05ba7d5f edgar_igl
                return;
217 b41f7df0 edgar_igl
        else if (r == PR_SRS)
218 b41f7df0 edgar_igl
                tcg_gen_andi_tl(cpu_PR[r], tn, 3);
219 b41f7df0 edgar_igl
        else {
220 2a44f7f1 edgar_igl
                if (r == PR_PID) 
221 a7812ae4 pbrook
                        gen_helper_tlb_flush_pid(tn);
222 a1aebcb8 edgar_igl
                if (dc->tb_flags & S_FLAG && r == PR_SPC) 
223 a7812ae4 pbrook
                        gen_helper_spc_write(tn);
224 2a44f7f1 edgar_igl
                else if (r == PR_CCS)
225 2a44f7f1 edgar_igl
                        dc->cpustate_changed = 1;
226 28de16da edgar_igl
                tcg_gen_mov_tl(cpu_PR[r], tn);
227 b41f7df0 edgar_igl
        }
228 05ba7d5f edgar_igl
}
229 05ba7d5f edgar_igl
230 1884533c Edgar E. Iglesias
/* Sign extend at translation time.  */
231 1884533c Edgar E. Iglesias
static int sign_extend(unsigned int val, unsigned int width)
232 1884533c Edgar E. Iglesias
{
233 1884533c Edgar E. Iglesias
        int sval;
234 1884533c Edgar E. Iglesias
235 1884533c Edgar E. Iglesias
        /* LSL.  */
236 1884533c Edgar E. Iglesias
        val <<= 31 - width;
237 1884533c Edgar E. Iglesias
        sval = val;
238 1884533c Edgar E. Iglesias
        /* ASR.  */
239 1884533c Edgar E. Iglesias
        sval >>= 31 - width;
240 1884533c Edgar E. Iglesias
        return sval;
241 1884533c Edgar E. Iglesias
}
242 1884533c Edgar E. Iglesias
243 7de141cb Edgar E. Iglesias
static int cris_fetch(DisasContext *dc, uint32_t addr,
244 7de141cb Edgar E. Iglesias
                      unsigned int size, unsigned int sign)
245 7de141cb Edgar E. Iglesias
{
246 7de141cb Edgar E. Iglesias
        int r;
247 7de141cb Edgar E. Iglesias
248 7de141cb Edgar E. Iglesias
        switch (size) {
249 7de141cb Edgar E. Iglesias
                case 4:
250 7de141cb Edgar E. Iglesias
                {
251 7de141cb Edgar E. Iglesias
                        r = ldl_code(addr);
252 7de141cb Edgar E. Iglesias
                        break;
253 7de141cb Edgar E. Iglesias
                }
254 7de141cb Edgar E. Iglesias
                case 2:
255 7de141cb Edgar E. Iglesias
                {
256 7de141cb Edgar E. Iglesias
                        if (sign) {
257 7de141cb Edgar E. Iglesias
                                r = ldsw_code(addr);
258 7de141cb Edgar E. Iglesias
                        } else {
259 7de141cb Edgar E. Iglesias
                                r = lduw_code(addr);
260 7de141cb Edgar E. Iglesias
                        }
261 7de141cb Edgar E. Iglesias
                        break;
262 7de141cb Edgar E. Iglesias
                }
263 7de141cb Edgar E. Iglesias
                case 1:
264 7de141cb Edgar E. Iglesias
                {
265 7de141cb Edgar E. Iglesias
                        if (sign) {
266 7de141cb Edgar E. Iglesias
                                r = ldsb_code(addr);
267 7de141cb Edgar E. Iglesias
                        } else {
268 7de141cb Edgar E. Iglesias
                                r = ldub_code(addr);
269 7de141cb Edgar E. Iglesias
                        }
270 7de141cb Edgar E. Iglesias
                        break;
271 7de141cb Edgar E. Iglesias
                }
272 7de141cb Edgar E. Iglesias
                default:
273 7de141cb Edgar E. Iglesias
                        cpu_abort(dc->env, "Invalid fetch size %d\n", size);
274 7de141cb Edgar E. Iglesias
                        break;
275 7de141cb Edgar E. Iglesias
        }
276 7de141cb Edgar E. Iglesias
        return r;
277 7de141cb Edgar E. Iglesias
}
278 7de141cb Edgar E. Iglesias
279 40e9eddd Edgar E. Iglesias
static void cris_lock_irq(DisasContext *dc)
280 40e9eddd Edgar E. Iglesias
{
281 40e9eddd Edgar E. Iglesias
        dc->clear_locked_irq = 0;
282 40e9eddd Edgar E. Iglesias
        t_gen_mov_env_TN(locked_irq, tcg_const_tl(1));
283 40e9eddd Edgar E. Iglesias
}
284 40e9eddd Edgar E. Iglesias
285 dceaf394 edgar_igl
static inline void t_gen_raise_exception(uint32_t index)
286 05ba7d5f edgar_igl
{
287 a7812ae4 pbrook
        TCGv_i32 tmp = tcg_const_i32(index);
288 a7812ae4 pbrook
        gen_helper_raise_exception(tmp);
289 a7812ae4 pbrook
        tcg_temp_free_i32(tmp);
290 05ba7d5f edgar_igl
}
291 05ba7d5f edgar_igl
292 05ba7d5f edgar_igl
static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
293 05ba7d5f edgar_igl
{
294 7dcfb089 edgar_igl
        TCGv t0, t_31;
295 05ba7d5f edgar_igl
296 a7812ae4 pbrook
        t0 = tcg_temp_new();
297 44696296 edgar_igl
        t_31 = tcg_const_tl(31);
298 05ba7d5f edgar_igl
        tcg_gen_shl_tl(d, a, b);
299 7dcfb089 edgar_igl
300 7dcfb089 edgar_igl
        tcg_gen_sub_tl(t0, t_31, b);
301 7dcfb089 edgar_igl
        tcg_gen_sar_tl(t0, t0, t_31);
302 7dcfb089 edgar_igl
        tcg_gen_and_tl(t0, t0, d);
303 7dcfb089 edgar_igl
        tcg_gen_xor_tl(d, d, t0);
304 7dcfb089 edgar_igl
        tcg_temp_free(t0);
305 7dcfb089 edgar_igl
        tcg_temp_free(t_31);
306 05ba7d5f edgar_igl
}
307 05ba7d5f edgar_igl
308 05ba7d5f edgar_igl
static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
309 05ba7d5f edgar_igl
{
310 7dcfb089 edgar_igl
        TCGv t0, t_31;
311 05ba7d5f edgar_igl
312 a7812ae4 pbrook
        t0 = tcg_temp_new();
313 a7812ae4 pbrook
        t_31 = tcg_temp_new();
314 05ba7d5f edgar_igl
        tcg_gen_shr_tl(d, a, b);
315 7dcfb089 edgar_igl
316 7dcfb089 edgar_igl
        tcg_gen_movi_tl(t_31, 31);
317 7dcfb089 edgar_igl
        tcg_gen_sub_tl(t0, t_31, b);
318 7dcfb089 edgar_igl
        tcg_gen_sar_tl(t0, t0, t_31);
319 7dcfb089 edgar_igl
        tcg_gen_and_tl(t0, t0, d);
320 7dcfb089 edgar_igl
        tcg_gen_xor_tl(d, d, t0);
321 7dcfb089 edgar_igl
        tcg_temp_free(t0);
322 7dcfb089 edgar_igl
        tcg_temp_free(t_31);
323 05ba7d5f edgar_igl
}
324 05ba7d5f edgar_igl
325 05ba7d5f edgar_igl
static void t_gen_asr(TCGv d, TCGv a, TCGv b)
326 05ba7d5f edgar_igl
{
327 7dcfb089 edgar_igl
        TCGv t0, t_31;
328 05ba7d5f edgar_igl
329 a7812ae4 pbrook
        t0 = tcg_temp_new();
330 a7812ae4 pbrook
        t_31 = tcg_temp_new();
331 05ba7d5f edgar_igl
        tcg_gen_sar_tl(d, a, b);
332 7dcfb089 edgar_igl
333 7dcfb089 edgar_igl
        tcg_gen_movi_tl(t_31, 31);
334 7dcfb089 edgar_igl
        tcg_gen_sub_tl(t0, t_31, b);
335 7dcfb089 edgar_igl
        tcg_gen_sar_tl(t0, t0, t_31);
336 7dcfb089 edgar_igl
        tcg_gen_or_tl(d, d, t0);
337 7dcfb089 edgar_igl
        tcg_temp_free(t0);
338 7dcfb089 edgar_igl
        tcg_temp_free(t_31);
339 05ba7d5f edgar_igl
}
340 05ba7d5f edgar_igl
341 3157a0a9 edgar_igl
/* 64-bit signed mul, lower result in d and upper in d2.  */
342 3157a0a9 edgar_igl
static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
343 3157a0a9 edgar_igl
{
344 a7812ae4 pbrook
        TCGv_i64 t0, t1;
345 3157a0a9 edgar_igl
346 a7812ae4 pbrook
        t0 = tcg_temp_new_i64();
347 a7812ae4 pbrook
        t1 = tcg_temp_new_i64();
348 3157a0a9 edgar_igl
349 a7812ae4 pbrook
        tcg_gen_ext_i32_i64(t0, a);
350 a7812ae4 pbrook
        tcg_gen_ext_i32_i64(t1, b);
351 3157a0a9 edgar_igl
        tcg_gen_mul_i64(t0, t0, t1);
352 3157a0a9 edgar_igl
353 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d, t0);
354 3157a0a9 edgar_igl
        tcg_gen_shri_i64(t0, t0, 32);
355 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d2, t0);
356 b41f7df0 edgar_igl
357 a7812ae4 pbrook
        tcg_temp_free_i64(t0);
358 a7812ae4 pbrook
        tcg_temp_free_i64(t1);
359 3157a0a9 edgar_igl
}
360 3157a0a9 edgar_igl
361 3157a0a9 edgar_igl
/* 64-bit unsigned muls, lower result in d and upper in d2.  */
362 3157a0a9 edgar_igl
static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
363 3157a0a9 edgar_igl
{
364 a7812ae4 pbrook
        TCGv_i64 t0, t1;
365 3157a0a9 edgar_igl
366 a7812ae4 pbrook
        t0 = tcg_temp_new_i64();
367 a7812ae4 pbrook
        t1 = tcg_temp_new_i64();
368 3157a0a9 edgar_igl
369 3157a0a9 edgar_igl
        tcg_gen_extu_i32_i64(t0, a);
370 3157a0a9 edgar_igl
        tcg_gen_extu_i32_i64(t1, b);
371 3157a0a9 edgar_igl
        tcg_gen_mul_i64(t0, t0, t1);
372 3157a0a9 edgar_igl
373 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d, t0);
374 3157a0a9 edgar_igl
        tcg_gen_shri_i64(t0, t0, 32);
375 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d2, t0);
376 b41f7df0 edgar_igl
377 a7812ae4 pbrook
        tcg_temp_free_i64(t0);
378 a7812ae4 pbrook
        tcg_temp_free_i64(t1);
379 3157a0a9 edgar_igl
}
380 3157a0a9 edgar_igl
381 30abcfc7 edgar_igl
static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
382 aae6b32a edgar_igl
{
383 aae6b32a edgar_igl
        int l1;
384 aae6b32a edgar_igl
385 aae6b32a edgar_igl
        l1 = gen_new_label();
386 aae6b32a edgar_igl
387 aae6b32a edgar_igl
        /* 
388 aae6b32a edgar_igl
         * d <<= 1
389 aae6b32a edgar_igl
         * if (d >= s)
390 aae6b32a edgar_igl
         *    d -= s;
391 aae6b32a edgar_igl
         */
392 30abcfc7 edgar_igl
        tcg_gen_shli_tl(d, a, 1);
393 30abcfc7 edgar_igl
        tcg_gen_brcond_tl(TCG_COND_LTU, d, b, l1);
394 30abcfc7 edgar_igl
        tcg_gen_sub_tl(d, d, b);
395 aae6b32a edgar_igl
        gen_set_label(l1);
396 aae6b32a edgar_igl
}
397 aae6b32a edgar_igl
398 40e9eddd Edgar E. Iglesias
static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs)
399 40e9eddd Edgar E. Iglesias
{
400 40e9eddd Edgar E. Iglesias
        TCGv t;
401 40e9eddd Edgar E. Iglesias
402 40e9eddd Edgar E. Iglesias
        /* 
403 40e9eddd Edgar E. Iglesias
         * d <<= 1
404 40e9eddd Edgar E. Iglesias
         * if (n)
405 40e9eddd Edgar E. Iglesias
         *    d += s;
406 40e9eddd Edgar E. Iglesias
         */
407 40e9eddd Edgar E. Iglesias
        t = tcg_temp_new();
408 40e9eddd Edgar E. Iglesias
        tcg_gen_shli_tl(d, a, 1);
409 40e9eddd Edgar E. Iglesias
        tcg_gen_shli_tl(t, ccs, 31 - 3);
410 40e9eddd Edgar E. Iglesias
        tcg_gen_sari_tl(t, t, 31);
411 40e9eddd Edgar E. Iglesias
        tcg_gen_and_tl(t, t, b);
412 40e9eddd Edgar E. Iglesias
        tcg_gen_add_tl(d, d, t);
413 40e9eddd Edgar E. Iglesias
        tcg_temp_free(t);
414 40e9eddd Edgar E. Iglesias
}
415 40e9eddd Edgar E. Iglesias
416 3157a0a9 edgar_igl
/* Extended arithmetics on CRIS.  */
417 3157a0a9 edgar_igl
static inline void t_gen_add_flag(TCGv d, int flag)
418 3157a0a9 edgar_igl
{
419 3157a0a9 edgar_igl
        TCGv c;
420 3157a0a9 edgar_igl
421 a7812ae4 pbrook
        c = tcg_temp_new();
422 3157a0a9 edgar_igl
        t_gen_mov_TN_preg(c, PR_CCS);
423 3157a0a9 edgar_igl
        /* Propagate carry into d.  */
424 3157a0a9 edgar_igl
        tcg_gen_andi_tl(c, c, 1 << flag);
425 3157a0a9 edgar_igl
        if (flag)
426 3157a0a9 edgar_igl
                tcg_gen_shri_tl(c, c, flag);
427 3157a0a9 edgar_igl
        tcg_gen_add_tl(d, d, c);
428 30abcfc7 edgar_igl
        tcg_temp_free(c);
429 3157a0a9 edgar_igl
}
430 3157a0a9 edgar_igl
431 30abcfc7 edgar_igl
static inline void t_gen_addx_carry(DisasContext *dc, TCGv d)
432 3157a0a9 edgar_igl
{
433 30abcfc7 edgar_igl
        if (dc->flagx_known) {
434 30abcfc7 edgar_igl
                if (dc->flags_x) {
435 30abcfc7 edgar_igl
                        TCGv c;
436 30abcfc7 edgar_igl
            
437 a7812ae4 pbrook
                        c = tcg_temp_new();
438 30abcfc7 edgar_igl
                        t_gen_mov_TN_preg(c, PR_CCS);
439 30abcfc7 edgar_igl
                        /* C flag is already at bit 0.  */
440 30abcfc7 edgar_igl
                        tcg_gen_andi_tl(c, c, C_FLAG);
441 30abcfc7 edgar_igl
                        tcg_gen_add_tl(d, d, c);
442 30abcfc7 edgar_igl
                        tcg_temp_free(c);
443 30abcfc7 edgar_igl
                }
444 30abcfc7 edgar_igl
        } else {
445 30abcfc7 edgar_igl
                TCGv x, c;
446 3157a0a9 edgar_igl
447 a7812ae4 pbrook
                x = tcg_temp_new();
448 a7812ae4 pbrook
                c = tcg_temp_new();
449 30abcfc7 edgar_igl
                t_gen_mov_TN_preg(x, PR_CCS);
450 30abcfc7 edgar_igl
                tcg_gen_mov_tl(c, x);
451 3157a0a9 edgar_igl
452 30abcfc7 edgar_igl
                /* Propagate carry into d if X is set. Branch free.  */
453 30abcfc7 edgar_igl
                tcg_gen_andi_tl(c, c, C_FLAG);
454 30abcfc7 edgar_igl
                tcg_gen_andi_tl(x, x, X_FLAG);
455 30abcfc7 edgar_igl
                tcg_gen_shri_tl(x, x, 4);
456 3157a0a9 edgar_igl
457 30abcfc7 edgar_igl
                tcg_gen_and_tl(x, x, c);
458 30abcfc7 edgar_igl
                tcg_gen_add_tl(d, d, x);        
459 30abcfc7 edgar_igl
                tcg_temp_free(x);
460 30abcfc7 edgar_igl
                tcg_temp_free(c);
461 30abcfc7 edgar_igl
        }
462 3157a0a9 edgar_igl
}
463 3157a0a9 edgar_igl
464 a39f8f3a edgar_igl
static inline void t_gen_subx_carry(DisasContext *dc, TCGv d)
465 3157a0a9 edgar_igl
{
466 30abcfc7 edgar_igl
        if (dc->flagx_known) {
467 30abcfc7 edgar_igl
                if (dc->flags_x) {
468 30abcfc7 edgar_igl
                        TCGv c;
469 30abcfc7 edgar_igl
            
470 a7812ae4 pbrook
                        c = tcg_temp_new();
471 30abcfc7 edgar_igl
                        t_gen_mov_TN_preg(c, PR_CCS);
472 30abcfc7 edgar_igl
                        /* C flag is already at bit 0.  */
473 30abcfc7 edgar_igl
                        tcg_gen_andi_tl(c, c, C_FLAG);
474 30abcfc7 edgar_igl
                        tcg_gen_sub_tl(d, d, c);
475 30abcfc7 edgar_igl
                        tcg_temp_free(c);
476 30abcfc7 edgar_igl
                }
477 30abcfc7 edgar_igl
        } else {
478 a39f8f3a edgar_igl
                TCGv x, c;
479 a39f8f3a edgar_igl
480 a7812ae4 pbrook
                x = tcg_temp_new();
481 a7812ae4 pbrook
                c = tcg_temp_new();
482 a39f8f3a edgar_igl
                t_gen_mov_TN_preg(x, PR_CCS);
483 a39f8f3a edgar_igl
                tcg_gen_mov_tl(c, x);
484 a39f8f3a edgar_igl
485 a39f8f3a edgar_igl
                /* Propagate carry into d if X is set. Branch free.  */
486 a39f8f3a edgar_igl
                tcg_gen_andi_tl(c, c, C_FLAG);
487 a39f8f3a edgar_igl
                tcg_gen_andi_tl(x, x, X_FLAG);
488 a39f8f3a edgar_igl
                tcg_gen_shri_tl(x, x, 4);
489 a39f8f3a edgar_igl
490 a39f8f3a edgar_igl
                tcg_gen_and_tl(x, x, c);
491 a39f8f3a edgar_igl
                tcg_gen_sub_tl(d, d, x);
492 30abcfc7 edgar_igl
                tcg_temp_free(x);
493 30abcfc7 edgar_igl
                tcg_temp_free(c);
494 a39f8f3a edgar_igl
        }
495 3157a0a9 edgar_igl
}
496 3157a0a9 edgar_igl
497 3157a0a9 edgar_igl
/* Swap the two bytes within each half word of the s operand.
498 3157a0a9 edgar_igl
   T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff)  */
499 3157a0a9 edgar_igl
static inline void t_gen_swapb(TCGv d, TCGv s)
500 3157a0a9 edgar_igl
{
501 3157a0a9 edgar_igl
        TCGv t, org_s;
502 3157a0a9 edgar_igl
503 a7812ae4 pbrook
        t = tcg_temp_new();
504 a7812ae4 pbrook
        org_s = tcg_temp_new();
505 3157a0a9 edgar_igl
506 3157a0a9 edgar_igl
        /* d and s may refer to the same object.  */
507 3157a0a9 edgar_igl
        tcg_gen_mov_tl(org_s, s);
508 3157a0a9 edgar_igl
        tcg_gen_shli_tl(t, org_s, 8);
509 3157a0a9 edgar_igl
        tcg_gen_andi_tl(d, t, 0xff00ff00);
510 3157a0a9 edgar_igl
        tcg_gen_shri_tl(t, org_s, 8);
511 3157a0a9 edgar_igl
        tcg_gen_andi_tl(t, t, 0x00ff00ff);
512 3157a0a9 edgar_igl
        tcg_gen_or_tl(d, d, t);
513 30abcfc7 edgar_igl
        tcg_temp_free(t);
514 30abcfc7 edgar_igl
        tcg_temp_free(org_s);
515 3157a0a9 edgar_igl
}
516 3157a0a9 edgar_igl
517 3157a0a9 edgar_igl
/* Swap the halfwords of the s operand.  */
518 3157a0a9 edgar_igl
static inline void t_gen_swapw(TCGv d, TCGv s)
519 3157a0a9 edgar_igl
{
520 3157a0a9 edgar_igl
        TCGv t;
521 3157a0a9 edgar_igl
        /* d and s refer the same object.  */
522 a7812ae4 pbrook
        t = tcg_temp_new();
523 3157a0a9 edgar_igl
        tcg_gen_mov_tl(t, s);
524 3157a0a9 edgar_igl
        tcg_gen_shli_tl(d, t, 16);
525 3157a0a9 edgar_igl
        tcg_gen_shri_tl(t, t, 16);
526 3157a0a9 edgar_igl
        tcg_gen_or_tl(d, d, t);
527 30abcfc7 edgar_igl
        tcg_temp_free(t);
528 3157a0a9 edgar_igl
}
529 3157a0a9 edgar_igl
530 3157a0a9 edgar_igl
/* Reverse the within each byte.
531 3157a0a9 edgar_igl
   T0 = (((T0 << 7) & 0x80808080) |
532 3157a0a9 edgar_igl
   ((T0 << 5) & 0x40404040) |
533 3157a0a9 edgar_igl
   ((T0 << 3) & 0x20202020) |
534 3157a0a9 edgar_igl
   ((T0 << 1) & 0x10101010) |
535 3157a0a9 edgar_igl
   ((T0 >> 1) & 0x08080808) |
536 3157a0a9 edgar_igl
   ((T0 >> 3) & 0x04040404) |
537 3157a0a9 edgar_igl
   ((T0 >> 5) & 0x02020202) |
538 3157a0a9 edgar_igl
   ((T0 >> 7) & 0x01010101));
539 3157a0a9 edgar_igl
 */
540 3157a0a9 edgar_igl
static inline void t_gen_swapr(TCGv d, TCGv s)
541 3157a0a9 edgar_igl
{
542 3157a0a9 edgar_igl
        struct {
543 3157a0a9 edgar_igl
                int shift; /* LSL when positive, LSR when negative.  */
544 3157a0a9 edgar_igl
                uint32_t mask;
545 3157a0a9 edgar_igl
        } bitrev [] = {
546 3157a0a9 edgar_igl
                {7, 0x80808080},
547 3157a0a9 edgar_igl
                {5, 0x40404040},
548 3157a0a9 edgar_igl
                {3, 0x20202020},
549 3157a0a9 edgar_igl
                {1, 0x10101010},
550 3157a0a9 edgar_igl
                {-1, 0x08080808},
551 3157a0a9 edgar_igl
                {-3, 0x04040404},
552 3157a0a9 edgar_igl
                {-5, 0x02020202},
553 3157a0a9 edgar_igl
                {-7, 0x01010101}
554 3157a0a9 edgar_igl
        };
555 3157a0a9 edgar_igl
        int i;
556 3157a0a9 edgar_igl
        TCGv t, org_s;
557 3157a0a9 edgar_igl
558 3157a0a9 edgar_igl
        /* d and s refer the same object.  */
559 a7812ae4 pbrook
        t = tcg_temp_new();
560 a7812ae4 pbrook
        org_s = tcg_temp_new();
561 3157a0a9 edgar_igl
        tcg_gen_mov_tl(org_s, s);
562 3157a0a9 edgar_igl
563 3157a0a9 edgar_igl
        tcg_gen_shli_tl(t, org_s,  bitrev[0].shift);
564 3157a0a9 edgar_igl
        tcg_gen_andi_tl(d, t,  bitrev[0].mask);
565 b1503cda malc
        for (i = 1; i < ARRAY_SIZE(bitrev); i++) {
566 3157a0a9 edgar_igl
                if (bitrev[i].shift >= 0) {
567 3157a0a9 edgar_igl
                        tcg_gen_shli_tl(t, org_s,  bitrev[i].shift);
568 3157a0a9 edgar_igl
                } else {
569 3157a0a9 edgar_igl
                        tcg_gen_shri_tl(t, org_s,  -bitrev[i].shift);
570 3157a0a9 edgar_igl
                }
571 3157a0a9 edgar_igl
                tcg_gen_andi_tl(t, t,  bitrev[i].mask);
572 3157a0a9 edgar_igl
                tcg_gen_or_tl(d, d, t);
573 3157a0a9 edgar_igl
        }
574 30abcfc7 edgar_igl
        tcg_temp_free(t);
575 30abcfc7 edgar_igl
        tcg_temp_free(org_s);
576 3157a0a9 edgar_igl
}
577 3157a0a9 edgar_igl
578 cf1d97f0 edgar_igl
static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
579 17ac9754 edgar_igl
{
580 17ac9754 edgar_igl
        TCGv btaken;
581 17ac9754 edgar_igl
        int l1;
582 17ac9754 edgar_igl
583 17ac9754 edgar_igl
        l1 = gen_new_label();
584 a7812ae4 pbrook
        btaken = tcg_temp_new();
585 17ac9754 edgar_igl
586 17ac9754 edgar_igl
        /* Conditional jmp.  */
587 2a44f7f1 edgar_igl
        tcg_gen_mov_tl(btaken, env_btaken);
588 cf1d97f0 edgar_igl
        tcg_gen_mov_tl(env_pc, pc_false);
589 cb63669a pbrook
        tcg_gen_brcondi_tl(TCG_COND_EQ, btaken, 0, l1);
590 cf1d97f0 edgar_igl
        tcg_gen_mov_tl(env_pc, pc_true);
591 17ac9754 edgar_igl
        gen_set_label(l1);
592 17ac9754 edgar_igl
593 30abcfc7 edgar_igl
        tcg_temp_free(btaken);
594 17ac9754 edgar_igl
}
595 17ac9754 edgar_igl
596 8170028d ths
static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
597 8170028d ths
{
598 8170028d ths
        TranslationBlock *tb;
599 8170028d ths
        tb = dc->tb;
600 8170028d ths
        if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
601 05ba7d5f edgar_igl
                tcg_gen_goto_tb(n);
602 50cfa95c edgar_igl
                tcg_gen_movi_tl(env_pc, dest);
603 05ba7d5f edgar_igl
                tcg_gen_exit_tb((long)tb + n);
604 8170028d ths
        } else {
605 2a44f7f1 edgar_igl
                tcg_gen_movi_tl(env_pc, dest);
606 05ba7d5f edgar_igl
                tcg_gen_exit_tb(0);
607 8170028d ths
        }
608 8170028d ths
}
609 8170028d ths
610 05ba7d5f edgar_igl
static inline void cris_clear_x_flag(DisasContext *dc)
611 05ba7d5f edgar_igl
{
612 2a44f7f1 edgar_igl
        if (dc->flagx_known && dc->flags_x)
613 2a44f7f1 edgar_igl
                dc->flags_uptodate = 0;
614 2a44f7f1 edgar_igl
615 30abcfc7 edgar_igl
        dc->flagx_known = 1;
616 b41f7df0 edgar_igl
        dc->flags_x = 0;
617 05ba7d5f edgar_igl
}
618 05ba7d5f edgar_igl
619 30abcfc7 edgar_igl
static void cris_flush_cc_state(DisasContext *dc)
620 8170028d ths
{
621 30abcfc7 edgar_igl
        if (dc->cc_size_uptodate != dc->cc_size) {
622 b41f7df0 edgar_igl
                tcg_gen_movi_tl(cc_size, dc->cc_size);
623 30abcfc7 edgar_igl
                dc->cc_size_uptodate = dc->cc_size;
624 30abcfc7 edgar_igl
        }
625 30abcfc7 edgar_igl
        tcg_gen_movi_tl(cc_op, dc->cc_op);
626 30abcfc7 edgar_igl
        tcg_gen_movi_tl(cc_mask, dc->cc_mask);
627 30abcfc7 edgar_igl
}
628 30abcfc7 edgar_igl
629 30abcfc7 edgar_igl
static void cris_evaluate_flags(DisasContext *dc)
630 30abcfc7 edgar_igl
{
631 6231868b edgar_igl
        if (dc->flags_uptodate)
632 6231868b edgar_igl
                return;
633 b41f7df0 edgar_igl
634 6231868b edgar_igl
        cris_flush_cc_state(dc);
635 6231868b edgar_igl
636 6231868b edgar_igl
        switch (dc->cc_op)
637 6231868b edgar_igl
        {
638 6231868b edgar_igl
        case CC_OP_MCP:
639 6231868b edgar_igl
                gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS],
640 6231868b edgar_igl
                                        cpu_PR[PR_CCS], cc_src,
641 6231868b edgar_igl
                                        cc_dest, cc_result);
642 6231868b edgar_igl
                break;
643 6231868b edgar_igl
        case CC_OP_MULS:
644 6231868b edgar_igl
                gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS],
645 6231868b edgar_igl
                                        cpu_PR[PR_CCS], cc_result,
646 6231868b edgar_igl
                                        cpu_PR[PR_MOF]);
647 6231868b edgar_igl
                break;
648 6231868b edgar_igl
        case CC_OP_MULU:
649 6231868b edgar_igl
                gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS],
650 6231868b edgar_igl
                                        cpu_PR[PR_CCS], cc_result,
651 6231868b edgar_igl
                                        cpu_PR[PR_MOF]);
652 6231868b edgar_igl
                break;
653 6231868b edgar_igl
        case CC_OP_MOVE:
654 6231868b edgar_igl
        case CC_OP_AND:
655 6231868b edgar_igl
        case CC_OP_OR:
656 6231868b edgar_igl
        case CC_OP_XOR:
657 6231868b edgar_igl
        case CC_OP_ASR:
658 6231868b edgar_igl
        case CC_OP_LSR:
659 6231868b edgar_igl
        case CC_OP_LSL:
660 6231868b edgar_igl
                switch (dc->cc_size)
661 8170028d ths
                {
662 6231868b edgar_igl
                case 4:
663 6231868b edgar_igl
                        gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
664 6231868b edgar_igl
                                                cpu_PR[PR_CCS], cc_result);
665 6231868b edgar_igl
                        break;
666 6231868b edgar_igl
                case 2:
667 6231868b edgar_igl
                        gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
668 6231868b edgar_igl
                                                cpu_PR[PR_CCS], cc_result);
669 6231868b edgar_igl
                        break;
670 6231868b edgar_igl
                default:
671 6231868b edgar_igl
                        gen_helper_evaluate_flags();
672 6231868b edgar_igl
                        break;
673 6231868b edgar_igl
                }
674 6231868b edgar_igl
                break;
675 6231868b edgar_igl
        case CC_OP_FLAGS:
676 6231868b edgar_igl
                /* live.  */
677 6231868b edgar_igl
                break;
678 6231868b edgar_igl
        case CC_OP_SUB:
679 6231868b edgar_igl
        case CC_OP_CMP:
680 6231868b edgar_igl
                if (dc->cc_size == 4)
681 6231868b edgar_igl
                        gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS],
682 6231868b edgar_igl
                                cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
683 6231868b edgar_igl
                else
684 6231868b edgar_igl
                        gen_helper_evaluate_flags();
685 6231868b edgar_igl
686 6231868b edgar_igl
                break;
687 6231868b edgar_igl
        default:
688 6231868b edgar_igl
                switch (dc->cc_size)
689 6231868b edgar_igl
                {
690 6231868b edgar_igl
                        case 4:
691 6231868b edgar_igl
                        gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS],
692 6231868b edgar_igl
                                cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
693 a8cf66bb edgar_igl
                                break;
694 8170028d ths
                        default:
695 6231868b edgar_igl
                                gen_helper_evaluate_flags();
696 6231868b edgar_igl
                                break;
697 8170028d ths
                }
698 6231868b edgar_igl
                break;
699 8170028d ths
        }
700 6231868b edgar_igl
701 6231868b edgar_igl
        if (dc->flagx_known) {
702 6231868b edgar_igl
                if (dc->flags_x)
703 6231868b edgar_igl
                        tcg_gen_ori_tl(cpu_PR[PR_CCS], 
704 6231868b edgar_igl
                                       cpu_PR[PR_CCS], X_FLAG);
705 40e9eddd Edgar E. Iglesias
                else if (dc->cc_op == CC_OP_FLAGS)
706 6231868b edgar_igl
                        tcg_gen_andi_tl(cpu_PR[PR_CCS], 
707 6231868b edgar_igl
                                        cpu_PR[PR_CCS], ~X_FLAG);
708 6231868b edgar_igl
        }
709 6231868b edgar_igl
        dc->flags_uptodate = 1;
710 8170028d ths
}
711 8170028d ths
712 8170028d ths
static void cris_cc_mask(DisasContext *dc, unsigned int mask)
713 8170028d ths
{
714 8170028d ths
        uint32_t ovl;
715 8170028d ths
716 2a44f7f1 edgar_igl
        if (!mask) {
717 2a44f7f1 edgar_igl
                dc->update_cc = 0;
718 2a44f7f1 edgar_igl
                return;
719 2a44f7f1 edgar_igl
        }        
720 2a44f7f1 edgar_igl
721 fd56059f balrog
        /* Check if we need to evaluate the condition codes due to 
722 fd56059f balrog
           CC overlaying.  */
723 8170028d ths
        ovl = (dc->cc_mask ^ mask) & ~mask;
724 8170028d ths
        if (ovl) {
725 8170028d ths
                /* TODO: optimize this case. It trigs all the time.  */
726 8170028d ths
                cris_evaluate_flags (dc);
727 8170028d ths
        }
728 8170028d ths
        dc->cc_mask = mask;
729 8170028d ths
        dc->update_cc = 1;
730 8170028d ths
}
731 8170028d ths
732 b41f7df0 edgar_igl
static void cris_update_cc_op(DisasContext *dc, int op, int size)
733 8170028d ths
{
734 8170028d ths
        dc->cc_op = op;
735 8170028d ths
        dc->cc_size = size;
736 30abcfc7 edgar_igl
        dc->flags_uptodate = 0;
737 8170028d ths
}
738 8170028d ths
739 30abcfc7 edgar_igl
static inline void cris_update_cc_x(DisasContext *dc)
740 30abcfc7 edgar_igl
{
741 30abcfc7 edgar_igl
        /* Save the x flag state at the time of the cc snapshot.  */
742 30abcfc7 edgar_igl
        if (dc->flagx_known) {
743 30abcfc7 edgar_igl
                if (dc->cc_x_uptodate == (2 | dc->flags_x))
744 30abcfc7 edgar_igl
                        return;
745 30abcfc7 edgar_igl
                tcg_gen_movi_tl(cc_x, dc->flags_x);
746 30abcfc7 edgar_igl
                dc->cc_x_uptodate = 2 | dc->flags_x;
747 30abcfc7 edgar_igl
        }
748 30abcfc7 edgar_igl
        else {
749 30abcfc7 edgar_igl
                tcg_gen_andi_tl(cc_x, cpu_PR[PR_CCS], X_FLAG);
750 30abcfc7 edgar_igl
                dc->cc_x_uptodate = 1;
751 30abcfc7 edgar_igl
        }
752 30abcfc7 edgar_igl
}
753 30abcfc7 edgar_igl
754 30abcfc7 edgar_igl
/* Update cc prior to executing ALU op. Needs source operands untouched.  */
755 30abcfc7 edgar_igl
static void cris_pre_alu_update_cc(DisasContext *dc, int op, 
756 30abcfc7 edgar_igl
                                   TCGv dst, TCGv src, int size)
757 8170028d ths
{
758 8170028d ths
        if (dc->update_cc) {
759 b41f7df0 edgar_igl
                cris_update_cc_op(dc, op, size);
760 30abcfc7 edgar_igl
                tcg_gen_mov_tl(cc_src, src);
761 30abcfc7 edgar_igl
762 30abcfc7 edgar_igl
                if (op != CC_OP_MOVE
763 30abcfc7 edgar_igl
                    && op != CC_OP_AND
764 30abcfc7 edgar_igl
                    && op != CC_OP_OR
765 30abcfc7 edgar_igl
                    && op != CC_OP_XOR
766 30abcfc7 edgar_igl
                    && op != CC_OP_ASR
767 30abcfc7 edgar_igl
                    && op != CC_OP_LSR
768 30abcfc7 edgar_igl
                    && op != CC_OP_LSL)
769 30abcfc7 edgar_igl
                        tcg_gen_mov_tl(cc_dest, dst);
770 30abcfc7 edgar_igl
771 30abcfc7 edgar_igl
                cris_update_cc_x(dc);
772 30abcfc7 edgar_igl
        }
773 30abcfc7 edgar_igl
}
774 3157a0a9 edgar_igl
775 30abcfc7 edgar_igl
/* Update cc after executing ALU op. needs the result.  */
776 30abcfc7 edgar_igl
static inline void cris_update_result(DisasContext *dc, TCGv res)
777 30abcfc7 edgar_igl
{
778 a8cf66bb edgar_igl
        if (dc->update_cc)
779 30abcfc7 edgar_igl
                tcg_gen_mov_tl(cc_result, res);
780 30abcfc7 edgar_igl
}
781 8170028d ths
782 30abcfc7 edgar_igl
/* Returns one if the write back stage should execute.  */
783 30abcfc7 edgar_igl
static void cris_alu_op_exec(DisasContext *dc, int op, 
784 30abcfc7 edgar_igl
                               TCGv dst, TCGv a, TCGv b, int size)
785 30abcfc7 edgar_igl
{
786 8170028d ths
        /* Emit the ALU insns.  */
787 8170028d ths
        switch (op)
788 8170028d ths
        {
789 8170028d ths
                case CC_OP_ADD:
790 30abcfc7 edgar_igl
                        tcg_gen_add_tl(dst, a, b);
791 8170028d ths
                        /* Extended arithmetics.  */
792 30abcfc7 edgar_igl
                        t_gen_addx_carry(dc, dst);
793 8170028d ths
                        break;
794 8170028d ths
                case CC_OP_ADDC:
795 30abcfc7 edgar_igl
                        tcg_gen_add_tl(dst, a, b);
796 30abcfc7 edgar_igl
                        t_gen_add_flag(dst, 0); /* C_FLAG.  */
797 8170028d ths
                        break;
798 8170028d ths
                case CC_OP_MCP:
799 30abcfc7 edgar_igl
                        tcg_gen_add_tl(dst, a, b);
800 30abcfc7 edgar_igl
                        t_gen_add_flag(dst, 8); /* R_FLAG.  */
801 8170028d ths
                        break;
802 8170028d ths
                case CC_OP_SUB:
803 30abcfc7 edgar_igl
                        tcg_gen_sub_tl(dst, a, b);
804 8170028d ths
                        /* Extended arithmetics.  */
805 30abcfc7 edgar_igl
                        t_gen_subx_carry(dc, dst);
806 8170028d ths
                        break;
807 8170028d ths
                case CC_OP_MOVE:
808 30abcfc7 edgar_igl
                        tcg_gen_mov_tl(dst, b);
809 8170028d ths
                        break;
810 8170028d ths
                case CC_OP_OR:
811 30abcfc7 edgar_igl
                        tcg_gen_or_tl(dst, a, b);
812 8170028d ths
                        break;
813 8170028d ths
                case CC_OP_AND:
814 30abcfc7 edgar_igl
                        tcg_gen_and_tl(dst, a, b);
815 8170028d ths
                        break;
816 8170028d ths
                case CC_OP_XOR:
817 30abcfc7 edgar_igl
                        tcg_gen_xor_tl(dst, a, b);
818 8170028d ths
                        break;
819 8170028d ths
                case CC_OP_LSL:
820 30abcfc7 edgar_igl
                        t_gen_lsl(dst, a, b);
821 8170028d ths
                        break;
822 8170028d ths
                case CC_OP_LSR:
823 30abcfc7 edgar_igl
                        t_gen_lsr(dst, a, b);
824 8170028d ths
                        break;
825 8170028d ths
                case CC_OP_ASR:
826 30abcfc7 edgar_igl
                        t_gen_asr(dst, a, b);
827 8170028d ths
                        break;
828 8170028d ths
                case CC_OP_NEG:
829 30abcfc7 edgar_igl
                        tcg_gen_neg_tl(dst, b);
830 8170028d ths
                        /* Extended arithmetics.  */
831 30abcfc7 edgar_igl
                        t_gen_subx_carry(dc, dst);
832 8170028d ths
                        break;
833 8170028d ths
                case CC_OP_LZ:
834 c38ac98d edgar_igl
                        gen_helper_lz(dst, b);
835 8170028d ths
                        break;
836 8170028d ths
                case CC_OP_MULS:
837 30abcfc7 edgar_igl
                        t_gen_muls(dst, cpu_PR[PR_MOF], a, b);
838 30abcfc7 edgar_igl
                        break;
839 8170028d ths
                case CC_OP_MULU:
840 30abcfc7 edgar_igl
                        t_gen_mulu(dst, cpu_PR[PR_MOF], a, b);
841 30abcfc7 edgar_igl
                        break;
842 8170028d ths
                case CC_OP_DSTEP:
843 30abcfc7 edgar_igl
                        t_gen_cris_dstep(dst, a, b);
844 8170028d ths
                        break;
845 40e9eddd Edgar E. Iglesias
                case CC_OP_MSTEP:
846 40e9eddd Edgar E. Iglesias
                        t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]);
847 40e9eddd Edgar E. Iglesias
                        break;
848 8170028d ths
                case CC_OP_BOUND:
849 3157a0a9 edgar_igl
                {
850 3157a0a9 edgar_igl
                        int l1;
851 3157a0a9 edgar_igl
                        l1 = gen_new_label();
852 30abcfc7 edgar_igl
                        tcg_gen_mov_tl(dst, a);
853 30abcfc7 edgar_igl
                        tcg_gen_brcond_tl(TCG_COND_LEU, a, b, l1);
854 30abcfc7 edgar_igl
                        tcg_gen_mov_tl(dst, b);
855 3157a0a9 edgar_igl
                        gen_set_label(l1);
856 3157a0a9 edgar_igl
                }
857 3157a0a9 edgar_igl
                break;
858 8170028d ths
                case CC_OP_CMP:
859 30abcfc7 edgar_igl
                        tcg_gen_sub_tl(dst, a, b);
860 8170028d ths
                        /* Extended arithmetics.  */
861 30abcfc7 edgar_igl
                        t_gen_subx_carry(dc, dst);
862 8170028d ths
                        break;
863 8170028d ths
                default:
864 93fcfe39 aliguori
                        qemu_log("illegal ALU op.\n");
865 8170028d ths
                        BUG();
866 8170028d ths
                        break;
867 8170028d ths
        }
868 8170028d ths
869 8170028d ths
        if (size == 1)
870 30abcfc7 edgar_igl
                tcg_gen_andi_tl(dst, dst, 0xff);
871 8170028d ths
        else if (size == 2)
872 30abcfc7 edgar_igl
                tcg_gen_andi_tl(dst, dst, 0xffff);
873 30abcfc7 edgar_igl
}
874 30abcfc7 edgar_igl
875 30abcfc7 edgar_igl
static void cris_alu(DisasContext *dc, int op,
876 30abcfc7 edgar_igl
                               TCGv d, TCGv op_a, TCGv op_b, int size)
877 30abcfc7 edgar_igl
{
878 30abcfc7 edgar_igl
        TCGv tmp;
879 30abcfc7 edgar_igl
        int writeback;
880 30abcfc7 edgar_igl
881 30abcfc7 edgar_igl
        writeback = 1;
882 31c18d87 edgar_igl
883 31c18d87 edgar_igl
        if (op == CC_OP_CMP) {
884 a7812ae4 pbrook
                tmp = tcg_temp_new();
885 30abcfc7 edgar_igl
                writeback = 0;
886 31c18d87 edgar_igl
        } else if (size == 4) {
887 30abcfc7 edgar_igl
                tmp = d;
888 30abcfc7 edgar_igl
                writeback = 0;
889 44696296 edgar_igl
        } else
890 a7812ae4 pbrook
                tmp = tcg_temp_new();
891 44696296 edgar_igl
892 30abcfc7 edgar_igl
893 30abcfc7 edgar_igl
        cris_pre_alu_update_cc(dc, op, op_a, op_b, size);
894 30abcfc7 edgar_igl
        cris_alu_op_exec(dc, op, tmp, op_a, op_b, size);
895 30abcfc7 edgar_igl
        cris_update_result(dc, tmp);
896 05ba7d5f edgar_igl
897 8170028d ths
        /* Writeback.  */
898 8170028d ths
        if (writeback) {
899 30abcfc7 edgar_igl
                if (size == 1)
900 30abcfc7 edgar_igl
                        tcg_gen_andi_tl(d, d, ~0xff);
901 30abcfc7 edgar_igl
                else
902 30abcfc7 edgar_igl
                        tcg_gen_andi_tl(d, d, ~0xffff);
903 30abcfc7 edgar_igl
                tcg_gen_or_tl(d, d, tmp);
904 8170028d ths
        }
905 a7812ae4 pbrook
        if (!TCGV_EQUAL(tmp, d))
906 31c18d87 edgar_igl
                tcg_temp_free(tmp);
907 8170028d ths
}
908 8170028d ths
909 8170028d ths
static int arith_cc(DisasContext *dc)
910 8170028d ths
{
911 8170028d ths
        if (dc->update_cc) {
912 8170028d ths
                switch (dc->cc_op) {
913 30abcfc7 edgar_igl
                        case CC_OP_ADDC: return 1;
914 8170028d ths
                        case CC_OP_ADD: return 1;
915 8170028d ths
                        case CC_OP_SUB: return 1;
916 30abcfc7 edgar_igl
                        case CC_OP_DSTEP: return 1;
917 8170028d ths
                        case CC_OP_LSL: return 1;
918 8170028d ths
                        case CC_OP_LSR: return 1;
919 8170028d ths
                        case CC_OP_ASR: return 1;
920 8170028d ths
                        case CC_OP_CMP: return 1;
921 30abcfc7 edgar_igl
                        case CC_OP_NEG: return 1;
922 30abcfc7 edgar_igl
                        case CC_OP_OR: return 1;
923 459e5185 edgar_igl
                        case CC_OP_AND: return 1;
924 30abcfc7 edgar_igl
                        case CC_OP_XOR: return 1;
925 30abcfc7 edgar_igl
                        case CC_OP_MULU: return 1;
926 30abcfc7 edgar_igl
                        case CC_OP_MULS: return 1;
927 8170028d ths
                        default:
928 8170028d ths
                                return 0;
929 8170028d ths
                }
930 8170028d ths
        }
931 8170028d ths
        return 0;
932 8170028d ths
}
933 8170028d ths
934 c5631f48 edgar_igl
static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
935 8170028d ths
{
936 2a44f7f1 edgar_igl
        int arith_opt, move_opt;
937 8170028d ths
938 8170028d ths
        /* TODO: optimize more condition codes.  */
939 dceaf394 edgar_igl
940 dceaf394 edgar_igl
        /*
941 dceaf394 edgar_igl
         * If the flags are live, we've gotta look into the bits of CCS.
942 dceaf394 edgar_igl
         * Otherwise, if we just did an arithmetic operation we try to
943 dceaf394 edgar_igl
         * evaluate the condition code faster.
944 dceaf394 edgar_igl
         *
945 dceaf394 edgar_igl
         * When this function is done, T0 should be non-zero if the condition
946 dceaf394 edgar_igl
         * code is true.
947 dceaf394 edgar_igl
         */
948 30abcfc7 edgar_igl
        arith_opt = arith_cc(dc) && !dc->flags_uptodate;
949 459e5185 edgar_igl
        move_opt = (dc->cc_op == CC_OP_MOVE);
950 8170028d ths
        switch (cond) {
951 8170028d ths
                case CC_EQ:
952 40e9eddd Edgar E. Iglesias
                        if ((arith_opt || move_opt)
953 40e9eddd Edgar E. Iglesias
                            && dc->cc_x_uptodate != (2 | X_FLAG)) {
954 dceaf394 edgar_igl
                                /* If cc_result is zero, T0 should be 
955 dceaf394 edgar_igl
                                   non-zero otherwise T0 should be zero.  */
956 dceaf394 edgar_igl
                                int l1;
957 dceaf394 edgar_igl
                                l1 = gen_new_label();
958 c5631f48 edgar_igl
                                tcg_gen_movi_tl(cc, 0);
959 cb63669a pbrook
                                tcg_gen_brcondi_tl(TCG_COND_NE, cc_result, 
960 cb63669a pbrook
                                                   0, l1);
961 c5631f48 edgar_igl
                                tcg_gen_movi_tl(cc, 1);
962 dceaf394 edgar_igl
                                gen_set_label(l1);
963 dceaf394 edgar_igl
                        }
964 8170028d ths
                        else {
965 8170028d ths
                                cris_evaluate_flags(dc);
966 c5631f48 edgar_igl
                                tcg_gen_andi_tl(cc, 
967 dceaf394 edgar_igl
                                                cpu_PR[PR_CCS], Z_FLAG);
968 8170028d ths
                        }
969 8170028d ths
                        break;
970 8170028d ths
                case CC_NE:
971 40e9eddd Edgar E. Iglesias
                        if ((arith_opt || move_opt)
972 40e9eddd Edgar E. Iglesias
                            && dc->cc_x_uptodate != (2 | X_FLAG)) {
973 c5631f48 edgar_igl
                                tcg_gen_mov_tl(cc, cc_result);
974 40e9eddd Edgar E. Iglesias
                         } else {
975 8170028d ths
                                cris_evaluate_flags(dc);
976 c5631f48 edgar_igl
                                tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
977 dceaf394 edgar_igl
                                                Z_FLAG);
978 c5631f48 edgar_igl
                                tcg_gen_andi_tl(cc, cc, Z_FLAG);
979 8170028d ths
                        }
980 8170028d ths
                        break;
981 8170028d ths
                case CC_CS:
982 8170028d ths
                        cris_evaluate_flags(dc);
983 c5631f48 edgar_igl
                        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], C_FLAG);
984 8170028d ths
                        break;
985 8170028d ths
                case CC_CC:
986 8170028d ths
                        cris_evaluate_flags(dc);
987 c5631f48 edgar_igl
                        tcg_gen_xori_tl(cc, cpu_PR[PR_CCS], C_FLAG);
988 c5631f48 edgar_igl
                        tcg_gen_andi_tl(cc, cc, C_FLAG);
989 8170028d ths
                        break;
990 8170028d ths
                case CC_VS:
991 8170028d ths
                        cris_evaluate_flags(dc);
992 c5631f48 edgar_igl
                        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], V_FLAG);
993 8170028d ths
                        break;
994 8170028d ths
                case CC_VC:
995 8170028d ths
                        cris_evaluate_flags(dc);
996 c5631f48 edgar_igl
                        tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
997 dceaf394 edgar_igl
                                        V_FLAG);
998 c5631f48 edgar_igl
                        tcg_gen_andi_tl(cc, cc, V_FLAG);
999 8170028d ths
                        break;
1000 8170028d ths
                case CC_PL:
1001 2a44f7f1 edgar_igl
                        if (arith_opt || move_opt) {
1002 2a44f7f1 edgar_igl
                                int bits = 31;
1003 2a44f7f1 edgar_igl
1004 2a44f7f1 edgar_igl
                                if (dc->cc_size == 1)
1005 2a44f7f1 edgar_igl
                                        bits = 7;
1006 2a44f7f1 edgar_igl
                                else if (dc->cc_size == 2)
1007 2a44f7f1 edgar_igl
                                        bits = 15;        
1008 2a44f7f1 edgar_igl
1009 c5631f48 edgar_igl
                                tcg_gen_shri_tl(cc, cc_result, bits);
1010 c5631f48 edgar_igl
                                tcg_gen_xori_tl(cc, cc, 1);
1011 2a44f7f1 edgar_igl
                        } else {
1012 8170028d ths
                                cris_evaluate_flags(dc);
1013 c5631f48 edgar_igl
                                tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
1014 dceaf394 edgar_igl
                                                N_FLAG);
1015 c5631f48 edgar_igl
                                tcg_gen_andi_tl(cc, cc, N_FLAG);
1016 8170028d ths
                        }
1017 8170028d ths
                        break;
1018 8170028d ths
                case CC_MI:
1019 2a44f7f1 edgar_igl
                        if (arith_opt || move_opt) {
1020 2a44f7f1 edgar_igl
                                int bits = 31;
1021 2a44f7f1 edgar_igl
1022 2a44f7f1 edgar_igl
                                if (dc->cc_size == 1)
1023 2a44f7f1 edgar_igl
                                        bits = 7;
1024 2a44f7f1 edgar_igl
                                else if (dc->cc_size == 2)
1025 2a44f7f1 edgar_igl
                                        bits = 15;        
1026 2a44f7f1 edgar_igl
1027 f3bc5238 Edgar E. Iglesias
                                tcg_gen_shri_tl(cc, cc_result, bits);
1028 f3bc5238 Edgar E. Iglesias
                                tcg_gen_andi_tl(cc, cc, 1);
1029 dceaf394 edgar_igl
                        }
1030 8170028d ths
                        else {
1031 8170028d ths
                                cris_evaluate_flags(dc);
1032 c5631f48 edgar_igl
                                tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
1033 dceaf394 edgar_igl
                                                N_FLAG);
1034 8170028d ths
                        }
1035 8170028d ths
                        break;
1036 8170028d ths
                case CC_LS:
1037 8170028d ths
                        cris_evaluate_flags(dc);
1038 c5631f48 edgar_igl
                        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
1039 dceaf394 edgar_igl
                                        C_FLAG | Z_FLAG);
1040 8170028d ths
                        break;
1041 8170028d ths
                case CC_HI:
1042 8170028d ths
                        cris_evaluate_flags(dc);
1043 dceaf394 edgar_igl
                        {
1044 dceaf394 edgar_igl
                                TCGv tmp;
1045 dceaf394 edgar_igl
1046 a7812ae4 pbrook
                                tmp = tcg_temp_new();
1047 dceaf394 edgar_igl
                                tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS],
1048 dceaf394 edgar_igl
                                                C_FLAG | Z_FLAG);
1049 dceaf394 edgar_igl
                                /* Overlay the C flag on top of the Z.  */
1050 c5631f48 edgar_igl
                                tcg_gen_shli_tl(cc, tmp, 2);
1051 c5631f48 edgar_igl
                                tcg_gen_and_tl(cc, tmp, cc);
1052 c5631f48 edgar_igl
                                tcg_gen_andi_tl(cc, cc, Z_FLAG);
1053 dceaf394 edgar_igl
1054 30abcfc7 edgar_igl
                                tcg_temp_free(tmp);
1055 dceaf394 edgar_igl
                        }
1056 8170028d ths
                        break;
1057 8170028d ths
                case CC_GE:
1058 8170028d ths
                        cris_evaluate_flags(dc);
1059 dceaf394 edgar_igl
                        /* Overlay the V flag on top of the N.  */
1060 c5631f48 edgar_igl
                        tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
1061 c5631f48 edgar_igl
                        tcg_gen_xor_tl(cc,
1062 c5631f48 edgar_igl
                                       cpu_PR[PR_CCS], cc);
1063 c5631f48 edgar_igl
                        tcg_gen_andi_tl(cc, cc, N_FLAG);
1064 c5631f48 edgar_igl
                        tcg_gen_xori_tl(cc, cc, N_FLAG);
1065 8170028d ths
                        break;
1066 8170028d ths
                case CC_LT:
1067 8170028d ths
                        cris_evaluate_flags(dc);
1068 dceaf394 edgar_igl
                        /* Overlay the V flag on top of the N.  */
1069 c5631f48 edgar_igl
                        tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
1070 c5631f48 edgar_igl
                        tcg_gen_xor_tl(cc,
1071 c5631f48 edgar_igl
                                       cpu_PR[PR_CCS], cc);
1072 c5631f48 edgar_igl
                        tcg_gen_andi_tl(cc, cc, N_FLAG);
1073 8170028d ths
                        break;
1074 8170028d ths
                case CC_GT:
1075 8170028d ths
                        cris_evaluate_flags(dc);
1076 dceaf394 edgar_igl
                        {
1077 dceaf394 edgar_igl
                                TCGv n, z;
1078 dceaf394 edgar_igl
1079 a7812ae4 pbrook
                                n = tcg_temp_new();
1080 a7812ae4 pbrook
                                z = tcg_temp_new();
1081 dceaf394 edgar_igl
1082 dceaf394 edgar_igl
                                /* To avoid a shift we overlay everything on
1083 dceaf394 edgar_igl
                                   the V flag.  */
1084 dceaf394 edgar_igl
                                tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1085 dceaf394 edgar_igl
                                tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1086 dceaf394 edgar_igl
                                /* invert Z.  */
1087 dceaf394 edgar_igl
                                tcg_gen_xori_tl(z, z, 2);
1088 dceaf394 edgar_igl
1089 dceaf394 edgar_igl
                                tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1090 dceaf394 edgar_igl
                                tcg_gen_xori_tl(n, n, 2);
1091 c5631f48 edgar_igl
                                tcg_gen_and_tl(cc, z, n);
1092 c5631f48 edgar_igl
                                tcg_gen_andi_tl(cc, cc, 2);
1093 dceaf394 edgar_igl
1094 30abcfc7 edgar_igl
                                tcg_temp_free(n);
1095 30abcfc7 edgar_igl
                                tcg_temp_free(z);
1096 dceaf394 edgar_igl
                        }
1097 8170028d ths
                        break;
1098 8170028d ths
                case CC_LE:
1099 8170028d ths
                        cris_evaluate_flags(dc);
1100 dceaf394 edgar_igl
                        {
1101 dceaf394 edgar_igl
                                TCGv n, z;
1102 dceaf394 edgar_igl
1103 a7812ae4 pbrook
                                n = tcg_temp_new();
1104 a7812ae4 pbrook
                                z = tcg_temp_new();
1105 dceaf394 edgar_igl
1106 dceaf394 edgar_igl
                                /* To avoid a shift we overlay everything on
1107 dceaf394 edgar_igl
                                   the V flag.  */
1108 dceaf394 edgar_igl
                                tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1109 dceaf394 edgar_igl
                                tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1110 dceaf394 edgar_igl
1111 dceaf394 edgar_igl
                                tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1112 c5631f48 edgar_igl
                                tcg_gen_or_tl(cc, z, n);
1113 c5631f48 edgar_igl
                                tcg_gen_andi_tl(cc, cc, 2);
1114 dceaf394 edgar_igl
1115 30abcfc7 edgar_igl
                                tcg_temp_free(n);
1116 30abcfc7 edgar_igl
                                tcg_temp_free(z);
1117 dceaf394 edgar_igl
                        }
1118 8170028d ths
                        break;
1119 8170028d ths
                case CC_P:
1120 8170028d ths
                        cris_evaluate_flags(dc);
1121 c5631f48 edgar_igl
                        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], P_FLAG);
1122 8170028d ths
                        break;
1123 8170028d ths
                case CC_A:
1124 c5631f48 edgar_igl
                        tcg_gen_movi_tl(cc, 1);
1125 8170028d ths
                        break;
1126 8170028d ths
                default:
1127 8170028d ths
                        BUG();
1128 8170028d ths
                        break;
1129 8170028d ths
        };
1130 8170028d ths
}
1131 8170028d ths
1132 2a44f7f1 edgar_igl
static void cris_store_direct_jmp(DisasContext *dc)
1133 2a44f7f1 edgar_igl
{
1134 2a44f7f1 edgar_igl
        /* Store the direct jmp state into the cpu-state.  */
1135 2a44f7f1 edgar_igl
        if (dc->jmp == JMP_DIRECT) {
1136 2a44f7f1 edgar_igl
                tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1137 2a44f7f1 edgar_igl
                tcg_gen_movi_tl(env_btaken, 1);
1138 2a44f7f1 edgar_igl
        }
1139 2a44f7f1 edgar_igl
}
1140 2a44f7f1 edgar_igl
1141 2a44f7f1 edgar_igl
static void cris_prepare_cc_branch (DisasContext *dc, 
1142 2a44f7f1 edgar_igl
                                    int offset, int cond)
1143 8170028d ths
{
1144 8170028d ths
        /* This helps us re-schedule the micro-code to insns in delay-slots
1145 8170028d ths
           before the actual jump.  */
1146 8170028d ths
        dc->delayed_branch = 2;
1147 2a44f7f1 edgar_igl
        dc->jmp_pc = dc->pc + offset;
1148 2a44f7f1 edgar_igl
1149 8170028d ths
        if (cond != CC_A)
1150 8170028d ths
        {
1151 2a44f7f1 edgar_igl
                dc->jmp = JMP_INDIRECT;
1152 c5631f48 edgar_igl
                gen_tst_cc (dc, env_btaken, cond);
1153 2a44f7f1 edgar_igl
                tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1154 2a44f7f1 edgar_igl
        } else {
1155 2a44f7f1 edgar_igl
                /* Allow chaining.  */
1156 2a44f7f1 edgar_igl
                dc->jmp = JMP_DIRECT;
1157 2a44f7f1 edgar_igl
        }
1158 8170028d ths
}
1159 8170028d ths
1160 b41f7df0 edgar_igl
1161 2a44f7f1 edgar_igl
/* jumps, when the dest is in a live reg for example. Direct should be set
1162 2a44f7f1 edgar_igl
   when the dest addr is constant to allow tb chaining.  */
1163 2a44f7f1 edgar_igl
static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
1164 8170028d ths
{
1165 8170028d ths
        /* This helps us re-schedule the micro-code to insns in delay-slots
1166 8170028d ths
           before the actual jump.  */
1167 8170028d ths
        dc->delayed_branch = 2;
1168 2a44f7f1 edgar_igl
        dc->jmp = type;
1169 2a44f7f1 edgar_igl
        if (type == JMP_INDIRECT)
1170 2a44f7f1 edgar_igl
                tcg_gen_movi_tl(env_btaken, 1);
1171 8170028d ths
}
1172 8170028d ths
1173 a7812ae4 pbrook
static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
1174 a7812ae4 pbrook
{
1175 a7812ae4 pbrook
        int mem_index = cpu_mmu_index(dc->env);
1176 a7812ae4 pbrook
1177 a7812ae4 pbrook
        /* If we get a fault on a delayslot we must keep the jmp state in
1178 a7812ae4 pbrook
           the cpu-state to be able to re-execute the jmp.  */
1179 a7812ae4 pbrook
        if (dc->delayed_branch == 1)
1180 a7812ae4 pbrook
                cris_store_direct_jmp(dc);
1181 a7812ae4 pbrook
1182 a7812ae4 pbrook
        tcg_gen_qemu_ld64(dst, addr, mem_index);
1183 a7812ae4 pbrook
}
1184 a7812ae4 pbrook
1185 9b32fbf8 edgar_igl
static void gen_load(DisasContext *dc, TCGv dst, TCGv addr, 
1186 9b32fbf8 edgar_igl
                     unsigned int size, int sign)
1187 8170028d ths
{
1188 b41f7df0 edgar_igl
        int mem_index = cpu_mmu_index(dc->env);
1189 b41f7df0 edgar_igl
1190 2a44f7f1 edgar_igl
        /* If we get a fault on a delayslot we must keep the jmp state in
1191 2a44f7f1 edgar_igl
           the cpu-state to be able to re-execute the jmp.  */
1192 2a44f7f1 edgar_igl
        if (dc->delayed_branch == 1)
1193 2a44f7f1 edgar_igl
                cris_store_direct_jmp(dc);
1194 2a44f7f1 edgar_igl
1195 8170028d ths
        if (size == 1) {
1196 8170028d ths
                if (sign)
1197 b41f7df0 edgar_igl
                        tcg_gen_qemu_ld8s(dst, addr, mem_index);
1198 8170028d ths
                else
1199 b41f7df0 edgar_igl
                        tcg_gen_qemu_ld8u(dst, addr, mem_index);
1200 8170028d ths
        }
1201 8170028d ths
        else if (size == 2) {
1202 8170028d ths
                if (sign)
1203 b41f7df0 edgar_igl
                        tcg_gen_qemu_ld16s(dst, addr, mem_index);
1204 8170028d ths
                else
1205 b41f7df0 edgar_igl
                        tcg_gen_qemu_ld16u(dst, addr, mem_index);
1206 8170028d ths
        }
1207 28de16da edgar_igl
        else if (size == 4) {
1208 30abcfc7 edgar_igl
                tcg_gen_qemu_ld32u(dst, addr, mem_index);
1209 8170028d ths
        }
1210 a7812ae4 pbrook
        else {
1211 a7812ae4 pbrook
                abort();
1212 28de16da edgar_igl
        }
1213 8170028d ths
}
1214 8170028d ths
1215 9b32fbf8 edgar_igl
static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
1216 9b32fbf8 edgar_igl
                       unsigned int size)
1217 8170028d ths
{
1218 b41f7df0 edgar_igl
        int mem_index = cpu_mmu_index(dc->env);
1219 b41f7df0 edgar_igl
1220 2a44f7f1 edgar_igl
        /* If we get a fault on a delayslot we must keep the jmp state in
1221 2a44f7f1 edgar_igl
           the cpu-state to be able to re-execute the jmp.  */
1222 2a44f7f1 edgar_igl
        if (dc->delayed_branch == 1)
1223 2a44f7f1 edgar_igl
                 cris_store_direct_jmp(dc);
1224 2a44f7f1 edgar_igl
1225 2a44f7f1 edgar_igl
1226 2a44f7f1 edgar_igl
        /* Conditional writes. We only support the kind were X and P are known
1227 2a44f7f1 edgar_igl
           at translation time.  */
1228 2a44f7f1 edgar_igl
        if (dc->flagx_known && dc->flags_x && (dc->tb_flags & P_FLAG)) {
1229 2a44f7f1 edgar_igl
                dc->postinc = 0;
1230 2a44f7f1 edgar_igl
                cris_evaluate_flags(dc);
1231 2a44f7f1 edgar_igl
                tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
1232 2a44f7f1 edgar_igl
                return;
1233 2a44f7f1 edgar_igl
        }
1234 2a44f7f1 edgar_igl
1235 b41f7df0 edgar_igl
        if (size == 1)
1236 17ac9754 edgar_igl
                tcg_gen_qemu_st8(val, addr, mem_index);
1237 b41f7df0 edgar_igl
        else if (size == 2)
1238 17ac9754 edgar_igl
                tcg_gen_qemu_st16(val, addr, mem_index);
1239 8170028d ths
        else
1240 17ac9754 edgar_igl
                tcg_gen_qemu_st32(val, addr, mem_index);
1241 2a44f7f1 edgar_igl
1242 2a44f7f1 edgar_igl
        if (dc->flagx_known && dc->flags_x) {
1243 2a44f7f1 edgar_igl
                cris_evaluate_flags(dc);
1244 2a44f7f1 edgar_igl
                tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
1245 2a44f7f1 edgar_igl
        }
1246 8170028d ths
}
1247 8170028d ths
1248 05ba7d5f edgar_igl
static inline void t_gen_sext(TCGv d, TCGv s, int size)
1249 8170028d ths
{
1250 8170028d ths
        if (size == 1)
1251 05ba7d5f edgar_igl
                tcg_gen_ext8s_i32(d, s);
1252 8170028d ths
        else if (size == 2)
1253 05ba7d5f edgar_igl
                tcg_gen_ext16s_i32(d, s);
1254 a7812ae4 pbrook
        else if(!TCGV_EQUAL(d, s))
1255 50cfa95c edgar_igl
                tcg_gen_mov_tl(d, s);
1256 8170028d ths
}
1257 8170028d ths
1258 05ba7d5f edgar_igl
static inline void t_gen_zext(TCGv d, TCGv s, int size)
1259 8170028d ths
{
1260 8170028d ths
        if (size == 1)
1261 86831435 pbrook
                tcg_gen_ext8u_i32(d, s);
1262 8170028d ths
        else if (size == 2)
1263 86831435 pbrook
                tcg_gen_ext16u_i32(d, s);
1264 a7812ae4 pbrook
        else if (!TCGV_EQUAL(d, s))
1265 50cfa95c edgar_igl
                tcg_gen_mov_tl(d, s);
1266 8170028d ths
}
1267 8170028d ths
1268 8170028d ths
#if DISAS_CRIS
1269 8170028d ths
static char memsize_char(int size)
1270 8170028d ths
{
1271 8170028d ths
        switch (size)
1272 8170028d ths
        {
1273 8170028d ths
                case 1: return 'b';  break;
1274 8170028d ths
                case 2: return 'w';  break;
1275 8170028d ths
                case 4: return 'd';  break;
1276 8170028d ths
                default:
1277 8170028d ths
                        return 'x';
1278 8170028d ths
                        break;
1279 8170028d ths
        }
1280 8170028d ths
}
1281 8170028d ths
#endif
1282 8170028d ths
1283 30abcfc7 edgar_igl
static inline unsigned int memsize_z(DisasContext *dc)
1284 8170028d ths
{
1285 8170028d ths
        return dc->zsize + 1;
1286 8170028d ths
}
1287 8170028d ths
1288 30abcfc7 edgar_igl
static inline unsigned int memsize_zz(DisasContext *dc)
1289 8170028d ths
{
1290 8170028d ths
        switch (dc->zzsize)
1291 8170028d ths
        {
1292 8170028d ths
                case 0: return 1;
1293 8170028d ths
                case 1: return 2;
1294 8170028d ths
                default:
1295 8170028d ths
                        return 4;
1296 8170028d ths
        }
1297 8170028d ths
}
1298 8170028d ths
1299 c7d05695 edgar_igl
static inline void do_postinc (DisasContext *dc, int size)
1300 8170028d ths
{
1301 c7d05695 edgar_igl
        if (dc->postinc)
1302 c7d05695 edgar_igl
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
1303 8170028d ths
}
1304 8170028d ths
1305 30abcfc7 edgar_igl
static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
1306 43d7ac4e edgar_igl
                                   int size, int s_ext, TCGv dst)
1307 8170028d ths
{
1308 8170028d ths
        if (s_ext)
1309 30abcfc7 edgar_igl
                t_gen_sext(dst, cpu_R[rs], size);
1310 8170028d ths
        else
1311 30abcfc7 edgar_igl
                t_gen_zext(dst, cpu_R[rs], size);
1312 8170028d ths
}
1313 8170028d ths
1314 8170028d ths
/* Prepare T0 and T1 for a register alu operation.
1315 8170028d ths
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1316 8170028d ths
   needed.  */
1317 8170028d ths
static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
1318 fb48f71b edgar_igl
                          int size, int s_ext, TCGv dst, TCGv src)
1319 8170028d ths
{
1320 fb48f71b edgar_igl
        dec_prep_move_r(dc, rs, rd, size, s_ext, src);
1321 8170028d ths
1322 8170028d ths
        if (s_ext)
1323 fb48f71b edgar_igl
                t_gen_sext(dst, cpu_R[rd], size);
1324 8170028d ths
        else
1325 fb48f71b edgar_igl
                t_gen_zext(dst, cpu_R[rd], size);
1326 8170028d ths
}
1327 8170028d ths
1328 30abcfc7 edgar_igl
static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize,
1329 30abcfc7 edgar_igl
                           TCGv dst)
1330 8170028d ths
{
1331 0d84be5b Blue Swirl
        unsigned int rs;
1332 8170028d ths
        uint32_t imm;
1333 8170028d ths
        int is_imm;
1334 8170028d ths
        int insn_len = 2;
1335 8170028d ths
1336 8170028d ths
        rs = dc->op1;
1337 8170028d ths
        is_imm = rs == 15 && dc->postinc;
1338 8170028d ths
1339 8170028d ths
        /* Load [$rs] onto T1.  */
1340 8170028d ths
        if (is_imm) {
1341 8170028d ths
                insn_len = 2 + memsize;
1342 8170028d ths
                if (memsize == 1)
1343 8170028d ths
                        insn_len++;
1344 8170028d ths
1345 7de141cb Edgar E. Iglesias
                imm = cris_fetch(dc, dc->pc + 2, memsize, s_ext);
1346 30abcfc7 edgar_igl
                tcg_gen_movi_tl(dst, imm);
1347 8170028d ths
                dc->postinc = 0;
1348 8170028d ths
        } else {
1349 30abcfc7 edgar_igl
                cris_flush_cc_state(dc);
1350 30abcfc7 edgar_igl
                gen_load(dc, dst, cpu_R[rs], memsize, 0);
1351 8170028d ths
                if (s_ext)
1352 30abcfc7 edgar_igl
                        t_gen_sext(dst, dst, memsize);
1353 8170028d ths
                else
1354 30abcfc7 edgar_igl
                        t_gen_zext(dst, dst, memsize);
1355 8170028d ths
        }
1356 cf1d97f0 edgar_igl
        return insn_len;
1357 cf1d97f0 edgar_igl
}
1358 cf1d97f0 edgar_igl
1359 cf1d97f0 edgar_igl
/* Prepare T0 and T1 for a memory + alu operation.
1360 cf1d97f0 edgar_igl
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1361 cf1d97f0 edgar_igl
   needed.  */
1362 31c18d87 edgar_igl
static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize,
1363 31c18d87 edgar_igl
                          TCGv dst, TCGv src)
1364 cf1d97f0 edgar_igl
{
1365 cf1d97f0 edgar_igl
        int insn_len;
1366 cf1d97f0 edgar_igl
1367 31c18d87 edgar_igl
        insn_len = dec_prep_move_m(dc, s_ext, memsize, src);
1368 31c18d87 edgar_igl
        tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
1369 8170028d ths
        return insn_len;
1370 8170028d ths
}
1371 8170028d ths
1372 8170028d ths
#if DISAS_CRIS
1373 8170028d ths
static const char *cc_name(int cc)
1374 8170028d ths
{
1375 9b32fbf8 edgar_igl
        static const char *cc_names[16] = {
1376 8170028d ths
                "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1377 8170028d ths
                "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1378 8170028d ths
        };
1379 8170028d ths
        assert(cc < 16);
1380 8170028d ths
        return cc_names[cc];
1381 8170028d ths
}
1382 8170028d ths
#endif
1383 8170028d ths
1384 b41f7df0 edgar_igl
/* Start of insn decoders.  */
1385 b41f7df0 edgar_igl
1386 a699a7be Edgar E. Iglesias
static int dec_bccq(DisasContext *dc)
1387 8170028d ths
{
1388 8170028d ths
        int32_t offset;
1389 8170028d ths
        int sign;
1390 8170028d ths
        uint32_t cond = dc->op2;
1391 8170028d ths
1392 8170028d ths
        offset = EXTRACT_FIELD (dc->ir, 1, 7);
1393 8170028d ths
        sign = EXTRACT_FIELD(dc->ir, 0, 0);
1394 8170028d ths
1395 8170028d ths
        offset *= 2;
1396 8170028d ths
        offset |= sign << 8;
1397 8170028d ths
        offset = sign_extend(offset, 8);
1398 8170028d ths
1399 d12d51d5 aliguori
        LOG_DIS("b%s %x\n", cc_name(cond), dc->pc + offset);
1400 2a44f7f1 edgar_igl
1401 8170028d ths
        /* op2 holds the condition-code.  */
1402 8170028d ths
        cris_cc_mask(dc, 0);
1403 8170028d ths
        cris_prepare_cc_branch (dc, offset, cond);
1404 8170028d ths
        return 2;
1405 8170028d ths
}
1406 a699a7be Edgar E. Iglesias
static int dec_addoq(DisasContext *dc)
1407 8170028d ths
{
1408 b41f7df0 edgar_igl
        int32_t imm;
1409 8170028d ths
1410 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1411 8170028d ths
        imm = sign_extend(dc->op1, 7);
1412 8170028d ths
1413 d12d51d5 aliguori
        LOG_DIS("addoq %d, $r%u\n", imm, dc->op2);
1414 8170028d ths
        cris_cc_mask(dc, 0);
1415 8170028d ths
        /* Fetch register operand,  */
1416 b41f7df0 edgar_igl
        tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
1417 fb48f71b edgar_igl
1418 8170028d ths
        return 2;
1419 8170028d ths
}
1420 a699a7be Edgar E. Iglesias
static int dec_addq(DisasContext *dc)
1421 8170028d ths
{
1422 d12d51d5 aliguori
        LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
1423 8170028d ths
1424 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1425 8170028d ths
1426 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1427 30abcfc7 edgar_igl
1428 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_ADD,
1429 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1430 8170028d ths
        return 2;
1431 8170028d ths
}
1432 a699a7be Edgar E. Iglesias
static int dec_moveq(DisasContext *dc)
1433 8170028d ths
{
1434 8170028d ths
        uint32_t imm;
1435 8170028d ths
1436 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1437 8170028d ths
        imm = sign_extend(dc->op1, 5);
1438 d12d51d5 aliguori
        LOG_DIS("moveq %d, $r%u\n", imm, dc->op2);
1439 8170028d ths
1440 46e246c9 Edgar E. Iglesias
        tcg_gen_movi_tl(cpu_R[dc->op2], imm);
1441 8170028d ths
        return 2;
1442 8170028d ths
}
1443 a699a7be Edgar E. Iglesias
static int dec_subq(DisasContext *dc)
1444 8170028d ths
{
1445 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1446 8170028d ths
1447 d12d51d5 aliguori
        LOG_DIS("subq %u, $r%u\n", dc->op1, dc->op2);
1448 8170028d ths
1449 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1450 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_SUB,
1451 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1452 8170028d ths
        return 2;
1453 8170028d ths
}
1454 a699a7be Edgar E. Iglesias
static int dec_cmpq(DisasContext *dc)
1455 8170028d ths
{
1456 8170028d ths
        uint32_t imm;
1457 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1458 8170028d ths
        imm = sign_extend(dc->op1, 5);
1459 8170028d ths
1460 d12d51d5 aliguori
        LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2);
1461 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1462 30abcfc7 edgar_igl
1463 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_CMP,
1464 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1465 8170028d ths
        return 2;
1466 8170028d ths
}
1467 a699a7be Edgar E. Iglesias
static int dec_andq(DisasContext *dc)
1468 8170028d ths
{
1469 8170028d ths
        uint32_t imm;
1470 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1471 8170028d ths
        imm = sign_extend(dc->op1, 5);
1472 8170028d ths
1473 d12d51d5 aliguori
        LOG_DIS("andq %d, $r%d\n", imm, dc->op2);
1474 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1475 30abcfc7 edgar_igl
1476 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_AND,
1477 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1478 8170028d ths
        return 2;
1479 8170028d ths
}
1480 a699a7be Edgar E. Iglesias
static int dec_orq(DisasContext *dc)
1481 8170028d ths
{
1482 8170028d ths
        uint32_t imm;
1483 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1484 8170028d ths
        imm = sign_extend(dc->op1, 5);
1485 d12d51d5 aliguori
        LOG_DIS("orq %d, $r%d\n", imm, dc->op2);
1486 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1487 30abcfc7 edgar_igl
1488 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_OR,
1489 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1490 8170028d ths
        return 2;
1491 8170028d ths
}
1492 a699a7be Edgar E. Iglesias
static int dec_btstq(DisasContext *dc)
1493 8170028d ths
{
1494 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1495 d12d51d5 aliguori
        LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);
1496 17ac9754 edgar_igl
1497 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1498 abd5c94e edgar_igl
        cris_evaluate_flags(dc);
1499 abd5c94e edgar_igl
        gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
1500 abd5c94e edgar_igl
                        tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
1501 abd5c94e edgar_igl
        cris_alu(dc, CC_OP_MOVE,
1502 abd5c94e edgar_igl
                 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1503 b41f7df0 edgar_igl
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1504 30abcfc7 edgar_igl
        dc->flags_uptodate = 1;
1505 8170028d ths
        return 2;
1506 8170028d ths
}
1507 a699a7be Edgar E. Iglesias
static int dec_asrq(DisasContext *dc)
1508 8170028d ths
{
1509 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1510 d12d51d5 aliguori
        LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
1511 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1512 30abcfc7 edgar_igl
1513 2a44f7f1 edgar_igl
        tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1514 2a44f7f1 edgar_igl
        cris_alu(dc, CC_OP_MOVE,
1515 30abcfc7 edgar_igl
                    cpu_R[dc->op2],
1516 2a44f7f1 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], 4);
1517 8170028d ths
        return 2;
1518 8170028d ths
}
1519 a699a7be Edgar E. Iglesias
static int dec_lslq(DisasContext *dc)
1520 8170028d ths
{
1521 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1522 d12d51d5 aliguori
        LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
1523 8170028d ths
1524 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1525 30abcfc7 edgar_igl
1526 2a44f7f1 edgar_igl
        tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1527 2a44f7f1 edgar_igl
1528 2a44f7f1 edgar_igl
        cris_alu(dc, CC_OP_MOVE,
1529 30abcfc7 edgar_igl
                    cpu_R[dc->op2],
1530 2a44f7f1 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], 4);
1531 8170028d ths
        return 2;
1532 8170028d ths
}
1533 a699a7be Edgar E. Iglesias
static int dec_lsrq(DisasContext *dc)
1534 8170028d ths
{
1535 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1536 d12d51d5 aliguori
        LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
1537 8170028d ths
1538 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1539 30abcfc7 edgar_igl
1540 2a44f7f1 edgar_igl
        tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1541 2a44f7f1 edgar_igl
        cris_alu(dc, CC_OP_MOVE,
1542 30abcfc7 edgar_igl
                    cpu_R[dc->op2],
1543 2a44f7f1 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], 4);
1544 8170028d ths
        return 2;
1545 8170028d ths
}
1546 8170028d ths
1547 a699a7be Edgar E. Iglesias
static int dec_move_r(DisasContext *dc)
1548 8170028d ths
{
1549 8170028d ths
        int size = memsize_zz(dc);
1550 8170028d ths
1551 d12d51d5 aliguori
        LOG_DIS("move.%c $r%u, $r%u\n",
1552 d12d51d5 aliguori
                    memsize_char(size), dc->op1, dc->op2);
1553 8170028d ths
1554 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1555 30abcfc7 edgar_igl
        if (size == 4) {
1556 30abcfc7 edgar_igl
                dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
1557 30abcfc7 edgar_igl
                cris_cc_mask(dc, CC_MASK_NZ);
1558 30abcfc7 edgar_igl
                cris_update_cc_op(dc, CC_OP_MOVE, 4);
1559 30abcfc7 edgar_igl
                cris_update_cc_x(dc);
1560 30abcfc7 edgar_igl
                cris_update_result(dc, cpu_R[dc->op2]);
1561 30abcfc7 edgar_igl
        }
1562 30abcfc7 edgar_igl
        else {
1563 43d7ac4e edgar_igl
                TCGv t0;
1564 43d7ac4e edgar_igl
1565 a7812ae4 pbrook
                t0 = tcg_temp_new();
1566 43d7ac4e edgar_igl
                dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1567 30abcfc7 edgar_igl
                cris_alu(dc, CC_OP_MOVE,
1568 30abcfc7 edgar_igl
                         cpu_R[dc->op2],
1569 43d7ac4e edgar_igl
                         cpu_R[dc->op2], t0, size);
1570 43d7ac4e edgar_igl
                tcg_temp_free(t0);
1571 30abcfc7 edgar_igl
        }
1572 8170028d ths
        return 2;
1573 8170028d ths
}
1574 8170028d ths
1575 a699a7be Edgar E. Iglesias
static int dec_scc_r(DisasContext *dc)
1576 8170028d ths
{
1577 8170028d ths
        int cond = dc->op2;
1578 8170028d ths
1579 d12d51d5 aliguori
        LOG_DIS("s%s $r%u\n",
1580 d12d51d5 aliguori
                    cc_name(cond), dc->op1);
1581 8170028d ths
1582 8170028d ths
        if (cond != CC_A)
1583 8170028d ths
        {
1584 dceaf394 edgar_igl
                int l1;
1585 dceaf394 edgar_igl
1586 c5631f48 edgar_igl
                gen_tst_cc (dc, cpu_R[dc->op1], cond);
1587 dceaf394 edgar_igl
                l1 = gen_new_label();
1588 c5631f48 edgar_igl
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->op1], 0, l1);
1589 dceaf394 edgar_igl
                tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1590 dceaf394 edgar_igl
                gen_set_label(l1);
1591 8170028d ths
        }
1592 8170028d ths
        else
1593 dceaf394 edgar_igl
                tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1594 8170028d ths
1595 8170028d ths
        cris_cc_mask(dc, 0);
1596 8170028d ths
        return 2;
1597 8170028d ths
}
1598 8170028d ths
1599 fb48f71b edgar_igl
static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t)
1600 fb48f71b edgar_igl
{
1601 fb48f71b edgar_igl
        if (size == 4) {
1602 fb48f71b edgar_igl
                t[0] = cpu_R[dc->op2];
1603 fb48f71b edgar_igl
                t[1] = cpu_R[dc->op1];
1604 fb48f71b edgar_igl
        } else {
1605 a7812ae4 pbrook
                t[0] = tcg_temp_new();
1606 a7812ae4 pbrook
                t[1] = tcg_temp_new();
1607 fb48f71b edgar_igl
        }
1608 fb48f71b edgar_igl
}
1609 fb48f71b edgar_igl
1610 fb48f71b edgar_igl
static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
1611 fb48f71b edgar_igl
{
1612 fb48f71b edgar_igl
        if (size != 4) {
1613 fb48f71b edgar_igl
                tcg_temp_free(t[0]);
1614 fb48f71b edgar_igl
                tcg_temp_free(t[1]);
1615 fb48f71b edgar_igl
        }
1616 fb48f71b edgar_igl
}
1617 fb48f71b edgar_igl
1618 a699a7be Edgar E. Iglesias
static int dec_and_r(DisasContext *dc)
1619 8170028d ths
{
1620 fb48f71b edgar_igl
        TCGv t[2];
1621 8170028d ths
        int size = memsize_zz(dc);
1622 8170028d ths
1623 d12d51d5 aliguori
        LOG_DIS("and.%c $r%u, $r%u\n",
1624 d12d51d5 aliguori
                    memsize_char(size), dc->op1, dc->op2);
1625 fb48f71b edgar_igl
1626 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1627 30abcfc7 edgar_igl
1628 fb48f71b edgar_igl
        cris_alu_alloc_temps(dc, size, t);
1629 fb48f71b edgar_igl
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1630 fb48f71b edgar_igl
        cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
1631 fb48f71b edgar_igl
        cris_alu_free_temps(dc, size, t);
1632 8170028d ths
        return 2;
1633 8170028d ths
}
1634 8170028d ths
1635 a699a7be Edgar E. Iglesias
static int dec_lz_r(DisasContext *dc)
1636 8170028d ths
{
1637 fb48f71b edgar_igl
        TCGv t0;
1638 d12d51d5 aliguori
        LOG_DIS("lz $r%u, $r%u\n",
1639 d12d51d5 aliguori
                    dc->op1, dc->op2);
1640 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1641 a7812ae4 pbrook
        t0 = tcg_temp_new();
1642 fb48f71b edgar_igl
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
1643 fb48f71b edgar_igl
        cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1644 fb48f71b edgar_igl
        tcg_temp_free(t0);
1645 8170028d ths
        return 2;
1646 8170028d ths
}
1647 8170028d ths
1648 a699a7be Edgar E. Iglesias
static int dec_lsl_r(DisasContext *dc)
1649 8170028d ths
{
1650 fb48f71b edgar_igl
        TCGv t[2];
1651 8170028d ths
        int size = memsize_zz(dc);
1652 8170028d ths
1653 d12d51d5 aliguori
        LOG_DIS("lsl.%c $r%u, $r%u\n",
1654 d12d51d5 aliguori
                    memsize_char(size), dc->op1, dc->op2);
1655 30abcfc7 edgar_igl
1656 fb48f71b edgar_igl
        cris_cc_mask(dc, CC_MASK_NZ);
1657 fb48f71b edgar_igl
        cris_alu_alloc_temps(dc, size, t);
1658 fb48f71b edgar_igl
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1659 fb48f71b edgar_igl
        tcg_gen_andi_tl(t[1], t[1], 63);
1660 fb48f71b edgar_igl
        cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size);
1661 fb48f71b edgar_igl
        cris_alu_alloc_temps(dc, size, t);
1662 8170028d ths
        return 2;
1663 8170028d ths
}
1664 8170028d ths
1665 a699a7be Edgar E. Iglesias
static int dec_lsr_r(DisasContext *dc)
1666 8170028d ths
{
1667 fb48f71b edgar_igl
        TCGv t[2];
1668 8170028d ths
        int size = memsize_zz(dc);
1669 8170028d ths
1670 d12d51d5 aliguori
        LOG_DIS("lsr.%c $r%u, $r%u\n",
1671 d12d51d5 aliguori
                    memsize_char(size), dc->op1, dc->op2);
1672 30abcfc7 edgar_igl
1673 fb48f71b edgar_igl
        cris_cc_mask(dc, CC_MASK_NZ);
1674 fb48f71b edgar_igl
        cris_alu_alloc_temps(dc, size, t);
1675 fb48f71b edgar_igl
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1676 fb48f71b edgar_igl
        tcg_gen_andi_tl(t[1], t[1], 63);
1677 fb48f71b edgar_igl
        cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size);
1678 fb48f71b edgar_igl
        cris_alu_free_temps(dc, size, t);
1679 8170028d ths
        return 2;
1680 8170028d ths
}
1681 8170028d ths
1682 a699a7be Edgar E. Iglesias
static int dec_asr_r(DisasContext *dc)
1683 8170028d ths
{
1684 fb48f71b edgar_igl
        TCGv t[2];
1685 8170028d ths
        int size = memsize_zz(dc);
1686 8170028d ths
1687 d12d51d5 aliguori
        LOG_DIS("asr.%c $r%u, $r%u\n",
1688 d12d51d5 aliguori
                    memsize_char(size), dc->op1, dc->op2);
1689 30abcfc7 edgar_igl
1690 fb48f71b edgar_igl
        cris_cc_mask(dc, CC_MASK_NZ);
1691 fb48f71b edgar_igl
        cris_alu_alloc_temps(dc, size, t);
1692 fb48f71b edgar_igl
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1693 fb48f71b edgar_igl
        tcg_gen_andi_tl(t[1], t[1], 63);
1694 fb48f71b edgar_igl
        cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
1695 fb48f71b edgar_igl
        cris_alu_free_temps(dc, size, t);
1696 8170028d ths
        return 2;
1697 8170028d ths
}
1698 8170028d ths
1699 a699a7be Edgar E. Iglesias
static int dec_muls_r(DisasContext *dc)
1700 8170028d ths
{
1701 fb48f71b edgar_igl
        TCGv t[2];
1702 8170028d ths
        int size = memsize_zz(dc);
1703 8170028d ths
1704 d12d51d5 aliguori
        LOG_DIS("muls.%c $r%u, $r%u\n",
1705 d12d51d5 aliguori
                    memsize_char(size), dc->op1, dc->op2);
1706 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZV);
1707 fb48f71b edgar_igl
        cris_alu_alloc_temps(dc, size, t);
1708 fb48f71b edgar_igl
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1709 30abcfc7 edgar_igl
1710 fb48f71b edgar_igl
        cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
1711 fb48f71b edgar_igl
        cris_alu_free_temps(dc, size, t);
1712 8170028d ths
        return 2;
1713 8170028d ths
}
1714 8170028d ths
1715 a699a7be Edgar E. Iglesias
static int dec_mulu_r(DisasContext *dc)
1716 8170028d ths
{
1717 fb48f71b edgar_igl
        TCGv t[2];
1718 8170028d ths
        int size = memsize_zz(dc);
1719 8170028d ths
1720 d12d51d5 aliguori
        LOG_DIS("mulu.%c $r%u, $r%u\n",
1721 d12d51d5 aliguori
                    memsize_char(size), dc->op1, dc->op2);
1722 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZV);
1723 fb48f71b edgar_igl
        cris_alu_alloc_temps(dc, size, t);
1724 fb48f71b edgar_igl
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1725 30abcfc7 edgar_igl
1726 fb48f71b edgar_igl
        cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
1727 fb48f71b edgar_igl
        cris_alu_alloc_temps(dc, size, t);
1728 8170028d ths
        return 2;
1729 8170028d ths
}
1730 8170028d ths
1731 8170028d ths
1732 a699a7be Edgar E. Iglesias
static int dec_dstep_r(DisasContext *dc)
1733 8170028d ths
{
1734 d12d51d5 aliguori
        LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
1735 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1736 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_DSTEP,
1737 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1738 8170028d ths
        return 2;
1739 8170028d ths
}
1740 8170028d ths
1741 a699a7be Edgar E. Iglesias
static int dec_xor_r(DisasContext *dc)
1742 8170028d ths
{
1743 fb48f71b edgar_igl
        TCGv t[2];
1744 8170028d ths
        int size = memsize_zz(dc);
1745 d12d51d5 aliguori
        LOG_DIS("xor.%c $r%u, $r%u\n",
1746 d12d51d5 aliguori
                    memsize_char(size), dc->op1, dc->op2);
1747 8170028d ths
        BUG_ON(size != 4); /* xor is dword.  */
1748 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1749 fb48f71b edgar_igl
        cris_alu_alloc_temps(dc, size, t);
1750 fb48f71b edgar_igl
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1751 30abcfc7 edgar_igl
1752 fb48f71b edgar_igl
        cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
1753 fb48f71b edgar_igl
        cris_alu_free_temps(dc, size, t);
1754 8170028d ths
        return 2;
1755 8170028d ths
}
1756 8170028d ths
1757 a699a7be Edgar E. Iglesias
static int dec_bound_r(DisasContext *dc)
1758 8170028d ths
{
1759 fb48f71b edgar_igl
        TCGv l0;
1760 8170028d ths
        int size = memsize_zz(dc);
1761 d12d51d5 aliguori
        LOG_DIS("bound.%c $r%u, $r%u\n",
1762 d12d51d5 aliguori
                    memsize_char(size), dc->op1, dc->op2);
1763 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1764 a7812ae4 pbrook
        l0 = tcg_temp_local_new();
1765 fb48f71b edgar_igl
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
1766 31c18d87 edgar_igl
        cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
1767 31c18d87 edgar_igl
        tcg_temp_free(l0);
1768 8170028d ths
        return 2;
1769 8170028d ths
}
1770 8170028d ths
1771 a699a7be Edgar E. Iglesias
static int dec_cmp_r(DisasContext *dc)
1772 8170028d ths
{
1773 fb48f71b edgar_igl
        TCGv t[2];
1774 8170028d ths
        int size = memsize_zz(dc);
1775 d12d51d5 aliguori
        LOG_DIS("cmp.%c $r%u, $r%u\n",
1776 d12d51d5 aliguori
                    memsize_char(size), dc->op1, dc->op2);
1777 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1778 fb48f71b edgar_igl
        cris_alu_alloc_temps(dc, size, t);
1779 fb48f71b edgar_igl
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1780 30abcfc7 edgar_igl
1781 fb48f71b edgar_igl
        cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
1782 fb48f71b edgar_igl
        cris_alu_free_temps(dc, size, t);
1783 8170028d ths
        return 2;
1784 8170028d ths
}
1785 8170028d ths
1786 a699a7be Edgar E. Iglesias
static int dec_abs_r(DisasContext *dc)
1787 8170028d ths
{
1788 7dcfb089 edgar_igl
        TCGv t0;
1789 3157a0a9 edgar_igl
1790 d12d51d5 aliguori
        LOG_DIS("abs $r%u, $r%u\n",
1791 d12d51d5 aliguori
                    dc->op1, dc->op2);
1792 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1793 3157a0a9 edgar_igl
1794 a7812ae4 pbrook
        t0 = tcg_temp_new();
1795 7dcfb089 edgar_igl
        tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31);
1796 7dcfb089 edgar_igl
        tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0);
1797 7dcfb089 edgar_igl
        tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0);
1798 7dcfb089 edgar_igl
        tcg_temp_free(t0);
1799 7dcfb089 edgar_igl
1800 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_MOVE,
1801 7dcfb089 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1802 8170028d ths
        return 2;
1803 8170028d ths
}
1804 8170028d ths
1805 a699a7be Edgar E. Iglesias
static int dec_add_r(DisasContext *dc)
1806 8170028d ths
{
1807 fb48f71b edgar_igl
        TCGv t[2];
1808 8170028d ths
        int size = memsize_zz(dc);
1809 d12d51d5 aliguori
        LOG_DIS("add.%c $r%u, $r%u\n",
1810 d12d51d5 aliguori
                    memsize_char(size), dc->op1, dc->op2);
1811 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1812 fb48f71b edgar_igl
        cris_alu_alloc_temps(dc, size, t);
1813 fb48f71b edgar_igl
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1814 30abcfc7 edgar_igl
1815 fb48f71b edgar_igl
        cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
1816 fb48f71b edgar_igl
        cris_alu_free_temps(dc, size, t);
1817 8170028d ths
        return 2;
1818 8170028d ths
}
1819 8170028d ths
1820 a699a7be Edgar E. Iglesias
static int dec_addc_r(DisasContext *dc)
1821 8170028d ths
{
1822 d12d51d5 aliguori
        LOG_DIS("addc $r%u, $r%u\n",
1823 d12d51d5 aliguori
                    dc->op1, dc->op2);
1824 8170028d ths
        cris_evaluate_flags(dc);
1825 a8cf66bb edgar_igl
        /* Set for this insn.  */
1826 a8cf66bb edgar_igl
        dc->flagx_known = 1;
1827 a8cf66bb edgar_igl
        dc->flags_x = X_FLAG;
1828 a8cf66bb edgar_igl
1829 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1830 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_ADDC,
1831 fb48f71b edgar_igl
                 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1832 8170028d ths
        return 2;
1833 8170028d ths
}
1834 8170028d ths
1835 a699a7be Edgar E. Iglesias
static int dec_mcp_r(DisasContext *dc)
1836 8170028d ths
{
1837 d12d51d5 aliguori
        LOG_DIS("mcp $p%u, $r%u\n",
1838 d12d51d5 aliguori
                     dc->op2, dc->op1);
1839 8170028d ths
        cris_evaluate_flags(dc);
1840 8170028d ths
        cris_cc_mask(dc, CC_MASK_RNZV);
1841 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_MCP,
1842 30abcfc7 edgar_igl
                    cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
1843 8170028d ths
        return 2;
1844 8170028d ths
}
1845 8170028d ths
1846 8170028d ths
#if DISAS_CRIS
1847 8170028d ths
static char * swapmode_name(int mode, char *modename) {
1848 8170028d ths
        int i = 0;
1849 8170028d ths
        if (mode & 8)
1850 8170028d ths
                modename[i++] = 'n';
1851 8170028d ths
        if (mode & 4)
1852 8170028d ths
                modename[i++] = 'w';
1853 8170028d ths
        if (mode & 2)
1854 8170028d ths
                modename[i++] = 'b';
1855 8170028d ths
        if (mode & 1)
1856 8170028d ths
                modename[i++] = 'r';
1857 8170028d ths
        modename[i++] = 0;
1858 8170028d ths
        return modename;
1859 8170028d ths
}
1860 8170028d ths
#endif
1861 8170028d ths
1862 a699a7be Edgar E. Iglesias
static int dec_swap_r(DisasContext *dc)
1863 8170028d ths
{
1864 fb48f71b edgar_igl
        TCGv t0;
1865 cf1d97f0 edgar_igl
#if DISAS_CRIS
1866 cf1d97f0 edgar_igl
        char modename[4];
1867 cf1d97f0 edgar_igl
#endif
1868 d12d51d5 aliguori
        LOG_DIS("swap%s $r%u\n",
1869 d12d51d5 aliguori
                     swapmode_name(dc->op2, modename), dc->op1);
1870 8170028d ths
1871 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1872 a7812ae4 pbrook
        t0 = tcg_temp_new();
1873 fb48f71b edgar_igl
        t_gen_mov_TN_reg(t0, dc->op1);
1874 8170028d ths
        if (dc->op2 & 8)
1875 fb48f71b edgar_igl
                tcg_gen_not_tl(t0, t0);
1876 8170028d ths
        if (dc->op2 & 4)
1877 fb48f71b edgar_igl
                t_gen_swapw(t0, t0);
1878 8170028d ths
        if (dc->op2 & 2)
1879 fb48f71b edgar_igl
                t_gen_swapb(t0, t0);
1880 8170028d ths
        if (dc->op2 & 1)
1881 fb48f71b edgar_igl
                t_gen_swapr(t0, t0);
1882 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_MOVE,
1883 fb48f71b edgar_igl
                    cpu_R[dc->op1], cpu_R[dc->op1], t0, 4);
1884 f4b147f6 edgar_igl
        tcg_temp_free(t0);
1885 8170028d ths
        return 2;
1886 8170028d ths
}
1887 8170028d ths
1888 a699a7be Edgar E. Iglesias
static int dec_or_r(DisasContext *dc)
1889 8170028d ths
{
1890 fb48f71b edgar_igl
        TCGv t[2];
1891 8170028d ths
        int size = memsize_zz(dc);
1892 d12d51d5 aliguori
        LOG_DIS("or.%c $r%u, $r%u\n",
1893 d12d51d5 aliguori
                    memsize_char(size), dc->op1, dc->op2);
1894 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1895 fb48f71b edgar_igl
        cris_alu_alloc_temps(dc, size, t);
1896 fb48f71b edgar_igl
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1897 fb48f71b edgar_igl
        cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
1898 fb48f71b edgar_igl
        cris_alu_free_temps(dc, size, t);
1899 8170028d ths
        return 2;
1900 8170028d ths
}
1901 8170028d ths
1902 a699a7be Edgar E. Iglesias
static int dec_addi_r(DisasContext *dc)
1903 8170028d ths
{
1904 fb48f71b edgar_igl
        TCGv t0;
1905 d12d51d5 aliguori
        LOG_DIS("addi.%c $r%u, $r%u\n",
1906 d12d51d5 aliguori
                    memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1907 8170028d ths
        cris_cc_mask(dc, 0);
1908 a7812ae4 pbrook
        t0 = tcg_temp_new();
1909 fb48f71b edgar_igl
        tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1910 fb48f71b edgar_igl
        tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0);
1911 f4b147f6 edgar_igl
        tcg_temp_free(t0);
1912 8170028d ths
        return 2;
1913 8170028d ths
}
1914 8170028d ths
1915 a699a7be Edgar E. Iglesias
static int dec_addi_acr(DisasContext *dc)
1916 8170028d ths
{
1917 fb48f71b edgar_igl
        TCGv t0;
1918 d12d51d5 aliguori
        LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
1919 d12d51d5 aliguori
                  memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1920 8170028d ths
        cris_cc_mask(dc, 0);
1921 a7812ae4 pbrook
        t0 = tcg_temp_new();
1922 fb48f71b edgar_igl
        tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1923 fb48f71b edgar_igl
        tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
1924 f4b147f6 edgar_igl
        tcg_temp_free(t0);
1925 8170028d ths
        return 2;
1926 8170028d ths
}
1927 8170028d ths
1928 a699a7be Edgar E. Iglesias
static int dec_neg_r(DisasContext *dc)
1929 8170028d ths
{
1930 fb48f71b edgar_igl
        TCGv t[2];
1931 8170028d ths
        int size = memsize_zz(dc);
1932 d12d51d5 aliguori
        LOG_DIS("neg.%c $r%u, $r%u\n",
1933 d12d51d5 aliguori
                    memsize_char(size), dc->op1, dc->op2);
1934 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1935 fb48f71b edgar_igl
        cris_alu_alloc_temps(dc, size, t);
1936 fb48f71b edgar_igl
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1937 30abcfc7 edgar_igl
1938 fb48f71b edgar_igl
        cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
1939 fb48f71b edgar_igl
        cris_alu_free_temps(dc, size, t);
1940 8170028d ths
        return 2;
1941 8170028d ths
}
1942 8170028d ths
1943 a699a7be Edgar E. Iglesias
static int dec_btst_r(DisasContext *dc)
1944 8170028d ths
{
1945 d12d51d5 aliguori
        LOG_DIS("btst $r%u, $r%u\n",
1946 d12d51d5 aliguori
                    dc->op1, dc->op2);
1947 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1948 abd5c94e edgar_igl
        cris_evaluate_flags(dc);
1949 abd5c94e edgar_igl
        gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
1950 abd5c94e edgar_igl
                        cpu_R[dc->op1], cpu_PR[PR_CCS]);
1951 abd5c94e edgar_igl
        cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
1952 abd5c94e edgar_igl
                 cpu_R[dc->op2], cpu_R[dc->op2], 4);
1953 b41f7df0 edgar_igl
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1954 30abcfc7 edgar_igl
        dc->flags_uptodate = 1;
1955 8170028d ths
        return 2;
1956 8170028d ths
}
1957 8170028d ths
1958 a699a7be Edgar E. Iglesias
static int dec_sub_r(DisasContext *dc)
1959 8170028d ths
{
1960 fb48f71b edgar_igl
        TCGv t[2];
1961 8170028d ths
        int size = memsize_zz(dc);
1962 d12d51d5 aliguori
        LOG_DIS("sub.%c $r%u, $r%u\n",
1963 d12d51d5 aliguori
                    memsize_char(size), dc->op1, dc->op2);
1964 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1965 fb48f71b edgar_igl
        cris_alu_alloc_temps(dc, size, t);
1966 fb48f71b edgar_igl
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1967 fb48f71b edgar_igl
        cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
1968 fb48f71b edgar_igl
        cris_alu_free_temps(dc, size, t);
1969 8170028d ths
        return 2;
1970 8170028d ths
}
1971 8170028d ths
1972 8170028d ths
/* Zero extension. From size to dword.  */
1973 a699a7be Edgar E. Iglesias
static int dec_movu_r(DisasContext *dc)
1974 8170028d ths
{
1975 fb48f71b edgar_igl
        TCGv t0;
1976 8170028d ths
        int size = memsize_z(dc);
1977 d12d51d5 aliguori
        LOG_DIS("movu.%c $r%u, $r%u\n",
1978 8170028d ths
                    memsize_char(size),
1979 d12d51d5 aliguori
                    dc->op1, dc->op2);
1980 8170028d ths
1981 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1982 a7812ae4 pbrook
        t0 = tcg_temp_new();
1983 fb48f71b edgar_igl
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1984 fb48f71b edgar_igl
        cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1985 fb48f71b edgar_igl
        tcg_temp_free(t0);
1986 8170028d ths
        return 2;
1987 8170028d ths
}
1988 8170028d ths
1989 8170028d ths
/* Sign extension. From size to dword.  */
1990 a699a7be Edgar E. Iglesias
static int dec_movs_r(DisasContext *dc)
1991 8170028d ths
{
1992 fb48f71b edgar_igl
        TCGv t0;
1993 8170028d ths
        int size = memsize_z(dc);
1994 d12d51d5 aliguori
        LOG_DIS("movs.%c $r%u, $r%u\n",
1995 8170028d ths
                    memsize_char(size),
1996 d12d51d5 aliguori
                    dc->op1, dc->op2);
1997 8170028d ths
1998 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1999 a7812ae4 pbrook
        t0 = tcg_temp_new();
2000 8170028d ths
        /* Size can only be qi or hi.  */
2001 fb48f71b edgar_igl
        t_gen_sext(t0, cpu_R[dc->op1], size);
2002 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_MOVE,
2003 fb48f71b edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op1], t0, 4);
2004 fb48f71b edgar_igl
        tcg_temp_free(t0);
2005 8170028d ths
        return 2;
2006 8170028d ths
}
2007 8170028d ths
2008 8170028d ths
/* zero extension. From size to dword.  */
2009 a699a7be Edgar E. Iglesias
static int dec_addu_r(DisasContext *dc)
2010 8170028d ths
{
2011 fb48f71b edgar_igl
        TCGv t0;
2012 8170028d ths
        int size = memsize_z(dc);
2013 d12d51d5 aliguori
        LOG_DIS("addu.%c $r%u, $r%u\n",
2014 8170028d ths
                    memsize_char(size),
2015 d12d51d5 aliguori
                    dc->op1, dc->op2);
2016 8170028d ths
2017 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
2018 a7812ae4 pbrook
        t0 = tcg_temp_new();
2019 8170028d ths
        /* Size can only be qi or hi.  */
2020 fb48f71b edgar_igl
        t_gen_zext(t0, cpu_R[dc->op1], size);
2021 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_ADD,
2022 fb48f71b edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2023 fb48f71b edgar_igl
        tcg_temp_free(t0);
2024 8170028d ths
        return 2;
2025 8170028d ths
}
2026 05ba7d5f edgar_igl
2027 8170028d ths
/* Sign extension. From size to dword.  */
2028 a699a7be Edgar E. Iglesias
static int dec_adds_r(DisasContext *dc)
2029 8170028d ths
{
2030 fb48f71b edgar_igl
        TCGv t0;
2031 8170028d ths
        int size = memsize_z(dc);
2032 d12d51d5 aliguori
        LOG_DIS("adds.%c $r%u, $r%u\n",
2033 8170028d ths
                    memsize_char(size),
2034 d12d51d5 aliguori
                    dc->op1, dc->op2);
2035 8170028d ths
2036 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
2037 a7812ae4 pbrook
        t0 = tcg_temp_new();
2038 8170028d ths
        /* Size can only be qi or hi.  */
2039 fb48f71b edgar_igl
        t_gen_sext(t0, cpu_R[dc->op1], size);
2040 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_ADD,
2041 fb48f71b edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2042 fb48f71b edgar_igl
        tcg_temp_free(t0);
2043 8170028d ths
        return 2;
2044 8170028d ths
}
2045 8170028d ths
2046 8170028d ths
/* Zero extension. From size to dword.  */
2047 a699a7be Edgar E. Iglesias
static int dec_subu_r(DisasContext *dc)
2048 8170028d ths
{
2049 fb48f71b edgar_igl
        TCGv t0;
2050 8170028d ths
        int size = memsize_z(dc);
2051 d12d51d5 aliguori
        LOG_DIS("subu.%c $r%u, $r%u\n",
2052 8170028d ths
                    memsize_char(size),
2053 d12d51d5 aliguori
                    dc->op1, dc->op2);
2054 8170028d ths
2055 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
2056 a7812ae4 pbrook
        t0 = tcg_temp_new();
2057 8170028d ths
        /* Size can only be qi or hi.  */
2058 fb48f71b edgar_igl
        t_gen_zext(t0, cpu_R[dc->op1], size);
2059 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_SUB,
2060 fb48f71b edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2061 fb48f71b edgar_igl
        tcg_temp_free(t0);
2062 8170028d ths
        return 2;
2063 8170028d ths
}
2064 8170028d ths
2065 8170028d ths
/* Sign extension. From size to dword.  */
2066 a699a7be Edgar E. Iglesias
static int dec_subs_r(DisasContext *dc)
2067 8170028d ths
{
2068 fb48f71b edgar_igl
        TCGv t0;
2069 8170028d ths
        int size = memsize_z(dc);
2070 d12d51d5 aliguori
        LOG_DIS("subs.%c $r%u, $r%u\n",
2071 8170028d ths
                    memsize_char(size),
2072 d12d51d5 aliguori
                    dc->op1, dc->op2);
2073 8170028d ths
2074 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
2075 a7812ae4 pbrook
        t0 = tcg_temp_new();
2076 8170028d ths
        /* Size can only be qi or hi.  */
2077 fb48f71b edgar_igl
        t_gen_sext(t0, cpu_R[dc->op1], size);
2078 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_SUB,
2079 fb48f71b edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2080 fb48f71b edgar_igl
        tcg_temp_free(t0);
2081 8170028d ths
        return 2;
2082 8170028d ths
}
2083 8170028d ths
2084 a699a7be Edgar E. Iglesias
static int dec_setclrf(DisasContext *dc)
2085 8170028d ths
{
2086 8170028d ths
        uint32_t flags;
2087 8170028d ths
        int set = (~dc->opcode >> 2) & 1;
2088 8170028d ths
2089 fb48f71b edgar_igl
2090 8170028d ths
        flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
2091 8170028d ths
                | EXTRACT_FIELD(dc->ir, 0, 3);
2092 cf1d97f0 edgar_igl
        if (set && flags == 0) {
2093 d12d51d5 aliguori
                LOG_DIS("nop\n");
2094 30abcfc7 edgar_igl
                return 2;
2095 cf1d97f0 edgar_igl
        } else if (!set && (flags & 0x20)) {
2096 d12d51d5 aliguori
                LOG_DIS("di\n");
2097 cf1d97f0 edgar_igl
        }
2098 cf1d97f0 edgar_igl
        else {
2099 d12d51d5 aliguori
                LOG_DIS("%sf %x\n",
2100 cf1d97f0 edgar_igl
                             set ? "set" : "clr",
2101 d12d51d5 aliguori
                            flags);
2102 cf1d97f0 edgar_igl
        }
2103 8170028d ths
2104 fb48f71b edgar_igl
        /* User space is not allowed to touch these. Silently ignore.  */
2105 2a44f7f1 edgar_igl
        if (dc->tb_flags & U_FLAG) {
2106 a1aebcb8 edgar_igl
                flags &= ~(S_FLAG | I_FLAG | U_FLAG);
2107 2a44f7f1 edgar_igl
        }
2108 2a44f7f1 edgar_igl
2109 2a44f7f1 edgar_igl
        if (flags & X_FLAG) {
2110 30abcfc7 edgar_igl
                dc->flagx_known = 1;
2111 2a44f7f1 edgar_igl
                if (set)
2112 2a44f7f1 edgar_igl
                        dc->flags_x = X_FLAG;
2113 2a44f7f1 edgar_igl
                else
2114 2a44f7f1 edgar_igl
                        dc->flags_x = 0;
2115 8170028d ths
        }
2116 8170028d ths
2117 40e9eddd Edgar E. Iglesias
        /* Break the TB if any of the SPI flag changes.  */
2118 40e9eddd Edgar E. Iglesias
        if (flags & (P_FLAG | S_FLAG)) {
2119 40e9eddd Edgar E. Iglesias
                tcg_gen_movi_tl(env_pc, dc->pc + 2);
2120 40e9eddd Edgar E. Iglesias
                dc->is_jmp = DISAS_UPDATE;
2121 40e9eddd Edgar E. Iglesias
                dc->cpustate_changed = 1;
2122 2a44f7f1 edgar_igl
        }
2123 40e9eddd Edgar E. Iglesias
2124 40e9eddd Edgar E. Iglesias
        /* For the I flag, only act on posedge.  */
2125 40e9eddd Edgar E. Iglesias
        if ((flags & I_FLAG)) {
2126 40e9eddd Edgar E. Iglesias
                tcg_gen_movi_tl(env_pc, dc->pc + 2);
2127 40e9eddd Edgar E. Iglesias
                dc->is_jmp = DISAS_UPDATE;
2128 a1aebcb8 edgar_igl
                dc->cpustate_changed = 1;
2129 a1aebcb8 edgar_igl
        }
2130 2a44f7f1 edgar_igl
2131 2a44f7f1 edgar_igl
2132 8170028d ths
        /* Simply decode the flags.  */
2133 8170028d ths
        cris_evaluate_flags (dc);
2134 b41f7df0 edgar_igl
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2135 30abcfc7 edgar_igl
        cris_update_cc_x(dc);
2136 b41f7df0 edgar_igl
        tcg_gen_movi_tl(cc_op, dc->cc_op);
2137 b41f7df0 edgar_igl
2138 dceaf394 edgar_igl
        if (set) {
2139 2a44f7f1 edgar_igl
                if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) {
2140 dceaf394 edgar_igl
                        /* Enter user mode.  */
2141 dceaf394 edgar_igl
                        t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
2142 dceaf394 edgar_igl
                        tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
2143 2a44f7f1 edgar_igl
                        dc->cpustate_changed = 1;
2144 dceaf394 edgar_igl
                }
2145 dceaf394 edgar_igl
                tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
2146 dceaf394 edgar_igl
        }
2147 8170028d ths
        else
2148 dceaf394 edgar_igl
                tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
2149 dceaf394 edgar_igl
2150 30abcfc7 edgar_igl
        dc->flags_uptodate = 1;
2151 b41f7df0 edgar_igl
        dc->clear_x = 0;
2152 8170028d ths
        return 2;
2153 8170028d ths
}
2154 8170028d ths
2155 a699a7be Edgar E. Iglesias
static int dec_move_rs(DisasContext *dc)
2156 8170028d ths
{
2157 d12d51d5 aliguori
        LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
2158 8170028d ths
        cris_cc_mask(dc, 0);
2159 a7812ae4 pbrook
        gen_helper_movl_sreg_reg(tcg_const_tl(dc->op2), tcg_const_tl(dc->op1));
2160 8170028d ths
        return 2;
2161 8170028d ths
}
2162 a699a7be Edgar E. Iglesias
static int dec_move_sr(DisasContext *dc)
2163 8170028d ths
{
2164 d12d51d5 aliguori
        LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
2165 8170028d ths
        cris_cc_mask(dc, 0);
2166 a7812ae4 pbrook
        gen_helper_movl_reg_sreg(tcg_const_tl(dc->op1), tcg_const_tl(dc->op2));
2167 8170028d ths
        return 2;
2168 8170028d ths
}
2169 dceaf394 edgar_igl
2170 a699a7be Edgar E. Iglesias
static int dec_move_rp(DisasContext *dc)
2171 8170028d ths
{
2172 fb48f71b edgar_igl
        TCGv t[2];
2173 d12d51d5 aliguori
        LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
2174 8170028d ths
        cris_cc_mask(dc, 0);
2175 b41f7df0 edgar_igl
2176 a7812ae4 pbrook
        t[0] = tcg_temp_new();
2177 b41f7df0 edgar_igl
        if (dc->op2 == PR_CCS) {
2178 b41f7df0 edgar_igl
                cris_evaluate_flags(dc);
2179 fb48f71b edgar_igl
                t_gen_mov_TN_reg(t[0], dc->op1);
2180 2a44f7f1 edgar_igl
                if (dc->tb_flags & U_FLAG) {
2181 a7812ae4 pbrook
                        t[1] = tcg_temp_new();
2182 b41f7df0 edgar_igl
                        /* User space is not allowed to touch all flags.  */
2183 fb48f71b edgar_igl
                        tcg_gen_andi_tl(t[0], t[0], 0x39f);
2184 fb48f71b edgar_igl
                        tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
2185 fb48f71b edgar_igl
                        tcg_gen_or_tl(t[0], t[1], t[0]);
2186 fb48f71b edgar_igl
                        tcg_temp_free(t[1]);
2187 b41f7df0 edgar_igl
                }
2188 b41f7df0 edgar_igl
        }
2189 b41f7df0 edgar_igl
        else
2190 fb48f71b edgar_igl
                t_gen_mov_TN_reg(t[0], dc->op1);
2191 b41f7df0 edgar_igl
2192 fb48f71b edgar_igl
        t_gen_mov_preg_TN(dc, dc->op2, t[0]);
2193 b41f7df0 edgar_igl
        if (dc->op2 == PR_CCS) {
2194 b41f7df0 edgar_igl
                cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2195 30abcfc7 edgar_igl
                dc->flags_uptodate = 1;
2196 b41f7df0 edgar_igl
        }
2197 fb48f71b edgar_igl
        tcg_temp_free(t[0]);
2198 8170028d ths
        return 2;
2199 8170028d ths
}
2200 a699a7be Edgar E. Iglesias
static int dec_move_pr(DisasContext *dc)
2201 8170028d ths
{
2202 fb48f71b edgar_igl
        TCGv t0;
2203 40e9eddd Edgar E. Iglesias
        LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
2204 8170028d ths
        cris_cc_mask(dc, 0);
2205 2a44f7f1 edgar_igl
2206 2a44f7f1 edgar_igl
        if (dc->op2 == PR_CCS)
2207 b41f7df0 edgar_igl
                cris_evaluate_flags(dc);
2208 2a44f7f1 edgar_igl
2209 40e9eddd Edgar E. Iglesias
        if (dc->op2 == PR_DZ) {
2210 40e9eddd Edgar E. Iglesias
                tcg_gen_movi_tl(cpu_R[dc->op1], 0);
2211 40e9eddd Edgar E. Iglesias
        } else {
2212 40e9eddd Edgar E. Iglesias
                t0 = tcg_temp_new();
2213 40e9eddd Edgar E. Iglesias
                t_gen_mov_TN_preg(t0, dc->op2);
2214 40e9eddd Edgar E. Iglesias
                cris_alu(dc, CC_OP_MOVE,
2215 40e9eddd Edgar E. Iglesias
                         cpu_R[dc->op1], cpu_R[dc->op1], t0,
2216 40e9eddd Edgar E. Iglesias
                         preg_sizes[dc->op2]);
2217 40e9eddd Edgar E. Iglesias
                tcg_temp_free(t0);
2218 40e9eddd Edgar E. Iglesias
        }
2219 8170028d ths
        return 2;
2220 8170028d ths
}
2221 8170028d ths
2222 a699a7be Edgar E. Iglesias
static int dec_move_mr(DisasContext *dc)
2223 8170028d ths
{
2224 8170028d ths
        int memsize = memsize_zz(dc);
2225 8170028d ths
        int insn_len;
2226 d12d51d5 aliguori
        LOG_DIS("move.%c [$r%u%s, $r%u\n",
2227 8170028d ths
                    memsize_char(memsize),
2228 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2229 d12d51d5 aliguori
                    dc->op2);
2230 8170028d ths
2231 30abcfc7 edgar_igl
        if (memsize == 4) {
2232 30abcfc7 edgar_igl
                insn_len = dec_prep_move_m(dc, 0, 4, cpu_R[dc->op2]);
2233 30abcfc7 edgar_igl
                cris_cc_mask(dc, CC_MASK_NZ);
2234 30abcfc7 edgar_igl
                cris_update_cc_op(dc, CC_OP_MOVE, 4);
2235 30abcfc7 edgar_igl
                cris_update_cc_x(dc);
2236 30abcfc7 edgar_igl
                cris_update_result(dc, cpu_R[dc->op2]);
2237 30abcfc7 edgar_igl
        }
2238 30abcfc7 edgar_igl
        else {
2239 fb48f71b edgar_igl
                TCGv t0;
2240 fb48f71b edgar_igl
2241 a7812ae4 pbrook
                t0 = tcg_temp_new();
2242 fb48f71b edgar_igl
                insn_len = dec_prep_move_m(dc, 0, memsize, t0);
2243 30abcfc7 edgar_igl
                cris_cc_mask(dc, CC_MASK_NZ);
2244 30abcfc7 edgar_igl
                cris_alu(dc, CC_OP_MOVE,
2245 fb48f71b edgar_igl
                            cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
2246 fb48f71b edgar_igl
                tcg_temp_free(t0);
2247 30abcfc7 edgar_igl
        }
2248 8170028d ths
        do_postinc(dc, memsize);
2249 8170028d ths
        return insn_len;
2250 8170028d ths
}
2251 8170028d ths
2252 31c18d87 edgar_igl
static inline void cris_alu_m_alloc_temps(TCGv *t)
2253 31c18d87 edgar_igl
{
2254 a7812ae4 pbrook
        t[0] = tcg_temp_new();
2255 a7812ae4 pbrook
        t[1] = tcg_temp_new();
2256 31c18d87 edgar_igl
}
2257 31c18d87 edgar_igl
2258 31c18d87 edgar_igl
static inline void cris_alu_m_free_temps(TCGv *t)
2259 31c18d87 edgar_igl
{
2260 31c18d87 edgar_igl
        tcg_temp_free(t[0]);
2261 31c18d87 edgar_igl
        tcg_temp_free(t[1]);
2262 31c18d87 edgar_igl
}
2263 31c18d87 edgar_igl
2264 a699a7be Edgar E. Iglesias
static int dec_movs_m(DisasContext *dc)
2265 8170028d ths
{
2266 31c18d87 edgar_igl
        TCGv t[2];
2267 8170028d ths
        int memsize = memsize_z(dc);
2268 8170028d ths
        int insn_len;
2269 d12d51d5 aliguori
        LOG_DIS("movs.%c [$r%u%s, $r%u\n",
2270 8170028d ths
                    memsize_char(memsize),
2271 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2272 d12d51d5 aliguori
                    dc->op2);
2273 8170028d ths
2274 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2275 8170028d ths
        /* sign extend.  */
2276 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2277 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZ);
2278 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_MOVE,
2279 31c18d87 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2280 8170028d ths
        do_postinc(dc, memsize);
2281 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2282 8170028d ths
        return insn_len;
2283 8170028d ths
}
2284 8170028d ths
2285 a699a7be Edgar E. Iglesias
static int dec_addu_m(DisasContext *dc)
2286 8170028d ths
{
2287 31c18d87 edgar_igl
        TCGv t[2];
2288 8170028d ths
        int memsize = memsize_z(dc);
2289 8170028d ths
        int insn_len;
2290 d12d51d5 aliguori
        LOG_DIS("addu.%c [$r%u%s, $r%u\n",
2291 8170028d ths
                    memsize_char(memsize),
2292 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2293 d12d51d5 aliguori
                    dc->op2);
2294 8170028d ths
2295 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2296 8170028d ths
        /* sign extend.  */
2297 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2298 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2299 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_ADD,
2300 31c18d87 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2301 8170028d ths
        do_postinc(dc, memsize);
2302 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2303 8170028d ths
        return insn_len;
2304 8170028d ths
}
2305 8170028d ths
2306 a699a7be Edgar E. Iglesias
static int dec_adds_m(DisasContext *dc)
2307 8170028d ths
{
2308 31c18d87 edgar_igl
        TCGv t[2];
2309 8170028d ths
        int memsize = memsize_z(dc);
2310 8170028d ths
        int insn_len;
2311 d12d51d5 aliguori
        LOG_DIS("adds.%c [$r%u%s, $r%u\n",
2312 8170028d ths
                    memsize_char(memsize),
2313 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2314 d12d51d5 aliguori
                    dc->op2);
2315 8170028d ths
2316 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2317 8170028d ths
        /* sign extend.  */
2318 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2319 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2320 31c18d87 edgar_igl
        cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2321 8170028d ths
        do_postinc(dc, memsize);
2322 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2323 8170028d ths
        return insn_len;
2324 8170028d ths
}
2325 8170028d ths
2326 a699a7be Edgar E. Iglesias
static int dec_subu_m(DisasContext *dc)
2327 8170028d ths
{
2328 31c18d87 edgar_igl
        TCGv t[2];
2329 8170028d ths
        int memsize = memsize_z(dc);
2330 8170028d ths
        int insn_len;
2331 d12d51d5 aliguori
        LOG_DIS("subu.%c [$r%u%s, $r%u\n",
2332 8170028d ths
                    memsize_char(memsize),
2333 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2334 d12d51d5 aliguori
                    dc->op2);
2335 8170028d ths
2336 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2337 8170028d ths
        /* sign extend.  */
2338 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2339 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2340 31c18d87 edgar_igl
        cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2341 8170028d ths
        do_postinc(dc, memsize);
2342 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2343 8170028d ths
        return insn_len;
2344 8170028d ths
}
2345 8170028d ths
2346 a699a7be Edgar E. Iglesias
static int dec_subs_m(DisasContext *dc)
2347 8170028d ths
{
2348 31c18d87 edgar_igl
        TCGv t[2];
2349 8170028d ths
        int memsize = memsize_z(dc);
2350 8170028d ths
        int insn_len;
2351 d12d51d5 aliguori
        LOG_DIS("subs.%c [$r%u%s, $r%u\n",
2352 8170028d ths
                    memsize_char(memsize),
2353 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2354 d12d51d5 aliguori
                    dc->op2);
2355 8170028d ths
2356 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2357 8170028d ths
        /* sign extend.  */
2358 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2359 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2360 31c18d87 edgar_igl
        cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2361 8170028d ths
        do_postinc(dc, memsize);
2362 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2363 8170028d ths
        return insn_len;
2364 8170028d ths
}
2365 8170028d ths
2366 a699a7be Edgar E. Iglesias
static int dec_movu_m(DisasContext *dc)
2367 8170028d ths
{
2368 31c18d87 edgar_igl
        TCGv t[2];
2369 8170028d ths
        int memsize = memsize_z(dc);
2370 8170028d ths
        int insn_len;
2371 8170028d ths
2372 d12d51d5 aliguori
        LOG_DIS("movu.%c [$r%u%s, $r%u\n",
2373 8170028d ths
                    memsize_char(memsize),
2374 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2375 d12d51d5 aliguori
                    dc->op2);
2376 8170028d ths
2377 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2378 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2379 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZ);
2380 31c18d87 edgar_igl
        cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2381 8170028d ths
        do_postinc(dc, memsize);
2382 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2383 8170028d ths
        return insn_len;
2384 8170028d ths
}
2385 8170028d ths
2386 a699a7be Edgar E. Iglesias
static int dec_cmpu_m(DisasContext *dc)
2387 8170028d ths
{
2388 31c18d87 edgar_igl
        TCGv t[2];
2389 8170028d ths
        int memsize = memsize_z(dc);
2390 8170028d ths
        int insn_len;
2391 d12d51d5 aliguori
        LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
2392 8170028d ths
                    memsize_char(memsize),
2393 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2394 d12d51d5 aliguori
                    dc->op2);
2395 8170028d ths
2396 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2397 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2398 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2399 31c18d87 edgar_igl
        cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2400 8170028d ths
        do_postinc(dc, memsize);
2401 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2402 8170028d ths
        return insn_len;
2403 8170028d ths
}
2404 8170028d ths
2405 a699a7be Edgar E. Iglesias
static int dec_cmps_m(DisasContext *dc)
2406 8170028d ths
{
2407 31c18d87 edgar_igl
        TCGv t[2];
2408 8170028d ths
        int memsize = memsize_z(dc);
2409 8170028d ths
        int insn_len;
2410 d12d51d5 aliguori
        LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
2411 8170028d ths
                    memsize_char(memsize),
2412 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2413 d12d51d5 aliguori
                    dc->op2);
2414 8170028d ths
2415 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2416 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2417 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2418 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_CMP,
2419 31c18d87 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2420 30abcfc7 edgar_igl
                    memsize_zz(dc));
2421 8170028d ths
        do_postinc(dc, memsize);
2422 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2423 8170028d ths
        return insn_len;
2424 8170028d ths
}
2425 8170028d ths
2426 a699a7be Edgar E. Iglesias
static int dec_cmp_m(DisasContext *dc)
2427 8170028d ths
{
2428 31c18d87 edgar_igl
        TCGv t[2];
2429 8170028d ths
        int memsize = memsize_zz(dc);
2430 8170028d ths
        int insn_len;
2431 d12d51d5 aliguori
        LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
2432 8170028d ths
                    memsize_char(memsize),
2433 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2434 d12d51d5 aliguori
                    dc->op2);
2435 8170028d ths
2436 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2437 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2438 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2439 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_CMP,
2440 31c18d87 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2441 30abcfc7 edgar_igl
                    memsize_zz(dc));
2442 8170028d ths
        do_postinc(dc, memsize);
2443 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2444 8170028d ths
        return insn_len;
2445 8170028d ths
}
2446 8170028d ths
2447 a699a7be Edgar E. Iglesias
static int dec_test_m(DisasContext *dc)
2448 8170028d ths
{
2449 31c18d87 edgar_igl
        TCGv t[2];
2450 8170028d ths
        int memsize = memsize_zz(dc);
2451 8170028d ths
        int insn_len;
2452 ce24e07b Edgar E. Iglesias
        LOG_DIS("test.%c [$r%u%s] op2=%x\n",
2453 8170028d ths
                    memsize_char(memsize),
2454 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2455 d12d51d5 aliguori
                    dc->op2);
2456 8170028d ths
2457 dceaf394 edgar_igl
        cris_evaluate_flags(dc);
2458 dceaf394 edgar_igl
2459 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2460 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2461 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
2462 dceaf394 edgar_igl
        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
2463 b41f7df0 edgar_igl
2464 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_CMP,
2465 31c18d87 edgar_igl
                 cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc));
2466 8170028d ths
        do_postinc(dc, memsize);
2467 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2468 8170028d ths
        return insn_len;
2469 8170028d ths
}
2470 8170028d ths
2471 a699a7be Edgar E. Iglesias
static int dec_and_m(DisasContext *dc)
2472 8170028d ths
{
2473 31c18d87 edgar_igl
        TCGv t[2];
2474 8170028d ths
        int memsize = memsize_zz(dc);
2475 8170028d ths
        int insn_len;
2476 ce24e07b Edgar E. Iglesias
        LOG_DIS("and.%c [$r%u%s, $r%u\n",
2477 8170028d ths
                    memsize_char(memsize),
2478 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2479 d12d51d5 aliguori
                    dc->op2);
2480 8170028d ths
2481 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2482 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2483 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZ);
2484 31c18d87 edgar_igl
        cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2485 8170028d ths
        do_postinc(dc, memsize);
2486 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2487 8170028d ths
        return insn_len;
2488 8170028d ths
}
2489 8170028d ths
2490 a699a7be Edgar E. Iglesias
static int dec_add_m(DisasContext *dc)
2491 8170028d ths
{
2492 31c18d87 edgar_igl
        TCGv t[2];
2493 8170028d ths
        int memsize = memsize_zz(dc);
2494 8170028d ths
        int insn_len;
2495 ce24e07b Edgar E. Iglesias
        LOG_DIS("add.%c [$r%u%s, $r%u\n",
2496 8170028d ths
                    memsize_char(memsize),
2497 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2498 d12d51d5 aliguori
                    dc->op2);
2499 8170028d ths
2500 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2501 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2502 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2503 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_ADD,
2504 31c18d87 edgar_igl
                 cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2505 8170028d ths
        do_postinc(dc, memsize);
2506 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2507 8170028d ths
        return insn_len;
2508 8170028d ths
}
2509 8170028d ths
2510 a699a7be Edgar E. Iglesias
static int dec_addo_m(DisasContext *dc)
2511 8170028d ths
{
2512 31c18d87 edgar_igl
        TCGv t[2];
2513 8170028d ths
        int memsize = memsize_zz(dc);
2514 8170028d ths
        int insn_len;
2515 ce24e07b Edgar E. Iglesias
        LOG_DIS("add.%c [$r%u%s, $r%u\n",
2516 8170028d ths
                    memsize_char(memsize),
2517 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2518 d12d51d5 aliguori
                    dc->op2);
2519 8170028d ths
2520 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2521 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2522 b41f7df0 edgar_igl
        cris_cc_mask(dc, 0);
2523 31c18d87 edgar_igl
        cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
2524 8170028d ths
        do_postinc(dc, memsize);
2525 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2526 8170028d ths
        return insn_len;
2527 8170028d ths
}
2528 8170028d ths
2529 a699a7be Edgar E. Iglesias
static int dec_bound_m(DisasContext *dc)
2530 8170028d ths
{
2531 31c18d87 edgar_igl
        TCGv l[2];
2532 8170028d ths
        int memsize = memsize_zz(dc);
2533 8170028d ths
        int insn_len;
2534 ce24e07b Edgar E. Iglesias
        LOG_DIS("bound.%c [$r%u%s, $r%u\n",
2535 8170028d ths
                    memsize_char(memsize),
2536 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2537 d12d51d5 aliguori
                    dc->op2);
2538 8170028d ths
2539 a7812ae4 pbrook
        l[0] = tcg_temp_local_new();
2540 a7812ae4 pbrook
        l[1] = tcg_temp_local_new();
2541 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 0, memsize, l[0], l[1]);
2542 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZ);
2543 31c18d87 edgar_igl
        cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
2544 8170028d ths
        do_postinc(dc, memsize);
2545 31c18d87 edgar_igl
        tcg_temp_free(l[0]);
2546 31c18d87 edgar_igl
        tcg_temp_free(l[1]);
2547 8170028d ths
        return insn_len;
2548 8170028d ths
}
2549 8170028d ths
2550 a699a7be Edgar E. Iglesias
static int dec_addc_mr(DisasContext *dc)
2551 8170028d ths
{
2552 31c18d87 edgar_igl
        TCGv t[2];
2553 8170028d ths
        int insn_len = 2;
2554 d12d51d5 aliguori
        LOG_DIS("addc [$r%u%s, $r%u\n",
2555 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2556 d12d51d5 aliguori
                    dc->op2);
2557 8170028d ths
2558 8170028d ths
        cris_evaluate_flags(dc);
2559 a8cf66bb edgar_igl
2560 a8cf66bb edgar_igl
        /* Set for this insn.  */
2561 a8cf66bb edgar_igl
        dc->flagx_known = 1;
2562 a8cf66bb edgar_igl
        dc->flags_x = X_FLAG;
2563 a8cf66bb edgar_igl
2564 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2565 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 0, 4, t[0], t[1]);
2566 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2567 31c18d87 edgar_igl
        cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
2568 8170028d ths
        do_postinc(dc, 4);
2569 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2570 8170028d ths
        return insn_len;
2571 8170028d ths
}
2572 8170028d ths
2573 a699a7be Edgar E. Iglesias
static int dec_sub_m(DisasContext *dc)
2574 8170028d ths
{
2575 31c18d87 edgar_igl
        TCGv t[2];
2576 8170028d ths
        int memsize = memsize_zz(dc);
2577 8170028d ths
        int insn_len;
2578 d12d51d5 aliguori
        LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2579 8170028d ths
                    memsize_char(memsize),
2580 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2581 d12d51d5 aliguori
                    dc->op2, dc->ir, dc->zzsize);
2582 8170028d ths
2583 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2584 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2585 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2586 31c18d87 edgar_igl
        cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
2587 8170028d ths
        do_postinc(dc, memsize);
2588 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2589 8170028d ths
        return insn_len;
2590 8170028d ths
}
2591 8170028d ths
2592 a699a7be Edgar E. Iglesias
static int dec_or_m(DisasContext *dc)
2593 8170028d ths
{
2594 31c18d87 edgar_igl
        TCGv t[2];
2595 8170028d ths
        int memsize = memsize_zz(dc);
2596 8170028d ths
        int insn_len;
2597 ce24e07b Edgar E. Iglesias
        LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
2598 8170028d ths
                    memsize_char(memsize),
2599 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2600 d12d51d5 aliguori
                    dc->op2, dc->pc);
2601 8170028d ths
2602 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2603 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2604 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZ);
2605 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_OR,
2606 31c18d87 edgar_igl
                    cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2607 8170028d ths
        do_postinc(dc, memsize);
2608 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2609 8170028d ths
        return insn_len;
2610 8170028d ths
}
2611 8170028d ths
2612 a699a7be Edgar E. Iglesias
static int dec_move_mp(DisasContext *dc)
2613 8170028d ths
{
2614 31c18d87 edgar_igl
        TCGv t[2];
2615 8170028d ths
        int memsize = memsize_zz(dc);
2616 8170028d ths
        int insn_len = 2;
2617 8170028d ths
2618 d12d51d5 aliguori
        LOG_DIS("move.%c [$r%u%s, $p%u\n",
2619 8170028d ths
                    memsize_char(memsize),
2620 8170028d ths
                    dc->op1,
2621 8170028d ths
                    dc->postinc ? "+]" : "]",
2622 d12d51d5 aliguori
                    dc->op2);
2623 8170028d ths
2624 31c18d87 edgar_igl
        cris_alu_m_alloc_temps(t);
2625 31c18d87 edgar_igl
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2626 b41f7df0 edgar_igl
        cris_cc_mask(dc, 0);
2627 b41f7df0 edgar_igl
        if (dc->op2 == PR_CCS) {
2628 b41f7df0 edgar_igl
                cris_evaluate_flags(dc);
2629 2a44f7f1 edgar_igl
                if (dc->tb_flags & U_FLAG) {
2630 b41f7df0 edgar_igl
                        /* User space is not allowed to touch all flags.  */
2631 31c18d87 edgar_igl
                        tcg_gen_andi_tl(t[1], t[1], 0x39f);
2632 31c18d87 edgar_igl
                        tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
2633 31c18d87 edgar_igl
                        tcg_gen_or_tl(t[1], t[0], t[1]);
2634 b41f7df0 edgar_igl
                }
2635 b41f7df0 edgar_igl
        }
2636 b41f7df0 edgar_igl
2637 31c18d87 edgar_igl
        t_gen_mov_preg_TN(dc, dc->op2, t[1]);
2638 8170028d ths
2639 8170028d ths
        do_postinc(dc, memsize);
2640 31c18d87 edgar_igl
        cris_alu_m_free_temps(t);
2641 8170028d ths
        return insn_len;
2642 8170028d ths
}
2643 8170028d ths
2644 a699a7be Edgar E. Iglesias
static int dec_move_pm(DisasContext *dc)
2645 8170028d ths
{
2646 31c18d87 edgar_igl
        TCGv t0;
2647 8170028d ths
        int memsize;
2648 8170028d ths
2649 8170028d ths
        memsize = preg_sizes[dc->op2];
2650 8170028d ths
2651 d12d51d5 aliguori
        LOG_DIS("move.%c $p%u, [$r%u%s\n",
2652 fd56059f balrog
                     memsize_char(memsize), 
2653 d12d51d5 aliguori
                     dc->op2, dc->op1, dc->postinc ? "+]" : "]");
2654 8170028d ths
2655 fd56059f balrog
        /* prepare store. Address in T0, value in T1.  */
2656 17ac9754 edgar_igl
        if (dc->op2 == PR_CCS)
2657 17ac9754 edgar_igl
                cris_evaluate_flags(dc);
2658 a7812ae4 pbrook
        t0 = tcg_temp_new();
2659 31c18d87 edgar_igl
        t_gen_mov_TN_preg(t0, dc->op2);
2660 30abcfc7 edgar_igl
        cris_flush_cc_state(dc);
2661 31c18d87 edgar_igl
        gen_store(dc, cpu_R[dc->op1], t0, memsize);
2662 31c18d87 edgar_igl
        tcg_temp_free(t0);
2663 17ac9754 edgar_igl
2664 b41f7df0 edgar_igl
        cris_cc_mask(dc, 0);
2665 8170028d ths
        if (dc->postinc)
2666 17ac9754 edgar_igl
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2667 8170028d ths
        return 2;
2668 8170028d ths
}
2669 8170028d ths
2670 a699a7be Edgar E. Iglesias
static int dec_movem_mr(DisasContext *dc)
2671 8170028d ths
{
2672 a7812ae4 pbrook
        TCGv_i64 tmp[16];
2673 a7812ae4 pbrook
        TCGv tmp32;
2674 31c18d87 edgar_igl
        TCGv addr;
2675 8170028d ths
        int i;
2676 28de16da edgar_igl
        int nr = dc->op2 + 1;
2677 8170028d ths
2678 d12d51d5 aliguori
        LOG_DIS("movem [$r%u%s, $r%u\n", dc->op1,
2679 d12d51d5 aliguori
                    dc->postinc ? "+]" : "]", dc->op2);
2680 8170028d ths
2681 a7812ae4 pbrook
        addr = tcg_temp_new();
2682 28de16da edgar_igl
        /* There are probably better ways of doing this.  */
2683 30abcfc7 edgar_igl
        cris_flush_cc_state(dc);
2684 28de16da edgar_igl
        for (i = 0; i < (nr >> 1); i++) {
2685 a7812ae4 pbrook
                tmp[i] = tcg_temp_new_i64();
2686 31c18d87 edgar_igl
                tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2687 a7812ae4 pbrook
                gen_load64(dc, tmp[i], addr);
2688 28de16da edgar_igl
        }
2689 28de16da edgar_igl
        if (nr & 1) {
2690 a7812ae4 pbrook
                tmp32 = tcg_temp_new_i32();
2691 31c18d87 edgar_igl
                tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2692 a7812ae4 pbrook
                gen_load(dc, tmp32, addr, 4, 0);
2693 cc53adbc edgar_igl
        } else
2694 cc53adbc edgar_igl
                TCGV_UNUSED(tmp32);
2695 31c18d87 edgar_igl
        tcg_temp_free(addr);
2696 17ac9754 edgar_igl
2697 28de16da edgar_igl
        for (i = 0; i < (nr >> 1); i++) {
2698 28de16da edgar_igl
                tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]);
2699 28de16da edgar_igl
                tcg_gen_shri_i64(tmp[i], tmp[i], 32);
2700 28de16da edgar_igl
                tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
2701 a7812ae4 pbrook
                tcg_temp_free_i64(tmp[i]);
2702 28de16da edgar_igl
        }
2703 28de16da edgar_igl
        if (nr & 1) {
2704 a7812ae4 pbrook
                tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
2705 a7812ae4 pbrook
                tcg_temp_free(tmp32);
2706 17ac9754 edgar_igl
        }
2707 17ac9754 edgar_igl
2708 05ba7d5f edgar_igl
        /* writeback the updated pointer value.  */
2709 05ba7d5f edgar_igl
        if (dc->postinc)
2710 28de16da edgar_igl
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);
2711 b41f7df0 edgar_igl
2712 b41f7df0 edgar_igl
        /* gen_load might want to evaluate the previous insns flags.  */
2713 b41f7df0 edgar_igl
        cris_cc_mask(dc, 0);
2714 8170028d ths
        return 2;
2715 8170028d ths
}
2716 8170028d ths
2717 a699a7be Edgar E. Iglesias
static int dec_movem_rm(DisasContext *dc)
2718 8170028d ths
{
2719 30abcfc7 edgar_igl
        TCGv tmp;
2720 31c18d87 edgar_igl
        TCGv addr;
2721 8170028d ths
        int i;
2722 8170028d ths
2723 d12d51d5 aliguori
        LOG_DIS("movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
2724 d12d51d5 aliguori
                     dc->postinc ? "+]" : "]");
2725 8170028d ths
2726 30abcfc7 edgar_igl
        cris_flush_cc_state(dc);
2727 30abcfc7 edgar_igl
2728 a7812ae4 pbrook
        tmp = tcg_temp_new();
2729 a7812ae4 pbrook
        addr = tcg_temp_new();
2730 30abcfc7 edgar_igl
        tcg_gen_movi_tl(tmp, 4);
2731 31c18d87 edgar_igl
        tcg_gen_mov_tl(addr, cpu_R[dc->op1]);
2732 8170028d ths
        for (i = 0; i <= dc->op2; i++) {
2733 17ac9754 edgar_igl
                /* Displace addr.  */
2734 8170028d ths
                /* Perform the store.  */
2735 31c18d87 edgar_igl
                gen_store(dc, addr, cpu_R[i], 4);
2736 31c18d87 edgar_igl
                tcg_gen_add_tl(addr, addr, tmp);
2737 8170028d ths
        }
2738 17ac9754 edgar_igl
        if (dc->postinc)
2739 31c18d87 edgar_igl
                tcg_gen_mov_tl(cpu_R[dc->op1], addr);
2740 b41f7df0 edgar_igl
        cris_cc_mask(dc, 0);
2741 30abcfc7 edgar_igl
        tcg_temp_free(tmp);
2742 31c18d87 edgar_igl
        tcg_temp_free(addr);
2743 8170028d ths
        return 2;
2744 8170028d ths
}
2745 8170028d ths
2746 a699a7be Edgar E. Iglesias
static int dec_move_rm(DisasContext *dc)
2747 8170028d ths
{
2748 8170028d ths
        int memsize;
2749 8170028d ths
2750 8170028d ths
        memsize = memsize_zz(dc);
2751 8170028d ths
2752 ce24e07b Edgar E. Iglesias
        LOG_DIS("move.%c $r%u, [$r%u]\n",
2753 ce24e07b Edgar E. Iglesias
                     memsize_char(memsize), dc->op2, dc->op1);
2754 8170028d ths
2755 8170028d ths
        /* prepare store.  */
2756 30abcfc7 edgar_igl
        cris_flush_cc_state(dc);
2757 17ac9754 edgar_igl
        gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
2758 17ac9754 edgar_igl
2759 8170028d ths
        if (dc->postinc)
2760 17ac9754 edgar_igl
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2761 b41f7df0 edgar_igl
        cris_cc_mask(dc, 0);
2762 8170028d ths
        return 2;
2763 8170028d ths
}
2764 8170028d ths
2765 a699a7be Edgar E. Iglesias
static int dec_lapcq(DisasContext *dc)
2766 8170028d ths
{
2767 d12d51d5 aliguori
        LOG_DIS("lapcq %x, $r%u\n",
2768 d12d51d5 aliguori
                    dc->pc + dc->op1*2, dc->op2);
2769 8170028d ths
        cris_cc_mask(dc, 0);
2770 30abcfc7 edgar_igl
        tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2);
2771 8170028d ths
        return 2;
2772 8170028d ths
}
2773 8170028d ths
2774 a699a7be Edgar E. Iglesias
static int dec_lapc_im(DisasContext *dc)
2775 8170028d ths
{
2776 8170028d ths
        unsigned int rd;
2777 8170028d ths
        int32_t imm;
2778 b41f7df0 edgar_igl
        int32_t pc;
2779 8170028d ths
2780 8170028d ths
        rd = dc->op2;
2781 8170028d ths
2782 8170028d ths
        cris_cc_mask(dc, 0);
2783 7de141cb Edgar E. Iglesias
        imm = cris_fetch(dc, dc->pc + 2, 4, 0);
2784 d12d51d5 aliguori
        LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
2785 b41f7df0 edgar_igl
2786 b41f7df0 edgar_igl
        pc = dc->pc;
2787 b41f7df0 edgar_igl
        pc += imm;
2788 46e246c9 Edgar E. Iglesias
        tcg_gen_movi_tl(cpu_R[rd], pc);
2789 05ba7d5f edgar_igl
        return 6;
2790 8170028d ths
}
2791 8170028d ths
2792 8170028d ths
/* Jump to special reg.  */
2793 a699a7be Edgar E. Iglesias
static int dec_jump_p(DisasContext *dc)
2794 8170028d ths
{
2795 d12d51d5 aliguori
        LOG_DIS("jump $p%u\n", dc->op2);
2796 b41f7df0 edgar_igl
2797 17ac9754 edgar_igl
        if (dc->op2 == PR_CCS)
2798 17ac9754 edgar_igl
                cris_evaluate_flags(dc);
2799 31c18d87 edgar_igl
        t_gen_mov_TN_preg(env_btarget, dc->op2);
2800 b41f7df0 edgar_igl
        /* rete will often have low bit set to indicate delayslot.  */
2801 31c18d87 edgar_igl
        tcg_gen_andi_tl(env_btarget, env_btarget, ~1);
2802 17ac9754 edgar_igl
        cris_cc_mask(dc, 0);
2803 2a44f7f1 edgar_igl
        cris_prepare_jmp(dc, JMP_INDIRECT);
2804 8170028d ths
        return 2;
2805 8170028d ths
}
2806 8170028d ths
2807 8170028d ths
/* Jump and save.  */
2808 a699a7be Edgar E. Iglesias
static int dec_jas_r(DisasContext *dc)
2809 8170028d ths
{
2810 d12d51d5 aliguori
        LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2);
2811 8170028d ths
        cris_cc_mask(dc, 0);
2812 b41f7df0 edgar_igl
        /* Store the return address in Pd.  */
2813 b41f7df0 edgar_igl
        tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2814 b41f7df0 edgar_igl
        if (dc->op2 > 15)
2815 b41f7df0 edgar_igl
                abort();
2816 30abcfc7 edgar_igl
        t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4));
2817 b41f7df0 edgar_igl
2818 2a44f7f1 edgar_igl
        cris_prepare_jmp(dc, JMP_INDIRECT);
2819 8170028d ths
        return 2;
2820 8170028d ths
}
2821 8170028d ths
2822 a699a7be Edgar E. Iglesias
static int dec_jas_im(DisasContext *dc)
2823 8170028d ths
{
2824 8170028d ths
        uint32_t imm;
2825 8170028d ths
2826 7de141cb Edgar E. Iglesias
        imm = cris_fetch(dc, dc->pc + 2, 4, 0);
2827 8170028d ths
2828 d12d51d5 aliguori
        LOG_DIS("jas 0x%x\n", imm);
2829 8170028d ths
        cris_cc_mask(dc, 0);
2830 17ac9754 edgar_igl
        /* Store the return address in Pd.  */
2831 cf1d97f0 edgar_igl
        t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2832 2a44f7f1 edgar_igl
2833 2a44f7f1 edgar_igl
        dc->jmp_pc = imm;
2834 2a44f7f1 edgar_igl
        cris_prepare_jmp(dc, JMP_DIRECT);
2835 8170028d ths
        return 6;
2836 8170028d ths
}
2837 8170028d ths
2838 a699a7be Edgar E. Iglesias
static int dec_jasc_im(DisasContext *dc)
2839 8170028d ths
{
2840 8170028d ths
        uint32_t imm;
2841 8170028d ths
2842 7de141cb Edgar E. Iglesias
        imm = cris_fetch(dc, dc->pc + 2, 4, 0);
2843 8170028d ths
2844 d12d51d5 aliguori
        LOG_DIS("jasc 0x%x\n", imm);
2845 8170028d ths
        cris_cc_mask(dc, 0);
2846 17ac9754 edgar_igl
        /* Store the return address in Pd.  */
2847 2a44f7f1 edgar_igl
        t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8 + 4));
2848 2a44f7f1 edgar_igl
2849 2a44f7f1 edgar_igl
        dc->jmp_pc = imm;
2850 2a44f7f1 edgar_igl
        cris_prepare_jmp(dc, JMP_DIRECT);
2851 8170028d ths
        return 6;
2852 8170028d ths
}
2853 8170028d ths
2854 a699a7be Edgar E. Iglesias
static int dec_jasc_r(DisasContext *dc)
2855 8170028d ths
{
2856 d12d51d5 aliguori
        LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2);
2857 8170028d ths
        cris_cc_mask(dc, 0);
2858 17ac9754 edgar_igl
        /* Store the return address in Pd.  */
2859 2a44f7f1 edgar_igl
        tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2860 2a44f7f1 edgar_igl
        t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4 + 4));
2861 2a44f7f1 edgar_igl
        cris_prepare_jmp(dc, JMP_INDIRECT);
2862 8170028d ths
        return 2;
2863 8170028d ths
}
2864 8170028d ths
2865 a699a7be Edgar E. Iglesias
static int dec_bcc_im(DisasContext *dc)
2866 8170028d ths
{
2867 8170028d ths
        int32_t offset;
2868 8170028d ths
        uint32_t cond = dc->op2;
2869 8170028d ths
2870 7de141cb Edgar E. Iglesias
        offset = cris_fetch(dc, dc->pc + 2, 2, 1);
2871 8170028d ths
2872 d12d51d5 aliguori
        LOG_DIS("b%s %d pc=%x dst=%x\n",
2873 8170028d ths
                    cc_name(cond), offset,
2874 d12d51d5 aliguori
                    dc->pc, dc->pc + offset);
2875 8170028d ths
2876 8170028d ths
        cris_cc_mask(dc, 0);
2877 8170028d ths
        /* op2 holds the condition-code.  */
2878 8170028d ths
        cris_prepare_cc_branch (dc, offset, cond);
2879 8170028d ths
        return 4;
2880 8170028d ths
}
2881 8170028d ths
2882 a699a7be Edgar E. Iglesias
static int dec_bas_im(DisasContext *dc)
2883 8170028d ths
{
2884 8170028d ths
        int32_t simm;
2885 8170028d ths
2886 8170028d ths
2887 7de141cb Edgar E. Iglesias
        simm = cris_fetch(dc, dc->pc + 2, 4, 0);
2888 8170028d ths
2889 d12d51d5 aliguori
        LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2890 8170028d ths
        cris_cc_mask(dc, 0);
2891 2a44f7f1 edgar_igl
        /* Store the return address in Pd.  */
2892 2a44f7f1 edgar_igl
        t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2893 2a44f7f1 edgar_igl
2894 2a44f7f1 edgar_igl
        dc->jmp_pc = dc->pc + simm;
2895 2a44f7f1 edgar_igl
        cris_prepare_jmp(dc, JMP_DIRECT);
2896 8170028d ths
        return 6;
2897 8170028d ths
}
2898 8170028d ths
2899 a699a7be Edgar E. Iglesias
static int dec_basc_im(DisasContext *dc)
2900 8170028d ths
{
2901 8170028d ths
        int32_t simm;
2902 7de141cb Edgar E. Iglesias
        simm = cris_fetch(dc, dc->pc + 2, 4, 0);
2903 8170028d ths
2904 d12d51d5 aliguori
        LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2905 8170028d ths
        cris_cc_mask(dc, 0);
2906 2a44f7f1 edgar_igl
        /* Store the return address in Pd.  */
2907 2a44f7f1 edgar_igl
        t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 12));
2908 2a44f7f1 edgar_igl
2909 2a44f7f1 edgar_igl
        dc->jmp_pc = dc->pc + simm;
2910 2a44f7f1 edgar_igl
        cris_prepare_jmp(dc, JMP_DIRECT);
2911 8170028d ths
        return 6;
2912 8170028d ths
}
2913 8170028d ths
2914 a699a7be Edgar E. Iglesias
static int dec_rfe_etc(DisasContext *dc)
2915 8170028d ths
{
2916 8170028d ths
        cris_cc_mask(dc, 0);
2917 8170028d ths
2918 213fb478 edgar_igl
        if (dc->op2 == 15) {
2919 213fb478 edgar_igl
                t_gen_mov_env_TN(halted, tcg_const_tl(1));
2920 213fb478 edgar_igl
                tcg_gen_movi_tl(env_pc, dc->pc + 2);
2921 213fb478 edgar_igl
                t_gen_raise_exception(EXCP_HLT);
2922 05ba7d5f edgar_igl
                return 2;
2923 213fb478 edgar_igl
        }
2924 8170028d ths
2925 8170028d ths
        switch (dc->op2 & 7) {
2926 8170028d ths
                case 2:
2927 8170028d ths
                        /* rfe.  */
2928 d12d51d5 aliguori
                        LOG_DIS("rfe\n");
2929 8170028d ths
                        cris_evaluate_flags(dc);
2930 a7812ae4 pbrook
                        gen_helper_rfe();
2931 b41f7df0 edgar_igl
                        dc->is_jmp = DISAS_UPDATE;
2932 8170028d ths
                        break;
2933 8170028d ths
                case 5:
2934 8170028d ths
                        /* rfn.  */
2935 d12d51d5 aliguori
                        LOG_DIS("rfn\n");
2936 a7cfbba0 edgar_igl
                        cris_evaluate_flags(dc);
2937 a7812ae4 pbrook
                        gen_helper_rfn();
2938 a7cfbba0 edgar_igl
                        dc->is_jmp = DISAS_UPDATE;
2939 8170028d ths
                        break;
2940 8170028d ths
                case 6:
2941 d12d51d5 aliguori
                        LOG_DIS("break %d\n", dc->op1);
2942 a1aebcb8 edgar_igl
                        cris_evaluate_flags (dc);
2943 8170028d ths
                        /* break.  */
2944 cddffe37 edgar_igl
                        tcg_gen_movi_tl(env_pc, dc->pc + 2);
2945 a1aebcb8 edgar_igl
2946 8170028d ths
                        /* Breaks start at 16 in the exception vector.  */
2947 dceaf394 edgar_igl
                        t_gen_mov_env_TN(trap_vector, 
2948 dceaf394 edgar_igl
                                         tcg_const_tl(dc->op1 + 16));
2949 dceaf394 edgar_igl
                        t_gen_raise_exception(EXCP_BREAK);
2950 b41f7df0 edgar_igl
                        dc->is_jmp = DISAS_UPDATE;
2951 8170028d ths
                        break;
2952 8170028d ths
                default:
2953 8170028d ths
                        printf ("op2=%x\n", dc->op2);
2954 8170028d ths
                        BUG();
2955 8170028d ths
                        break;
2956 8170028d ths
2957 8170028d ths
        }
2958 8170028d ths
        return 2;
2959 8170028d ths
}
2960 8170028d ths
2961 a699a7be Edgar E. Iglesias
static int dec_ftag_fidx_d_m(DisasContext *dc)
2962 5d4a534d edgar_igl
{
2963 5d4a534d edgar_igl
        return 2;
2964 5d4a534d edgar_igl
}
2965 5d4a534d edgar_igl
2966 a699a7be Edgar E. Iglesias
static int dec_ftag_fidx_i_m(DisasContext *dc)
2967 5d4a534d edgar_igl
{
2968 5d4a534d edgar_igl
        return 2;
2969 5d4a534d edgar_igl
}
2970 5d4a534d edgar_igl
2971 a699a7be Edgar E. Iglesias
static int dec_null(DisasContext *dc)
2972 8170028d ths
{
2973 8170028d ths
        printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2974 8170028d ths
                dc->pc, dc->opcode, dc->op1, dc->op2);
2975 8170028d ths
        fflush(NULL);
2976 8170028d ths
        BUG();
2977 8170028d ths
        return 2;
2978 8170028d ths
}
2979 8170028d ths
2980 9b32fbf8 edgar_igl
static struct decoder_info {
2981 8170028d ths
        struct {
2982 8170028d ths
                uint32_t bits;
2983 8170028d ths
                uint32_t mask;
2984 8170028d ths
        };
2985 a699a7be Edgar E. Iglesias
        int (*dec)(DisasContext *dc);
2986 8170028d ths
} decinfo[] = {
2987 8170028d ths
        /* Order matters here.  */
2988 8170028d ths
        {DEC_MOVEQ, dec_moveq},
2989 8170028d ths
        {DEC_BTSTQ, dec_btstq},
2990 8170028d ths
        {DEC_CMPQ, dec_cmpq},
2991 8170028d ths
        {DEC_ADDOQ, dec_addoq},
2992 8170028d ths
        {DEC_ADDQ, dec_addq},
2993 8170028d ths
        {DEC_SUBQ, dec_subq},
2994 8170028d ths
        {DEC_ANDQ, dec_andq},
2995 8170028d ths
        {DEC_ORQ, dec_orq},
2996 8170028d ths
        {DEC_ASRQ, dec_asrq},
2997 8170028d ths
        {DEC_LSLQ, dec_lslq},
2998 8170028d ths
        {DEC_LSRQ, dec_lsrq},
2999 8170028d ths
        {DEC_BCCQ, dec_bccq},
3000 8170028d ths
3001 8170028d ths
        {DEC_BCC_IM, dec_bcc_im},
3002 8170028d ths
        {DEC_JAS_IM, dec_jas_im},
3003 8170028d ths
        {DEC_JAS_R, dec_jas_r},
3004 8170028d ths
        {DEC_JASC_IM, dec_jasc_im},
3005 8170028d ths
        {DEC_JASC_R, dec_jasc_r},
3006 8170028d ths
        {DEC_BAS_IM, dec_bas_im},
3007 8170028d ths
        {DEC_BASC_IM, dec_basc_im},
3008 8170028d ths
        {DEC_JUMP_P, dec_jump_p},
3009 8170028d ths
        {DEC_LAPC_IM, dec_lapc_im},
3010 8170028d ths
        {DEC_LAPCQ, dec_lapcq},
3011 8170028d ths
3012 8170028d ths
        {DEC_RFE_ETC, dec_rfe_etc},
3013 8170028d ths
        {DEC_ADDC_MR, dec_addc_mr},
3014 8170028d ths
3015 8170028d ths
        {DEC_MOVE_MP, dec_move_mp},
3016 8170028d ths
        {DEC_MOVE_PM, dec_move_pm},
3017 8170028d ths
        {DEC_MOVEM_MR, dec_movem_mr},
3018 8170028d ths
        {DEC_MOVEM_RM, dec_movem_rm},
3019 8170028d ths
        {DEC_MOVE_PR, dec_move_pr},
3020 8170028d ths
        {DEC_SCC_R, dec_scc_r},
3021 8170028d ths
        {DEC_SETF, dec_setclrf},
3022 8170028d ths
        {DEC_CLEARF, dec_setclrf},
3023 8170028d ths
3024 8170028d ths
        {DEC_MOVE_SR, dec_move_sr},
3025 8170028d ths
        {DEC_MOVE_RP, dec_move_rp},
3026 8170028d ths
        {DEC_SWAP_R, dec_swap_r},
3027 8170028d ths
        {DEC_ABS_R, dec_abs_r},
3028 8170028d ths
        {DEC_LZ_R, dec_lz_r},
3029 8170028d ths
        {DEC_MOVE_RS, dec_move_rs},
3030 8170028d ths
        {DEC_BTST_R, dec_btst_r},
3031 8170028d ths
        {DEC_ADDC_R, dec_addc_r},
3032 8170028d ths
3033 8170028d ths
        {DEC_DSTEP_R, dec_dstep_r},
3034 8170028d ths
        {DEC_XOR_R, dec_xor_r},
3035 8170028d ths
        {DEC_MCP_R, dec_mcp_r},
3036 8170028d ths
        {DEC_CMP_R, dec_cmp_r},
3037 8170028d ths
3038 8170028d ths
        {DEC_ADDI_R, dec_addi_r},
3039 8170028d ths
        {DEC_ADDI_ACR, dec_addi_acr},
3040 8170028d ths
3041 8170028d ths
        {DEC_ADD_R, dec_add_r},
3042 8170028d ths
        {DEC_SUB_R, dec_sub_r},
3043 8170028d ths
3044 8170028d ths
        {DEC_ADDU_R, dec_addu_r},
3045 8170028d ths
        {DEC_ADDS_R, dec_adds_r},
3046 8170028d ths
        {DEC_SUBU_R, dec_subu_r},
3047 8170028d ths
        {DEC_SUBS_R, dec_subs_r},
3048 8170028d ths
        {DEC_LSL_R, dec_lsl_r},
3049 8170028d ths
3050 8170028d ths
        {DEC_AND_R, dec_and_r},
3051 8170028d ths
        {DEC_OR_R, dec_or_r},
3052 8170028d ths
        {DEC_BOUND_R, dec_bound_r},
3053 8170028d ths
        {DEC_ASR_R, dec_asr_r},
3054 8170028d ths
        {DEC_LSR_R, dec_lsr_r},
3055 8170028d ths
3056 8170028d ths
        {DEC_MOVU_R, dec_movu_r},
3057 8170028d ths
        {DEC_MOVS_R, dec_movs_r},
3058 8170028d ths
        {DEC_NEG_R, dec_neg_r},
3059 8170028d ths
        {DEC_MOVE_R, dec_move_r},
3060 8170028d ths
3061 5d4a534d edgar_igl
        {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
3062 5d4a534d edgar_igl
        {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
3063 8170028d ths
3064 8170028d ths
        {DEC_MULS_R, dec_muls_r},
3065 8170028d ths
        {DEC_MULU_R, dec_mulu_r},
3066 8170028d ths
3067 8170028d ths
        {DEC_ADDU_M, dec_addu_m},
3068 8170028d ths
        {DEC_ADDS_M, dec_adds_m},
3069 8170028d ths
        {DEC_SUBU_M, dec_subu_m},
3070 8170028d ths
        {DEC_SUBS_M, dec_subs_m},
3071 8170028d ths
3072 8170028d ths
        {DEC_CMPU_M, dec_cmpu_m},
3073 8170028d ths
        {DEC_CMPS_M, dec_cmps_m},
3074 8170028d ths
        {DEC_MOVU_M, dec_movu_m},
3075 8170028d ths
        {DEC_MOVS_M, dec_movs_m},
3076 8170028d ths
3077 8170028d ths
        {DEC_CMP_M, dec_cmp_m},
3078 8170028d ths
        {DEC_ADDO_M, dec_addo_m},
3079 8170028d ths
        {DEC_BOUND_M, dec_bound_m},
3080 8170028d ths
        {DEC_ADD_M, dec_add_m},
3081 8170028d ths
        {DEC_SUB_M, dec_sub_m},
3082 8170028d ths
        {DEC_AND_M, dec_and_m},
3083 8170028d ths
        {DEC_OR_M, dec_or_m},
3084 8170028d ths
        {DEC_MOVE_RM, dec_move_rm},
3085 8170028d ths
        {DEC_TEST_M, dec_test_m},
3086 8170028d ths
        {DEC_MOVE_MR, dec_move_mr},
3087 8170028d ths
3088 8170028d ths
        {{0, 0}, dec_null}
3089 8170028d ths
};
3090 8170028d ths
3091 40e9eddd Edgar E. Iglesias
static unsigned int crisv32_decoder(DisasContext *dc)
3092 8170028d ths
{
3093 a699a7be Edgar E. Iglesias
        int insn_len = 2;
3094 8170028d ths
        int i;
3095 8170028d ths
3096 8fec2b8c aliguori
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
3097 28de16da edgar_igl
                tcg_gen_debug_insn_start(dc->pc);
3098 28de16da edgar_igl
3099 8170028d ths
        /* Load a halfword onto the instruction register.  */
3100 7de141cb Edgar E. Iglesias
        dc->ir = cris_fetch(dc, dc->pc, 2, 0);
3101 8170028d ths
3102 8170028d ths
        /* Now decode it.  */
3103 8170028d ths
        dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
3104 8170028d ths
        dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
3105 8170028d ths
        dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
3106 8170028d ths
        dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
3107 8170028d ths
        dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
3108 8170028d ths
        dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
3109 8170028d ths
3110 8170028d ths
        /* Large switch for all insns.  */
3111 b1503cda malc
        for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
3112 8170028d ths
                if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
3113 8170028d ths
                {
3114 8170028d ths
                        insn_len = decinfo[i].dec(dc);
3115 8170028d ths
                        break;
3116 8170028d ths
                }
3117 8170028d ths
        }
3118 8170028d ths
3119 dd20fcd0 edgar_igl
#if !defined(CONFIG_USER_ONLY)
3120 a1aebcb8 edgar_igl
        /* Single-stepping ?  */
3121 a1aebcb8 edgar_igl
        if (dc->tb_flags & S_FLAG) {
3122 a1aebcb8 edgar_igl
                int l1;
3123 a1aebcb8 edgar_igl
3124 a1aebcb8 edgar_igl
                l1 = gen_new_label();
3125 dd20fcd0 edgar_igl
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_PR[PR_SPC], dc->pc, l1);
3126 a1aebcb8 edgar_igl
                /* We treat SPC as a break with an odd trap vector.  */
3127 a1aebcb8 edgar_igl
                cris_evaluate_flags (dc);
3128 a1aebcb8 edgar_igl
                t_gen_mov_env_TN(trap_vector, tcg_const_tl(3));
3129 a1aebcb8 edgar_igl
                tcg_gen_movi_tl(env_pc, dc->pc + insn_len);
3130 cddffe37 edgar_igl
                tcg_gen_movi_tl(cpu_PR[PR_SPC], dc->pc + insn_len);
3131 a1aebcb8 edgar_igl
                t_gen_raise_exception(EXCP_BREAK);
3132 a1aebcb8 edgar_igl
                gen_set_label(l1);
3133 a1aebcb8 edgar_igl
        }
3134 a1aebcb8 edgar_igl
#endif
3135 8170028d ths
        return insn_len;
3136 8170028d ths
}
3137 8170028d ths
3138 8170028d ths
static void check_breakpoint(CPUState *env, DisasContext *dc)
3139 8170028d ths
{
3140 a1d1bb31 aliguori
        CPUBreakpoint *bp;
3141 a1d1bb31 aliguori
3142 72cf2d4f Blue Swirl
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
3143 72cf2d4f Blue Swirl
                QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
3144 a1d1bb31 aliguori
                        if (bp->pc == dc->pc) {
3145 8170028d ths
                                cris_evaluate_flags (dc);
3146 2a44f7f1 edgar_igl
                                tcg_gen_movi_tl(env_pc, dc->pc);
3147 dceaf394 edgar_igl
                                t_gen_raise_exception(EXCP_DEBUG);
3148 8170028d ths
                                dc->is_jmp = DISAS_UPDATE;
3149 8170028d ths
                        }
3150 8170028d ths
                }
3151 8170028d ths
        }
3152 8170028d ths
}
3153 8170028d ths
3154 40e9eddd Edgar E. Iglesias
#include "translate_v10.c"
3155 cf1d97f0 edgar_igl
3156 cf1d97f0 edgar_igl
/*
3157 cf1d97f0 edgar_igl
 * Delay slots on QEMU/CRIS.
3158 cf1d97f0 edgar_igl
 *
3159 cf1d97f0 edgar_igl
 * If an exception hits on a delayslot, the core will let ERP (the Exception
3160 cf1d97f0 edgar_igl
 * Return Pointer) point to the branch (the previous) insn and set the lsb to
3161 cf1d97f0 edgar_igl
 * to give SW a hint that the exception actually hit on the dslot.
3162 cf1d97f0 edgar_igl
 *
3163 cf1d97f0 edgar_igl
 * CRIS expects all PC addresses to be 16-bit aligned. The lsb is ignored by
3164 cf1d97f0 edgar_igl
 * the core and any jmp to an odd addresses will mask off that lsb. It is 
3165 cf1d97f0 edgar_igl
 * simply there to let sw know there was an exception on a dslot.
3166 cf1d97f0 edgar_igl
 *
3167 cf1d97f0 edgar_igl
 * When the software returns from an exception, the branch will re-execute.
3168 cf1d97f0 edgar_igl
 * On QEMU care needs to be taken when a branch+delayslot sequence is broken
3169 cf1d97f0 edgar_igl
 * and the branch and delayslot dont share pages.
3170 cf1d97f0 edgar_igl
 *
3171 cf1d97f0 edgar_igl
 * The TB contaning the branch insn will set up env->btarget and evaluate 
3172 cf1d97f0 edgar_igl
 * env->btaken. When the translation loop exits we will note that the branch 
3173 cf1d97f0 edgar_igl
 * sequence is broken and let env->dslot be the size of the branch insn (those
3174 cf1d97f0 edgar_igl
 * vary in length).
3175 cf1d97f0 edgar_igl
 *
3176 cf1d97f0 edgar_igl
 * The TB contaning the delayslot will have the PC of its real insn (i.e no lsb
3177 cf1d97f0 edgar_igl
 * set). It will also expect to have env->dslot setup with the size of the 
3178 cf1d97f0 edgar_igl
 * delay slot so that env->pc - env->dslot point to the branch insn. This TB 
3179 cf1d97f0 edgar_igl
 * will execute the dslot and take the branch, either to btarget or just one 
3180 cf1d97f0 edgar_igl
 * insn ahead.
3181 cf1d97f0 edgar_igl
 *
3182 cf1d97f0 edgar_igl
 * When exceptions occur, we check for env->dslot in do_interrupt to detect 
3183 cf1d97f0 edgar_igl
 * broken branch sequences and setup $erp accordingly (i.e let it point to the
3184 cf1d97f0 edgar_igl
 * branch and set lsb). Then env->dslot gets cleared so that the exception 
3185 cf1d97f0 edgar_igl
 * handler can enter. When returning from exceptions (jump $erp) the lsb gets
3186 cf1d97f0 edgar_igl
 * masked off and we will reexecute the branch insn.
3187 cf1d97f0 edgar_igl
 *
3188 cf1d97f0 edgar_igl
 */
3189 cf1d97f0 edgar_igl
3190 8170028d ths
/* generate intermediate code for basic block 'tb'.  */
3191 2cfc5f17 ths
static void
3192 8170028d ths
gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
3193 8170028d ths
                               int search_pc)
3194 8170028d ths
{
3195 8170028d ths
        uint16_t *gen_opc_end;
3196 8170028d ths
           uint32_t pc_start;
3197 40e9eddd Edgar E. Iglesias
        unsigned int insn_len, orig_flags;
3198 8170028d ths
        int j, lj;
3199 cf1d97f0 edgar_igl
        struct DisasContext ctx;
3200 8170028d ths
        struct DisasContext *dc = &ctx;
3201 8170028d ths
        uint32_t next_page_start;
3202 2a44f7f1 edgar_igl
        target_ulong npc;
3203 2e70f6ef pbrook
        int num_insns;
3204 2e70f6ef pbrook
        int max_insns;
3205 8170028d ths
3206 93fcfe39 aliguori
        qemu_log_try_set_file(stderr);
3207 a825e703 edgar_igl
3208 40e9eddd Edgar E. Iglesias
        if (env->pregs[PR_VR] == 32)
3209 40e9eddd Edgar E. Iglesias
                dc->decoder = crisv32_decoder;
3210 40e9eddd Edgar E. Iglesias
        else
3211 40e9eddd Edgar E. Iglesias
                dc->decoder = crisv10_decoder;
3212 40e9eddd Edgar E. Iglesias
3213 73e51723 edgar_igl
        /* Odd PC indicates that branch is rexecuting due to exception in the
3214 73e51723 edgar_igl
         * delayslot, like in real hw.
3215 73e51723 edgar_igl
         */
3216 73e51723 edgar_igl
        pc_start = tb->pc & ~1;
3217 8170028d ths
        dc->env = env;
3218 8170028d ths
        dc->tb = tb;
3219 8170028d ths
3220 8170028d ths
        gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3221 8170028d ths
3222 8170028d ths
        dc->is_jmp = DISAS_NEXT;
3223 b41f7df0 edgar_igl
        dc->ppc = pc_start;
3224 8170028d ths
        dc->pc = pc_start;
3225 8170028d ths
        dc->singlestep_enabled = env->singlestep_enabled;
3226 30abcfc7 edgar_igl
        dc->flags_uptodate = 1;
3227 30abcfc7 edgar_igl
        dc->flagx_known = 1;
3228 30abcfc7 edgar_igl
        dc->flags_x = tb->flags & X_FLAG;
3229 30abcfc7 edgar_igl
        dc->cc_x_uptodate = 0;
3230 b41f7df0 edgar_igl
        dc->cc_mask = 0;
3231 cf1d97f0 edgar_igl
        dc->update_cc = 0;
3232 40e9eddd Edgar E. Iglesias
        dc->clear_prefix = 0;
3233 40e9eddd Edgar E. Iglesias
        dc->clear_locked_irq = 1;
3234 30abcfc7 edgar_igl
3235 b41f7df0 edgar_igl
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
3236 30abcfc7 edgar_igl
        dc->cc_size_uptodate = -1;
3237 b41f7df0 edgar_igl
3238 cf1d97f0 edgar_igl
        /* Decode TB flags.  */
3239 40e9eddd Edgar E. Iglesias
        orig_flags = dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
3240 40e9eddd Edgar E. Iglesias
                                        | X_FLAG | PFIX_FLAG);
3241 cf1d97f0 edgar_igl
        dc->delayed_branch = !!(tb->flags & 7);
3242 2a44f7f1 edgar_igl
        if (dc->delayed_branch)
3243 2a44f7f1 edgar_igl
                dc->jmp = JMP_INDIRECT;
3244 2a44f7f1 edgar_igl
        else
3245 2a44f7f1 edgar_igl
                dc->jmp = JMP_NOJMP;
3246 2a44f7f1 edgar_igl
3247 2a44f7f1 edgar_igl
        dc->cpustate_changed = 0;
3248 b41f7df0 edgar_igl
3249 8fec2b8c aliguori
        if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3250 93fcfe39 aliguori
                qemu_log(
3251 0bfcd599 Blue Swirl
                        "srch=%d pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n"
3252 30abcfc7 edgar_igl
                        "pid=%x usp=%x\n"
3253 b41f7df0 edgar_igl
                        "%x.%x.%x.%x\n"
3254 b41f7df0 edgar_igl
                        "%x.%x.%x.%x\n"
3255 b41f7df0 edgar_igl
                        "%x.%x.%x.%x\n"
3256 b41f7df0 edgar_igl
                        "%x.%x.%x.%x\n",
3257 d297f464 edgar_igl
                        search_pc, dc->pc, dc->ppc,
3258 0bfcd599 Blue Swirl
                        (uint64_t)tb->flags,
3259 d297f464 edgar_igl
                        env->btarget, (unsigned)tb->flags & 7,
3260 cf1d97f0 edgar_igl
                        env->pregs[PR_CCS], 
3261 b41f7df0 edgar_igl
                        env->pregs[PR_PID], env->pregs[PR_USP],
3262 b41f7df0 edgar_igl
                        env->regs[0], env->regs[1], env->regs[2], env->regs[3],
3263 b41f7df0 edgar_igl
                        env->regs[4], env->regs[5], env->regs[6], env->regs[7],
3264 b41f7df0 edgar_igl
                        env->regs[8], env->regs[9],
3265 b41f7df0 edgar_igl
                        env->regs[10], env->regs[11],
3266 b41f7df0 edgar_igl
                        env->regs[12], env->regs[13],
3267 b41f7df0 edgar_igl
                        env->regs[14], env->regs[15]);
3268 93fcfe39 aliguori
                qemu_log("--------------\n");
3269 93fcfe39 aliguori
                qemu_log("IN: %s\n", lookup_symbol(pc_start));
3270 b41f7df0 edgar_igl
        }
3271 3157a0a9 edgar_igl
3272 8170028d ths
        next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
3273 8170028d ths
        lj = -1;
3274 2e70f6ef pbrook
        num_insns = 0;
3275 2e70f6ef pbrook
        max_insns = tb->cflags & CF_COUNT_MASK;
3276 2e70f6ef pbrook
        if (max_insns == 0)
3277 2e70f6ef pbrook
            max_insns = CF_COUNT_MASK;
3278 2e70f6ef pbrook
3279 2e70f6ef pbrook
        gen_icount_start();
3280 8170028d ths
        do
3281 8170028d ths
        {
3282 8170028d ths
                check_breakpoint(env, dc);
3283 8170028d ths
3284 8170028d ths
                if (search_pc) {
3285 8170028d ths
                        j = gen_opc_ptr - gen_opc_buf;
3286 8170028d ths
                        if (lj < j) {
3287 8170028d ths
                                lj++;
3288 8170028d ths
                                while (lj < j)
3289 8170028d ths
                                        gen_opc_instr_start[lj++] = 0;
3290 8170028d ths
                        }
3291 cf1d97f0 edgar_igl
                        if (dc->delayed_branch == 1)
3292 b41f7df0 edgar_igl
                                gen_opc_pc[lj] = dc->ppc | 1;
3293 cf1d97f0 edgar_igl
                        else
3294 b41f7df0 edgar_igl
                                gen_opc_pc[lj] = dc->pc;
3295 cf1d97f0 edgar_igl
                        gen_opc_instr_start[lj] = 1;
3296 2e70f6ef pbrook
                        gen_opc_icount[lj] = num_insns;
3297 cf1d97f0 edgar_igl
                }
3298 cf1d97f0 edgar_igl
3299 cf1d97f0 edgar_igl
                /* Pretty disas.  */
3300 d12d51d5 aliguori
                LOG_DIS("%8.8x:\t", dc->pc);
3301 8170028d ths
3302 2e70f6ef pbrook
                if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
3303 2e70f6ef pbrook
                    gen_io_start();
3304 b41f7df0 edgar_igl
                dc->clear_x = 1;
3305 28de16da edgar_igl
3306 40e9eddd Edgar E. Iglesias
                insn_len = dc->decoder(dc);
3307 b41f7df0 edgar_igl
                dc->ppc = dc->pc;
3308 8170028d ths
                dc->pc += insn_len;
3309 b41f7df0 edgar_igl
                if (dc->clear_x)
3310 b41f7df0 edgar_igl
                        cris_clear_x_flag(dc);
3311 8170028d ths
3312 2e70f6ef pbrook
                num_insns++;
3313 8170028d ths
                /* Check for delayed branches here. If we do it before
3314 bf20dc07 ths
                   actually generating any host code, the simulator will just
3315 8170028d ths
                   loop doing nothing for on this program location.  */
3316 8170028d ths
                if (dc->delayed_branch) {
3317 8170028d ths
                        dc->delayed_branch--;
3318 8170028d ths
                        if (dc->delayed_branch == 0)
3319 8170028d ths
                        {
3320 2a44f7f1 edgar_igl
                                if (tb->flags & 7)
3321 2a44f7f1 edgar_igl
                                        t_gen_mov_env_TN(dslot, 
3322 2a44f7f1 edgar_igl
                                                tcg_const_tl(0));
3323 2a44f7f1 edgar_igl
                                if (dc->jmp == JMP_DIRECT) {
3324 2a44f7f1 edgar_igl
                                        dc->is_jmp = DISAS_NEXT;
3325 2a44f7f1 edgar_igl
                                } else {
3326 2a44f7f1 edgar_igl
                                        t_gen_cc_jmp(env_btarget, 
3327 2a44f7f1 edgar_igl
                                                     tcg_const_tl(dc->pc));
3328 2a44f7f1 edgar_igl
                                        dc->is_jmp = DISAS_JUMP;
3329 2a44f7f1 edgar_igl
                                }
3330 2a44f7f1 edgar_igl
                                break;
3331 8170028d ths
                        }
3332 8170028d ths
                }
3333 8170028d ths
3334 73e51723 edgar_igl
                /* If we are rexecuting a branch due to exceptions on
3335 73e51723 edgar_igl
                   delay slots dont break.  */
3336 73e51723 edgar_igl
                if (!(tb->pc & 1) && env->singlestep_enabled)
3337 8170028d ths
                        break;
3338 fb48f71b edgar_igl
        } while (!dc->is_jmp && !dc->cpustate_changed
3339 fb48f71b edgar_igl
                 && gen_opc_ptr < gen_opc_end
3340 1b530a6d aurel32
                 && !singlestep
3341 2e70f6ef pbrook
                 && (dc->pc < next_page_start)
3342 2e70f6ef pbrook
                 && num_insns < max_insns);
3343 b41f7df0 edgar_igl
3344 40e9eddd Edgar E. Iglesias
        if (dc->tb_flags != orig_flags) {
3345 40e9eddd Edgar E. Iglesias
                dc->cpustate_changed = 1;
3346 40e9eddd Edgar E. Iglesias
        }
3347 40e9eddd Edgar E. Iglesias
3348 40e9eddd Edgar E. Iglesias
        if (dc->clear_locked_irq)
3349 40e9eddd Edgar E. Iglesias
                t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
3350 40e9eddd Edgar E. Iglesias
3351 2a44f7f1 edgar_igl
        npc = dc->pc;
3352 2a44f7f1 edgar_igl
        if (dc->jmp == JMP_DIRECT && !dc->delayed_branch)
3353 2a44f7f1 edgar_igl
                npc = dc->jmp_pc;
3354 2a44f7f1 edgar_igl
3355 2e70f6ef pbrook
        if (tb->cflags & CF_LAST_IO)
3356 2e70f6ef pbrook
            gen_io_end();
3357 2a44f7f1 edgar_igl
        /* Force an update if the per-tb cpu state has changed.  */
3358 2a44f7f1 edgar_igl
        if (dc->is_jmp == DISAS_NEXT
3359 2a44f7f1 edgar_igl
            && (dc->cpustate_changed || !dc->flagx_known 
3360 2a44f7f1 edgar_igl
            || (dc->flags_x != (tb->flags & X_FLAG)))) {
3361 2a44f7f1 edgar_igl
                dc->is_jmp = DISAS_UPDATE;
3362 2a44f7f1 edgar_igl
                tcg_gen_movi_tl(env_pc, npc);
3363 2a44f7f1 edgar_igl
        }
3364 cf1d97f0 edgar_igl
        /* Broken branch+delayslot sequence.  */
3365 b41f7df0 edgar_igl
        if (dc->delayed_branch == 1) {
3366 cf1d97f0 edgar_igl
                /* Set env->dslot to the size of the branch insn.  */
3367 cf1d97f0 edgar_igl
                t_gen_mov_env_TN(dslot, tcg_const_tl(dc->pc - dc->ppc));
3368 2a44f7f1 edgar_igl
                cris_store_direct_jmp(dc);
3369 8170028d ths
        }
3370 8170028d ths
3371 8170028d ths
        cris_evaluate_flags (dc);
3372 2a44f7f1 edgar_igl
3373 551bd27f ths
        if (unlikely(env->singlestep_enabled)) {
3374 89cc7382 edgar_igl
                if (dc->is_jmp == DISAS_NEXT)
3375 89cc7382 edgar_igl
                        tcg_gen_movi_tl(env_pc, npc);
3376 dceaf394 edgar_igl
                t_gen_raise_exception(EXCP_DEBUG);
3377 8170028d ths
        } else {
3378 8170028d ths
                switch(dc->is_jmp) {
3379 8170028d ths
                        case DISAS_NEXT:
3380 2a44f7f1 edgar_igl
                                gen_goto_tb(dc, 1, npc);
3381 8170028d ths
                                break;
3382 8170028d ths
                        default:
3383 8170028d ths
                        case DISAS_JUMP:
3384 8170028d ths
                        case DISAS_UPDATE:
3385 8170028d ths
                                /* indicate that the hash table must be used
3386 8170028d ths
                                   to find the next TB */
3387 57fec1fe bellard
                                tcg_gen_exit_tb(0);
3388 8170028d ths
                                break;
3389 4f400ab5 edgar_igl
                        case DISAS_SWI:
3390 8170028d ths
                        case DISAS_TB_JUMP:
3391 8170028d ths
                                /* nothing more to generate */
3392 8170028d ths
                                break;
3393 8170028d ths
                }
3394 8170028d ths
        }
3395 2e70f6ef pbrook
        gen_icount_end(tb, num_insns);
3396 8170028d ths
        *gen_opc_ptr = INDEX_op_end;
3397 8170028d ths
        if (search_pc) {
3398 8170028d ths
                j = gen_opc_ptr - gen_opc_buf;
3399 8170028d ths
                lj++;
3400 8170028d ths
                while (lj <= j)
3401 8170028d ths
                        gen_opc_instr_start[lj++] = 0;
3402 8170028d ths
        } else {
3403 8170028d ths
                tb->size = dc->pc - pc_start;
3404 2e70f6ef pbrook
                tb->icount = num_insns;
3405 8170028d ths
        }
3406 8170028d ths
3407 8170028d ths
#ifdef DEBUG_DISAS
3408 a1aebcb8 edgar_igl
#if !DISAS_CRIS
3409 8fec2b8c aliguori
        if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3410 40e9eddd Edgar E. Iglesias
                log_target_disas(pc_start, dc->pc - pc_start,
3411 40e9eddd Edgar E. Iglesias
                                 dc->env->pregs[PR_VR]);
3412 211ecdc0 Stefan Weil
                qemu_log("\nisize=%d osize=%td\n",
3413 b41f7df0 edgar_igl
                        dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
3414 8170028d ths
        }
3415 8170028d ths
#endif
3416 a1aebcb8 edgar_igl
#endif
3417 8170028d ths
}
3418 8170028d ths
3419 2cfc5f17 ths
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
3420 8170028d ths
{
3421 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 0);
3422 8170028d ths
}
3423 8170028d ths
3424 2cfc5f17 ths
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
3425 8170028d ths
{
3426 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 1);
3427 8170028d ths
}
3428 8170028d ths
3429 8170028d ths
void cpu_dump_state (CPUState *env, FILE *f,
3430 8170028d ths
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
3431 8170028d ths
                     int flags)
3432 8170028d ths
{
3433 8170028d ths
        int i;
3434 8170028d ths
        uint32_t srs;
3435 8170028d ths
3436 8170028d ths
        if (!env || !f)
3437 8170028d ths
                return;
3438 8170028d ths
3439 8170028d ths
        cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
3440 30abcfc7 edgar_igl
                    "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
3441 9004627f edgar_igl
                    env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
3442 8170028d ths
                    env->cc_op,
3443 30abcfc7 edgar_igl
                    env->cc_src, env->cc_dest, env->cc_result, env->cc_mask);
3444 30abcfc7 edgar_igl
3445 8170028d ths
3446 8170028d ths
        for (i = 0; i < 16; i++) {
3447 416c6060 Edgar E. Iglesias
                cpu_fprintf(f, "%s=%8.8x ",regnames[i], env->regs[i]);
3448 8170028d ths
                if ((i + 1) % 4 == 0)
3449 8170028d ths
                        cpu_fprintf(f, "\n");
3450 8170028d ths
        }
3451 8170028d ths
        cpu_fprintf(f, "\nspecial regs:\n");
3452 8170028d ths
        for (i = 0; i < 16; i++) {
3453 416c6060 Edgar E. Iglesias
                cpu_fprintf(f, "%s=%8.8x ", pregnames[i], env->pregs[i]);
3454 8170028d ths
                if ((i + 1) % 4 == 0)
3455 8170028d ths
                        cpu_fprintf(f, "\n");
3456 8170028d ths
        }
3457 9004627f edgar_igl
        srs = env->pregs[PR_SRS];
3458 b41f7df0 edgar_igl
        cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
3459 8170028d ths
        if (srs < 256) {
3460 8170028d ths
                for (i = 0; i < 16; i++) {
3461 8170028d ths
                        cpu_fprintf(f, "s%2.2d=%8.8x ",
3462 8170028d ths
                                    i, env->sregs[srs][i]);
3463 8170028d ths
                        if ((i + 1) % 4 == 0)
3464 8170028d ths
                                cpu_fprintf(f, "\n");
3465 8170028d ths
                }
3466 8170028d ths
        }
3467 8170028d ths
        cpu_fprintf(f, "\n\n");
3468 8170028d ths
3469 8170028d ths
}
3470 8170028d ths
3471 40e9eddd Edgar E. Iglesias
struct
3472 40e9eddd Edgar E. Iglesias
{
3473 40e9eddd Edgar E. Iglesias
    uint32_t vr;
3474 40e9eddd Edgar E. Iglesias
    const char *name;
3475 40e9eddd Edgar E. Iglesias
} cris_cores[] = {
3476 40e9eddd Edgar E. Iglesias
        {8, "crisv8"},
3477 40e9eddd Edgar E. Iglesias
        {9, "crisv9"},
3478 40e9eddd Edgar E. Iglesias
        {10, "crisv10"},
3479 40e9eddd Edgar E. Iglesias
        {11, "crisv11"},
3480 40e9eddd Edgar E. Iglesias
        {32, "crisv32"},
3481 40e9eddd Edgar E. Iglesias
};
3482 40e9eddd Edgar E. Iglesias
3483 40e9eddd Edgar E. Iglesias
void cris_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
3484 40e9eddd Edgar E. Iglesias
{
3485 40e9eddd Edgar E. Iglesias
    unsigned int i;
3486 40e9eddd Edgar E. Iglesias
3487 40e9eddd Edgar E. Iglesias
    (*cpu_fprintf)(f, "Available CPUs:\n");
3488 40e9eddd Edgar E. Iglesias
    for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
3489 40e9eddd Edgar E. Iglesias
        (*cpu_fprintf)(f, "  %s\n", cris_cores[i].name);
3490 40e9eddd Edgar E. Iglesias
    }
3491 40e9eddd Edgar E. Iglesias
}
3492 40e9eddd Edgar E. Iglesias
3493 40e9eddd Edgar E. Iglesias
static uint32_t vr_by_name(const char *name)
3494 40e9eddd Edgar E. Iglesias
{
3495 40e9eddd Edgar E. Iglesias
    unsigned int i;
3496 40e9eddd Edgar E. Iglesias
    for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
3497 40e9eddd Edgar E. Iglesias
        if (strcmp(name, cris_cores[i].name) == 0) {
3498 40e9eddd Edgar E. Iglesias
            return cris_cores[i].vr;
3499 40e9eddd Edgar E. Iglesias
        }
3500 40e9eddd Edgar E. Iglesias
    }
3501 40e9eddd Edgar E. Iglesias
    return 32;
3502 40e9eddd Edgar E. Iglesias
}
3503 40e9eddd Edgar E. Iglesias
3504 aaed909a bellard
CPUCRISState *cpu_cris_init (const char *cpu_model)
3505 8170028d ths
{
3506 8170028d ths
        CPUCRISState *env;
3507 a7cfbba0 edgar_igl
        static int tcg_initialized = 0;
3508 a825e703 edgar_igl
        int i;
3509 8170028d ths
3510 8170028d ths
        env = qemu_mallocz(sizeof(CPUCRISState));
3511 a7cfbba0 edgar_igl
3512 40e9eddd Edgar E. Iglesias
        env->pregs[PR_VR] = vr_by_name(cpu_model);
3513 8170028d ths
        cpu_exec_init(env);
3514 a7cfbba0 edgar_igl
        cpu_reset(env);
3515 0bf46a40 aliguori
        qemu_init_vcpu(env);
3516 a7cfbba0 edgar_igl
3517 a7cfbba0 edgar_igl
        if (tcg_initialized)
3518 a7cfbba0 edgar_igl
                return env;
3519 a7cfbba0 edgar_igl
3520 a7cfbba0 edgar_igl
        tcg_initialized = 1;
3521 05ba7d5f edgar_igl
3522 40e9eddd Edgar E. Iglesias
#define GEN_HELPER 2
3523 40e9eddd Edgar E. Iglesias
#include "helper.h"
3524 40e9eddd Edgar E. Iglesias
3525 40e9eddd Edgar E. Iglesias
        if (env->pregs[PR_VR] < 32) {
3526 40e9eddd Edgar E. Iglesias
                cpu_crisv10_init(env);
3527 40e9eddd Edgar E. Iglesias
                return env; 
3528 40e9eddd Edgar E. Iglesias
        }
3529 40e9eddd Edgar E. Iglesias
3530 40e9eddd Edgar E. Iglesias
3531 a7812ae4 pbrook
        cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
3532 a7812ae4 pbrook
        cc_x = tcg_global_mem_new(TCG_AREG0,
3533 30abcfc7 edgar_igl
                                  offsetof(CPUState, cc_x), "cc_x");
3534 a7812ae4 pbrook
        cc_src = tcg_global_mem_new(TCG_AREG0,
3535 a825e703 edgar_igl
                                    offsetof(CPUState, cc_src), "cc_src");
3536 a7812ae4 pbrook
        cc_dest = tcg_global_mem_new(TCG_AREG0,
3537 30abcfc7 edgar_igl
                                     offsetof(CPUState, cc_dest),
3538 a825e703 edgar_igl
                                     "cc_dest");
3539 a7812ae4 pbrook
        cc_result = tcg_global_mem_new(TCG_AREG0,
3540 30abcfc7 edgar_igl
                                       offsetof(CPUState, cc_result),
3541 a825e703 edgar_igl
                                       "cc_result");
3542 a7812ae4 pbrook
        cc_op = tcg_global_mem_new(TCG_AREG0,
3543 a825e703 edgar_igl
                                   offsetof(CPUState, cc_op), "cc_op");
3544 a7812ae4 pbrook
        cc_size = tcg_global_mem_new(TCG_AREG0,
3545 30abcfc7 edgar_igl
                                     offsetof(CPUState, cc_size),
3546 a825e703 edgar_igl
                                     "cc_size");
3547 a7812ae4 pbrook
        cc_mask = tcg_global_mem_new(TCG_AREG0,
3548 a825e703 edgar_igl
                                     offsetof(CPUState, cc_mask),
3549 a825e703 edgar_igl
                                     "cc_mask");
3550 a825e703 edgar_igl
3551 a7812ae4 pbrook
        env_pc = tcg_global_mem_new(TCG_AREG0, 
3552 30abcfc7 edgar_igl
                                    offsetof(CPUState, pc),
3553 30abcfc7 edgar_igl
                                    "pc");
3554 a7812ae4 pbrook
        env_btarget = tcg_global_mem_new(TCG_AREG0,
3555 30abcfc7 edgar_igl
                                         offsetof(CPUState, btarget),
3556 30abcfc7 edgar_igl
                                         "btarget");
3557 a7812ae4 pbrook
        env_btaken = tcg_global_mem_new(TCG_AREG0,
3558 2a44f7f1 edgar_igl
                                         offsetof(CPUState, btaken),
3559 2a44f7f1 edgar_igl
                                         "btaken");
3560 a825e703 edgar_igl
        for (i = 0; i < 16; i++) {
3561 a7812ae4 pbrook
                cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
3562 30abcfc7 edgar_igl
                                              offsetof(CPUState, regs[i]),
3563 a825e703 edgar_igl
                                              regnames[i]);
3564 a825e703 edgar_igl
        }
3565 a825e703 edgar_igl
        for (i = 0; i < 16; i++) {
3566 a7812ae4 pbrook
                cpu_PR[i] = tcg_global_mem_new(TCG_AREG0,
3567 30abcfc7 edgar_igl
                                               offsetof(CPUState, pregs[i]),
3568 a825e703 edgar_igl
                                               pregnames[i]);
3569 a825e703 edgar_igl
        }
3570 a825e703 edgar_igl
3571 8170028d ths
        return env;
3572 8170028d ths
}
3573 8170028d ths
3574 8170028d ths
void cpu_reset (CPUCRISState *env)
3575 8170028d ths
{
3576 40e9eddd Edgar E. Iglesias
        uint32_t vr;
3577 40e9eddd Edgar E. Iglesias
3578 eca1bdf4 aliguori
        if (qemu_loglevel_mask(CPU_LOG_RESET)) {
3579 eca1bdf4 aliguori
                qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
3580 eca1bdf4 aliguori
                log_cpu_state(env, 0);
3581 eca1bdf4 aliguori
        }
3582 eca1bdf4 aliguori
3583 40e9eddd Edgar E. Iglesias
        vr = env->pregs[PR_VR];
3584 8170028d ths
        memset(env, 0, offsetof(CPUCRISState, breakpoints));
3585 40e9eddd Edgar E. Iglesias
        env->pregs[PR_VR] = vr;
3586 8170028d ths
        tlb_flush(env, 1);
3587 b41f7df0 edgar_igl
3588 b41f7df0 edgar_igl
#if defined(CONFIG_USER_ONLY)
3589 b41f7df0 edgar_igl
        /* start in user mode with interrupts enabled.  */
3590 40e9eddd Edgar E. Iglesias
        env->pregs[PR_CCS] |= U_FLAG | I_FLAG | P_FLAG;
3591 b41f7df0 edgar_igl
#else
3592 52819664 edgar_igl
        cris_mmu_init(env);
3593 b41f7df0 edgar_igl
        env->pregs[PR_CCS] = 0;
3594 b41f7df0 edgar_igl
#endif
3595 8170028d ths
}
3596 d2856f1a aurel32
3597 d2856f1a aurel32
void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
3598 d2856f1a aurel32
                 unsigned long searched_pc, int pc_pos, void *puc)
3599 d2856f1a aurel32
{
3600 17ac9754 edgar_igl
        env->pc = gen_opc_pc[pc_pos];
3601 d2856f1a aurel32
}