Statistics
| Branch: | Revision:

root / target-cris / translate.c @ 390efc54

History | View | Annotate | Download (74 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 8170028d ths
 * License along with this library; if not, write to the Free Software
19 8170028d ths
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 8170028d ths
 */
21 8170028d ths
22 b41f7df0 edgar_igl
/*
23 b41f7df0 edgar_igl
 * FIXME:
24 b41f7df0 edgar_igl
 * The condition code translation is in desperate need of attention. It's slow
25 b41f7df0 edgar_igl
 * and for system simulation it seems buggy. It sucks.
26 b41f7df0 edgar_igl
 */
27 b41f7df0 edgar_igl
28 8170028d ths
#include <stdarg.h>
29 8170028d ths
#include <stdlib.h>
30 8170028d ths
#include <stdio.h>
31 8170028d ths
#include <string.h>
32 8170028d ths
#include <inttypes.h>
33 8170028d ths
#include <assert.h>
34 8170028d ths
35 8170028d ths
#include "cpu.h"
36 8170028d ths
#include "exec-all.h"
37 8170028d ths
#include "disas.h"
38 57fec1fe bellard
#include "tcg-op.h"
39 05ba7d5f edgar_igl
#include "helper.h"
40 8170028d ths
#include "crisv32-decode.h"
41 ca10f867 aurel32
#include "qemu-common.h"
42 8170028d ths
43 8170028d ths
#define CRIS_STATS 0
44 8170028d ths
#if CRIS_STATS
45 8170028d ths
#define STATS(x) x
46 8170028d ths
#else
47 8170028d ths
#define STATS(x)
48 8170028d ths
#endif
49 8170028d ths
50 8170028d ths
#define DISAS_CRIS 0
51 8170028d ths
#if DISAS_CRIS
52 8170028d ths
#define DIS(x) x
53 8170028d ths
#else
54 8170028d ths
#define DIS(x)
55 8170028d ths
#endif
56 8170028d ths
57 b41f7df0 edgar_igl
#define D(x)
58 8170028d ths
#define BUG() (gen_BUG(dc, __FILE__, __LINE__))
59 8170028d ths
#define BUG_ON(x) ({if (x) BUG();})
60 8170028d ths
61 4f400ab5 edgar_igl
#define DISAS_SWI 5
62 4f400ab5 edgar_igl
63 8170028d ths
/* Used by the decoder.  */
64 8170028d ths
#define EXTRACT_FIELD(src, start, end) \
65 8170028d ths
            (((src) >> start) & ((1 << (end - start + 1)) - 1))
66 8170028d ths
67 8170028d ths
#define CC_MASK_NZ 0xc
68 8170028d ths
#define CC_MASK_NZV 0xe
69 8170028d ths
#define CC_MASK_NZVC 0xf
70 8170028d ths
#define CC_MASK_RNZV 0x10e
71 8170028d ths
72 a825e703 edgar_igl
TCGv cpu_env;
73 a825e703 edgar_igl
TCGv cpu_T[2];
74 a825e703 edgar_igl
TCGv cpu_R[16];
75 a825e703 edgar_igl
TCGv cpu_PR[16];
76 a825e703 edgar_igl
TCGv cc_src;
77 a825e703 edgar_igl
TCGv cc_dest;
78 a825e703 edgar_igl
TCGv cc_result;
79 a825e703 edgar_igl
TCGv cc_op;
80 a825e703 edgar_igl
TCGv cc_size;
81 a825e703 edgar_igl
TCGv cc_mask;
82 05ba7d5f edgar_igl
83 b41f7df0 edgar_igl
TCGv env_btarget;
84 b41f7df0 edgar_igl
TCGv env_pc;
85 b41f7df0 edgar_igl
86 8170028d ths
/* This is the state at translation time.  */
87 8170028d ths
typedef struct DisasContext {
88 8170028d ths
        CPUState *env;
89 b41f7df0 edgar_igl
        target_ulong pc, ppc;
90 8170028d ths
91 8170028d ths
        /* Decoder.  */
92 8170028d ths
        uint32_t ir;
93 8170028d ths
        uint32_t opcode;
94 8170028d ths
        unsigned int op1;
95 8170028d ths
        unsigned int op2;
96 8170028d ths
        unsigned int zsize, zzsize;
97 8170028d ths
        unsigned int mode;
98 8170028d ths
        unsigned int postinc;
99 8170028d ths
100 8170028d ths
        int update_cc;
101 8170028d ths
        int cc_op;
102 8170028d ths
        int cc_size;
103 8170028d ths
        uint32_t cc_mask;
104 b41f7df0 edgar_igl
        int flags_live; /* Wether or not $ccs is uptodate.  */
105 b41f7df0 edgar_igl
        int flagx_live; /* Wether or not flags_x has the x flag known at
106 b41f7df0 edgar_igl
                           translation time.  */
107 8170028d ths
        int flags_x;
108 b41f7df0 edgar_igl
        int clear_x; /* Clear x after this insn?  */
109 8170028d ths
110 b41f7df0 edgar_igl
        int user; /* user or kernel mode.  */
111 8170028d ths
        int is_jmp;
112 8170028d ths
        int dyn_jmp;
113 8170028d ths
114 8170028d ths
        uint32_t delayed_pc;
115 8170028d ths
        int delayed_branch;
116 8170028d ths
        int bcc;
117 8170028d ths
        uint32_t condlabel;
118 8170028d ths
119 8170028d ths
        struct TranslationBlock *tb;
120 8170028d ths
        int singlestep_enabled;
121 8170028d ths
} DisasContext;
122 8170028d ths
123 8170028d ths
void cris_prepare_jmp (DisasContext *dc, uint32_t dst);
124 8170028d ths
static void gen_BUG(DisasContext *dc, char *file, int line)
125 8170028d ths
{
126 8170028d ths
        printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
127 8170028d ths
        fprintf (logfile, "BUG: pc=%x %s %d\n", dc->pc, file, line);
128 8170028d ths
        cpu_dump_state (dc->env, stdout, fprintf, 0);
129 8170028d ths
        fflush(NULL);
130 8170028d ths
        cris_prepare_jmp (dc, 0x70000000 + line);
131 8170028d ths
}
132 8170028d ths
133 a825e703 edgar_igl
const char *regnames[] =
134 a825e703 edgar_igl
{
135 a825e703 edgar_igl
        "$r0", "$r1", "$r2", "$r3",
136 a825e703 edgar_igl
        "$r4", "$r5", "$r6", "$r7",
137 a825e703 edgar_igl
        "$r8", "$r9", "$r10", "$r11",
138 a825e703 edgar_igl
        "$r12", "$r13", "$sp", "$acr",
139 a825e703 edgar_igl
};
140 a825e703 edgar_igl
const char *pregnames[] =
141 a825e703 edgar_igl
{
142 a825e703 edgar_igl
        "$bz", "$vr", "$pid", "$srs",
143 a825e703 edgar_igl
        "$wz", "$exs", "$eda", "$mof",
144 a825e703 edgar_igl
        "$dz", "$ebp", "$erp", "$srp",
145 a825e703 edgar_igl
        "$nrp", "$ccs", "$usp", "$spc",
146 a825e703 edgar_igl
};
147 a825e703 edgar_igl
148 05ba7d5f edgar_igl
/* We need this table to handle preg-moves with implicit width.  */
149 05ba7d5f edgar_igl
int preg_sizes[] = {
150 05ba7d5f edgar_igl
        1, /* bz.  */
151 05ba7d5f edgar_igl
        1, /* vr.  */
152 05ba7d5f edgar_igl
        4, /* pid.  */
153 05ba7d5f edgar_igl
        1, /* srs.  */
154 05ba7d5f edgar_igl
        2, /* wz.  */
155 05ba7d5f edgar_igl
        4, 4, 4,
156 05ba7d5f edgar_igl
        4, 4, 4, 4,
157 05ba7d5f edgar_igl
        4, 4, 4, 4,
158 05ba7d5f edgar_igl
};
159 05ba7d5f edgar_igl
160 05ba7d5f edgar_igl
#define t_gen_mov_TN_env(tn, member) \
161 3157a0a9 edgar_igl
 _t_gen_mov_TN_env((tn), offsetof(CPUState, member))
162 05ba7d5f edgar_igl
#define t_gen_mov_env_TN(member, tn) \
163 3157a0a9 edgar_igl
 _t_gen_mov_env_TN(offsetof(CPUState, member), (tn))
164 05ba7d5f edgar_igl
165 b41f7df0 edgar_igl
static inline void t_gen_mov_TN_reg(TCGv tn, int r)
166 b41f7df0 edgar_igl
{
167 b41f7df0 edgar_igl
        if (r < 0 || r > 15)
168 b41f7df0 edgar_igl
                fprintf(stderr, "wrong register read $r%d\n", r);
169 b41f7df0 edgar_igl
        tcg_gen_mov_tl(tn, cpu_R[r]);
170 b41f7df0 edgar_igl
}
171 b41f7df0 edgar_igl
static inline void t_gen_mov_reg_TN(int r, TCGv tn)
172 b41f7df0 edgar_igl
{
173 b41f7df0 edgar_igl
        if (r < 0 || r > 15)
174 b41f7df0 edgar_igl
                fprintf(stderr, "wrong register write $r%d\n", r);
175 b41f7df0 edgar_igl
        tcg_gen_mov_tl(cpu_R[r], tn);
176 b41f7df0 edgar_igl
}
177 05ba7d5f edgar_igl
178 05ba7d5f edgar_igl
static inline void _t_gen_mov_TN_env(TCGv tn, int offset)
179 05ba7d5f edgar_igl
{
180 b41f7df0 edgar_igl
        if (offset > sizeof (CPUState))
181 b41f7df0 edgar_igl
                fprintf(stderr, "wrong load from env from off=%d\n", offset);
182 05ba7d5f edgar_igl
        tcg_gen_ld_tl(tn, cpu_env, offset);
183 05ba7d5f edgar_igl
}
184 05ba7d5f edgar_igl
static inline void _t_gen_mov_env_TN(int offset, TCGv tn)
185 05ba7d5f edgar_igl
{
186 b41f7df0 edgar_igl
        if (offset > sizeof (CPUState))
187 b41f7df0 edgar_igl
                fprintf(stderr, "wrong store to env at off=%d\n", offset);
188 05ba7d5f edgar_igl
        tcg_gen_st_tl(tn, cpu_env, offset);
189 05ba7d5f edgar_igl
}
190 05ba7d5f edgar_igl
191 05ba7d5f edgar_igl
static inline void t_gen_mov_TN_preg(TCGv tn, int r)
192 05ba7d5f edgar_igl
{
193 b41f7df0 edgar_igl
        if (r < 0 || r > 15)
194 b41f7df0 edgar_igl
                fprintf(stderr, "wrong register read $p%d\n", r);
195 05ba7d5f edgar_igl
        if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
196 3157a0a9 edgar_igl
                tcg_gen_mov_tl(tn, tcg_const_tl(0));
197 05ba7d5f edgar_igl
        else if (r == PR_VR)
198 3157a0a9 edgar_igl
                tcg_gen_mov_tl(tn, tcg_const_tl(32));
199 b41f7df0 edgar_igl
        else if (r == PR_EXS) {
200 b41f7df0 edgar_igl
                printf("read from EXS!\n");
201 b41f7df0 edgar_igl
                tcg_gen_mov_tl(tn, cpu_PR[r]);
202 b41f7df0 edgar_igl
        }
203 b41f7df0 edgar_igl
        else if (r == PR_EDA) {
204 b41f7df0 edgar_igl
                printf("read from EDA!\n");
205 b41f7df0 edgar_igl
                tcg_gen_mov_tl(tn, cpu_PR[r]);
206 b41f7df0 edgar_igl
        }
207 05ba7d5f edgar_igl
        else
208 a825e703 edgar_igl
                tcg_gen_mov_tl(tn, cpu_PR[r]);
209 05ba7d5f edgar_igl
}
210 05ba7d5f edgar_igl
static inline void t_gen_mov_preg_TN(int r, TCGv tn)
211 05ba7d5f edgar_igl
{
212 b41f7df0 edgar_igl
        if (r < 0 || r > 15)
213 b41f7df0 edgar_igl
                fprintf(stderr, "wrong register write $p%d\n", r);
214 05ba7d5f edgar_igl
        if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
215 05ba7d5f edgar_igl
                return;
216 b41f7df0 edgar_igl
        else if (r == PR_SRS)
217 b41f7df0 edgar_igl
                tcg_gen_andi_tl(cpu_PR[r], tn, 3);
218 b41f7df0 edgar_igl
        else {
219 b41f7df0 edgar_igl
                if (r == PR_PID) {
220 b41f7df0 edgar_igl
                        tcg_gen_helper_0_0(helper_tlb_flush);
221 b41f7df0 edgar_igl
                }
222 a825e703 edgar_igl
                tcg_gen_mov_tl(cpu_PR[r], tn);
223 b41f7df0 edgar_igl
        }
224 05ba7d5f edgar_igl
}
225 05ba7d5f edgar_igl
226 dceaf394 edgar_igl
static inline void t_gen_raise_exception(uint32_t index)
227 05ba7d5f edgar_igl
{
228 dceaf394 edgar_igl
        tcg_gen_helper_0_1(helper_raise_exception, tcg_const_tl(index));
229 05ba7d5f edgar_igl
}
230 05ba7d5f edgar_igl
231 05ba7d5f edgar_igl
static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
232 05ba7d5f edgar_igl
{
233 05ba7d5f edgar_igl
        int l1;
234 05ba7d5f edgar_igl
235 05ba7d5f edgar_igl
        l1 = gen_new_label();
236 05ba7d5f edgar_igl
        /* Speculative shift. */
237 05ba7d5f edgar_igl
        tcg_gen_shl_tl(d, a, b);
238 17ac9754 edgar_igl
        tcg_gen_brcond_tl(TCG_COND_LEU, b, tcg_const_tl(31), l1);
239 05ba7d5f edgar_igl
        /* Clear dst if shift operands were to large.  */
240 05ba7d5f edgar_igl
        tcg_gen_movi_tl(d, 0);
241 05ba7d5f edgar_igl
        gen_set_label(l1);
242 05ba7d5f edgar_igl
}
243 05ba7d5f edgar_igl
244 05ba7d5f edgar_igl
static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
245 05ba7d5f edgar_igl
{
246 05ba7d5f edgar_igl
        int l1;
247 05ba7d5f edgar_igl
248 05ba7d5f edgar_igl
        l1 = gen_new_label();
249 05ba7d5f edgar_igl
        /* Speculative shift. */
250 05ba7d5f edgar_igl
        tcg_gen_shr_tl(d, a, b);
251 17ac9754 edgar_igl
        tcg_gen_brcond_tl(TCG_COND_LEU, b, tcg_const_tl(31), l1);
252 05ba7d5f edgar_igl
        /* Clear dst if shift operands were to large.  */
253 05ba7d5f edgar_igl
        tcg_gen_movi_tl(d, 0);
254 05ba7d5f edgar_igl
        gen_set_label(l1);
255 05ba7d5f edgar_igl
}
256 05ba7d5f edgar_igl
257 05ba7d5f edgar_igl
static void t_gen_asr(TCGv d, TCGv a, TCGv b)
258 05ba7d5f edgar_igl
{
259 05ba7d5f edgar_igl
        int l1;
260 05ba7d5f edgar_igl
261 05ba7d5f edgar_igl
        l1 = gen_new_label();
262 05ba7d5f edgar_igl
        /* Speculative shift. */
263 05ba7d5f edgar_igl
        tcg_gen_sar_tl(d, a, b);
264 17ac9754 edgar_igl
        tcg_gen_brcond_tl(TCG_COND_LEU, b, tcg_const_tl(31), l1);
265 05ba7d5f edgar_igl
        /* Clear dst if shift operands were to large.  */
266 b41f7df0 edgar_igl
        tcg_gen_sar_tl(d, a, tcg_const_tl(30));
267 05ba7d5f edgar_igl
        gen_set_label(l1);
268 05ba7d5f edgar_igl
}
269 05ba7d5f edgar_igl
270 3157a0a9 edgar_igl
/* 64-bit signed mul, lower result in d and upper in d2.  */
271 3157a0a9 edgar_igl
static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
272 3157a0a9 edgar_igl
{
273 3157a0a9 edgar_igl
        TCGv t0, t1;
274 3157a0a9 edgar_igl
275 3157a0a9 edgar_igl
        t0 = tcg_temp_new(TCG_TYPE_I64);
276 3157a0a9 edgar_igl
        t1 = tcg_temp_new(TCG_TYPE_I64);
277 3157a0a9 edgar_igl
278 3157a0a9 edgar_igl
        tcg_gen_ext32s_i64(t0, a);
279 3157a0a9 edgar_igl
        tcg_gen_ext32s_i64(t1, b);
280 3157a0a9 edgar_igl
        tcg_gen_mul_i64(t0, t0, t1);
281 3157a0a9 edgar_igl
282 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d, t0);
283 3157a0a9 edgar_igl
        tcg_gen_shri_i64(t0, t0, 32);
284 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d2, t0);
285 b41f7df0 edgar_igl
286 b41f7df0 edgar_igl
        tcg_gen_discard_i64(t0);
287 b41f7df0 edgar_igl
        tcg_gen_discard_i64(t1);
288 3157a0a9 edgar_igl
}
289 3157a0a9 edgar_igl
290 3157a0a9 edgar_igl
/* 64-bit unsigned muls, lower result in d and upper in d2.  */
291 3157a0a9 edgar_igl
static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
292 3157a0a9 edgar_igl
{
293 3157a0a9 edgar_igl
        TCGv t0, t1;
294 3157a0a9 edgar_igl
295 3157a0a9 edgar_igl
        t0 = tcg_temp_new(TCG_TYPE_I64);
296 3157a0a9 edgar_igl
        t1 = tcg_temp_new(TCG_TYPE_I64);
297 3157a0a9 edgar_igl
298 3157a0a9 edgar_igl
        tcg_gen_extu_i32_i64(t0, a);
299 3157a0a9 edgar_igl
        tcg_gen_extu_i32_i64(t1, b);
300 3157a0a9 edgar_igl
        tcg_gen_mul_i64(t0, t0, t1);
301 3157a0a9 edgar_igl
302 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d, t0);
303 3157a0a9 edgar_igl
        tcg_gen_shri_i64(t0, t0, 32);
304 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d2, t0);
305 b41f7df0 edgar_igl
306 b41f7df0 edgar_igl
        tcg_gen_discard_i64(t0);
307 b41f7df0 edgar_igl
        tcg_gen_discard_i64(t1);
308 3157a0a9 edgar_igl
}
309 3157a0a9 edgar_igl
310 d059c172 edgar_igl
/* 32bit branch-free binary search for counting leading zeros.  */
311 d059c172 edgar_igl
static void t_gen_lz_i32(TCGv d, TCGv x)
312 d059c172 edgar_igl
{
313 d059c172 edgar_igl
        TCGv y, m, n;
314 d059c172 edgar_igl
315 d059c172 edgar_igl
        y = tcg_temp_new(TCG_TYPE_I32);
316 d059c172 edgar_igl
        m = tcg_temp_new(TCG_TYPE_I32);
317 d059c172 edgar_igl
        n = tcg_temp_new(TCG_TYPE_I32);
318 d059c172 edgar_igl
319 d059c172 edgar_igl
        /* y = -(x >> 16)  */
320 d059c172 edgar_igl
        tcg_gen_shri_i32(y, x, 16);
321 390efc54 pbrook
        tcg_gen_neg_i32(y, y);
322 d059c172 edgar_igl
323 d059c172 edgar_igl
        /* m = (y >> 16) & 16  */
324 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
325 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 16);
326 d059c172 edgar_igl
327 d059c172 edgar_igl
        /* n = 16 - m  */
328 d059c172 edgar_igl
        tcg_gen_sub_i32(n, tcg_const_i32(16), m);
329 d059c172 edgar_igl
        /* x = x >> m  */
330 d059c172 edgar_igl
        tcg_gen_shr_i32(x, x, m);
331 d059c172 edgar_igl
332 d059c172 edgar_igl
        /* y = x - 0x100  */
333 d059c172 edgar_igl
        tcg_gen_subi_i32(y, x, 0x100);
334 d059c172 edgar_igl
        /* m = (y >> 16) & 8  */
335 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
336 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 8);
337 d059c172 edgar_igl
        /* n = n + m  */
338 d059c172 edgar_igl
        tcg_gen_add_i32(n, n, m);
339 d059c172 edgar_igl
        /* x = x << m  */
340 d059c172 edgar_igl
        tcg_gen_shl_i32(x, x, m);
341 d059c172 edgar_igl
342 d059c172 edgar_igl
        /* y = x - 0x1000  */
343 d059c172 edgar_igl
        tcg_gen_subi_i32(y, x, 0x1000);
344 d059c172 edgar_igl
        /* m = (y >> 16) & 4  */
345 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
346 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 4);
347 d059c172 edgar_igl
        /* n = n + m  */
348 d059c172 edgar_igl
        tcg_gen_add_i32(n, n, m);
349 d059c172 edgar_igl
        /* x = x << m  */
350 d059c172 edgar_igl
        tcg_gen_shl_i32(x, x, m);
351 d059c172 edgar_igl
352 d059c172 edgar_igl
        /* y = x - 0x4000  */
353 d059c172 edgar_igl
        tcg_gen_subi_i32(y, x, 0x4000);
354 d059c172 edgar_igl
        /* m = (y >> 16) & 2  */
355 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
356 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 2);
357 d059c172 edgar_igl
        /* n = n + m  */
358 d059c172 edgar_igl
        tcg_gen_add_i32(n, n, m);
359 d059c172 edgar_igl
        /* x = x << m  */
360 d059c172 edgar_igl
        tcg_gen_shl_i32(x, x, m);
361 d059c172 edgar_igl
362 d059c172 edgar_igl
        /* y = x >> 14  */
363 d059c172 edgar_igl
        tcg_gen_shri_i32(y, x, 14);
364 d059c172 edgar_igl
        /* m = y & ~(y >> 1)  */
365 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 1);
366 d059c172 edgar_igl
        tcg_gen_xori_i32(m, m, 0xffffffff);
