Statistics
| Branch: | Revision:

root / target-cris / translate.c @ 2e70f6ef

History | View | Annotate | Download (80.6 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 cf1d97f0 edgar_igl
 * The condition code translation is in need of attention.
25 b41f7df0 edgar_igl
 */
26 b41f7df0 edgar_igl
27 8170028d ths
#include <stdarg.h>
28 8170028d ths
#include <stdlib.h>
29 8170028d ths
#include <stdio.h>
30 8170028d ths
#include <string.h>
31 8170028d ths
#include <inttypes.h>
32 8170028d ths
#include <assert.h>
33 8170028d ths
34 8170028d ths
#include "cpu.h"
35 8170028d ths
#include "exec-all.h"
36 8170028d ths
#include "disas.h"
37 57fec1fe bellard
#include "tcg-op.h"
38 05ba7d5f edgar_igl
#include "helper.h"
39 8170028d ths
#include "crisv32-decode.h"
40 ca10f867 aurel32
#include "qemu-common.h"
41 8170028d ths
42 8170028d ths
#define DISAS_CRIS 0
43 8170028d ths
#if DISAS_CRIS
44 8170028d ths
#define DIS(x) x
45 8170028d ths
#else
46 8170028d ths
#define DIS(x)
47 8170028d ths
#endif
48 8170028d ths
49 b41f7df0 edgar_igl
#define D(x)
50 8170028d ths
#define BUG() (gen_BUG(dc, __FILE__, __LINE__))
51 8170028d ths
#define BUG_ON(x) ({if (x) BUG();})
52 8170028d ths
53 4f400ab5 edgar_igl
#define DISAS_SWI 5
54 4f400ab5 edgar_igl
55 8170028d ths
/* Used by the decoder.  */
56 8170028d ths
#define EXTRACT_FIELD(src, start, end) \
57 8170028d ths
            (((src) >> start) & ((1 << (end - start + 1)) - 1))
58 8170028d ths
59 8170028d ths
#define CC_MASK_NZ 0xc
60 8170028d ths
#define CC_MASK_NZV 0xe
61 8170028d ths
#define CC_MASK_NZVC 0xf
62 8170028d ths
#define CC_MASK_RNZV 0x10e
63 8170028d ths
64 a825e703 edgar_igl
TCGv cpu_env;
65 a825e703 edgar_igl
TCGv cpu_T[2];
66 a825e703 edgar_igl
TCGv cpu_R[16];
67 a825e703 edgar_igl
TCGv cpu_PR[16];
68 30abcfc7 edgar_igl
TCGv cc_x;
69 a825e703 edgar_igl
TCGv cc_src;
70 a825e703 edgar_igl
TCGv cc_dest;
71 a825e703 edgar_igl
TCGv cc_result;
72 a825e703 edgar_igl
TCGv cc_op;
73 a825e703 edgar_igl
TCGv cc_size;
74 a825e703 edgar_igl
TCGv cc_mask;
75 05ba7d5f edgar_igl
76 2a44f7f1 edgar_igl
TCGv env_btaken;
77 b41f7df0 edgar_igl
TCGv env_btarget;
78 b41f7df0 edgar_igl
TCGv env_pc;
79 b41f7df0 edgar_igl
80 2e70f6ef pbrook
#include "gen-icount.h"
81 2e70f6ef pbrook
82 8170028d ths
/* This is the state at translation time.  */
83 8170028d ths
typedef struct DisasContext {
84 8170028d ths
        CPUState *env;
85 b41f7df0 edgar_igl
        target_ulong pc, ppc;
86 8170028d ths
87 8170028d ths
        /* Decoder.  */
88 8170028d ths
        uint32_t ir;
89 8170028d ths
        uint32_t opcode;
90 8170028d ths
        unsigned int op1;
91 8170028d ths
        unsigned int op2;
92 8170028d ths
        unsigned int zsize, zzsize;
93 8170028d ths
        unsigned int mode;
94 8170028d ths
        unsigned int postinc;
95 8170028d ths
96 8170028d ths
        int update_cc;
97 8170028d ths
        int cc_op;
98 8170028d ths
        int cc_size;
99 8170028d ths
        uint32_t cc_mask;
100 30abcfc7 edgar_igl
101 30abcfc7 edgar_igl
        int cc_size_uptodate; /* -1 invalid or last written value.  */
102 30abcfc7 edgar_igl
103 30abcfc7 edgar_igl
        int cc_x_uptodate;  /* 1 - ccs, 2 - known | X_FLAG. 0 not uptodate.  */
104 30abcfc7 edgar_igl
        int flags_uptodate; /* Wether or not $ccs is uptodate.  */
105 30abcfc7 edgar_igl
        int flagx_known; /* Wether or not flags_x has the x flag known at
106 30abcfc7 edgar_igl
                            translation time.  */
107 8170028d ths
        int flags_x;
108 8170028d ths
109 30abcfc7 edgar_igl
        int clear_x; /* Clear x after this insn?  */
110 2a44f7f1 edgar_igl
        int cpustate_changed;
111 2a44f7f1 edgar_igl
        unsigned int tb_flags; /* tb dependent flags.  */
112 8170028d ths
        int is_jmp;
113 8170028d ths
114 2a44f7f1 edgar_igl
#define JMP_NOJMP    0
115 2a44f7f1 edgar_igl
#define JMP_DIRECT   1
116 2a44f7f1 edgar_igl
#define JMP_INDIRECT 2
117 2a44f7f1 edgar_igl
        int jmp; /* 0=nojmp, 1=direct, 2=indirect.  */ 
118 2a44f7f1 edgar_igl
        uint32_t jmp_pc;
119 2a44f7f1 edgar_igl
120 8170028d ths
        int delayed_branch;
121 8170028d ths
122 8170028d ths
        struct TranslationBlock *tb;
123 8170028d ths
        int singlestep_enabled;
124 8170028d ths
} DisasContext;
125 8170028d ths
126 8170028d ths
static void gen_BUG(DisasContext *dc, char *file, int line)
127 8170028d ths
{
128 8170028d ths
        printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
129 8170028d ths
        fprintf (logfile, "BUG: pc=%x %s %d\n", dc->pc, file, line);
130 cf1d97f0 edgar_igl
        cpu_abort(dc->env, "%s:%d\n", file, 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 cf1d97f0 edgar_igl
static inline void t_gen_mov_preg_TN(DisasContext *dc, 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 a825e703 edgar_igl
                tcg_gen_mov_tl(cpu_PR[r], tn);
220 2a44f7f1 edgar_igl
                if (r == PR_PID) 
221 cf1d97f0 edgar_igl
                        tcg_gen_helper_0_1(helper_tlb_flush_pid, tn);
222 2a44f7f1 edgar_igl
                else if (r == PR_CCS)
223 2a44f7f1 edgar_igl
                        dc->cpustate_changed = 1;
224 b41f7df0 edgar_igl
        }
225 05ba7d5f edgar_igl
}
226 05ba7d5f edgar_igl
227 dceaf394 edgar_igl
static inline void t_gen_raise_exception(uint32_t index)
228 05ba7d5f edgar_igl
{
229 dceaf394 edgar_igl
        tcg_gen_helper_0_1(helper_raise_exception, tcg_const_tl(index));
230 05ba7d5f edgar_igl
}
231 05ba7d5f edgar_igl
232 05ba7d5f edgar_igl
static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
233 05ba7d5f edgar_igl
{
234 05ba7d5f edgar_igl
        int l1;
235 05ba7d5f edgar_igl
236 05ba7d5f edgar_igl
        l1 = gen_new_label();
237 05ba7d5f edgar_igl
        /* Speculative shift. */
238 05ba7d5f edgar_igl
        tcg_gen_shl_tl(d, a, b);
239 cb63669a pbrook
        tcg_gen_brcondi_tl(TCG_COND_LEU, b, 31, l1);
240 05ba7d5f edgar_igl
        /* Clear dst if shift operands were to large.  */
241 05ba7d5f edgar_igl
        tcg_gen_movi_tl(d, 0);
242 05ba7d5f edgar_igl
        gen_set_label(l1);
243 05ba7d5f edgar_igl
}
244 05ba7d5f edgar_igl
245 05ba7d5f edgar_igl
static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
246 05ba7d5f edgar_igl
{
247 05ba7d5f edgar_igl
        int l1;
248 05ba7d5f edgar_igl
249 05ba7d5f edgar_igl
        l1 = gen_new_label();
250 05ba7d5f edgar_igl
        /* Speculative shift. */
251 05ba7d5f edgar_igl
        tcg_gen_shr_tl(d, a, b);
252 cb63669a pbrook
        tcg_gen_brcondi_tl(TCG_COND_LEU, b, 31, l1);
253 05ba7d5f edgar_igl
        /* Clear dst if shift operands were to large.  */
254 05ba7d5f edgar_igl
        tcg_gen_movi_tl(d, 0);
255 05ba7d5f edgar_igl
        gen_set_label(l1);
256 05ba7d5f edgar_igl
}
257 05ba7d5f edgar_igl
258 05ba7d5f edgar_igl
static void t_gen_asr(TCGv d, TCGv a, TCGv b)
259 05ba7d5f edgar_igl
{
260 05ba7d5f edgar_igl
        int l1;
261 05ba7d5f edgar_igl
262 05ba7d5f edgar_igl
        l1 = gen_new_label();
263 05ba7d5f edgar_igl
        /* Speculative shift. */
264 05ba7d5f edgar_igl
        tcg_gen_sar_tl(d, a, b);
265 cb63669a pbrook
        tcg_gen_brcondi_tl(TCG_COND_LEU, b, 31, l1);
266 05ba7d5f edgar_igl
        /* Clear dst if shift operands were to large.  */
267 b41f7df0 edgar_igl
        tcg_gen_sar_tl(d, a, tcg_const_tl(30));
268 05ba7d5f edgar_igl
        gen_set_label(l1);
269 05ba7d5f edgar_igl
}
270 05ba7d5f edgar_igl
271 3157a0a9 edgar_igl
/* 64-bit signed mul, lower result in d and upper in d2.  */
272 3157a0a9 edgar_igl
static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
273 3157a0a9 edgar_igl
{
274 3157a0a9 edgar_igl
        TCGv t0, t1;
275 3157a0a9 edgar_igl
276 3157a0a9 edgar_igl
        t0 = tcg_temp_new(TCG_TYPE_I64);
277 3157a0a9 edgar_igl
        t1 = tcg_temp_new(TCG_TYPE_I64);
278 3157a0a9 edgar_igl
279 3157a0a9 edgar_igl
        tcg_gen_ext32s_i64(t0, a);
280 3157a0a9 edgar_igl
        tcg_gen_ext32s_i64(t1, b);
281 3157a0a9 edgar_igl
        tcg_gen_mul_i64(t0, t0, t1);
282 3157a0a9 edgar_igl
283 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d, t0);
284 3157a0a9 edgar_igl
        tcg_gen_shri_i64(t0, t0, 32);
285 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d2, t0);
286 b41f7df0 edgar_igl
287 30abcfc7 edgar_igl
        tcg_temp_free(t0);
288 30abcfc7 edgar_igl
        tcg_temp_free(t1);
289 3157a0a9 edgar_igl
}
290 3157a0a9 edgar_igl
291 3157a0a9 edgar_igl
/* 64-bit unsigned muls, lower result in d and upper in d2.  */
292 3157a0a9 edgar_igl
static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
293 3157a0a9 edgar_igl
{
294 3157a0a9 edgar_igl
        TCGv t0, t1;
295 3157a0a9 edgar_igl
296 3157a0a9 edgar_igl
        t0 = tcg_temp_new(TCG_TYPE_I64);
297 3157a0a9 edgar_igl
        t1 = tcg_temp_new(TCG_TYPE_I64);
298 3157a0a9 edgar_igl
299 3157a0a9 edgar_igl
        tcg_gen_extu_i32_i64(t0, a);
300 3157a0a9 edgar_igl
        tcg_gen_extu_i32_i64(t1, b);
301 3157a0a9 edgar_igl
        tcg_gen_mul_i64(t0, t0, t1);
302 3157a0a9 edgar_igl
303 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d, t0);
304 3157a0a9 edgar_igl
        tcg_gen_shri_i64(t0, t0, 32);
