Statistics
| Branch: | Revision:

root / target-cris / translate.c @ cb380f61

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