367 d059c172 edgar_igl
        tcg_gen_and_i32(m, m, y);
368 d059c172 edgar_igl
369 d059c172 edgar_igl
        /* d = n + 2 - m  */
370 d059c172 edgar_igl
        tcg_gen_addi_i32(d, n, 2);
371 d059c172 edgar_igl
        tcg_gen_sub_i32(d, d, m);
372 d059c172 edgar_igl
373 d059c172 edgar_igl
        tcg_gen_discard_i32(y);
374 d059c172 edgar_igl
        tcg_gen_discard_i32(m);
375 d059c172 edgar_igl
        tcg_gen_discard_i32(n);
376 d059c172 edgar_igl
}
377 d059c172 edgar_igl
378 dceaf394 edgar_igl
static void t_gen_btst(TCGv d, TCGv s)
379 dceaf394 edgar_igl
{
380 dceaf394 edgar_igl
        TCGv sbit;
381 dceaf394 edgar_igl
        TCGv bset;
382 dceaf394 edgar_igl
        int l1;
383 dceaf394 edgar_igl
384 dceaf394 edgar_igl
        /* des ref:
385 dceaf394 edgar_igl
           The N flag is set according to the selected bit in the dest reg.
386 dceaf394 edgar_igl
           The Z flag is set if the selected bit and all bits to the right are
387 dceaf394 edgar_igl
           zero.
388 dceaf394 edgar_igl
           The X flag is cleared.
389 dceaf394 edgar_igl
           Other flags are left untouched.
390 dceaf394 edgar_igl
           The destination reg is not affected.
391 dceaf394 edgar_igl

392 dceaf394 edgar_igl
        unsigned int fz, sbit, bset, mask, masked_t0;
393 dceaf394 edgar_igl

394 dceaf394 edgar_igl
        sbit = T1 & 31;
395 dceaf394 edgar_igl
        bset = !!(T0 & (1 << sbit));
396 dceaf394 edgar_igl
        mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1;
397 dceaf394 edgar_igl
        masked_t0 = T0 & mask;
398 dceaf394 edgar_igl
        fz = !(masked_t0 | bset);
399 dceaf394 edgar_igl

400 dceaf394 edgar_igl
        // Clear the X, N and Z flags.
401 dceaf394 edgar_igl
        T0 = env->pregs[PR_CCS] & ~(X_FLAG | N_FLAG | Z_FLAG);
402 dceaf394 edgar_igl
        // Set the N and Z flags accordingly.
403 dceaf394 edgar_igl
        T0 |= (bset << 3) | (fz << 2);
404 dceaf394 edgar_igl
        */
405 dceaf394 edgar_igl
406 dceaf394 edgar_igl
        l1 = gen_new_label();
407 dceaf394 edgar_igl
        sbit = tcg_temp_new(TCG_TYPE_TL);
408 dceaf394 edgar_igl
        bset = tcg_temp_new(TCG_TYPE_TL);
409 dceaf394 edgar_igl
410 dceaf394 edgar_igl
        /* Compute bset and sbit.  */
411 dceaf394 edgar_igl
        tcg_gen_andi_tl(sbit, s, 31);
412 dceaf394 edgar_igl
        tcg_gen_shl_tl(s, tcg_const_tl(1), sbit);
413 dceaf394 edgar_igl
        tcg_gen_and_tl(bset, d, s);
414 dceaf394 edgar_igl
        tcg_gen_shr_tl(bset, bset, sbit);
415 dceaf394 edgar_igl
        /* Displace to N_FLAG.  */
416 dceaf394 edgar_igl
        tcg_gen_shli_tl(bset, bset, 3);
417 dceaf394 edgar_igl
418 dceaf394 edgar_igl
        tcg_gen_shl_tl(sbit, tcg_const_tl(2), sbit);
419 dceaf394 edgar_igl
        tcg_gen_subi_tl(sbit, sbit, 1);
420 dceaf394 edgar_igl
        tcg_gen_and_tl(sbit, d, sbit);
421 dceaf394 edgar_igl
422 dceaf394 edgar_igl
        tcg_gen_andi_tl(d, cpu_PR[PR_CCS], ~(X_FLAG | N_FLAG | Z_FLAG));
423 dceaf394 edgar_igl
        /* or in the N_FLAG.  */
424 dceaf394 edgar_igl
        tcg_gen_or_tl(d, d, bset);
425 dceaf394 edgar_igl
        tcg_gen_brcond_tl(TCG_COND_NE, sbit, tcg_const_tl(0), l1);
426 dceaf394 edgar_igl
        /* or in the Z_FLAG.  */
427 dceaf394 edgar_igl
        tcg_gen_ori_tl(d, d, Z_FLAG);
428 dceaf394 edgar_igl
        gen_set_label(l1);
429 dceaf394 edgar_igl
430 dceaf394 edgar_igl
        tcg_gen_discard_tl(sbit);
431 dceaf394 edgar_igl
        tcg_gen_discard_tl(bset);
432 dceaf394 edgar_igl
}
433 dceaf394 edgar_igl
434 aae6b32a edgar_igl
static void t_gen_cris_dstep(TCGv d, TCGv s)
435 aae6b32a edgar_igl
{
436 aae6b32a edgar_igl
        int l1;
437 aae6b32a edgar_igl
438 aae6b32a edgar_igl
        l1 = gen_new_label();
439 aae6b32a edgar_igl
440 aae6b32a edgar_igl
        /* 
441 aae6b32a edgar_igl
         * d <<= 1
442 aae6b32a edgar_igl
         * if (d >= s)
443 aae6b32a edgar_igl
         *    d -= s;
444 aae6b32a edgar_igl
         */
445 aae6b32a edgar_igl
        tcg_gen_shli_tl(d, d, 1);
446 aae6b32a edgar_igl
        tcg_gen_brcond_tl(TCG_COND_LTU, d, s, l1);
447 aae6b32a edgar_igl
        tcg_gen_sub_tl(d, d, s);
448 aae6b32a edgar_igl
        gen_set_label(l1);
449 aae6b32a edgar_igl
}
450 aae6b32a edgar_igl
451 3157a0a9 edgar_igl
/* Extended arithmetics on CRIS.  */
452 3157a0a9 edgar_igl
static inline void t_gen_add_flag(TCGv d, int flag)
453 3157a0a9 edgar_igl
{
454 3157a0a9 edgar_igl
        TCGv c;
455 3157a0a9 edgar_igl
456 3157a0a9 edgar_igl
        c = tcg_temp_new(TCG_TYPE_TL);
457 3157a0a9 edgar_igl
        t_gen_mov_TN_preg(c, PR_CCS);
458 3157a0a9 edgar_igl
        /* Propagate carry into d.  */
459 3157a0a9 edgar_igl
        tcg_gen_andi_tl(c, c, 1 << flag);
460 3157a0a9 edgar_igl
        if (flag)
461 3157a0a9 edgar_igl
                tcg_gen_shri_tl(c, c, flag);
462 3157a0a9 edgar_igl
        tcg_gen_add_tl(d, d, c);
463 b41f7df0 edgar_igl
        tcg_gen_discard_tl(c);
464 3157a0a9 edgar_igl
}
465 3157a0a9 edgar_igl
466 3157a0a9 edgar_igl
static inline void t_gen_addx_carry(TCGv d)
467 3157a0a9 edgar_igl
{
468 3157a0a9 edgar_igl
        TCGv x, c;
469 3157a0a9 edgar_igl
470 3157a0a9 edgar_igl
        x = tcg_temp_new(TCG_TYPE_TL);
471 3157a0a9 edgar_igl
        c = tcg_temp_new(TCG_TYPE_TL);
472 3157a0a9 edgar_igl
        t_gen_mov_TN_preg(x, PR_CCS);
473 3157a0a9 edgar_igl
        tcg_gen_mov_tl(c, x);
474 3157a0a9 edgar_igl
475 3157a0a9 edgar_igl
        /* Propagate carry into d if X is set. Branch free.  */
476 3157a0a9 edgar_igl
        tcg_gen_andi_tl(c, c, C_FLAG);
477 3157a0a9 edgar_igl
        tcg_gen_andi_tl(x, x, X_FLAG);
478 3157a0a9 edgar_igl
        tcg_gen_shri_tl(x, x, 4);
479 3157a0a9 edgar_igl
480 3157a0a9 edgar_igl
        tcg_gen_and_tl(x, x, c);
481 3157a0a9 edgar_igl
        tcg_gen_add_tl(d, d, x);        
482 b41f7df0 edgar_igl
        tcg_gen_discard_tl(x);
483 b41f7df0 edgar_igl
        tcg_gen_discard_tl(c);
484 3157a0a9 edgar_igl
}
485 3157a0a9 edgar_igl
486 3157a0a9 edgar_igl
static inline void t_gen_subx_carry(TCGv d)
487 3157a0a9 edgar_igl
{
488 3157a0a9 edgar_igl
        TCGv x, c;
489 3157a0a9 edgar_igl
490 3157a0a9 edgar_igl
        x = tcg_temp_new(TCG_TYPE_TL);
491 3157a0a9 edgar_igl
        c = tcg_temp_new(TCG_TYPE_TL);
492 3157a0a9 edgar_igl
        t_gen_mov_TN_preg(x, PR_CCS);
493 3157a0a9 edgar_igl
        tcg_gen_mov_tl(c, x);
494 3157a0a9 edgar_igl
495 3157a0a9 edgar_igl
        /* Propagate carry into d if X is set. Branch free.  */
496 3157a0a9 edgar_igl
        tcg_gen_andi_tl(c, c, C_FLAG);
497 3157a0a9 edgar_igl
        tcg_gen_andi_tl(x, x, X_FLAG);
498 3157a0a9 edgar_igl
        tcg_gen_shri_tl(x, x, 4);
499 3157a0a9 edgar_igl
500 3157a0a9 edgar_igl
        tcg_gen_and_tl(x, x, c);
501 3157a0a9 edgar_igl
        tcg_gen_sub_tl(d, d, x);
502 b41f7df0 edgar_igl
        tcg_gen_discard_tl(x);
503 b41f7df0 edgar_igl
        tcg_gen_discard_tl(c);
504 3157a0a9 edgar_igl
}
505 3157a0a9 edgar_igl
506 3157a0a9 edgar_igl
/* Swap the two bytes within each half word of the s operand.
507 3157a0a9 edgar_igl
   T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff)  */
508 3157a0a9 edgar_igl
static inline void t_gen_swapb(TCGv d, TCGv s)
509 3157a0a9 edgar_igl
{
510 3157a0a9 edgar_igl
        TCGv t, org_s;
511 3157a0a9 edgar_igl
512 3157a0a9 edgar_igl
        t = tcg_temp_new(TCG_TYPE_TL);
513 3157a0a9 edgar_igl
        org_s = tcg_temp_new(TCG_TYPE_TL);
514 3157a0a9 edgar_igl
515 3157a0a9 edgar_igl
        /* d and s may refer to the same object.  */
516 3157a0a9 edgar_igl
        tcg_gen_mov_tl(org_s, s);
517 3157a0a9 edgar_igl
        tcg_gen_shli_tl(t, org_s, 8);
518 3157a0a9 edgar_igl
        tcg_gen_andi_tl(d, t, 0xff00ff00);
519 3157a0a9 edgar_igl
        tcg_gen_shri_tl(t, org_s, 8);
520 3157a0a9 edgar_igl
        tcg_gen_andi_tl(t, t, 0x00ff00ff);
521 3157a0a9 edgar_igl
        tcg_gen_or_tl(d, d, t);
522 b41f7df0 edgar_igl
        tcg_gen_discard_tl(t);
523 b41f7df0 edgar_igl
        tcg_gen_discard_tl(org_s);
524 3157a0a9 edgar_igl
}
525 3157a0a9 edgar_igl
526 3157a0a9 edgar_igl
/* Swap the halfwords of the s operand.  */
527 3157a0a9 edgar_igl
static inline void t_gen_swapw(TCGv d, TCGv s)
528 3157a0a9 edgar_igl
{
529 3157a0a9 edgar_igl
        TCGv t;
530 3157a0a9 edgar_igl
        /* d and s refer the same object.  */
531 3157a0a9 edgar_igl
        t = tcg_temp_new(TCG_TYPE_TL);
532 3157a0a9 edgar_igl
        tcg_gen_mov_tl(t, s);
533 3157a0a9 edgar_igl
        tcg_gen_shli_tl(d, t, 16);
534 3157a0a9 edgar_igl
        tcg_gen_shri_tl(t, t, 16);
535 3157a0a9 edgar_igl
        tcg_gen_or_tl(d, d, t);
536 b41f7df0 edgar_igl
        tcg_gen_discard_tl(t);
537 3157a0a9 edgar_igl
}
538 3157a0a9 edgar_igl
539 3157a0a9 edgar_igl
/* Reverse the within each byte.
540 3157a0a9 edgar_igl
   T0 = (((T0 << 7) & 0x80808080) |
541 3157a0a9 edgar_igl
   ((T0 << 5) & 0x40404040) |
542 3157a0a9 edgar_igl
   ((T0 << 3) & 0x20202020) |
543 3157a0a9 edgar_igl
   ((T0 << 1) & 0x10101010) |
544 3157a0a9 edgar_igl
   ((T0 >> 1) & 0x08080808) |
545 3157a0a9 edgar_igl
   ((T0 >> 3) & 0x04040404) |
546 3157a0a9 edgar_igl
   ((T0 >> 5) & 0x02020202) |
547 3157a0a9 edgar_igl
   ((T0 >> 7) & 0x01010101));
548 3157a0a9 edgar_igl
 */
549 3157a0a9 edgar_igl
static inline void t_gen_swapr(TCGv d, TCGv s)
550 3157a0a9 edgar_igl
{
551 3157a0a9 edgar_igl
        struct {
552 3157a0a9 edgar_igl
                int shift; /* LSL when positive, LSR when negative.  */
553 3157a0a9 edgar_igl
                uint32_t mask;
554 3157a0a9 edgar_igl
        } bitrev [] = {
555 3157a0a9 edgar_igl
                {7, 0x80808080},
556 3157a0a9 edgar_igl
                {5, 0x40404040},
557 3157a0a9 edgar_igl
                {3, 0x20202020},
558 3157a0a9 edgar_igl
                {1, 0x10101010},
559 3157a0a9 edgar_igl
                {-1, 0x08080808},
560 3157a0a9 edgar_igl
                {-3, 0x04040404},
561 3157a0a9 edgar_igl
                {-5, 0x02020202},
562 3157a0a9 edgar_igl
                {-7, 0x01010101}
563 3157a0a9 edgar_igl
        };
564 3157a0a9 edgar_igl
        int i;
565 3157a0a9 edgar_igl
        TCGv t, org_s;
566 3157a0a9 edgar_igl
567 3157a0a9 edgar_igl
        /* d and s refer the same object.  */
568 3157a0a9 edgar_igl
        t = tcg_temp_new(TCG_TYPE_TL);
569 3157a0a9 edgar_igl
        org_s = tcg_temp_new(TCG_TYPE_TL);
570 3157a0a9 edgar_igl
        tcg_gen_mov_tl(org_s, s);
571 3157a0a9 edgar_igl
572 3157a0a9 edgar_igl
        tcg_gen_shli_tl(t, org_s,  bitrev[0].shift);
573 3157a0a9 edgar_igl
        tcg_gen_andi_tl(d, t,  bitrev[0].mask);
574 3157a0a9 edgar_igl
        for (i = 1; i < sizeof bitrev / sizeof bitrev[0]; i++) {
575 3157a0a9 edgar_igl
                if (bitrev[i].shift >= 0) {
576 3157a0a9 edgar_igl
                        tcg_gen_shli_tl(t, org_s,  bitrev[i].shift);
577 3157a0a9 edgar_igl
                } else {
578 3157a0a9 edgar_igl
                        tcg_gen_shri_tl(t, org_s,  -bitrev[i].shift);
579 3157a0a9 edgar_igl
                }
580 3157a0a9 edgar_igl
                tcg_gen_andi_tl(t, t,  bitrev[i].mask);
581 3157a0a9 edgar_igl
                tcg_gen_or_tl(d, d, t);
582 3157a0a9 edgar_igl
        }
583 b41f7df0 edgar_igl
        tcg_gen_discard_tl(t);
584 b41f7df0 edgar_igl
        tcg_gen_discard_tl(org_s);
585 3157a0a9 edgar_igl
}
586 3157a0a9 edgar_igl
587 17ac9754 edgar_igl
static void t_gen_cc_jmp(target_ulong pc_true, target_ulong pc_false)
588 17ac9754 edgar_igl
{
589 17ac9754 edgar_igl
        TCGv btaken;
590 17ac9754 edgar_igl
        int l1;
591 17ac9754 edgar_igl
592 17ac9754 edgar_igl
        l1 = gen_new_label();
593 17ac9754 edgar_igl
        btaken = tcg_temp_new(TCG_TYPE_TL);
594 17ac9754 edgar_igl
595 17ac9754 edgar_igl
        /* Conditional jmp.  */
596 17ac9754 edgar_igl
        t_gen_mov_TN_env(btaken, btaken);
597 17ac9754 edgar_igl
        tcg_gen_movi_tl(env_pc, pc_false);
598 17ac9754 edgar_igl
        tcg_gen_brcond_tl(TCG_COND_EQ, btaken, tcg_const_tl(0), l1);
599 17ac9754 edgar_igl
        tcg_gen_movi_tl(env_pc, pc_true);
600 17ac9754 edgar_igl
        gen_set_label(l1);
601 17ac9754 edgar_igl
602 17ac9754 edgar_igl
        tcg_gen_discard_tl(btaken);
603 17ac9754 edgar_igl
}
604 17ac9754 edgar_igl
605 8170028d ths
static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
606 8170028d ths
{
607 8170028d ths
        TranslationBlock *tb;
608 8170028d ths
        tb = dc->tb;
609 8170028d ths
        if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
610 05ba7d5f edgar_igl
                tcg_gen_goto_tb(n);
611 50cfa95c edgar_igl
                tcg_gen_movi_tl(env_pc, dest);
612 05ba7d5f edgar_igl
                tcg_gen_exit_tb((long)tb + n);
613 8170028d ths
        } else {
614 50cfa95c edgar_igl
                tcg_gen_mov_tl(env_pc, cpu_T[0]);
615 05ba7d5f edgar_igl
                tcg_gen_exit_tb(0);
616 8170028d ths
        }