305 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d2, t0);
306 b41f7df0 edgar_igl
307 30abcfc7 edgar_igl
        tcg_temp_free(t0);
308 30abcfc7 edgar_igl
        tcg_temp_free(t1);
309 3157a0a9 edgar_igl
}
310 3157a0a9 edgar_igl
311 d059c172 edgar_igl
/* 32bit branch-free binary search for counting leading zeros.  */
312 d059c172 edgar_igl
static void t_gen_lz_i32(TCGv d, TCGv x)
313 d059c172 edgar_igl
{
314 d059c172 edgar_igl
        TCGv y, m, n;
315 d059c172 edgar_igl
316 d059c172 edgar_igl
        y = tcg_temp_new(TCG_TYPE_I32);
317 d059c172 edgar_igl
        m = tcg_temp_new(TCG_TYPE_I32);
318 d059c172 edgar_igl
        n = tcg_temp_new(TCG_TYPE_I32);
319 d059c172 edgar_igl
320 d059c172 edgar_igl
        /* y = -(x >> 16)  */
321 d059c172 edgar_igl
        tcg_gen_shri_i32(y, x, 16);
322 390efc54 pbrook
        tcg_gen_neg_i32(y, y);
323 d059c172 edgar_igl
324 d059c172 edgar_igl
        /* m = (y >> 16) & 16  */
325 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
326 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 16);
327 d059c172 edgar_igl
328 d059c172 edgar_igl
        /* n = 16 - m  */