617 8170028d ths
}
618 8170028d ths
619 8170028d ths
/* Sign extend at translation time.  */
620 8170028d ths
static int sign_extend(unsigned int val, unsigned int width)
621 8170028d ths
{
622 8170028d ths
        int sval;
623 8170028d ths
624 8170028d ths
        /* LSL.  */
625 8170028d ths
        val <<= 31 - width;
626 8170028d ths
        sval = val;
627 8170028d ths
        /* ASR.  */
628 8170028d ths
        sval >>= 31 - width;
629 8170028d ths
        return sval;
630 8170028d ths
}
631 8170028d ths
632 05ba7d5f edgar_igl
static inline void cris_clear_x_flag(DisasContext *dc)
633 05ba7d5f edgar_igl
{
634 b41f7df0 edgar_igl
        if (!dc->flagx_live 
635 b41f7df0 edgar_igl
            || (dc->flagx_live && dc->flags_x)
636 b41f7df0 edgar_igl
            || dc->cc_op != CC_OP_FLAGS)
637 b41f7df0 edgar_igl
                tcg_gen_andi_i32(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~X_FLAG);
638 b41f7df0 edgar_igl
        dc->flagx_live = 1;
639 b41f7df0 edgar_igl
        dc->flags_x = 0;
640 05ba7d5f edgar_igl
}
641 05ba7d5f edgar_igl
642 8170028d ths
static void cris_evaluate_flags(DisasContext *dc)
643 8170028d ths
{
644 8170028d ths
        if (!dc->flags_live) {
645 b41f7df0 edgar_igl
                tcg_gen_movi_tl(cc_op, dc->cc_op);
646 b41f7df0 edgar_igl
                tcg_gen_movi_tl(cc_size, dc->cc_size);
647 b41f7df0 edgar_igl
                tcg_gen_movi_tl(cc_mask, dc->cc_mask);
648 b41f7df0 edgar_igl
649 8170028d ths
                switch (dc->cc_op)
650 8170028d ths
                {
651 8170028d ths
                        case CC_OP_MCP:
652 b41f7df0 edgar_igl
                                tcg_gen_helper_0_0(helper_evaluate_flags_mcp);
653 8170028d ths
                                break;
654 8170028d ths
                        case CC_OP_MULS:
655 b41f7df0 edgar_igl
                                tcg_gen_helper_0_0(helper_evaluate_flags_muls);
656 8170028d ths
                                break;
657 8170028d ths
                        case CC_OP_MULU:
658 b41f7df0 edgar_igl
                                tcg_gen_helper_0_0(helper_evaluate_flags_mulu);
659 8170028d ths
                                break;
660 8170028d ths
                        case CC_OP_MOVE:
661 8170028d ths
                                switch (dc->cc_size)
662 8170028d ths
                                {
663 8170028d ths
                                        case 4:
664 b41f7df0 edgar_igl
                                                tcg_gen_helper_0_0(helper_evaluate_flags_move_4);
665 8170028d ths
                                                break;
666 8170028d ths
                                        case 2:
667 b41f7df0 edgar_igl
                                                tcg_gen_helper_0_0(helper_evaluate_flags_move_2);
668 8170028d ths
                                                break;
669 8170028d ths
                                        default:
670 b41f7df0 edgar_igl
                                                tcg_gen_helper_0_0(helper_evaluate_flags);
671 8170028d ths
                                                break;
672 8170028d ths
                                }
673 8170028d ths
                                break;
674 b41f7df0 edgar_igl
                        case CC_OP_FLAGS:
675 b41f7df0 edgar_igl
                                /* live.  */
676 b41f7df0 edgar_igl
                                break;
677 8170028d ths
                        default:
678 8170028d ths
                        {
679 8170028d ths
                                switch (dc->cc_size)
680 8170028d ths
                                {
681 8170028d ths
                                        case 4:
682 b41f7df0 edgar_igl
                                                tcg_gen_helper_0_0(helper_evaluate_flags_alu_4);
683 8170028d ths
                                                break;
684 8170028d ths
                                        default:
685 b41f7df0 edgar_igl
                                                tcg_gen_helper_0_0(helper_evaluate_flags);
686 8170028d ths
                                                break;
687 8170028d ths
                                }
688 8170028d ths
                        }
689 8170028d ths
                        break;
690 8170028d ths
                }
691 8170028d ths
                dc->flags_live = 1;
692 8170028d ths
        }
693 8170028d ths
}
694 8170028d ths
695 8170028d ths
static void cris_cc_mask(DisasContext *dc, unsigned int mask)
696 8170028d ths
{
697 8170028d ths
        uint32_t ovl;
698 8170028d ths
699 fd56059f balrog
        /* Check if we need to evaluate the condition codes due to 
700 fd56059f balrog
           CC overlaying.  */
701 8170028d ths
        ovl = (dc->cc_mask ^ mask) & ~mask;
702 8170028d ths
        if (ovl) {
703 8170028d ths
                /* TODO: optimize this case. It trigs all the time.  */
704 8170028d ths
                cris_evaluate_flags (dc);
705 8170028d ths
        }
706 8170028d ths
        dc->cc_mask = mask;
707 8170028d ths
        dc->update_cc = 1;
708 a825e703 edgar_igl
709 8170028d ths
        if (mask == 0)
710 8170028d ths
                dc->update_cc = 0;
711 a825e703 edgar_igl
        else
712 8170028d ths
                dc->flags_live = 0;
713 8170028d ths
}
714 8170028d ths
715 b41f7df0 edgar_igl
static void cris_update_cc_op(DisasContext *dc, int op, int size)
716 8170028d ths
{
717 8170028d ths
        dc->cc_op = op;
718 8170028d ths
        dc->cc_size = size;
719 b41f7df0 edgar_igl
        dc->flags_live = 0;
720 8170028d ths
}
721 8170028d ths
722 8170028d ths
/* op is the operation.
723 8170028d ths
   T0, T1 are the operands.
724 8170028d ths
   dst is the destination reg.
725 8170028d ths
*/
726 8170028d ths
static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
727 8170028d ths
{
728 8170028d ths
        int writeback = 1;
729 8170028d ths
        if (dc->update_cc) {
730 b41f7df0 edgar_igl
                cris_update_cc_op(dc, op, size);
731 a825e703 edgar_igl
                tcg_gen_mov_tl(cc_dest, cpu_T[0]);
732 3157a0a9 edgar_igl
733 3157a0a9 edgar_igl
                /* FIXME: This shouldn't be needed. But we don't pass the
734 3157a0a9 edgar_igl
                 tests without it. Investigate.  */
735 3157a0a9 edgar_igl
                t_gen_mov_env_TN(cc_x_live, tcg_const_tl(dc->flagx_live));
736 3157a0a9 edgar_igl
                t_gen_mov_env_TN(cc_x, tcg_const_tl(dc->flags_x));
737 8170028d ths
        }
738 8170028d ths
739 8170028d ths
        /* Emit the ALU insns.  */
740 8170028d ths
        switch (op)
741 8170028d ths
        {
742 8170028d ths
                case CC_OP_ADD:
743 05ba7d5f edgar_igl
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
744 8170028d ths
                        /* Extended arithmetics.  */
745 3157a0a9 edgar_igl
                        t_gen_addx_carry(cpu_T[0]);
746 8170028d ths
                        break;
747 8170028d ths
                case CC_OP_ADDC:
748 05ba7d5f edgar_igl
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
749 3157a0a9 edgar_igl
                        t_gen_add_flag(cpu_T[0], 0); /* C_FLAG.  */
750 8170028d ths
                        break;
751 8170028d ths
                case CC_OP_MCP:
752 05ba7d5f edgar_igl
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
753 3157a0a9 edgar_igl
                        t_gen_add_flag(cpu_T[0], 8); /* R_FLAG.  */
754 8170028d ths
                        break;
755 8170028d ths
                case CC_OP_SUB:
756 390efc54 pbrook
                        tcg_gen_neg_tl(cpu_T[1], cpu_T[1]);
757 05ba7d5f edgar_igl
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
758 390efc54 pbrook
                        tcg_gen_neg_tl(cpu_T[1], cpu_T[1]);
759 8170028d ths
                        /* CRIS flag evaluation needs ~src.  */
760 3157a0a9 edgar_igl
                        tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
761 8170028d ths
762 8170028d ths
                        /* Extended arithmetics.  */
763 3157a0a9 edgar_igl
                        t_gen_subx_carry(cpu_T[0]);
764 8170028d ths
                        break;
765 8170028d ths
                case CC_OP_MOVE:
766 05ba7d5f edgar_igl
                        tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
767 8170028d ths
                        break;
768 8170028d ths
                case CC_OP_OR:
769 05ba7d5f edgar_igl
                        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
770 8170028d ths
                        break;
771 8170028d ths
                case CC_OP_AND:
772 05ba7d5f edgar_igl
                        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
773 8170028d ths
                        break;
774 8170028d ths
                case CC_OP_XOR:
775 05ba7d5f edgar_igl
                        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
776 8170028d ths
                        break;
777 8170028d ths
                case CC_OP_LSL:
778 05ba7d5f edgar_igl
                        t_gen_lsl(cpu_T[0], cpu_T[0], cpu_T[1]);
779 8170028d ths
                        break;
780 8170028d ths
                case CC_OP_LSR:
781 05ba7d5f edgar_igl
                        t_gen_lsr(cpu_T[0], cpu_T[0], cpu_T[1]);
782 8170028d ths
                        break;
783 8170028d ths
                case CC_OP_ASR:
784 05ba7d5f edgar_igl
                        t_gen_asr(cpu_T[0], cpu_T[0], cpu_T[1]);
785 8170028d ths
                        break;
786 8170028d ths
                case CC_OP_NEG:
787 390efc54 pbrook
                        tcg_gen_neg_tl(cpu_T[0], cpu_T[1]);
788 8170028d ths
                        /* Extended arithmetics.  */
789 3157a0a9 edgar_igl
                        t_gen_subx_carry(cpu_T[0]);
790 8170028d ths
                        break;
791 8170028d ths
                case CC_OP_LZ:
792 d059c172 edgar_igl
                        t_gen_lz_i32(cpu_T[0], cpu_T[1]);
793 8170028d ths
                        break;
794 8170028d ths
                case CC_OP_BTST:
795 dceaf394 edgar_igl
                        t_gen_btst(cpu_T[0], cpu_T[1]);
796 8170028d ths
                        writeback = 0;
797 8170028d ths
                        break;
798 8170028d ths
                case CC_OP_MULS:
799 3157a0a9 edgar_igl
                {
800 3157a0a9 edgar_igl
                        TCGv mof;
801 3157a0a9 edgar_igl
                        mof = tcg_temp_new(TCG_TYPE_TL);
802 3157a0a9 edgar_igl
                        t_gen_muls(cpu_T[0], mof, cpu_T[0], cpu_T[1]);
803 3157a0a9 edgar_igl
                        t_gen_mov_preg_TN(PR_MOF, mof);
804 b41f7df0 edgar_igl
                        tcg_gen_discard_tl(mof);
805 3157a0a9 edgar_igl
                }
806 3157a0a9 edgar_igl
                break;
807 8170028d ths
                case CC_OP_MULU:
808 3157a0a9 edgar_igl
                {
809 3157a0a9 edgar_igl
                        TCGv mof;
810 3157a0a9 edgar_igl
                        mof = tcg_temp_new(TCG_TYPE_TL);
811 3157a0a9 edgar_igl
                        t_gen_mulu(cpu_T[0], mof, cpu_T[0], cpu_T[1]);
812 3157a0a9 edgar_igl
                        t_gen_mov_preg_TN(PR_MOF, mof);
813 b41f7df0 edgar_igl
                        tcg_gen_discard_tl(mof);
814 3157a0a9 edgar_igl
                }
815 3157a0a9 edgar_igl
                break;
816 8170028d ths
                case CC_OP_DSTEP:
817 aae6b32a edgar_igl
                        t_gen_cris_dstep(cpu_T[0], cpu_T[1]);
818 8170028d ths
                        break;
819 8170028d ths
                case CC_OP_BOUND:
820 3157a0a9 edgar_igl
                {
821 3157a0a9 edgar_igl
                        int l1;
822 3157a0a9 edgar_igl
                        l1 = gen_new_label();
823 3157a0a9 edgar_igl
                        tcg_gen_brcond_tl(TCG_COND_LEU, 
824 3157a0a9 edgar_igl
                                          cpu_T[0], cpu_T[1], l1);
825 3157a0a9 edgar_igl
                        tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
826 3157a0a9 edgar_igl
                        gen_set_label(l1);
827 3157a0a9 edgar_igl
                }
828 3157a0a9 edgar_igl
                break;
829 8170028d ths
                case CC_OP_CMP:
830 390efc54 pbrook
                        tcg_gen_neg_tl(cpu_T[1], cpu_T[1]);
831 05ba7d5f edgar_igl
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
832 05ba7d5f edgar_igl
                        /* CRIS flag evaluation needs ~src.  */
833 390efc54 pbrook
                        tcg_gen_neg_tl(cpu_T[1], cpu_T[1]);
834 8170028d ths
                        /* CRIS flag evaluation needs ~src.  */
835 3157a0a9 edgar_igl
                        tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
836 8170028d ths
837 8170028d ths
                        /* Extended arithmetics.  */
838 3157a0a9 edgar_igl
                        t_gen_subx_carry(cpu_T[0]);
839 8170028d ths
                        writeback = 0;
840 8170028d ths
                        break;
841 8170028d ths
                default:
842 8170028d ths
                        fprintf (logfile, "illegal ALU op.\n");
843 8170028d ths
                        BUG();
844 8170028d ths
                        break;
845 8170028d ths
        }
846 8170028d ths
847 8170028d ths
        if (dc->update_cc)
848 a825e703 edgar_igl
                tcg_gen_mov_tl(cc_src, cpu_T[1]);
849 8170028d ths
850 8170028d ths
        if (size == 1)
851 05ba7d5f edgar_igl
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
852 8170028d ths
        else if (size == 2)
853 05ba7d5f edgar_igl
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
854 05ba7d5f edgar_igl
855 8170028d ths
        /* Writeback.  */
856 8170028d ths
        if (writeback) {
857 8170028d ths
                if (size == 4)
858 05ba7d5f edgar_igl
                        t_gen_mov_reg_TN(rd, cpu_T[0]);
859 8170028d ths
                else {
860 05ba7d5f edgar_igl
                        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
861 05ba7d5f edgar_igl
                        t_gen_mov_TN_reg(cpu_T[0], rd);
862 8170028d ths
                        if (size == 1)
863 05ba7d5f edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~0xff);
864 8170028d ths
                        else
865 05ba7d5f edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~0xffff);
866 05ba7d5f edgar_igl
                        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
867 05ba7d5f edgar_igl
                        t_gen_mov_reg_TN(rd, cpu_T[0]);
868 05ba7d5f edgar_igl
                        tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
869 8170028d ths
                }
870 8170028d ths
        }
871 8170028d ths
        if (dc->update_cc)
872 a825e703 edgar_igl
                tcg_gen_mov_tl(cc_result, cpu_T[0]);
873 8170028d ths
874 8170028d ths
        {
875 8170028d ths
                /* TODO: Optimize this.  */
876 8170028d ths
                if (!dc->flagx_live)
877 8170028d ths
                        cris_evaluate_flags(dc);
878 8170028d ths
        }
879 8170028d ths
}
880 8170028d ths
881 8170028d ths
static int arith_cc(DisasContext *dc)
882 8170028d ths
{
883 8170028d ths
        if (dc->update_cc) {
884 8170028d ths
                switch (dc->cc_op) {
885 8170028d ths
                        case CC_OP_ADD: return 1;
886 8170028d ths
                        case CC_OP_SUB: return 1;
887 8170028d ths
                        case CC_OP_LSL: return 1;
888 8170028d ths
                        case CC_OP_LSR: return 1;
889 8170028d ths
                        case CC_OP_ASR: return 1;
890 8170028d ths
                        case CC_OP_CMP: return 1;
891 8170028d ths
                        default:
892 8170028d ths
                                return 0;
893 8170028d ths
                }
894 8170028d ths
        }
895 8170028d ths
        return 0;
896 8170028d ths
}
897 8170028d ths
898 8170028d ths
static void gen_tst_cc (DisasContext *dc, int cond)
899 8170028d ths
{
900 8170028d ths
        int arith_opt;
901 8170028d ths
902 8170028d ths
        /* TODO: optimize more condition codes.  */
903 dceaf394 edgar_igl
904 dceaf394 edgar_igl
        /*
905 dceaf394 edgar_igl
         * If the flags are live, we've gotta look into the bits of CCS.
906 dceaf394 edgar_igl
         * Otherwise, if we just did an arithmetic operation we try to
907 dceaf394 edgar_igl
         * evaluate the condition code faster.
908 dceaf394 edgar_igl
         *
909 dceaf394 edgar_igl
         * When this function is done, T0 should be non-zero if the condition
910 dceaf394 edgar_igl
         * code is true.
911 dceaf394 edgar_igl
         */
912 8170028d ths
        arith_opt = arith_cc(dc) && !dc->flags_live;
913 8170028d ths
        switch (cond) {
914 8170028d ths
                case CC_EQ:
915 dceaf394 edgar_igl
                        if (arith_opt) {
916 dceaf394 edgar_igl
                                /* If cc_result is zero, T0 should be 
917 dceaf394 edgar_igl
                                   non-zero otherwise T0 should be zero.  */
918 dceaf394 edgar_igl
                                int l1;
919 dceaf394 edgar_igl
                                l1 = gen_new_label();
920 dceaf394 edgar_igl
                                tcg_gen_movi_tl(cpu_T[0], 0);
921 dceaf394 edgar_igl
                                tcg_gen_brcond_tl(TCG_COND_NE, cc_result, 
922 dceaf394 edgar_igl
                                                  tcg_const_tl(0), l1);
923 dceaf394 edgar_igl
                                tcg_gen_movi_tl(cpu_T[0], 1);
924 dceaf394 edgar_igl
                                gen_set_label(l1);
925 dceaf394 edgar_igl
                        }
926 8170028d ths
                        else {
927 8170028d ths
                                cris_evaluate_flags(dc);
928 dceaf394 edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], 
929 dceaf394 edgar_igl
                                                cpu_PR[PR_CCS], Z_FLAG);
930 8170028d ths
                        }
931 8170028d ths
                        break;
932 8170028d ths
                case CC_NE:
933 8170028d ths
                        if (arith_opt)
934 dceaf394 edgar_igl
                                tcg_gen_mov_tl(cpu_T[0], cc_result);
935 8170028d ths
                        else {
936 8170028d ths
                                cris_evaluate_flags(dc);
937 dceaf394 edgar_igl
                                tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS],
938 dceaf394 edgar_igl
                                                Z_FLAG);
939 dceaf394 edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], Z_FLAG);
940 8170028d ths
                        }
941 8170028d ths
                        break;
942 8170028d ths
                case CC_CS:
943 8170028d ths
                        cris_evaluate_flags(dc);
944 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], C_FLAG);
945 8170028d ths
                        break;
946 8170028d ths
                case CC_CC:
947 8170028d ths
                        cris_evaluate_flags(dc);
948 dceaf394 edgar_igl
                        tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS],
949 dceaf394 edgar_igl
                                        C_FLAG);
950 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], C_FLAG);
951 8170028d ths
                        break;
952 8170028d ths
                case CC_VS:
953 8170028d ths
                        cris_evaluate_flags(dc);
954 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], V_FLAG);
955 8170028d ths
                        break;
956 8170028d ths
                case CC_VC:
957 8170028d ths
                        cris_evaluate_flags(dc);
958 dceaf394 edgar_igl
                        tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS],
959 dceaf394 edgar_igl
                                        V_FLAG);
960 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], V_FLAG);
961 8170028d ths
                        break;
962 8170028d ths
                case CC_PL:
963 8170028d ths
                        if (arith_opt)
964 dceaf394 edgar_igl
                                tcg_gen_shli_tl(cpu_T[0], cc_result, 31);
965 8170028d ths
                        else {
966 8170028d ths
                                cris_evaluate_flags(dc);
967 dceaf394 edgar_igl
                                tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS],
968 dceaf394 edgar_igl
                                                N_FLAG);
969 dceaf394 edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], N_FLAG);
970 8170028d ths
                        }
971 8170028d ths
                        break;
972 8170028d ths
                case CC_MI:
973 dceaf394 edgar_igl
                        if (arith_opt) {
974 dceaf394 edgar_igl
                                tcg_gen_shli_tl(cpu_T[0], cc_result, 31);
975 dceaf394 edgar_igl
                                tcg_gen_xori_tl(cpu_T[0], cpu_T[0], 1);
976 dceaf394 edgar_igl
                        }
977 8170028d ths
                        else {
978 8170028d ths
                                cris_evaluate_flags(dc);
979 dceaf394 edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS],
980 dceaf394 edgar_igl
                                                N_FLAG);
981 8170028d ths
                        }
982 8170028d ths
                        break;
983 8170028d ths
                case CC_LS:
984 8170028d ths
                        cris_evaluate_flags(dc);
985 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS],
986 dceaf394 edgar_igl
                                        C_FLAG | Z_FLAG);
987 8170028d ths
                        break;
988 8170028d ths
                case CC_HI:
989 8170028d ths
                        cris_evaluate_flags(dc);
990 dceaf394 edgar_igl
                        {
991 dceaf394 edgar_igl
                                TCGv tmp;
992 dceaf394 edgar_igl
993 dceaf394 edgar_igl
                                tmp = tcg_temp_new(TCG_TYPE_TL);
994 dceaf394 edgar_igl
                                tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS],
995 dceaf394 edgar_igl
                                                C_FLAG | Z_FLAG);
996 dceaf394 edgar_igl
                                /* Overlay the C flag on top of the Z.  */
997 dceaf394 edgar_igl
                                tcg_gen_shli_tl(cpu_T[0], tmp, 2);
998 dceaf394 edgar_igl
                                tcg_gen_and_tl(cpu_T[0], tmp, cpu_T[0]);
999 dceaf394 edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], Z_FLAG);
1000 dceaf394 edgar_igl
1001 dceaf394 edgar_igl
                                tcg_gen_discard_tl(tmp);
1002 dceaf394 edgar_igl
                        }
1003 8170028d ths
                        break;
1004 8170028d ths
                case CC_GE:
1005 8170028d ths
                        cris_evaluate_flags(dc);
1006 dceaf394 edgar_igl
                        /* Overlay the V flag on top of the N.  */
1007 dceaf394 edgar_igl
                        tcg_gen_shli_tl(cpu_T[0], cpu_PR[PR_CCS], 2);
1008 dceaf394 edgar_igl
                        tcg_gen_xor_tl(cpu_T[0],
1009 dceaf394 edgar_igl
                                       cpu_PR[PR_CCS], cpu_T[0]);
1010 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], N_FLAG);
1011 dceaf394 edgar_igl
                        tcg_gen_xori_tl(cpu_T[0], cpu_T[0], N_FLAG);
1012 8170028d ths
                        break;
1013 8170028d ths
                case CC_LT:
1014 8170028d ths
                        cris_evaluate_flags(dc);
1015 dceaf394 edgar_igl
                        /* Overlay the V flag on top of the N.  */
1016 dceaf394 edgar_igl
                        tcg_gen_shli_tl(cpu_T[0], cpu_PR[PR_CCS], 2);
1017 dceaf394 edgar_igl
                        tcg_gen_xor_tl(cpu_T[0],
1018 dceaf394 edgar_igl
                                       cpu_PR[PR_CCS], cpu_T[0]);
1019 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], N_FLAG);
1020 8170028d ths
                        break;
1021 8170028d ths
                case CC_GT:
1022 8170028d ths
                        cris_evaluate_flags(dc);
1023 dceaf394 edgar_igl
                        {
1024 dceaf394 edgar_igl
                                TCGv n, z;
1025 dceaf394 edgar_igl
1026 dceaf394 edgar_igl
                                n = tcg_temp_new(TCG_TYPE_TL);
1027 dceaf394 edgar_igl
                                z = tcg_temp_new(TCG_TYPE_TL);
1028 dceaf394 edgar_igl
1029 dceaf394 edgar_igl
                                /* To avoid a shift we overlay everything on
1030 dceaf394 edgar_igl
                                   the V flag.  */
1031 dceaf394 edgar_igl
                                tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1032 dceaf394 edgar_igl
                                tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1033 dceaf394 edgar_igl
                                /* invert Z.  */
1034 dceaf394 edgar_igl
                                tcg_gen_xori_tl(z, z, 2);
1035 dceaf394 edgar_igl
1036 dceaf394 edgar_igl
                                tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1037 dceaf394 edgar_igl
                                tcg_gen_xori_tl(n, n, 2);
1038 dceaf394 edgar_igl
                                tcg_gen_and_tl(cpu_T[0], z, n);
1039 dceaf394 edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 2);
1040 dceaf394 edgar_igl
1041 dceaf394 edgar_igl
                                tcg_gen_discard_tl(n);
1042 dceaf394 edgar_igl
                                tcg_gen_discard_tl(z);
1043 dceaf394 edgar_igl
                        }
1044 8170028d ths
                        break;
1045 8170028d ths
                case CC_LE:
1046 8170028d ths
                        cris_evaluate_flags(dc);
1047 dceaf394 edgar_igl
                        {
1048 dceaf394 edgar_igl
                                TCGv n, z;
1049 dceaf394 edgar_igl
1050 dceaf394 edgar_igl
                                n = tcg_temp_new(TCG_TYPE_TL);
1051 dceaf394 edgar_igl
                                z = tcg_temp_new(TCG_TYPE_TL);
1052 dceaf394 edgar_igl
1053 dceaf394 edgar_igl
                                /* To avoid a shift we overlay everything on
1054 dceaf394 edgar_igl
                                   the V flag.  */
1055 dceaf394 edgar_igl
                                tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1056 dceaf394 edgar_igl
                                tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1057 dceaf394 edgar_igl
1058 dceaf394 edgar_igl
                                tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1059 dceaf394 edgar_igl
                                tcg_gen_or_tl(cpu_T[0], z, n);
1060 dceaf394 edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 2);
1061 dceaf394 edgar_igl
1062 dceaf394 edgar_igl
                                tcg_gen_discard_tl(n);
1063 dceaf394 edgar_igl
                                tcg_gen_discard_tl(z);
1064 dceaf394 edgar_igl
                        }
1065 8170028d ths
                        break;
1066 8170028d ths
                case CC_P:
1067 8170028d ths
                        cris_evaluate_flags(dc);
1068 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], P_FLAG);
1069 8170028d ths
                        break;
1070 8170028d ths
                case CC_A:
1071 8170028d ths
                        cris_evaluate_flags(dc);
1072 17ac9754 edgar_igl
                        tcg_gen_movi_tl(cpu_T[0], 1);
1073 8170028d ths
                        break;
1074 8170028d ths
                default:
1075 8170028d ths
                        BUG();
1076 8170028d ths
                        break;
1077 8170028d ths
        };
1078 8170028d ths
}
1079 8170028d ths
1080 8170028d ths
static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond)
1081 8170028d ths
{
1082 8170028d ths
        /* This helps us re-schedule the micro-code to insns in delay-slots
1083 8170028d ths
           before the actual jump.  */
1084 8170028d ths
        dc->delayed_branch = 2;
1085 8170028d ths
        dc->delayed_pc = dc->pc + offset;
1086 8170028d ths
        dc->bcc = cond;
1087 8170028d ths
        if (cond != CC_A)
1088 8170028d ths
        {
1089 8170028d ths
                gen_tst_cc (dc, cond);
1090 dceaf394 edgar_igl
                t_gen_mov_env_TN(btaken, cpu_T[0]);
1091 8170028d ths
        }
1092 b41f7df0 edgar_igl
        tcg_gen_movi_tl(env_btarget, dc->delayed_pc);
1093 8170028d ths
}
1094 8170028d ths
1095 b41f7df0 edgar_igl
1096 8170028d ths
/* Dynamic jumps, when the dest is in a live reg for example.  */
1097 8170028d ths
void cris_prepare_dyn_jmp (DisasContext *dc)
1098 8170028d ths
{
1099 8170028d ths
        /* This helps us re-schedule the micro-code to insns in delay-slots
1100 8170028d ths
           before the actual jump.  */
1101 8170028d ths
        dc->delayed_branch = 2;
1102 8170028d ths
        dc->dyn_jmp = 1;
1103 8170028d ths
        dc->bcc = CC_A;
1104 8170028d ths
}
1105 8170028d ths
1106 8170028d ths
void cris_prepare_jmp (DisasContext *dc, uint32_t dst)
1107 8170028d ths
{
1108 8170028d ths
        /* This helps us re-schedule the micro-code to insns in delay-slots
1109 8170028d ths
           before the actual jump.  */
1110 8170028d ths
        dc->delayed_branch = 2;
1111 8170028d ths
        dc->delayed_pc = dst;
1112 8170028d ths
        dc->dyn_jmp = 0;
1113 8170028d ths
        dc->bcc = CC_A;
1114 8170028d ths
}
1115 8170028d ths
1116 b41f7df0 edgar_igl
void gen_load(DisasContext *dc, TCGv dst, TCGv addr, 
1117 b41f7df0 edgar_igl
              unsigned int size, int sign)
1118 8170028d ths
{
1119 b41f7df0 edgar_igl
        int mem_index = cpu_mmu_index(dc->env);
1120 b41f7df0 edgar_igl
1121 8170028d ths
        if (size == 1) {
1122 8170028d ths
                if (sign)
1123 b41f7df0 edgar_igl
                        tcg_gen_qemu_ld8s(dst, addr, mem_index);
1124 8170028d ths
                else
1125 b41f7df0 edgar_igl
                        tcg_gen_qemu_ld8u(dst, addr, mem_index);
1126 8170028d ths
        }
1127 8170028d ths
        else if (size == 2) {
1128 8170028d ths
                if (sign)
1129 b41f7df0 edgar_igl
                        tcg_gen_qemu_ld16s(dst, addr, mem_index);
1130 8170028d ths
                else
1131 b41f7df0 edgar_igl
                        tcg_gen_qemu_ld16u(dst, addr, mem_index);
1132 8170028d ths
        }
1133 8170028d ths
        else {
1134 b41f7df0 edgar_igl
                tcg_gen_qemu_ld32s(dst, addr, mem_index);
1135 8170028d ths
        }
1136 8170028d ths
}
1137 8170028d ths
1138 17ac9754 edgar_igl
void gen_store (DisasContext *dc, TCGv addr, TCGv val,
1139 17ac9754 edgar_igl
                unsigned int size)
1140 8170028d ths
{
1141 b41f7df0 edgar_igl
        int mem_index = cpu_mmu_index(dc->env);
1142 b41f7df0 edgar_igl
1143 b41f7df0 edgar_igl
        cris_evaluate_flags(dc);
1144 b41f7df0 edgar_igl
1145 8170028d ths
        /* Remember, operands are flipped. CRIS has reversed order.  */
1146 b41f7df0 edgar_igl
        if (size == 1)
1147 17ac9754 edgar_igl
                tcg_gen_qemu_st8(val, addr, mem_index);
1148 b41f7df0 edgar_igl
        else if (size == 2)
1149 17ac9754 edgar_igl
                tcg_gen_qemu_st16(val, addr, mem_index);
1150 8170028d ths
        else
1151 17ac9754 edgar_igl
                tcg_gen_qemu_st32(val, addr, mem_index);
1152 8170028d ths
}
1153 8170028d ths
1154 05ba7d5f edgar_igl
static inline void t_gen_sext(TCGv d, TCGv s, int size)
1155 8170028d ths
{
1156 8170028d ths
        if (size == 1)
1157 05ba7d5f edgar_igl
                tcg_gen_ext8s_i32(d, s);
1158 8170028d ths
        else if (size == 2)
1159 05ba7d5f edgar_igl
                tcg_gen_ext16s_i32(d, s);
1160 50cfa95c edgar_igl
        else
1161 50cfa95c edgar_igl
                tcg_gen_mov_tl(d, s);
1162 8170028d ths
}
1163 8170028d ths
1164 05ba7d5f edgar_igl
static inline void t_gen_zext(TCGv d, TCGv s, int size)
1165 8170028d ths
{
1166 8170028d ths
        if (size == 1)
1167 86831435 pbrook
                tcg_gen_ext8u_i32(d, s);
1168 8170028d ths
        else if (size == 2)
1169 86831435 pbrook
                tcg_gen_ext16u_i32(d, s);
1170 50cfa95c edgar_igl
        else
1171 50cfa95c edgar_igl
                tcg_gen_mov_tl(d, s);
1172 8170028d ths
}
1173 8170028d ths
1174 8170028d ths
#if DISAS_CRIS
1175 8170028d ths
static char memsize_char(int size)
1176 8170028d ths
{
1177 8170028d ths
        switch (size)
1178 8170028d ths
        {
1179 8170028d ths
                case 1: return 'b';  break;
1180 8170028d ths
                case 2: return 'w';  break;
1181 8170028d ths
                case 4: return 'd';  break;
1182 8170028d ths
                default:
1183 8170028d ths
                        return 'x';
1184 8170028d ths
                        break;
1185 8170028d ths
        }
1186 8170028d ths
}
1187 8170028d ths
#endif
1188 8170028d ths
1189 8170028d ths
static unsigned int memsize_z(DisasContext *dc)
1190 8170028d ths
{
1191 8170028d ths
        return dc->zsize + 1;
1192 8170028d ths
}
1193 8170028d ths
1194 8170028d ths
static unsigned int memsize_zz(DisasContext *dc)
1195 8170028d ths
{
1196 8170028d ths
        switch (dc->zzsize)
1197 8170028d ths
        {
1198 8170028d ths
                case 0: return 1;
1199 8170028d ths
                case 1: return 2;
1200 8170028d ths
                default:
1201 8170028d ths
                        return 4;
1202 8170028d ths
        }
1203 8170028d ths
}
1204 8170028d ths
1205 c7d05695 edgar_igl
static inline void do_postinc (DisasContext *dc, int size)
1206 8170028d ths
{
1207 c7d05695 edgar_igl
        if (dc->postinc)
1208 c7d05695 edgar_igl
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
1209 8170028d ths
}
1210 8170028d ths
1211 8170028d ths
1212 8170028d ths
static void dec_prep_move_r(DisasContext *dc, int rs, int rd,
1213 8170028d ths
                            int size, int s_ext)
1214 8170028d ths
{
1215 8170028d ths
        if (s_ext)
1216 50cfa95c edgar_igl
                t_gen_sext(cpu_T[1], cpu_R[rs], size);
1217 8170028d ths
        else
1218 50cfa95c edgar_igl
                t_gen_zext(cpu_T[1], cpu_R[rs], size);
1219 8170028d ths
}
1220 8170028d ths
1221 8170028d ths
/* Prepare T0 and T1 for a register alu operation.
1222 8170028d ths
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1223 8170028d ths
   needed.  */
1224 8170028d ths
static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
1225 8170028d ths
                          int size, int s_ext)
1226 8170028d ths
{
1227 8170028d ths
        dec_prep_move_r(dc, rs, rd, size, s_ext);
1228 8170028d ths
1229 8170028d ths
        if (s_ext)
1230 50cfa95c edgar_igl
                t_gen_sext(cpu_T[0], cpu_R[rd], size);
1231 8170028d ths
        else
1232 50cfa95c edgar_igl
                t_gen_zext(cpu_T[0], cpu_R[rd], size);
1233 8170028d ths
}
1234 8170028d ths
1235 8170028d ths
/* Prepare T0 and T1 for a memory + alu operation.
1236 8170028d ths
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1237 8170028d ths
   needed.  */
1238 8170028d ths
static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
1239 8170028d ths
{
1240 8170028d ths
        unsigned int rs, rd;
1241 8170028d ths
        uint32_t imm;
1242 8170028d ths
        int is_imm;
1243 8170028d ths
        int insn_len = 2;
1244 8170028d ths
1245 8170028d ths
        rs = dc->op1;
1246 8170028d ths
        rd = dc->op2;
1247 8170028d ths
        is_imm = rs == 15 && dc->postinc;
1248 8170028d ths
1249 8170028d ths
        /* Load [$rs] onto T1.  */
1250 8170028d ths
        if (is_imm) {
1251 8170028d ths
                insn_len = 2 + memsize;
1252 8170028d ths
                if (memsize == 1)
1253 8170028d ths
                        insn_len++;
1254 8170028d ths
1255 8170028d ths
                if (memsize != 4) {
1256 8170028d ths
                        if (s_ext) {
1257 17ac9754 edgar_igl
                                if (memsize == 1)
1258 17ac9754 edgar_igl
                                        imm = ldsb_code(dc->pc + 2);
1259 17ac9754 edgar_igl
                                else
1260 17ac9754 edgar_igl
                                        imm = ldsw_code(dc->pc + 2);
1261 8170028d ths
                        } else {
1262 8170028d ths
                                if (memsize == 1)
1263 17ac9754 edgar_igl
                                        imm = ldub_code(dc->pc + 2);
1264 8170028d ths
                                else
1265 17ac9754 edgar_igl
                                        imm = lduw_code(dc->pc + 2);
1266 8170028d ths
                        }
1267 17ac9754 edgar_igl
                } else
1268 17ac9754 edgar_igl
                        imm = ldl_code(dc->pc + 2);
1269 17ac9754 edgar_igl
                        
1270 8170028d ths
                DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n",
1271 8170028d ths
                            imm, rd, s_ext, memsize));
1272 05ba7d5f edgar_igl
                tcg_gen_movi_tl(cpu_T[1], imm);
1273 8170028d ths
                dc->postinc = 0;
1274 8170028d ths
        } else {
1275 b41f7df0 edgar_igl
                gen_load(dc, cpu_T[1], cpu_R[rs], memsize, 0);
1276 8170028d ths
                if (s_ext)
1277 05ba7d5f edgar_igl
                        t_gen_sext(cpu_T[1], cpu_T[1], memsize);
1278 8170028d ths
                else
1279 05ba7d5f edgar_igl
                        t_gen_zext(cpu_T[1], cpu_T[1], memsize);
1280 8170028d ths
        }
1281 8170028d ths
1282 8170028d ths
        /* put dest in T0.  */
1283 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], rd);
1284 8170028d ths
        return insn_len;
1285 8170028d ths
}
1286 8170028d ths
1287 8170028d ths
#if DISAS_CRIS
1288 8170028d ths
static const char *cc_name(int cc)
1289 8170028d ths
{
1290 8170028d ths
        static char *cc_names[16] = {
1291 8170028d ths
                "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1292 8170028d ths
                "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1293 8170028d ths
        };
1294 8170028d ths
        assert(cc < 16);
1295 8170028d ths
        return cc_names[cc];
1296 8170028d ths
}
1297 8170028d ths
#endif
1298 8170028d ths
1299 b41f7df0 edgar_igl
/* Start of insn decoders.  */
1300 b41f7df0 edgar_igl
1301 8170028d ths
static unsigned int dec_bccq(DisasContext *dc)
1302 8170028d ths
{
1303 8170028d ths
        int32_t offset;
1304 8170028d ths
        int sign;
1305 8170028d ths
        uint32_t cond = dc->op2;
1306 8170028d ths
        int tmp;
1307 8170028d ths
1308 8170028d ths
        offset = EXTRACT_FIELD (dc->ir, 1, 7);
1309 8170028d ths
        sign = EXTRACT_FIELD(dc->ir, 0, 0);
1310 8170028d ths
1311 8170028d ths
        offset *= 2;
1312 8170028d ths
        offset |= sign << 8;
1313 8170028d ths
        tmp = offset;
1314 8170028d ths
        offset = sign_extend(offset, 8);
1315 8170028d ths
1316 8170028d ths
        /* op2 holds the condition-code.  */
1317 8170028d ths
        cris_cc_mask(dc, 0);
1318 8170028d ths
        cris_prepare_cc_branch (dc, offset, cond);
1319 8170028d ths
        return 2;
1320 8170028d ths
}
1321 8170028d ths
static unsigned int dec_addoq(DisasContext *dc)
1322 8170028d ths
{
1323 b41f7df0 edgar_igl
        int32_t imm;
1324 8170028d ths
1325 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1326 8170028d ths
        imm = sign_extend(dc->op1, 7);
1327 8170028d ths
1328 8170028d ths
        DIS(fprintf (logfile, "addoq %d, $r%u\n", imm, dc->op2));
1329 8170028d ths
        cris_cc_mask(dc, 0);
1330 8170028d ths
        /* Fetch register operand,  */
1331 b41f7df0 edgar_igl
        tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
1332 8170028d ths
        return 2;
1333 8170028d ths
}
1334 8170028d ths
static unsigned int dec_addq(DisasContext *dc)
1335 8170028d ths
{
1336 8170028d ths
        DIS(fprintf (logfile, "addq %u, $r%u\n", dc->op1, dc->op2));
1337 8170028d ths
1338 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1339 8170028d ths
1340 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1341 8170028d ths
        /* Fetch register operand,  */
1342 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1343 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[1], dc->op1);
1344 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1345 8170028d ths
        return 2;
1346 8170028d ths
}
1347 8170028d ths
static unsigned int dec_moveq(DisasContext *dc)
1348 8170028d ths
{
1349 8170028d ths
        uint32_t imm;
1350 8170028d ths
1351 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1352 8170028d ths
        imm = sign_extend(dc->op1, 5);
1353 8170028d ths
        DIS(fprintf (logfile, "moveq %d, $r%u\n", imm, dc->op2));
1354 8170028d ths
1355 3157a0a9 edgar_igl
        t_gen_mov_reg_TN(dc->op2, tcg_const_tl(imm));
1356 8170028d ths
        return 2;
1357 8170028d ths
}
1358 8170028d ths
static unsigned int dec_subq(DisasContext *dc)
1359 8170028d ths
{
1360 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1361 8170028d ths
1362 8170028d ths
        DIS(fprintf (logfile, "subq %u, $r%u\n", dc->op1, dc->op2));
1363 8170028d ths
1364 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1365 8170028d ths
        /* Fetch register operand,  */
1366 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1367 dceaf394 edgar_igl
        tcg_gen_movi_tl(cpu_T[1], dc->op1);
1368 8170028d ths
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1369 8170028d ths
        return 2;
1370 8170028d ths
}
1371 8170028d ths
static unsigned int dec_cmpq(DisasContext *dc)
1372 8170028d ths
{
1373 8170028d ths
        uint32_t imm;
1374 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1375 8170028d ths
        imm = sign_extend(dc->op1, 5);
1376 8170028d ths
1377 8170028d ths
        DIS(fprintf (logfile, "cmpq %d, $r%d\n", imm, dc->op2));
1378 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1379 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1380 dceaf394 edgar_igl
        tcg_gen_movi_tl(cpu_T[1], imm);
1381 8170028d ths
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
1382 8170028d ths
        return 2;
1383 8170028d ths
}
1384 8170028d ths
static unsigned int dec_andq(DisasContext *dc)
1385 8170028d ths
{
1386 8170028d ths
        uint32_t imm;
1387 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1388 8170028d ths
        imm = sign_extend(dc->op1, 5);
1389 8170028d ths
1390 8170028d ths
        DIS(fprintf (logfile, "andq %d, $r%d\n", imm, dc->op2));
1391 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1392 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1393 dceaf394 edgar_igl
        tcg_gen_movi_tl(cpu_T[1], imm);
1394 8170028d ths
        crisv32_alu_op(dc, CC_OP_AND, dc->op2, 4);
1395 8170028d ths
        return 2;
1396 8170028d ths
}
1397 8170028d ths
static unsigned int dec_orq(DisasContext *dc)
1398 8170028d ths
{
1399 8170028d ths
        uint32_t imm;
1400 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1401 8170028d ths
        imm = sign_extend(dc->op1, 5);
1402 8170028d ths
        DIS(fprintf (logfile, "orq %d, $r%d\n", imm, dc->op2));
1403 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1404 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1405 dceaf394 edgar_igl
        tcg_gen_movi_tl(cpu_T[1], imm);
1406 8170028d ths
        crisv32_alu_op(dc, CC_OP_OR, dc->op2, 4);
1407 8170028d ths
        return 2;
1408 8170028d ths
}
1409 8170028d ths
static unsigned int dec_btstq(DisasContext *dc)
1410 8170028d ths
{
1411 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1412 8170028d ths
        DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2));
1413 17ac9754 edgar_igl
1414 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1415 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1416 dceaf394 edgar_igl
        tcg_gen_movi_tl(cpu_T[1], dc->op1);
1417 8170028d ths
        crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
1418 8170028d ths
1419 b41f7df0 edgar_igl
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1420 3157a0a9 edgar_igl
        t_gen_mov_preg_TN(PR_CCS, cpu_T[0]);
1421 8170028d ths
        dc->flags_live = 1;
1422 8170028d ths
        return 2;