329 d059c172 edgar_igl
        tcg_gen_sub_i32(n, tcg_const_i32(16), m);
330 d059c172 edgar_igl
        /* x = x >> m  */
331 d059c172 edgar_igl
        tcg_gen_shr_i32(x, x, m);
332 d059c172 edgar_igl
333 d059c172 edgar_igl
        /* y = x - 0x100  */
334 d059c172 edgar_igl
        tcg_gen_subi_i32(y, x, 0x100);
335 d059c172 edgar_igl
        /* m = (y >> 16) & 8  */
336 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
337 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 8);
338 d059c172 edgar_igl
        /* n = n + m  */
339 d059c172 edgar_igl
        tcg_gen_add_i32(n, n, m);
340 d059c172 edgar_igl
        /* x = x << m  */
341 d059c172 edgar_igl
        tcg_gen_shl_i32(x, x, m);
342 d059c172 edgar_igl
343 d059c172 edgar_igl
        /* y = x - 0x1000  */
344 d059c172 edgar_igl
        tcg_gen_subi_i32(y, x, 0x1000);
345 d059c172 edgar_igl
        /* m = (y >> 16) & 4  */
346 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
347 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 4);
348 d059c172 edgar_igl
        /* n = n + m  */
349 d059c172 edgar_igl
        tcg_gen_add_i32(n, n, m);