1423 8170028d ths
}
1424 8170028d ths
static unsigned int dec_asrq(DisasContext *dc)
1425 8170028d ths
{
1426 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1427 8170028d ths
        DIS(fprintf (logfile, "asrq %u, $r%d\n", dc->op1, dc->op2));
1428 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1429 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1430 dceaf394 edgar_igl
        tcg_gen_movi_tl(cpu_T[1], dc->op1);
1431 8170028d ths
        crisv32_alu_op(dc, CC_OP_ASR, dc->op2, 4);
1432 8170028d ths
        return 2;
1433 8170028d ths
}
1434 8170028d ths
static unsigned int dec_lslq(DisasContext *dc)
1435 8170028d ths
{
1436 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1437 8170028d ths
        DIS(fprintf (logfile, "lslq %u, $r%d\n", dc->op1, dc->op2));
1438 8170028d ths
1439 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1440 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1441 dceaf394 edgar_igl
        tcg_gen_movi_tl(cpu_T[1], dc->op1);
1442 8170028d ths
        crisv32_alu_op(dc, CC_OP_LSL, dc->op2, 4);
1443 8170028d ths
        return 2;
1444 8170028d ths
}
1445 8170028d ths
static unsigned int dec_lsrq(DisasContext *dc)
1446 8170028d ths
{
1447 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1448 8170028d ths
        DIS(fprintf (logfile, "lsrq %u, $r%d\n", dc->op1, dc->op2));
1449 8170028d ths
1450 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1451 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1452 dceaf394 edgar_igl
        tcg_gen_movi_tl(cpu_T[1], dc->op1);
1453 8170028d ths
        crisv32_alu_op(dc, CC_OP_LSR, dc->op2, 4);
1454 8170028d ths
        return 2;
1455 8170028d ths
}
1456 8170028d ths
1457 8170028d ths
static unsigned int dec_move_r(DisasContext *dc)
1458 8170028d ths
{
1459 8170028d ths
        int size = memsize_zz(dc);
1460 8170028d ths
1461 8170028d ths
        DIS(fprintf (logfile, "move.%c $r%u, $r%u\n",
1462 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1463 8170028d ths
1464 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1465 8170028d ths
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
1466 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, size);
1467 8170028d ths
        return 2;
1468 8170028d ths
}
1469 8170028d ths
1470 8170028d ths
static unsigned int dec_scc_r(DisasContext *dc)
1471 8170028d ths
{
1472 8170028d ths
        int cond = dc->op2;
1473 8170028d ths
1474 8170028d ths
        DIS(fprintf (logfile, "s%s $r%u\n",
1475 8170028d ths
                    cc_name(cond), dc->op1));
1476 8170028d ths
1477 8170028d ths
        if (cond != CC_A)
1478 8170028d ths
        {
1479 dceaf394 edgar_igl
                int l1;
1480 dceaf394 edgar_igl
1481 8170028d ths
                gen_tst_cc (dc, cond);
1482 dceaf394 edgar_igl
1483 dceaf394 edgar_igl
                l1 = gen_new_label();
1484 dceaf394 edgar_igl
                tcg_gen_movi_tl(cpu_R[dc->op1], 0);
1485 dceaf394 edgar_igl
                tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[0], tcg_const_tl(0), l1);
1486 dceaf394 edgar_igl
                tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1487 dceaf394 edgar_igl
                gen_set_label(l1);
1488 8170028d ths
        }
1489 8170028d ths
        else
1490 dceaf394 edgar_igl
                tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1491 8170028d ths
1492 8170028d ths
        cris_cc_mask(dc, 0);
1493 8170028d ths
        return 2;
1494 8170028d ths
}
1495 8170028d ths
1496 8170028d ths
static unsigned int dec_and_r(DisasContext *dc)
1497 8170028d ths
{
1498 8170028d ths
        int size = memsize_zz(dc);
1499 8170028d ths
1500 8170028d ths
        DIS(fprintf (logfile, "and.%c $r%u, $r%u\n",
1501 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1502 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1503 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1504 8170028d ths
        crisv32_alu_op(dc, CC_OP_AND, dc->op2, size);
1505 8170028d ths
        return 2;
1506 8170028d ths
}
1507 8170028d ths
1508 8170028d ths
static unsigned int dec_lz_r(DisasContext *dc)
1509 8170028d ths
{
1510 8170028d ths
        DIS(fprintf (logfile, "lz $r%u, $r%u\n",
1511 8170028d ths
                    dc->op1, dc->op2));
1512 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1513 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1514 8170028d ths
        crisv32_alu_op(dc, CC_OP_LZ, dc->op2, 4);
1515 8170028d ths
        return 2;
1516 8170028d ths
}
1517 8170028d ths
1518 8170028d ths
static unsigned int dec_lsl_r(DisasContext *dc)
1519 8170028d ths
{
1520 8170028d ths
        int size = memsize_zz(dc);
1521 8170028d ths
1522 8170028d ths
        DIS(fprintf (logfile, "lsl.%c $r%u, $r%u\n",
1523 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1524 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1525 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1526 05ba7d5f edgar_igl
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
1527 8170028d ths
        crisv32_alu_op(dc, CC_OP_LSL, dc->op2, size);
1528 8170028d ths
        return 2;
1529 8170028d ths
}
1530 8170028d ths
1531 8170028d ths
static unsigned int dec_lsr_r(DisasContext *dc)
1532 8170028d ths
{
1533 8170028d ths
        int size = memsize_zz(dc);
1534 8170028d ths
1535 8170028d ths
        DIS(fprintf (logfile, "lsr.%c $r%u, $r%u\n",
1536 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1537 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1538 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1539 05ba7d5f edgar_igl
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
1540 8170028d ths
        crisv32_alu_op(dc, CC_OP_LSR, dc->op2, size);
1541 8170028d ths
        return 2;
1542 8170028d ths
}
1543 8170028d ths
1544 8170028d ths
static unsigned int dec_asr_r(DisasContext *dc)
1545 8170028d ths
{
1546 8170028d ths
        int size = memsize_zz(dc);
1547 8170028d ths
1548 8170028d ths
        DIS(fprintf (logfile, "asr.%c $r%u, $r%u\n",
1549 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1550 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1551 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
1552 05ba7d5f edgar_igl
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
1553 8170028d ths
        crisv32_alu_op(dc, CC_OP_ASR, dc->op2, size);
1554 8170028d ths
        return 2;
1555 8170028d ths
}
1556 8170028d ths
1557 8170028d ths
static unsigned int dec_muls_r(DisasContext *dc)
1558 8170028d ths
{
1559 8170028d ths
        int size = memsize_zz(dc);
1560 8170028d ths
1561 8170028d ths
        DIS(fprintf (logfile, "muls.%c $r%u, $r%u\n",
1562 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1563 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZV);
1564 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
1565 05ba7d5f edgar_igl
        t_gen_sext(cpu_T[0], cpu_T[0], size);
1566 8170028d ths
        crisv32_alu_op(dc, CC_OP_MULS, dc->op2, 4);
1567 8170028d ths
        return 2;
1568 8170028d ths
}
1569 8170028d ths
1570 8170028d ths
static unsigned int dec_mulu_r(DisasContext *dc)
1571 8170028d ths
{
1572 8170028d ths
        int size = memsize_zz(dc);
1573 8170028d ths
1574 8170028d ths
        DIS(fprintf (logfile, "mulu.%c $r%u, $r%u\n",
1575 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1576 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZV);
1577 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1578 05ba7d5f edgar_igl
        t_gen_zext(cpu_T[0], cpu_T[0], size);
1579 8170028d ths
        crisv32_alu_op(dc, CC_OP_MULU, dc->op2, 4);
1580 8170028d ths
        return 2;
1581 8170028d ths
}
1582 8170028d ths
1583 8170028d ths
1584 8170028d ths
static unsigned int dec_dstep_r(DisasContext *dc)
1585 8170028d ths
{
1586 8170028d ths
        DIS(fprintf (logfile, "dstep $r%u, $r%u\n", dc->op1, dc->op2));
1587 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1588 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1589 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1590 8170028d ths
        crisv32_alu_op(dc, CC_OP_DSTEP, dc->op2, 4);
1591 8170028d ths
        return 2;
1592 8170028d ths
}
1593 8170028d ths
1594 8170028d ths
static unsigned int dec_xor_r(DisasContext *dc)
1595 8170028d ths
{
1596 8170028d ths
        int size = memsize_zz(dc);
1597 8170028d ths
        DIS(fprintf (logfile, "xor.%c $r%u, $r%u\n",
1598 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1599 8170028d ths
        BUG_ON(size != 4); /* xor is dword.  */
1600 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1601 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1602 8170028d ths
        crisv32_alu_op(dc, CC_OP_XOR, dc->op2, 4);
1603 8170028d ths
        return 2;
1604 8170028d ths
}
1605 8170028d ths
1606 8170028d ths
static unsigned int dec_bound_r(DisasContext *dc)
1607 8170028d ths
{
1608 8170028d ths
        int size = memsize_zz(dc);
1609 8170028d ths
        DIS(fprintf (logfile, "bound.%c $r%u, $r%u\n",
1610 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1611 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1612 8170028d ths
        /* TODO: needs optmimization.  */
1613 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1614 8170028d ths
        /* rd should be 4.  */
1615 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1616 8170028d ths
        crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
1617 8170028d ths
        return 2;
1618 8170028d ths
}
1619 8170028d ths
1620 8170028d ths
static unsigned int dec_cmp_r(DisasContext *dc)
1621 8170028d ths
{
1622 8170028d ths
        int size = memsize_zz(dc);
1623 8170028d ths
        DIS(fprintf (logfile, "cmp.%c $r%u, $r%u\n",
1624 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1625 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1626 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1627 8170028d ths
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, size);
1628 8170028d ths
        return 2;
1629 8170028d ths
}
1630 8170028d ths
1631 8170028d ths
static unsigned int dec_abs_r(DisasContext *dc)
1632 8170028d ths
{
1633 3157a0a9 edgar_igl
        int l1;
1634 3157a0a9 edgar_igl
1635 8170028d ths
        DIS(fprintf (logfile, "abs $r%u, $r%u\n",
1636 8170028d ths
                    dc->op1, dc->op2));
1637 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1638 8170028d ths
        dec_prep_move_r(dc, dc->op1, dc->op2, 4, 0);
1639 3157a0a9 edgar_igl
1640 3157a0a9 edgar_igl
        /* TODO: consider a branch free approach.  */
1641 3157a0a9 edgar_igl
        l1 = gen_new_label();
1642 3157a0a9 edgar_igl
        tcg_gen_brcond_tl(TCG_COND_GE, cpu_T[1], tcg_const_tl(0), l1);
1643 390efc54 pbrook
        tcg_gen_neg_tl(cpu_T[1], cpu_T[1]);
1644 3157a0a9 edgar_igl
        gen_set_label(l1);
1645 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1646 8170028d ths
        return 2;
1647 8170028d ths
}
1648 8170028d ths
1649 8170028d ths
static unsigned int dec_add_r(DisasContext *dc)
1650 8170028d ths
{
1651 8170028d ths
        int size = memsize_zz(dc);
1652 8170028d ths
        DIS(fprintf (logfile, "add.%c $r%u, $r%u\n",
1653 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1654 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1655 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1656 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, size);
1657 8170028d ths
        return 2;
1658 8170028d ths
}
1659 8170028d ths
1660 8170028d ths
static unsigned int dec_addc_r(DisasContext *dc)
1661 8170028d ths
{
1662 8170028d ths
        DIS(fprintf (logfile, "addc $r%u, $r%u\n",
1663 8170028d ths
                    dc->op1, dc->op2));
1664 8170028d ths
        cris_evaluate_flags(dc);
1665 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1666 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1667 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
1668 8170028d ths
        return 2;
1669 8170028d ths
}
1670 8170028d ths
1671 8170028d ths
static unsigned int dec_mcp_r(DisasContext *dc)
1672 8170028d ths
{
1673 8170028d ths
        DIS(fprintf (logfile, "mcp $p%u, $r%u\n",
1674 8170028d ths
                     dc->op2, dc->op1));
1675 8170028d ths
        cris_evaluate_flags(dc);
1676 8170028d ths
        cris_cc_mask(dc, CC_MASK_RNZV);
1677 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1678 05ba7d5f edgar_igl
        t_gen_mov_TN_preg(cpu_T[1], dc->op2);
1679 8170028d ths
        crisv32_alu_op(dc, CC_OP_MCP, dc->op1, 4);
1680 8170028d ths
        return 2;
1681 8170028d ths
}
1682 8170028d ths
1683 8170028d ths
#if DISAS_CRIS
1684 8170028d ths
static char * swapmode_name(int mode, char *modename) {
1685 8170028d ths
        int i = 0;
1686 8170028d ths
        if (mode & 8)
1687 8170028d ths
                modename[i++] = 'n';
1688 8170028d ths
        if (mode & 4)
1689 8170028d ths
                modename[i++] = 'w';
1690 8170028d ths
        if (mode & 2)
1691 8170028d ths
                modename[i++] = 'b';
1692 8170028d ths
        if (mode & 1)
1693 8170028d ths
                modename[i++] = 'r';
1694 8170028d ths
        modename[i++] = 0;
1695 8170028d ths
        return modename;
1696 8170028d ths
}
1697 8170028d ths
#endif
1698 8170028d ths
1699 8170028d ths
static unsigned int dec_swap_r(DisasContext *dc)
1700 8170028d ths
{
1701 8170028d ths
        DIS(char modename[4]);
1702 8170028d ths
        DIS(fprintf (logfile, "swap%s $r%u\n",
1703 8170028d ths
                     swapmode_name(dc->op2, modename), dc->op1));
1704 8170028d ths
1705 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1706 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1707 8170028d ths
        if (dc->op2 & 8)
1708 3157a0a9 edgar_igl
                tcg_gen_xori_tl(cpu_T[0], cpu_T[0], -1);
1709 8170028d ths
        if (dc->op2 & 4)
1710 3157a0a9 edgar_igl
                t_gen_swapw(cpu_T[0], cpu_T[0]);
1711 8170028d ths
        if (dc->op2 & 2)
1712 3157a0a9 edgar_igl
                t_gen_swapb(cpu_T[0], cpu_T[0]);
1713 8170028d ths
        if (dc->op2 & 1)
1714 3157a0a9 edgar_igl
                t_gen_swapr(cpu_T[0], cpu_T[0]);
1715 3157a0a9 edgar_igl
        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1716 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1717 8170028d ths
        return 2;
1718 8170028d ths
}
1719 8170028d ths
1720 8170028d ths
static unsigned int dec_or_r(DisasContext *dc)
1721 8170028d ths
{
1722 8170028d ths
        int size = memsize_zz(dc);
1723 8170028d ths
        DIS(fprintf (logfile, "or.%c $r%u, $r%u\n",
1724 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1725 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1726 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1727 8170028d ths
        crisv32_alu_op(dc, CC_OP_OR, dc->op2, size);
1728 8170028d ths
        return 2;
1729 8170028d ths
}
1730 8170028d ths
1731 8170028d ths
static unsigned int dec_addi_r(DisasContext *dc)
1732 8170028d ths
{
1733 8170028d ths
        DIS(fprintf (logfile, "addi.%c $r%u, $r%u\n",
1734 8170028d ths
                    memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1735 8170028d ths
        cris_cc_mask(dc, 0);
1736 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1737 3157a0a9 edgar_igl
        t_gen_lsl(cpu_T[0], cpu_T[0], tcg_const_tl(dc->zzsize));
1738 05ba7d5f edgar_igl
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1739 05ba7d5f edgar_igl
        t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
1740 8170028d ths
        return 2;
1741 8170028d ths
}
1742 8170028d ths
1743 8170028d ths
static unsigned int dec_addi_acr(DisasContext *dc)
1744 8170028d ths
{
1745 8170028d ths
        DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n",
1746 b41f7df0 edgar_igl
                  memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1747 8170028d ths
        cris_cc_mask(dc, 0);
1748 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1749 3157a0a9 edgar_igl
        t_gen_lsl(cpu_T[0], cpu_T[0], tcg_const_tl(dc->zzsize));
1750 b41f7df0 edgar_igl
        
1751 05ba7d5f edgar_igl
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1752 05ba7d5f edgar_igl
        t_gen_mov_reg_TN(R_ACR, cpu_T[0]);
1753 8170028d ths
        return 2;
1754 8170028d ths
}
1755 8170028d ths
1756 8170028d ths
static unsigned int dec_neg_r(DisasContext *dc)
1757 8170028d ths
{
1758 8170028d ths
        int size = memsize_zz(dc);
1759 8170028d ths
        DIS(fprintf (logfile, "neg.%c $r%u, $r%u\n",
1760 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1761 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1762 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1763 8170028d ths
        crisv32_alu_op(dc, CC_OP_NEG, dc->op2, size);
1764 8170028d ths
        return 2;
1765 8170028d ths
}
1766 8170028d ths
1767 8170028d ths
static unsigned int dec_btst_r(DisasContext *dc)
1768 8170028d ths
{
1769 8170028d ths
        DIS(fprintf (logfile, "btst $r%u, $r%u\n",
1770 8170028d ths
                    dc->op1, dc->op2));
1771 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1772 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1773 8170028d ths
        crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
1774 8170028d ths
1775 b41f7df0 edgar_igl
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1776 3157a0a9 edgar_igl
        t_gen_mov_preg_TN(PR_CCS, cpu_T[0]);
1777 8170028d ths
        dc->flags_live = 1;
1778 8170028d ths
        return 2;
1779 8170028d ths
}
1780 8170028d ths
1781 8170028d ths
static unsigned int dec_sub_r(DisasContext *dc)
1782 8170028d ths
{
1783 8170028d ths
        int size = memsize_zz(dc);
1784 8170028d ths
        DIS(fprintf (logfile, "sub.%c $r%u, $r%u\n",
1785 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1786 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1787 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1788 8170028d ths
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, size);
1789 8170028d ths
        return 2;
1790 8170028d ths
}
1791 8170028d ths
1792 8170028d ths
/* Zero extension. From size to dword.  */
1793 8170028d ths
static unsigned int dec_movu_r(DisasContext *dc)
1794 8170028d ths
{
1795 8170028d ths
        int size = memsize_z(dc);
1796 8170028d ths
        DIS(fprintf (logfile, "movu.%c $r%u, $r%u\n",
1797 8170028d ths
                    memsize_char(size),
1798 8170028d ths
                    dc->op1, dc->op2));
1799 8170028d ths
1800 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1801 8170028d ths
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
1802 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1803 8170028d ths
        return 2;
1804 8170028d ths
}
1805 8170028d ths
1806 8170028d ths
/* Sign extension. From size to dword.  */
1807 8170028d ths
static unsigned int dec_movs_r(DisasContext *dc)
1808 8170028d ths
{
1809 8170028d ths
        int size = memsize_z(dc);
1810 8170028d ths
        DIS(fprintf (logfile, "movs.%c $r%u, $r%u\n",
1811 8170028d ths
                    memsize_char(size),
1812 8170028d ths
                    dc->op1, dc->op2));
1813 8170028d ths
1814 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1815 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1816 8170028d ths
        /* Size can only be qi or hi.  */
1817 05ba7d5f edgar_igl
        t_gen_sext(cpu_T[1], cpu_T[0], size);
1818 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1819 8170028d ths
        return 2;
1820 8170028d ths
}
1821 8170028d ths
1822 8170028d ths
/* zero extension. From size to dword.  */
1823 8170028d ths
static unsigned int dec_addu_r(DisasContext *dc)
1824 8170028d ths
{
1825 8170028d ths
        int size = memsize_z(dc);
1826 8170028d ths
        DIS(fprintf (logfile, "addu.%c $r%u, $r%u\n",
1827 8170028d ths
                    memsize_char(size),
1828 8170028d ths
                    dc->op1, dc->op2));
1829 8170028d ths
1830 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1831 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1832 8170028d ths
        /* Size can only be qi or hi.  */
1833 05ba7d5f edgar_igl
        t_gen_zext(cpu_T[1], cpu_T[1], size);
1834 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1835 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1836 8170028d ths
        return 2;
1837 8170028d ths
}
1838 05ba7d5f edgar_igl
1839 8170028d ths
/* Sign extension. From size to dword.  */
1840 8170028d ths
static unsigned int dec_adds_r(DisasContext *dc)
1841 8170028d ths
{
1842 8170028d ths
        int size = memsize_z(dc);
1843 8170028d ths
        DIS(fprintf (logfile, "adds.%c $r%u, $r%u\n",
1844 8170028d ths
                    memsize_char(size),
1845 8170028d ths
                    dc->op1, dc->op2));
1846 8170028d ths
1847 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1848 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1849 8170028d ths
        /* Size can only be qi or hi.  */
1850 05ba7d5f edgar_igl
        t_gen_sext(cpu_T[1], cpu_T[1], size);
1851 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1852 05ba7d5f edgar_igl
1853 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1854 8170028d ths
        return 2;
1855 8170028d ths
}
1856 8170028d ths
1857 8170028d ths
/* Zero extension. From size to dword.  */
1858 8170028d ths
static unsigned int dec_subu_r(DisasContext *dc)
1859 8170028d ths
{
1860 8170028d ths
        int size = memsize_z(dc);
1861 8170028d ths
        DIS(fprintf (logfile, "subu.%c $r%u, $r%u\n",
1862 8170028d ths
                    memsize_char(size),
1863 8170028d ths
                    dc->op1, dc->op2));
1864 8170028d ths
1865 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1866 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1867 8170028d ths
        /* Size can only be qi or hi.  */
1868 05ba7d5f edgar_igl
        t_gen_zext(cpu_T[1], cpu_T[1], size);
1869 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1870 8170028d ths
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1871 8170028d ths
        return 2;
1872 8170028d ths
}
1873 8170028d ths
1874 8170028d ths
/* Sign extension. From size to dword.  */
1875 8170028d ths
static unsigned int dec_subs_r(DisasContext *dc)
1876 8170028d ths
{
1877 8170028d ths
        int size = memsize_z(dc);
1878 8170028d ths
        DIS(fprintf (logfile, "subs.%c $r%u, $r%u\n",
1879 8170028d ths
                    memsize_char(size),
1880 8170028d ths
                    dc->op1, dc->op2));
1881 8170028d ths
1882 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1883 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1884 8170028d ths
        /* Size can only be qi or hi.  */
1885 05ba7d5f edgar_igl
        t_gen_sext(cpu_T[1], cpu_T[1], size);
1886 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1887 8170028d ths
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1888 8170028d ths
        return 2;
1889 8170028d ths
}
1890 8170028d ths
1891 8170028d ths
static unsigned int dec_setclrf(DisasContext *dc)
1892 8170028d ths
{
1893 8170028d ths
        uint32_t flags;
1894 8170028d ths
        int set = (~dc->opcode >> 2) & 1;
1895 8170028d ths
1896 8170028d ths
        flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
1897 8170028d ths
                | EXTRACT_FIELD(dc->ir, 0, 3);
1898 8170028d ths
        DIS(fprintf (logfile, "set=%d flags=%x\n", set, flags));
1899 8170028d ths
        if (set && flags == 0)
1900 8170028d ths
                DIS(fprintf (logfile, "nop\n"));
1901 8170028d ths
        else if (!set && (flags & 0x20))
1902 8170028d ths
                DIS(fprintf (logfile, "di\n"));
1903 8170028d ths
        else
1904 8170028d ths
                DIS(fprintf (logfile, "%sf %x\n",
1905 8170028d ths
                            set ? "set" : "clr",
1906 8170028d ths
                            flags));
1907 8170028d ths
1908 8170028d ths
        if (set && (flags & X_FLAG)) {
1909 8170028d ths
                dc->flagx_live = 1;
1910 8170028d ths
                dc->flags_x = 1;
1911 8170028d ths
        }
1912 8170028d ths
1913 8170028d ths
        /* Simply decode the flags.  */
1914 8170028d ths
        cris_evaluate_flags (dc);
1915 b41f7df0 edgar_igl
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1916 b41f7df0 edgar_igl
        tcg_gen_movi_tl(cc_op, dc->cc_op);
1917 b41f7df0 edgar_igl
1918 dceaf394 edgar_igl
        if (set) {
1919 dceaf394 edgar_igl
                if (!dc->user && (flags & U_FLAG)) {
1920 dceaf394 edgar_igl
                        /* Enter user mode.  */
1921 dceaf394 edgar_igl
                        t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
1922 dceaf394 edgar_igl
                        tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
1923 dceaf394 edgar_igl
                        dc->is_jmp = DISAS_UPDATE;
1924 dceaf394 edgar_igl
                }
1925 dceaf394 edgar_igl
                tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
1926 dceaf394 edgar_igl
        }
1927 8170028d ths
        else
1928 dceaf394 edgar_igl
                tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
1929 dceaf394 edgar_igl
1930 8170028d ths
        dc->flags_live = 1;
1931 b41f7df0 edgar_igl
        dc->clear_x = 0;
1932 8170028d ths
        return 2;
1933 8170028d ths
}
1934 8170028d ths
1935 8170028d ths
static unsigned int dec_move_rs(DisasContext *dc)
1936 8170028d ths
{
1937 8170028d ths
        DIS(fprintf (logfile, "move $r%u, $s%u\n", dc->op1, dc->op2));
1938 8170028d ths
        cris_cc_mask(dc, 0);
1939 dceaf394 edgar_igl
        tcg_gen_helper_0_2(helper_movl_sreg_reg, 
1940 dceaf394 edgar_igl
                           tcg_const_tl(dc->op2), tcg_const_tl(dc->op1));
1941 8170028d ths
        return 2;
1942 8170028d ths
}
1943 8170028d ths
static unsigned int dec_move_sr(DisasContext *dc)
1944 8170028d ths
{
1945 05ba7d5f edgar_igl
        DIS(fprintf (logfile, "move $s%u, $r%u\n", dc->op2, dc->op1));
1946 8170028d ths
        cris_cc_mask(dc, 0);
1947 dceaf394 edgar_igl
        tcg_gen_helper_0_2(helper_movl_reg_sreg, 
1948 dceaf394 edgar_igl
                           tcg_const_tl(dc->op1), tcg_const_tl(dc->op2));
1949 8170028d ths
        return 2;
1950 8170028d ths
}
1951 dceaf394 edgar_igl
1952 8170028d ths
static unsigned int dec_move_rp(DisasContext *dc)
1953 8170028d ths
{
1954 8170028d ths
        DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2));
1955 8170028d ths
        cris_cc_mask(dc, 0);
1956 b41f7df0 edgar_igl
1957 b41f7df0 edgar_igl
        if (dc->op2 == PR_CCS) {
1958 b41f7df0 edgar_igl
                cris_evaluate_flags(dc);
1959 b41f7df0 edgar_igl
                t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1960 b41f7df0 edgar_igl
                if (dc->user) {
1961 b41f7df0 edgar_igl
                        /* User space is not allowed to touch all flags.  */
1962 b41f7df0 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x39f);
1963 b41f7df0 edgar_igl
                        tcg_gen_andi_tl(cpu_T[1], cpu_PR[PR_CCS], ~0x39f);
1964 b41f7df0 edgar_igl
                        tcg_gen_or_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1965 b41f7df0 edgar_igl
                }
1966 b41f7df0 edgar_igl
        }
1967 b41f7df0 edgar_igl
        else
1968 b41f7df0 edgar_igl
                t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1969 b41f7df0 edgar_igl
1970 05ba7d5f edgar_igl
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
1971 b41f7df0 edgar_igl
        if (dc->op2 == PR_CCS) {
1972 b41f7df0 edgar_igl
                cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1973 b41f7df0 edgar_igl
                dc->flags_live = 1;
1974 b41f7df0 edgar_igl
        }
1975 8170028d ths
        return 2;
1976 8170028d ths
}
1977 8170028d ths
static unsigned int dec_move_pr(DisasContext *dc)
1978 8170028d ths
{
1979 8170028d ths
        DIS(fprintf (logfile, "move $p%u, $r%u\n", dc->op1, dc->op2));
1980 8170028d ths
        cris_cc_mask(dc, 0);
1981 fd56059f balrog
        /* Support register 0 is hardwired to zero. 
1982 fd56059f balrog
           Treat it specially. */
1983 fd56059f balrog
        if (dc->op2 == 0)
1984 05ba7d5f edgar_igl
                tcg_gen_movi_tl(cpu_T[1], 0);
1985 b41f7df0 edgar_igl
        else if (dc->op2 == PR_CCS) {
1986 b41f7df0 edgar_igl
                cris_evaluate_flags(dc);
1987 b41f7df0 edgar_igl
                t_gen_mov_TN_preg(cpu_T[1], dc->op2);
1988 b41f7df0 edgar_igl
        } else
1989 05ba7d5f edgar_igl
                t_gen_mov_TN_preg(cpu_T[1], dc->op2);
1990 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, preg_sizes[dc->op2]);
1991 8170028d ths
        return 2;
1992 8170028d ths
}
1993 8170028d ths
1994 8170028d ths
static unsigned int dec_move_mr(DisasContext *dc)
1995 8170028d ths
{
1996 8170028d ths
        int memsize = memsize_zz(dc);
1997 8170028d ths
        int insn_len;
1998 8170028d ths
        DIS(fprintf (logfile, "move.%c [$r%u%s, $r%u\n",
1999 8170028d ths
                    memsize_char(memsize),
2000 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2001 8170028d ths
                    dc->op2));
2002 8170028d ths
2003 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
2004 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZ);
2005 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, memsize);
2006 8170028d ths
        do_postinc(dc, memsize);
2007 8170028d ths
        return insn_len;
2008 8170028d ths
}
2009 8170028d ths
2010 8170028d ths
static unsigned int dec_movs_m(DisasContext *dc)
2011 8170028d ths
{
2012 8170028d ths
        int memsize = memsize_z(dc);
2013 8170028d ths
        int insn_len;
2014 8170028d ths
        DIS(fprintf (logfile, "movs.%c [$r%u%s, $r%u\n",
2015 8170028d ths
                    memsize_char(memsize),
2016 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2017 8170028d ths
                    dc->op2));
2018 8170028d ths
2019 8170028d ths
        /* sign extend.  */
2020 8170028d ths
        insn_len = dec_prep_alu_m(dc, 1, memsize);
2021 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZ);
2022 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
2023 8170028d ths
        do_postinc(dc, memsize);
2024 8170028d ths
        return insn_len;
2025 8170028d ths
}
2026 8170028d ths
2027 8170028d ths
static unsigned int dec_addu_m(DisasContext *dc)
2028 8170028d ths
{
2029 8170028d ths
        int memsize = memsize_z(dc);
2030 8170028d ths
        int insn_len;
2031 8170028d ths
        DIS(fprintf (logfile, "addu.%c [$r%u%s, $r%u\n",
2032 8170028d ths
                    memsize_char(memsize),
2033 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2034 8170028d ths
                    dc->op2));
2035 8170028d ths
2036 8170028d ths
        /* sign extend.  */
2037 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
2038 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2039 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
2040 8170028d ths
        do_postinc(dc, memsize);
2041 8170028d ths
        return insn_len;
2042 8170028d ths
}
2043 8170028d ths
2044 8170028d ths
static unsigned int dec_adds_m(DisasContext *dc)
2045 8170028d ths
{
2046 8170028d ths
        int memsize = memsize_z(dc);
2047 8170028d ths
        int insn_len;
2048 8170028d ths
        DIS(fprintf (logfile, "adds.%c [$r%u%s, $r%u\n",
2049 8170028d ths
                    memsize_char(memsize),
2050 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2051 8170028d ths
                    dc->op2));
2052 8170028d ths
2053 8170028d ths
        /* sign extend.  */
2054 8170028d ths
        insn_len = dec_prep_alu_m(dc, 1, memsize);
2055 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2056 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
2057 8170028d ths
        do_postinc(dc, memsize);
2058 8170028d ths
        return insn_len;
2059 8170028d ths
}
2060 8170028d ths
2061 8170028d ths
static unsigned int dec_subu_m(DisasContext *dc)
2062 8170028d ths
{
2063 8170028d ths
        int memsize = memsize_z(dc);
2064 8170028d ths
        int insn_len;
2065 8170028d ths
        DIS(fprintf (logfile, "subu.%c [$r%u%s, $r%u\n",
2066 8170028d ths
                    memsize_char(memsize),
2067 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2068 8170028d ths
                    dc->op2));
2069 8170028d ths
2070 8170028d ths
        /* sign extend.  */
2071 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
2072 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2073 8170028d ths
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
2074 8170028d ths
        do_postinc(dc, memsize);
2075 8170028d ths
        return insn_len;
2076 8170028d ths
}
2077 8170028d ths
2078 8170028d ths
static unsigned int dec_subs_m(DisasContext *dc)
2079 8170028d ths
{
2080 8170028d ths
        int memsize = memsize_z(dc);
2081 8170028d ths
        int insn_len;
2082 8170028d ths
        DIS(fprintf (logfile, "subs.%c [$r%u%s, $r%u\n",
2083 8170028d ths
                    memsize_char(memsize),
2084 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2085 8170028d ths
                    dc->op2));
2086 8170028d ths
2087 8170028d ths
        /* sign extend.  */
2088 8170028d ths
        insn_len = dec_prep_alu_m(dc, 1, memsize);
2089 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2090 8170028d ths
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
2091 8170028d ths
        do_postinc(dc, memsize);
2092 8170028d ths
        return insn_len;
2093 8170028d ths
}
2094 8170028d ths
2095 8170028d ths
static unsigned int dec_movu_m(DisasContext *dc)
2096 8170028d ths
{
2097 8170028d ths
        int memsize = memsize_z(dc);
2098 8170028d ths
        int insn_len;
2099 8170028d ths
2100 8170028d ths
        DIS(fprintf (logfile, "movu.%c [$r%u%s, $r%u\n",
2101 8170028d ths
                    memsize_char(memsize),
2102 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2103 8170028d ths
                    dc->op2));
2104 8170028d ths
2105 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
2106 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZ);
2107 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
2108 8170028d ths
        do_postinc(dc, memsize);
2109 8170028d ths
        return insn_len;
2110 8170028d ths
}
2111 8170028d ths
2112 8170028d ths
static unsigned int dec_cmpu_m(DisasContext *dc)
2113 8170028d ths
{
2114 8170028d ths
        int memsize = memsize_z(dc);
2115 8170028d ths
        int insn_len;
2116 8170028d ths
        DIS(fprintf (logfile, "cmpu.%c [$r%u%s, $r%u\n",
2117 8170028d ths
                    memsize_char(memsize),
2118 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2119 8170028d ths
                    dc->op2));
2120 8170028d ths
2121 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
2122 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2123 8170028d ths
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
2124 8170028d ths
        do_postinc(dc, memsize);
2125 8170028d ths
        return insn_len;
2126 8170028d ths
}
2127 8170028d ths
2128 8170028d ths
static unsigned int dec_cmps_m(DisasContext *dc)
2129 8170028d ths
{
2130 8170028d ths
        int memsize = memsize_z(dc);
2131 8170028d ths
        int insn_len;
2132 8170028d ths
        DIS(fprintf (logfile, "cmps.%c [$r%u%s, $r%u\n",
2133 8170028d ths
                    memsize_char(memsize),
2134 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2135 8170028d ths
                    dc->op2));
2136 8170028d ths
2137 8170028d ths
        insn_len = dec_prep_alu_m(dc, 1, memsize);
2138 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2139 8170028d ths
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
2140 8170028d ths
        do_postinc(dc, memsize);
2141 8170028d ths
        return insn_len;
2142 8170028d ths
}
2143 8170028d ths
2144 8170028d ths
static unsigned int dec_cmp_m(DisasContext *dc)
2145 8170028d ths
{
2146 8170028d ths
        int memsize = memsize_zz(dc);
2147 8170028d ths
        int insn_len;
2148 8170028d ths
        DIS(fprintf (logfile, "cmp.%c [$r%u%s, $r%u\n",
2149 8170028d ths
                    memsize_char(memsize),
2150 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2151 8170028d ths
                    dc->op2));
2152 8170028d ths
2153 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
2154 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2155 8170028d ths
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
2156 8170028d ths
        do_postinc(dc, memsize);
2157 8170028d ths
        return insn_len;
2158 8170028d ths
}
2159 8170028d ths
2160 8170028d ths
static unsigned int dec_test_m(DisasContext *dc)
2161 8170028d ths
{
2162 8170028d ths
        int memsize = memsize_zz(dc);
2163 8170028d ths
        int insn_len;
2164 8170028d ths
        DIS(fprintf (logfile, "test.%d [$r%u%s] op2=%x\n",
2165 8170028d ths
                    memsize_char(memsize),
2166 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2167 8170028d ths
                    dc->op2));
2168 8170028d ths
2169 dceaf394 edgar_igl
        cris_evaluate_flags(dc);
2170 dceaf394 edgar_igl
2171 b41f7df0 edgar_igl
        insn_len = dec_prep_alu_m(dc, 0, memsize);
2172 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
2173 dceaf394 edgar_igl
        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
2174 b41f7df0 edgar_igl
2175 05ba7d5f edgar_igl
        tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
2176 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[1], 0);
2177 8170028d ths
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
2178 8170028d ths
        do_postinc(dc, memsize);
2179 8170028d ths
        return insn_len;
2180 8170028d ths
}
2181 8170028d ths
2182 8170028d ths
static unsigned int dec_and_m(DisasContext *dc)
2183 8170028d ths
{
2184 8170028d ths
        int memsize = memsize_zz(dc);
2185 8170028d ths
        int insn_len;
2186 8170028d ths
        DIS(fprintf (logfile, "and.%d [$r%u%s, $r%u\n",
2187 8170028d ths
                    memsize_char(memsize),
2188 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2189 8170028d ths
                    dc->op2));
2190 8170028d ths
2191 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
2192 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZ);
2193 8170028d ths
        crisv32_alu_op(dc, CC_OP_AND, dc->op2, memsize_zz(dc));
2194 8170028d ths
        do_postinc(dc, memsize);
2195 8170028d ths
        return insn_len;
2196 8170028d ths
}
2197 8170028d ths
2198 8170028d ths
static unsigned int dec_add_m(DisasContext *dc)
2199 8170028d ths
{
2200 8170028d ths
        int memsize = memsize_zz(dc);
2201 8170028d ths
        int insn_len;
2202 8170028d ths
        DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
2203 8170028d ths
                    memsize_char(memsize),
2204 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2205 8170028d ths
                    dc->op2));
2206 8170028d ths
2207 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
2208 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2209 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, memsize_zz(dc));
2210 8170028d ths
        do_postinc(dc, memsize);
2211 8170028d ths
        return insn_len;
2212 8170028d ths
}
2213 8170028d ths
2214 8170028d ths
static unsigned int dec_addo_m(DisasContext *dc)
2215 8170028d ths
{
2216 8170028d ths
        int memsize = memsize_zz(dc);
2217 8170028d ths
        int insn_len;
2218 8170028d ths
        DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
2219 8170028d ths
                    memsize_char(memsize),
2220 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2221 8170028d ths
                    dc->op2));
2222 8170028d ths
2223 8170028d ths
        insn_len = dec_prep_alu_m(dc, 1, memsize);
2224 b41f7df0 edgar_igl
        cris_cc_mask(dc, 0);
2225 9004627f edgar_igl
        crisv32_alu_op(dc, CC_OP_ADD, R_ACR, 4);
2226 8170028d ths
        do_postinc(dc, memsize);
2227 8170028d ths
        return insn_len;
2228 8170028d ths
}
2229 8170028d ths
2230 8170028d ths
static unsigned int dec_bound_m(DisasContext *dc)
2231 8170028d ths
{
2232 8170028d ths
        int memsize = memsize_zz(dc);
2233 8170028d ths
        int insn_len;
2234 8170028d ths
        DIS(fprintf (logfile, "bound.%d [$r%u%s, $r%u\n",
2235 8170028d ths
                    memsize_char(memsize),
2236 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2237 8170028d ths
                    dc->op2));
2238 8170028d ths
2239 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
2240 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZ);
2241 8170028d ths
        crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
2242 8170028d ths
        do_postinc(dc, memsize);
2243 8170028d ths
        return insn_len;
2244 8170028d ths
}
2245 8170028d ths
2246 8170028d ths
static unsigned int dec_addc_mr(DisasContext *dc)
2247 8170028d ths
{
2248 8170028d ths
        int insn_len = 2;
2249 8170028d ths
        DIS(fprintf (logfile, "addc [$r%u%s, $r%u\n",
2250 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2251 8170028d ths
                    dc->op2));
2252 8170028d ths
2253 8170028d ths
        cris_evaluate_flags(dc);
2254 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, 4);
2255 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2256 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
2257 8170028d ths
        do_postinc(dc, 4);
2258 8170028d ths
        return insn_len;
2259 8170028d ths
}
2260 8170028d ths
2261 8170028d ths
static unsigned int dec_sub_m(DisasContext *dc)
2262 8170028d ths
{
2263 8170028d ths
        int memsize = memsize_zz(dc);
2264 8170028d ths
        int insn_len;
2265 8170028d ths
        DIS(fprintf (logfile, "sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2266 8170028d ths
                    memsize_char(memsize),
2267 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2268 8170028d ths
                    dc->op2, dc->ir, dc->zzsize));
2269 8170028d ths
2270 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
2271 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZVC);
2272 8170028d ths
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, memsize);
2273 8170028d ths
        do_postinc(dc, memsize);
2274 8170028d ths
        return insn_len;
2275 8170028d ths
}
2276 8170028d ths
2277 8170028d ths
static unsigned int dec_or_m(DisasContext *dc)
2278 8170028d ths
{
2279 8170028d ths
        int memsize = memsize_zz(dc);
2280 8170028d ths
        int insn_len;
2281 8170028d ths
        DIS(fprintf (logfile, "or.%d [$r%u%s, $r%u pc=%x\n",
2282 8170028d ths
                    memsize_char(memsize),
2283 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
2284 8170028d ths
                    dc->op2, dc->pc));
2285 8170028d ths
2286 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
2287 b41f7df0 edgar_igl
        cris_cc_mask(dc, CC_MASK_NZ);
2288 8170028d ths
        crisv32_alu_op(dc, CC_OP_OR, dc->op2, memsize_zz(dc));
2289 8170028d ths
        do_postinc(dc, memsize);
2290 8170028d ths
        return insn_len;
2291 8170028d ths
}
2292 8170028d ths
2293 8170028d ths
static unsigned int dec_move_mp(DisasContext *dc)
2294 8170028d ths
{
2295 8170028d ths
        int memsize = memsize_zz(dc);
2296 8170028d ths
        int insn_len = 2;
2297 8170028d ths
2298 8170028d ths
        DIS(fprintf (logfile, "move.%c [$r%u%s, $p%u\n",
2299 8170028d ths
                    memsize_char(memsize),
2300 8170028d ths
                    dc->op1,
2301 8170028d ths
                    dc->postinc ? "+]" : "]",
2302 8170028d ths
                    dc->op2));
2303 8170028d ths
2304 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
2305 b41f7df0 edgar_igl
        cris_cc_mask(dc, 0);
2306 b41f7df0 edgar_igl
        if (dc->op2 == PR_CCS) {
2307 b41f7df0 edgar_igl
                cris_evaluate_flags(dc);
2308 b41f7df0 edgar_igl
                if (dc->user) {
2309 b41f7df0 edgar_igl
                        /* User space is not allowed to touch all flags.  */
2310 b41f7df0 edgar_igl
                        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 0x39f);
2311 b41f7df0 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], ~0x39f);
2312 b41f7df0 edgar_igl
                        tcg_gen_or_tl(cpu_T[1], cpu_T[0], cpu_T[1]);
2313 b41f7df0 edgar_igl
                }
2314 b41f7df0 edgar_igl
        }
2315 b41f7df0 edgar_igl
2316 05ba7d5f edgar_igl
        t_gen_mov_preg_TN(dc->op2, cpu_T[1]);
2317 8170028d ths
2318 8170028d ths
        do_postinc(dc, memsize);
2319 8170028d ths
        return insn_len;
2320 8170028d ths
}
2321 8170028d ths
2322 8170028d ths
static unsigned int dec_move_pm(DisasContext *dc)
2323 8170028d ths
{
2324 8170028d ths
        int memsize;
2325 8170028d ths
2326 8170028d ths
        memsize = preg_sizes[dc->op2];
2327 8170028d ths
2328 fd56059f balrog
        DIS(fprintf (logfile, "move.%c $p%u, [$r%u%s\n",
2329 fd56059f balrog
                     memsize_char(memsize), 
2330 fd56059f balrog
                     dc->op2, dc->op1, dc->postinc ? "+]" : "]"));
2331 8170028d ths
2332 fd56059f balrog
        /* prepare store. Address in T0, value in T1.  */
2333 17ac9754 edgar_igl
        if (dc->op2 == PR_CCS)
2334 17ac9754 edgar_igl
                cris_evaluate_flags(dc);
2335 05ba7d5f edgar_igl
        t_gen_mov_TN_preg(cpu_T[1], dc->op2);
2336 17ac9754 edgar_igl
2337 17ac9754 edgar_igl
        gen_store(dc, cpu_R[dc->op1], cpu_T[1], memsize);
2338 17ac9754 edgar_igl
2339 b41f7df0 edgar_igl
        cris_cc_mask(dc, 0);
2340 8170028d ths
        if (dc->postinc)
2341 17ac9754 edgar_igl
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2342 8170028d ths
        return 2;
2343 8170028d ths
}
2344 8170028d ths
2345 8170028d ths
static unsigned int dec_movem_mr(DisasContext *dc)
2346 8170028d ths
{
2347 17ac9754 edgar_igl
        TCGv tmp[16];
2348 8170028d ths
        int i;
2349 8170028d ths
2350 8170028d ths
        DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1,
2351 8170028d ths
                    dc->postinc ? "+]" : "]", dc->op2));
2352 8170028d ths
2353 05ba7d5f edgar_igl
        /* fetch the address into T0 and T1.  */
2354 8170028d ths
        for (i = 0; i <= dc->op2; i++) {
2355 17ac9754 edgar_igl
                tmp[i] = tcg_temp_new(TCG_TYPE_TL);
2356 8170028d ths
                /* Perform the load onto regnum i. Always dword wide.  */
2357 17ac9754 edgar_igl
                tcg_gen_addi_tl(cpu_T[0], cpu_R[dc->op1], i * 4);
2358 17ac9754 edgar_igl
                gen_load(dc, tmp[i], cpu_T[0], 4, 0);
2359 8170028d ths
        }
2360 17ac9754 edgar_igl
2361 17ac9754 edgar_igl
        for (i = 0; i <= dc->op2; i++) {
2362 17ac9754 edgar_igl
                tcg_gen_mov_tl(cpu_R[i], tmp[i]);
2363 17ac9754 edgar_igl
                tcg_gen_discard_tl(tmp[i]);
2364 17ac9754 edgar_igl
        }
2365 17ac9754 edgar_igl
2366 05ba7d5f edgar_igl
        /* writeback the updated pointer value.  */
2367 05ba7d5f edgar_igl
        if (dc->postinc)
2368 17ac9754 edgar_igl
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], i * 4);
2369 b41f7df0 edgar_igl
2370 b41f7df0 edgar_igl
        /* gen_load might want to evaluate the previous insns flags.  */