350 d059c172 edgar_igl
        /* x = x << m  */
351 d059c172 edgar_igl
        tcg_gen_shl_i32(x, x, m);
352 d059c172 edgar_igl
353 d059c172 edgar_igl
        /* y = x - 0x4000  */
354 d059c172 edgar_igl
        tcg_gen_subi_i32(y, x, 0x4000);
355 d059c172 edgar_igl
        /* m = (y >> 16) & 2  */
356 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
357 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 2);
358 d059c172 edgar_igl
        /* n = n + m  */
359 d059c172 edgar_igl
        tcg_gen_add_i32(n, n, m);
360 d059c172 edgar_igl
        /* x = x << m  */
361 d059c172 edgar_igl
        tcg_gen_shl_i32(x, x, m);
362 d059c172 edgar_igl
363 d059c172 edgar_igl
        /* y = x >> 14  */
364 d059c172 edgar_igl
        tcg_gen_shri_i32(y, x, 14);
365 d059c172 edgar_igl
        /* m = y & ~(y >> 1)  */
366 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 1);
367 d1896336 edgar_igl
        tcg_gen_not_i32(m, m);
368 d059c172 edgar_igl
        tcg_gen_and_i32(m, m, y);
369 d059c172 edgar_igl
370 d059c172 edgar_igl
        /* d = n + 2 - m  */
371 d059c172 edgar_igl
        tcg_gen_addi_i32(d, n, 2);
372 d059c172 edgar_igl
        tcg_gen_sub_i32(d, d, m);
373 d059c172 edgar_igl
374 30abcfc7 edgar_igl
        tcg_temp_free(y);
375 30abcfc7 edgar_igl
        tcg_temp_free(m);
376 30abcfc7 edgar_igl
        tcg_temp_free(n);
377 d059c172 edgar_igl
}
378 d059c172 edgar_igl
379 30abcfc7 edgar_igl
static void t_gen_btst(TCGv d, TCGv a, TCGv b)
380 dceaf394 edgar_igl
{
381 dceaf394 edgar_igl
        TCGv sbit;
382 dceaf394 edgar_igl
        TCGv bset;
383 30abcfc7 edgar_igl
        TCGv t0;
384 dceaf394 edgar_igl
        int l1;
385 dceaf394 edgar_igl
386 dceaf394 edgar_igl
        /* des ref:
387 dceaf394 edgar_igl
           The N flag is set according to the selected bit in the dest reg.
388 dceaf394 edgar_igl
           The Z flag is set if the selected bit and all bits to the right are
389 dceaf394 edgar_igl
           zero.
390 dceaf394 edgar_igl
           The X flag is cleared.
391 dceaf394 edgar_igl
           Other flags are left untouched.
392 dceaf394 edgar_igl
           The destination reg is not affected.
393 dceaf394 edgar_igl

394 dceaf394 edgar_igl
        unsigned int fz, sbit, bset, mask, masked_t0;
395 dceaf394 edgar_igl

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

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