2371 b41f7df0 edgar_igl
        cris_cc_mask(dc, 0);
2372 8170028d ths
        return 2;
2373 8170028d ths
}
2374 8170028d ths
2375 8170028d ths
static unsigned int dec_movem_rm(DisasContext *dc)
2376 8170028d ths
{
2377 8170028d ths
        int i;
2378 8170028d ths
2379 8170028d ths
        DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
2380 8170028d ths
                     dc->postinc ? "+]" : "]"));
2381 8170028d ths
2382 8170028d ths
        for (i = 0; i <= dc->op2; i++) {
2383 17ac9754 edgar_igl
                /* Displace addr.  */
2384 17ac9754 edgar_igl
                tcg_gen_addi_tl(cpu_T[0], cpu_R[dc->op1], i * 4);
2385 8170028d ths
                /* Perform the store.  */
2386 17ac9754 edgar_igl
                gen_store(dc, cpu_T[0], cpu_R[i], 4);
2387 8170028d ths
        }
2388 17ac9754 edgar_igl
        if (dc->postinc)
2389 17ac9754 edgar_igl
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], i * 4);
2390 b41f7df0 edgar_igl
        cris_cc_mask(dc, 0);
2391 8170028d ths
        return 2;
2392 8170028d ths
}
2393 8170028d ths
2394 8170028d ths
static unsigned int dec_move_rm(DisasContext *dc)
2395 8170028d ths
{
2396 8170028d ths
        int memsize;
2397 8170028d ths
2398 8170028d ths
        memsize = memsize_zz(dc);
2399 8170028d ths
2400 8170028d ths
        DIS(fprintf (logfile, "move.%d $r%u, [$r%u]\n",
2401 8170028d ths
                     memsize, dc->op2, dc->op1));
2402 8170028d ths
2403 8170028d ths
        /* prepare store.  */
2404 17ac9754 edgar_igl
        gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
2405 17ac9754 edgar_igl
2406 8170028d ths
        if (dc->postinc)
2407 17ac9754 edgar_igl
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2408 b41f7df0 edgar_igl
        cris_cc_mask(dc, 0);
2409 8170028d ths
        return 2;
2410 8170028d ths
}
2411 8170028d ths
2412 8170028d ths
static unsigned int dec_lapcq(DisasContext *dc)
2413 8170028d ths
{
2414 8170028d ths
        DIS(fprintf (logfile, "lapcq %x, $r%u\n",
2415 8170028d ths
                    dc->pc + dc->op1*2, dc->op2));
2416 8170028d ths
        cris_cc_mask(dc, 0);
2417 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[1], dc->pc + dc->op1 * 2);
2418 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
2419 8170028d ths
        return 2;
2420 8170028d ths
}
2421 8170028d ths
2422 8170028d ths
static unsigned int dec_lapc_im(DisasContext *dc)
2423 8170028d ths
{
2424 8170028d ths
        unsigned int rd;
2425 8170028d ths
        int32_t imm;
2426 b41f7df0 edgar_igl
        int32_t pc;
2427 8170028d ths
2428 8170028d ths
        rd = dc->op2;
2429 8170028d ths
2430 8170028d ths
        cris_cc_mask(dc, 0);
2431 8170028d ths
        imm = ldl_code(dc->pc + 2);
2432 8170028d ths
        DIS(fprintf (logfile, "lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2));
2433 b41f7df0 edgar_igl
2434 b41f7df0 edgar_igl
        pc = dc->pc;
2435 b41f7df0 edgar_igl
        pc += imm;
2436 b41f7df0 edgar_igl
        t_gen_mov_reg_TN(rd, tcg_const_tl(pc));
2437 05ba7d5f edgar_igl
        return 6;
2438 8170028d ths
}
2439 8170028d ths
2440 8170028d ths
/* Jump to special reg.  */
2441 8170028d ths
static unsigned int dec_jump_p(DisasContext *dc)
2442 8170028d ths
{
2443 8170028d ths
        DIS(fprintf (logfile, "jump $p%u\n", dc->op2));
2444 b41f7df0 edgar_igl
2445 17ac9754 edgar_igl
        if (dc->op2 == PR_CCS)
2446 17ac9754 edgar_igl
                cris_evaluate_flags(dc);
2447 05ba7d5f edgar_igl
        t_gen_mov_TN_preg(cpu_T[0], dc->op2);
2448 b41f7df0 edgar_igl
        /* rete will often have low bit set to indicate delayslot.  */
2449 b41f7df0 edgar_igl
        tcg_gen_andi_tl(env_btarget, cpu_T[0], ~1);
2450 17ac9754 edgar_igl
        cris_cc_mask(dc, 0);
2451 8170028d ths
        cris_prepare_dyn_jmp(dc);
2452 8170028d ths
        return 2;
2453 8170028d ths
}
2454 8170028d ths
2455 8170028d ths
/* Jump and save.  */
2456 8170028d ths
static unsigned int dec_jas_r(DisasContext *dc)
2457 8170028d ths
{
2458 8170028d ths
        DIS(fprintf (logfile, "jas $r%u, $p%u\n", dc->op1, dc->op2));
2459 8170028d ths
        cris_cc_mask(dc, 0);
2460 b41f7df0 edgar_igl
        /* Store the return address in Pd.  */
2461 b41f7df0 edgar_igl
        tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2462 b41f7df0 edgar_igl
        if (dc->op2 > 15)
2463 b41f7df0 edgar_igl
                abort();
2464 17ac9754 edgar_igl
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 4);
2465 17ac9754 edgar_igl
        tcg_gen_mov_tl(cpu_PR[dc->op2], cpu_T[0]);
2466 b41f7df0 edgar_igl
2467 8170028d ths
        cris_prepare_dyn_jmp(dc);
2468 8170028d ths
        return 2;
2469 8170028d ths
}
2470 8170028d ths
2471 8170028d ths
static unsigned int dec_jas_im(DisasContext *dc)
2472 8170028d ths
{
2473 8170028d ths
        uint32_t imm;
2474 8170028d ths
2475 8170028d ths
        imm = ldl_code(dc->pc + 2);
2476 8170028d ths
2477 8170028d ths
        DIS(fprintf (logfile, "jas 0x%x\n", imm));
2478 8170028d ths
        cris_cc_mask(dc, 0);
2479 17ac9754 edgar_igl
        /* Store the return address in Pd.  */
2480 b41f7df0 edgar_igl
        tcg_gen_movi_tl(env_btarget, imm);
2481 a825e703 edgar_igl
        t_gen_mov_preg_TN(dc->op2, tcg_const_tl(dc->pc + 8));
2482 8170028d ths
        cris_prepare_dyn_jmp(dc);
2483 8170028d ths
        return 6;
2484 8170028d ths
}
2485 8170028d ths
2486 8170028d ths
static unsigned int dec_jasc_im(DisasContext *dc)
2487 8170028d ths
{
2488 8170028d ths
        uint32_t imm;
2489 8170028d ths
2490 8170028d ths
        imm = ldl_code(dc->pc + 2);
2491 8170028d ths
2492 8170028d ths
        DIS(fprintf (logfile, "jasc 0x%x\n", imm));
2493 8170028d ths
        cris_cc_mask(dc, 0);
2494 17ac9754 edgar_igl
        /* Store the return address in Pd.  */
2495 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[0], imm);
2496 73e51723 edgar_igl
        tcg_gen_mov_tl(env_btarget, cpu_T[0]);
2497 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 8 + 4);
2498 05ba7d5f edgar_igl
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
2499 8170028d ths
        cris_prepare_dyn_jmp(dc);
2500 8170028d ths
        return 6;
2501 8170028d ths
}
2502 8170028d ths
2503 8170028d ths
static unsigned int dec_jasc_r(DisasContext *dc)
2504 8170028d ths
{
2505 8170028d ths
        DIS(fprintf (logfile, "jasc_r $r%u, $p%u\n", dc->op1, dc->op2));
2506 8170028d ths
        cris_cc_mask(dc, 0);
2507 17ac9754 edgar_igl
        /* Store the return address in Pd.  */
2508 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2509 73e51723 edgar_igl
        tcg_gen_mov_tl(env_btarget, cpu_T[0]);
2510 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 4 + 4);
2511 05ba7d5f edgar_igl
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
2512 8170028d ths
        cris_prepare_dyn_jmp(dc);
2513 8170028d ths
        return 2;
2514 8170028d ths
}
2515 8170028d ths
2516 8170028d ths
static unsigned int dec_bcc_im(DisasContext *dc)
2517 8170028d ths
{
2518 8170028d ths
        int32_t offset;
2519 8170028d ths
        uint32_t cond = dc->op2;
2520 8170028d ths
2521 17ac9754 edgar_igl
        offset = ldsw_code(dc->pc + 2);
2522 8170028d ths
2523 8170028d ths
        DIS(fprintf (logfile, "b%s %d pc=%x dst=%x\n",
2524 8170028d ths
                    cc_name(cond), offset,
2525 8170028d ths
                    dc->pc, dc->pc + offset));
2526 8170028d ths
2527 8170028d ths
        cris_cc_mask(dc, 0);
2528 8170028d ths
        /* op2 holds the condition-code.  */
2529 8170028d ths
        cris_prepare_cc_branch (dc, offset, cond);
2530 8170028d ths
        return 4;
2531 8170028d ths
}
2532 8170028d ths
2533 8170028d ths
static unsigned int dec_bas_im(DisasContext *dc)
2534 8170028d ths
{
2535 8170028d ths
        int32_t simm;
2536 8170028d ths
2537 8170028d ths
2538 8170028d ths
        simm = ldl_code(dc->pc + 2);
2539 8170028d ths
2540 8170028d ths
        DIS(fprintf (logfile, "bas 0x%x, $p%u\n", dc->pc + simm, dc->op2));
2541 8170028d ths
        cris_cc_mask(dc, 0);
2542 8170028d ths
        /* Stor the return address in Pd.  */
2543 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[0], dc->pc + simm);
2544 73e51723 edgar_igl
        tcg_gen_mov_tl(env_btarget, cpu_T[0]);
2545 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 8);
2546 05ba7d5f edgar_igl
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
2547 8170028d ths
        cris_prepare_dyn_jmp(dc);
2548 8170028d ths
        return 6;
2549 8170028d ths
}
2550 8170028d ths
2551 8170028d ths
static unsigned int dec_basc_im(DisasContext *dc)
2552 8170028d ths
{
2553 8170028d ths
        int32_t simm;
2554 8170028d ths
        simm = ldl_code(dc->pc + 2);
2555 8170028d ths
2556 8170028d ths
        DIS(fprintf (logfile, "basc 0x%x, $p%u\n", dc->pc + simm, dc->op2));
2557 8170028d ths
        cris_cc_mask(dc, 0);
2558 8170028d ths
        /* Stor the return address in Pd.  */
2559 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[0], dc->pc + simm);
2560 73e51723 edgar_igl
        tcg_gen_mov_tl(env_btarget, cpu_T[0]);
2561 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 12);
2562 05ba7d5f edgar_igl
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
2563 8170028d ths
        cris_prepare_dyn_jmp(dc);
2564 8170028d ths
        return 6;
2565 8170028d ths
}
2566 8170028d ths
2567 8170028d ths
static unsigned int dec_rfe_etc(DisasContext *dc)
2568 8170028d ths
{
2569 8170028d ths
        DIS(fprintf (logfile, "rfe_etc opc=%x pc=0x%x op1=%d op2=%d\n",
2570 8170028d ths
                    dc->opcode, dc->pc, dc->op1, dc->op2));
2571 8170028d ths
2572 8170028d ths
        cris_cc_mask(dc, 0);
2573 8170028d ths
2574 8170028d ths
        if (dc->op2 == 15) /* ignore halt.  */
2575 05ba7d5f edgar_igl
                return 2;
2576 8170028d ths
2577 8170028d ths
        switch (dc->op2 & 7) {
2578 8170028d ths
                case 2:
2579 8170028d ths
                        /* rfe.  */
2580 8170028d ths
                        cris_evaluate_flags(dc);
2581 b41f7df0 edgar_igl
                        tcg_gen_helper_0_0(helper_rfe);
2582 b41f7df0 edgar_igl
                        dc->is_jmp = DISAS_UPDATE;
2583 8170028d ths
                        break;
2584 8170028d ths
                case 5:
2585 8170028d ths
                        /* rfn.  */
2586 8170028d ths
                        BUG();
2587 8170028d ths
                        break;
2588 8170028d ths
                case 6:
2589 8170028d ths
                        /* break.  */
2590 05ba7d5f edgar_igl
                        tcg_gen_movi_tl(cpu_T[0], dc->pc);
2591 3157a0a9 edgar_igl
                        t_gen_mov_env_TN(pc, cpu_T[0]);
2592 8170028d ths
                        /* Breaks start at 16 in the exception vector.  */
2593 dceaf394 edgar_igl
                        t_gen_mov_env_TN(trap_vector, 
2594 dceaf394 edgar_igl
                                         tcg_const_tl(dc->op1 + 16));
2595 dceaf394 edgar_igl
                        t_gen_raise_exception(EXCP_BREAK);
2596 b41f7df0 edgar_igl
                        dc->is_jmp = DISAS_UPDATE;
2597 8170028d ths
                        break;
2598 8170028d ths
                default:
2599 8170028d ths
                        printf ("op2=%x\n", dc->op2);
2600 8170028d ths
                        BUG();
2601 8170028d ths
                        break;
2602 8170028d ths
2603 8170028d ths
        }
2604 8170028d ths
        return 2;
2605 8170028d ths
}
2606 8170028d ths
2607 5d4a534d edgar_igl
static unsigned int dec_ftag_fidx_d_m(DisasContext *dc)
2608 5d4a534d edgar_igl
{
2609 5d4a534d edgar_igl
        /* Ignore D-cache flushes.  */
2610 5d4a534d edgar_igl
        return 2;
2611 5d4a534d edgar_igl
}
2612 5d4a534d edgar_igl
2613 5d4a534d edgar_igl
static unsigned int dec_ftag_fidx_i_m(DisasContext *dc)
2614 5d4a534d edgar_igl
{
2615 5d4a534d edgar_igl
        /* Ignore I-cache flushes.  */
2616 5d4a534d edgar_igl
        return 2;
2617 5d4a534d edgar_igl
}
2618 5d4a534d edgar_igl
2619 8170028d ths
static unsigned int dec_null(DisasContext *dc)
2620 8170028d ths
{
2621 8170028d ths
        printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2622 8170028d ths
                dc->pc, dc->opcode, dc->op1, dc->op2);
2623 8170028d ths
        fflush(NULL);
2624 8170028d ths
        BUG();
2625 8170028d ths
        return 2;
2626 8170028d ths
}
2627 8170028d ths
2628 8170028d ths
struct decoder_info {
2629 8170028d ths
        struct {
2630 8170028d ths
                uint32_t bits;
2631 8170028d ths
                uint32_t mask;
2632 8170028d ths
        };
2633 8170028d ths
        unsigned int (*dec)(DisasContext *dc);
2634 8170028d ths
} decinfo[] = {
2635 8170028d ths
        /* Order matters here.  */
2636 8170028d ths
        {DEC_MOVEQ, dec_moveq},
2637 8170028d ths
        {DEC_BTSTQ, dec_btstq},
2638 8170028d ths
        {DEC_CMPQ, dec_cmpq},
2639 8170028d ths
        {DEC_ADDOQ, dec_addoq},
2640 8170028d ths
        {DEC_ADDQ, dec_addq},
2641 8170028d ths
        {DEC_SUBQ, dec_subq},
2642 8170028d ths
        {DEC_ANDQ, dec_andq},
2643 8170028d ths
        {DEC_ORQ, dec_orq},
2644 8170028d ths
        {DEC_ASRQ, dec_asrq},
2645 8170028d ths
        {DEC_LSLQ, dec_lslq},
2646 8170028d ths
        {DEC_LSRQ, dec_lsrq},
2647 8170028d ths
        {DEC_BCCQ, dec_bccq},
2648 8170028d ths
2649 8170028d ths
        {DEC_BCC_IM, dec_bcc_im},
2650 8170028d ths
        {DEC_JAS_IM, dec_jas_im},
2651 8170028d ths
        {DEC_JAS_R, dec_jas_r},
2652 8170028d ths
        {DEC_JASC_IM, dec_jasc_im},
2653 8170028d ths
        {DEC_JASC_R, dec_jasc_r},
2654 8170028d ths
        {DEC_BAS_IM, dec_bas_im},
2655 8170028d ths
        {DEC_BASC_IM, dec_basc_im},
2656 8170028d ths
        {DEC_JUMP_P, dec_jump_p},
2657 8170028d ths
        {DEC_LAPC_IM, dec_lapc_im},
2658 8170028d ths
        {DEC_LAPCQ, dec_lapcq},
2659 8170028d ths
2660 8170028d ths
        {DEC_RFE_ETC, dec_rfe_etc},
2661 8170028d ths
        {DEC_ADDC_MR, dec_addc_mr},
2662 8170028d ths
2663 8170028d ths
        {DEC_MOVE_MP, dec_move_mp},
2664 8170028d ths
        {DEC_MOVE_PM, dec_move_pm},
2665 8170028d ths
        {DEC_MOVEM_MR, dec_movem_mr},
2666 8170028d ths
        {DEC_MOVEM_RM, dec_movem_rm},
2667 8170028d ths
        {DEC_MOVE_PR, dec_move_pr},
2668 8170028d ths
        {DEC_SCC_R, dec_scc_r},
2669 8170028d ths
        {DEC_SETF, dec_setclrf},
2670 8170028d ths
        {DEC_CLEARF, dec_setclrf},
2671 8170028d ths
2672 8170028d ths
        {DEC_MOVE_SR, dec_move_sr},
2673 8170028d ths
        {DEC_MOVE_RP, dec_move_rp},
2674 8170028d ths
        {DEC_SWAP_R, dec_swap_r},
2675 8170028d ths
        {DEC_ABS_R, dec_abs_r},
2676 8170028d ths
        {DEC_LZ_R, dec_lz_r},
2677 8170028d ths
        {DEC_MOVE_RS, dec_move_rs},
2678 8170028d ths
        {DEC_BTST_R, dec_btst_r},
2679 8170028d ths
        {DEC_ADDC_R, dec_addc_r},
2680 8170028d ths
2681 8170028d ths
        {DEC_DSTEP_R, dec_dstep_r},
2682 8170028d ths
        {DEC_XOR_R, dec_xor_r},
2683 8170028d ths
        {DEC_MCP_R, dec_mcp_r},
2684 8170028d ths
        {DEC_CMP_R, dec_cmp_r},
2685 8170028d ths
2686 8170028d ths
        {DEC_ADDI_R, dec_addi_r},
2687 8170028d ths
        {DEC_ADDI_ACR, dec_addi_acr},
2688 8170028d ths
2689 8170028d ths
        {DEC_ADD_R, dec_add_r},
2690 8170028d ths
        {DEC_SUB_R, dec_sub_r},
2691 8170028d ths
2692 8170028d ths
        {DEC_ADDU_R, dec_addu_r},
2693 8170028d ths
        {DEC_ADDS_R, dec_adds_r},
2694 8170028d ths
        {DEC_SUBU_R, dec_subu_r},
2695 8170028d ths
        {DEC_SUBS_R, dec_subs_r},
2696 8170028d ths
        {DEC_LSL_R, dec_lsl_r},
2697 8170028d ths
2698 8170028d ths
        {DEC_AND_R, dec_and_r},
2699 8170028d ths
        {DEC_OR_R, dec_or_r},
2700 8170028d ths
        {DEC_BOUND_R, dec_bound_r},
2701 8170028d ths
        {DEC_ASR_R, dec_asr_r},
2702 8170028d ths
        {DEC_LSR_R, dec_lsr_r},
2703 8170028d ths
2704 8170028d ths
        {DEC_MOVU_R, dec_movu_r},
2705 8170028d ths
        {DEC_MOVS_R, dec_movs_r},
2706 8170028d ths
        {DEC_NEG_R, dec_neg_r},
2707 8170028d ths
        {DEC_MOVE_R, dec_move_r},
2708 8170028d ths
2709 5d4a534d edgar_igl
        {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
2710 5d4a534d edgar_igl
        {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
2711 8170028d ths
2712 8170028d ths
        {DEC_MULS_R, dec_muls_r},
2713 8170028d ths
        {DEC_MULU_R, dec_mulu_r},
2714 8170028d ths
2715 8170028d ths
        {DEC_ADDU_M, dec_addu_m},
2716 8170028d ths
        {DEC_ADDS_M, dec_adds_m},
2717 8170028d ths
        {DEC_SUBU_M, dec_subu_m},
2718 8170028d ths
        {DEC_SUBS_M, dec_subs_m},
2719 8170028d ths
2720 8170028d ths
        {DEC_CMPU_M, dec_cmpu_m},
2721 8170028d ths
        {DEC_CMPS_M, dec_cmps_m},
2722 8170028d ths
        {DEC_MOVU_M, dec_movu_m},
2723 8170028d ths
        {DEC_MOVS_M, dec_movs_m},
2724 8170028d ths
2725 8170028d ths
        {DEC_CMP_M, dec_cmp_m},
2726 8170028d ths
        {DEC_ADDO_M, dec_addo_m},
2727 8170028d ths
        {DEC_BOUND_M, dec_bound_m},
2728 8170028d ths
        {DEC_ADD_M, dec_add_m},
2729 8170028d ths
        {DEC_SUB_M, dec_sub_m},
2730 8170028d ths
        {DEC_AND_M, dec_and_m},
2731 8170028d ths
        {DEC_OR_M, dec_or_m},
2732 8170028d ths
        {DEC_MOVE_RM, dec_move_rm},
2733 8170028d ths
        {DEC_TEST_M, dec_test_m},
2734 8170028d ths
        {DEC_MOVE_MR, dec_move_mr},
2735 8170028d ths
2736 8170028d ths
        {{0, 0}, dec_null}
2737 8170028d ths
};
2738 8170028d ths
2739 8170028d ths
static inline unsigned int
2740 8170028d ths
cris_decoder(DisasContext *dc)
2741 8170028d ths
{
2742 8170028d ths
        unsigned int insn_len = 2;
2743 8170028d ths
        int i;
2744 8170028d ths
2745 8170028d ths
        /* Load a halfword onto the instruction register.  */
2746 17ac9754 edgar_igl
        dc->ir = lduw_code(dc->pc);
2747 8170028d ths
2748 8170028d ths
        /* Now decode it.  */
2749 8170028d ths
        dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
2750 8170028d ths
        dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
2751 8170028d ths
        dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
2752 8170028d ths
        dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
2753 8170028d ths
        dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
2754 8170028d ths
        dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
2755 8170028d ths
2756 8170028d ths
        /* Large switch for all insns.  */
2757 8170028d ths
        for (i = 0; i < sizeof decinfo / sizeof decinfo[0]; i++) {
2758 8170028d ths
                if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
2759 8170028d ths
                {
2760 8170028d ths
                        insn_len = decinfo[i].dec(dc);
2761 8170028d ths
                        break;
2762 8170028d ths
                }
2763 8170028d ths
        }
2764 8170028d ths
2765 8170028d ths
        return insn_len;
2766 8170028d ths
}
2767 8170028d ths
2768 8170028d ths
static void check_breakpoint(CPUState *env, DisasContext *dc)
2769 8170028d ths
{
2770 8170028d ths
        int j;
2771 8170028d ths
        if (env->nb_breakpoints > 0) {
2772 8170028d ths
                for(j = 0; j < env->nb_breakpoints; j++) {
2773 8170028d ths
                        if (env->breakpoints[j] == dc->pc) {
2774 8170028d ths
                                cris_evaluate_flags (dc);
2775 05ba7d5f edgar_igl
                                tcg_gen_movi_tl(cpu_T[0], dc->pc);
2776 3157a0a9 edgar_igl
                                t_gen_mov_env_TN(pc, cpu_T[0]);
2777 dceaf394 edgar_igl
                                t_gen_raise_exception(EXCP_DEBUG);
2778 8170028d ths
                                dc->is_jmp = DISAS_UPDATE;
2779 8170028d ths
                        }
2780 8170028d ths
                }
2781 8170028d ths
        }
2782 8170028d ths
}
2783 8170028d ths
2784 8170028d ths
/* generate intermediate code for basic block 'tb'.  */
2785 8170028d ths
struct DisasContext ctx;
2786 8170028d ths
static int
2787 8170028d ths
gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2788 8170028d ths
                               int search_pc)
2789 8170028d ths
{
2790 8170028d ths
        uint16_t *gen_opc_end;
2791 8170028d ths
           uint32_t pc_start;
2792 8170028d ths
        unsigned int insn_len;
2793 8170028d ths
        int j, lj;
2794 8170028d ths
        struct DisasContext *dc = &ctx;
2795 8170028d ths
        uint32_t next_page_start;
2796 8170028d ths
2797 a825e703 edgar_igl
        if (!logfile)
2798 a825e703 edgar_igl
                logfile = stderr;
2799 a825e703 edgar_igl
2800 73e51723 edgar_igl
        /* Odd PC indicates that branch is rexecuting due to exception in the
2801 73e51723 edgar_igl
         * delayslot, like in real hw.
2802 73e51723 edgar_igl
         * FIXME: we need to handle the case were the branch and the insn in
2803 73e51723 edgar_igl
         *         the delayslot do not share pages.
2804 73e51723 edgar_igl
         */
2805 73e51723 edgar_igl
        pc_start = tb->pc & ~1;
2806 8170028d ths
        dc->env = env;
2807 8170028d ths
        dc->tb = tb;
2808 8170028d ths
2809 8170028d ths
        gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2810 8170028d ths
2811 8170028d ths
        dc->is_jmp = DISAS_NEXT;
2812 b41f7df0 edgar_igl
        dc->ppc = pc_start;
2813 8170028d ths
        dc->pc = pc_start;
2814 8170028d ths
        dc->singlestep_enabled = env->singlestep_enabled;
2815 b41f7df0 edgar_igl
        dc->flags_live = 1;
2816 8170028d ths
        dc->flagx_live = 0;
2817 8170028d ths
        dc->flags_x = 0;
2818 b41f7df0 edgar_igl
        dc->cc_mask = 0;
2819 b41f7df0 edgar_igl
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2820 b41f7df0 edgar_igl
2821 b41f7df0 edgar_igl
        dc->user = env->pregs[PR_CCS] & U_FLAG;
2822 b41f7df0 edgar_igl
        dc->delayed_branch = 0;
2823 b41f7df0 edgar_igl
2824 b41f7df0 edgar_igl
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2825 b41f7df0 edgar_igl
                fprintf(logfile,
2826 dceaf394 edgar_igl
                        "search=%d pc=%x ccs=%x pid=%x usp=%x dbg=%x %x %x\n"
2827 b41f7df0 edgar_igl
                        "%x.%x.%x.%x\n"
2828 b41f7df0 edgar_igl
                        "%x.%x.%x.%x\n"
2829 b41f7df0 edgar_igl
                        "%x.%x.%x.%x\n"
2830 b41f7df0 edgar_igl
                        "%x.%x.%x.%x\n",
2831 b41f7df0 edgar_igl
                        search_pc, env->pc, env->pregs[PR_CCS], 
2832 b41f7df0 edgar_igl
                        env->pregs[PR_PID], env->pregs[PR_USP],
2833 dceaf394 edgar_igl
                        env->debug1, env->debug2, env->debug3,
2834 b41f7df0 edgar_igl
                        env->regs[0], env->regs[1], env->regs[2], env->regs[3],
2835 b41f7df0 edgar_igl
                        env->regs[4], env->regs[5], env->regs[6], env->regs[7],
2836 b41f7df0 edgar_igl
                        env->regs[8], env->regs[9],
2837 b41f7df0 edgar_igl
                        env->regs[10], env->regs[11],
2838 b41f7df0 edgar_igl
                        env->regs[12], env->regs[13],
2839 b41f7df0 edgar_igl
                        env->regs[14], env->regs[15]);
2840 b41f7df0 edgar_igl
                
2841 b41f7df0 edgar_igl
        }
2842 3157a0a9 edgar_igl
2843 8170028d ths
        next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
2844 8170028d ths
        lj = -1;
2845 8170028d ths
        do
2846 8170028d ths
        {
2847 8170028d ths
                check_breakpoint(env, dc);
2848 4f400ab5 edgar_igl
                if (dc->is_jmp == DISAS_JUMP
2849 4f400ab5 edgar_igl
                    || dc->is_jmp == DISAS_SWI)
2850 8170028d ths
                        goto done;
2851 8170028d ths
2852 8170028d ths
                if (search_pc) {
2853 8170028d ths
                        j = gen_opc_ptr - gen_opc_buf;
2854 8170028d ths
                        if (lj < j) {
2855 8170028d ths
                                lj++;
2856 8170028d ths
                                while (lj < j)
2857 8170028d ths
                                        gen_opc_instr_start[lj++] = 0;
2858 8170028d ths
                        }
2859 b41f7df0 edgar_igl
                        if (dc->delayed_branch == 1) {
2860 b41f7df0 edgar_igl
                                gen_opc_pc[lj] = dc->ppc | 1;
2861 b41f7df0 edgar_igl
                                gen_opc_instr_start[lj] = 0;
2862 b41f7df0 edgar_igl
                        }
2863 b41f7df0 edgar_igl
                        else {
2864 b41f7df0 edgar_igl
                                gen_opc_pc[lj] = dc->pc;
2865 b41f7df0 edgar_igl
                                gen_opc_instr_start[lj] = 1;
2866 b41f7df0 edgar_igl
                        }
2867 8170028d ths
                }
2868 8170028d ths
2869 b41f7df0 edgar_igl
                dc->clear_x = 1;
2870 8170028d ths
                insn_len = cris_decoder(dc);
2871 b41f7df0 edgar_igl
                dc->ppc = dc->pc;
2872 8170028d ths
                dc->pc += insn_len;
2873 b41f7df0 edgar_igl
                if (dc->clear_x)
2874 b41f7df0 edgar_igl
                        cris_clear_x_flag(dc);
2875 8170028d ths
2876 8170028d ths
                /* Check for delayed branches here. If we do it before
2877 8170028d ths
                   actually genereating any host code, the simulator will just
2878 8170028d ths
                   loop doing nothing for on this program location.  */
2879 8170028d ths
                if (dc->delayed_branch) {
2880 8170028d ths
                        dc->delayed_branch--;
2881 8170028d ths
                        if (dc->delayed_branch == 0)
2882 8170028d ths
                        {
2883 8170028d ths
                                if (dc->bcc == CC_A) {
2884 17ac9754 edgar_igl
                                        tcg_gen_mov_tl(env_pc, env_btarget);
2885 b41f7df0 edgar_igl
                                        dc->is_jmp = DISAS_JUMP;
2886 8170028d ths
                                }
2887 8170028d ths
                                else {
2888 17ac9754 edgar_igl
                                        t_gen_cc_jmp(dc->delayed_pc, dc->pc);
2889 b41f7df0 edgar_igl
                                        dc->is_jmp = DISAS_JUMP;
2890 8170028d ths
                                }
2891 8170028d ths
                        }
2892 8170028d ths
                }
2893 8170028d ths
2894 73e51723 edgar_igl
                /* If we are rexecuting a branch due to exceptions on
2895 73e51723 edgar_igl
                   delay slots dont break.  */
2896 73e51723 edgar_igl
                if (!(tb->pc & 1) && env->singlestep_enabled)
2897 8170028d ths
                        break;
2898 8170028d ths
        } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end
2899 b41f7df0 edgar_igl
                 && ((dc->pc < next_page_start) || dc->delayed_branch));
2900 b41f7df0 edgar_igl
2901 b41f7df0 edgar_igl
        if (dc->delayed_branch == 1) {
2902 b41f7df0 edgar_igl
                /* Reexecute the last insn.  */
2903 73e51723 edgar_igl
                dc->pc = dc->ppc | 1;
2904 b41f7df0 edgar_igl
        }
2905 8170028d ths
2906 8170028d ths
        if (!dc->is_jmp) {
2907 b41f7df0 edgar_igl
                D(printf("!jmp pc=%x jmp=%d db=%d\n", dc->pc, 
2908 b41f7df0 edgar_igl
                         dc->is_jmp, dc->delayed_branch));
2909 b41f7df0 edgar_igl
                /* T0 and env_pc should hold the new pc.  */
2910 3157a0a9 edgar_igl
                tcg_gen_movi_tl(cpu_T[0], dc->pc);
2911 b41f7df0 edgar_igl
                tcg_gen_mov_tl(env_pc, cpu_T[0]);
2912 8170028d ths
        }
2913 8170028d ths
2914 8170028d ths
        cris_evaluate_flags (dc);
2915 8170028d ths
  done:
2916 8170028d ths
        if (__builtin_expect(env->singlestep_enabled, 0)) {
2917 dceaf394 edgar_igl
                t_gen_raise_exception(EXCP_DEBUG);
2918 8170028d ths
        } else {
2919 8170028d ths
                switch(dc->is_jmp) {
2920 8170028d ths
                        case DISAS_NEXT:
2921 8170028d ths
                                gen_goto_tb(dc, 1, dc->pc);
2922 8170028d ths
                                break;
2923 8170028d ths
                        default:
2924 8170028d ths
                        case DISAS_JUMP:
2925 8170028d ths
                        case DISAS_UPDATE:
2926 8170028d ths
                                /* indicate that the hash table must be used
2927 8170028d ths
                                   to find the next TB */
2928 57fec1fe bellard
                                tcg_gen_exit_tb(0);
2929 8170028d ths
                                break;
2930 4f400ab5 edgar_igl
                        case DISAS_SWI:
2931 8170028d ths
                        case DISAS_TB_JUMP:
2932 8170028d ths
                                /* nothing more to generate */
2933 8170028d ths
                                break;
2934 8170028d ths
                }
2935 8170028d ths
        }
2936 8170028d ths
        *gen_opc_ptr = INDEX_op_end;
2937 8170028d ths
        if (search_pc) {
2938 8170028d ths
                j = gen_opc_ptr - gen_opc_buf;
2939 8170028d ths
                lj++;
2940 8170028d ths
                while (lj <= j)
2941 8170028d ths
                        gen_opc_instr_start[lj++] = 0;
2942 8170028d ths
        } else {
2943 8170028d ths
                tb->size = dc->pc - pc_start;
2944 8170028d ths
        }
2945 8170028d ths
2946 8170028d ths
#ifdef DEBUG_DISAS
2947 8170028d ths
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2948 8170028d ths
                fprintf(logfile, "--------------\n");
2949 8170028d ths
                fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2950 17ac9754 edgar_igl
                target_disas(logfile, pc_start, dc->pc - pc_start, 0);
2951 b41f7df0 edgar_igl
                fprintf(logfile, "\nisize=%d osize=%d\n", 
2952 b41f7df0 edgar_igl
                        dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
2953 8170028d ths
        }
2954 8170028d ths
#endif
2955 8170028d ths
        return 0;
2956 8170028d ths
}
2957 8170028d ths
2958 8170028d ths
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
2959 8170028d ths
{
2960 8170028d ths
    return gen_intermediate_code_internal(env, tb, 0);
2961 8170028d ths
}
2962 8170028d ths
2963 8170028d ths
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2964 8170028d ths
{
2965 8170028d ths
    return gen_intermediate_code_internal(env, tb, 1);
2966 8170028d ths
}
2967 8170028d ths
2968 8170028d ths
void cpu_dump_state (CPUState *env, FILE *f,
2969 8170028d ths
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
2970 8170028d ths
                     int flags)
2971 8170028d ths
{
2972 8170028d ths
        int i;
2973 8170028d ths
        uint32_t srs;
2974 8170028d ths
2975 8170028d ths
        if (!env || !f)
2976 8170028d ths
                return;
2977 8170028d ths
2978 8170028d ths
        cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
2979 8170028d ths
                    "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n"
2980 8170028d ths
                    "debug=%x %x %x\n",
2981 9004627f edgar_igl
                    env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
2982 8170028d ths
                    env->cc_op,
2983 8170028d ths
                    env->cc_src, env->cc_dest, env->cc_result, env->cc_mask,
2984 8170028d ths
                    env->debug1, env->debug2, env->debug3);
2985 8170028d ths
2986 8170028d ths
        for (i = 0; i < 16; i++) {
2987 8170028d ths
                cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
2988 8170028d ths
                if ((i + 1) % 4 == 0)
2989 8170028d ths
                        cpu_fprintf(f, "\n");
2990 8170028d ths
        }
2991 8170028d ths
        cpu_fprintf(f, "\nspecial regs:\n");
2992 8170028d ths
        for (i = 0; i < 16; i++) {
2993 8170028d ths
                cpu_fprintf(f, "p%2.2d=%8.8x ", i, env->pregs[i]);
2994 8170028d ths
                if ((i + 1) % 4 == 0)
2995 8170028d ths
                        cpu_fprintf(f, "\n");
2996 8170028d ths
        }
2997 9004627f edgar_igl
        srs = env->pregs[PR_SRS];
2998 b41f7df0 edgar_igl
        cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
2999 8170028d ths
        if (srs < 256) {
3000 8170028d ths
                for (i = 0; i < 16; i++) {
3001 8170028d ths
                        cpu_fprintf(f, "s%2.2d=%8.8x ",
3002 8170028d ths
                                    i, env->sregs[srs][i]);
3003 8170028d ths
                        if ((i + 1) % 4 == 0)
3004 8170028d ths
                                cpu_fprintf(f, "\n");
3005 8170028d ths
                }
3006 8170028d ths
        }
3007 8170028d ths
        cpu_fprintf(f, "\n\n");
3008 8170028d ths
3009 8170028d ths
}
3010 8170028d ths
3011 05ba7d5f edgar_igl
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
3012 05ba7d5f edgar_igl
{
3013 05ba7d5f edgar_igl
}
3014 05ba7d5f edgar_igl
3015 aaed909a bellard
CPUCRISState *cpu_cris_init (const char *cpu_model)
3016 8170028d ths
{
3017 8170028d ths
        CPUCRISState *env;
3018 a825e703 edgar_igl
        int i;
3019 8170028d ths
3020 8170028d ths
        env = qemu_mallocz(sizeof(CPUCRISState));
3021 8170028d ths
        if (!env)
3022 8170028d ths
                return NULL;
3023 8170028d ths
        cpu_exec_init(env);
3024 05ba7d5f edgar_igl
3025 05ba7d5f edgar_igl
        tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
3026 05ba7d5f edgar_igl
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
3027 05ba7d5f edgar_igl
#if TARGET_LONG_BITS > HOST_LONG_BITS
3028 05ba7d5f edgar_igl
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, 
3029 05ba7d5f edgar_igl
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
3030 05ba7d5f edgar_igl
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
3031 05ba7d5f edgar_igl
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
3032 05ba7d5f edgar_igl
#else
3033 05ba7d5f edgar_igl
        cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
3034 05ba7d5f edgar_igl
        cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
3035 05ba7d5f edgar_igl
#endif
3036 05ba7d5f edgar_igl
3037 a825e703 edgar_igl
        cc_src = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
3038 a825e703 edgar_igl
                                    offsetof(CPUState, cc_src), "cc_src");
3039 a825e703 edgar_igl
        cc_dest = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
3040 a825e703 edgar_igl
                                     offsetof(CPUState, cc_dest), 
3041 a825e703 edgar_igl
                                     "cc_dest");
3042 a825e703 edgar_igl
        cc_result = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
3043 a825e703 edgar_igl
                                       offsetof(CPUState, cc_result), 
3044 a825e703 edgar_igl
                                       "cc_result");
3045 a825e703 edgar_igl
        cc_op = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
3046 a825e703 edgar_igl
                                   offsetof(CPUState, cc_op), "cc_op");
3047 a825e703 edgar_igl
        cc_size = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
3048 a825e703 edgar_igl
                                     offsetof(CPUState, cc_size), 
3049 a825e703 edgar_igl
                                     "cc_size");
3050 a825e703 edgar_igl
        cc_mask = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
3051 a825e703 edgar_igl
                                     offsetof(CPUState, cc_mask),
3052 a825e703 edgar_igl
                                     "cc_mask");
3053 a825e703 edgar_igl
3054 b41f7df0 edgar_igl
        env_pc = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
3055 b41f7df0 edgar_igl
                                     offsetof(CPUState, pc),
3056 b41f7df0 edgar_igl
                                     "pc");
3057 b41f7df0 edgar_igl
        env_btarget = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
3058 b41f7df0 edgar_igl
                                     offsetof(CPUState, btarget),
3059 b41f7df0 edgar_igl
                                     "btarget");
3060 b41f7df0 edgar_igl
3061 a825e703 edgar_igl
        for (i = 0; i < 16; i++) {
3062 a825e703 edgar_igl
                cpu_R[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
3063 a825e703 edgar_igl
                                              offsetof(CPUState, regs[i]), 
3064 a825e703 edgar_igl
                                              regnames[i]);
3065 a825e703 edgar_igl
        }
3066 a825e703 edgar_igl
        for (i = 0; i < 16; i++) {
3067 a825e703 edgar_igl
                cpu_PR[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
3068 a825e703 edgar_igl
                                               offsetof(CPUState, pregs[i]), 
3069 a825e703 edgar_igl
                                               pregnames[i]);
3070 a825e703 edgar_igl
        }
3071 a825e703 edgar_igl
3072 dceaf394 edgar_igl
        TCG_HELPER(helper_raise_exception);
3073 b41f7df0 edgar_igl
        TCG_HELPER(helper_store);
3074 b41f7df0 edgar_igl
        TCG_HELPER(helper_dump);
3075 b41f7df0 edgar_igl
        TCG_HELPER(helper_dummy);
3076 b41f7df0 edgar_igl
3077 dceaf394 edgar_igl
        TCG_HELPER(helper_tlb_flush);
3078 dceaf394 edgar_igl
        TCG_HELPER(helper_movl_sreg_reg);
3079 dceaf394 edgar_igl
        TCG_HELPER(helper_movl_reg_sreg);
3080 dceaf394 edgar_igl
        TCG_HELPER(helper_rfe);
3081 dceaf394 edgar_igl
3082 b41f7df0 edgar_igl
        TCG_HELPER(helper_evaluate_flags_muls);
3083 b41f7df0 edgar_igl
        TCG_HELPER(helper_evaluate_flags_mulu);
3084 b41f7df0 edgar_igl
        TCG_HELPER(helper_evaluate_flags_mcp);
3085 b41f7df0 edgar_igl
        TCG_HELPER(helper_evaluate_flags_alu_4);
3086 b41f7df0 edgar_igl
        TCG_HELPER(helper_evaluate_flags_move_4);
3087 b41f7df0 edgar_igl
        TCG_HELPER(helper_evaluate_flags_move_2);
3088 b41f7df0 edgar_igl
        TCG_HELPER(helper_evaluate_flags);
3089 b41f7df0 edgar_igl
3090 8170028d ths
        cpu_reset(env);
3091 8170028d ths
        return env;
3092 8170028d ths
}
3093 8170028d ths
3094 8170028d ths
void cpu_reset (CPUCRISState *env)
3095 8170028d ths
{
3096 8170028d ths
        memset(env, 0, offsetof(CPUCRISState, breakpoints));
3097 8170028d ths
        tlb_flush(env, 1);
3098 b41f7df0 edgar_igl
3099 b41f7df0 edgar_igl
#if defined(CONFIG_USER_ONLY)
3100 b41f7df0 edgar_igl
        /* start in user mode with interrupts enabled.  */
3101 b41f7df0 edgar_igl
        env->pregs[PR_CCS] |= U_FLAG | I_FLAG;
3102 b41f7df0 edgar_igl
#else
3103 b41f7df0 edgar_igl
        env->pregs[PR_CCS] = 0;
3104 b41f7df0 edgar_igl
#endif
3105 8170028d ths
}
3106 d2856f1a aurel32
3107 d2856f1a aurel32
void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
3108 d2856f1a aurel32
                 unsigned long searched_pc, int pc_pos, void *puc)
3109 d2856f1a aurel32
{
3110 17ac9754 edgar_igl
        env->pc = gen_opc_pc[pc_pos];
3111 d2856f1a aurel32
}