Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (79.8 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 8170028d ths
/* This is the state at translation time.  */
81 8170028d ths
typedef struct DisasContext {
82 8170028d ths
        CPUState *env;
83 b41f7df0 edgar_igl
        target_ulong pc, ppc;
84 8170028d ths
85 8170028d ths
        /* Decoder.  */
86 8170028d ths
        uint32_t ir;
87 8170028d ths
        uint32_t opcode;
88 8170028d ths
        unsigned int op1;
89 8170028d ths
        unsigned int op2;
90 8170028d ths
        unsigned int zsize, zzsize;
91 8170028d ths
        unsigned int mode;
92 8170028d ths
        unsigned int postinc;
93 8170028d ths
94 8170028d ths
        int update_cc;
95 8170028d ths
        int cc_op;
96 8170028d ths
        int cc_size;
97 8170028d ths
        uint32_t cc_mask;
98 30abcfc7 edgar_igl
99 30abcfc7 edgar_igl
        int cc_size_uptodate; /* -1 invalid or last written value.  */
100 30abcfc7 edgar_igl
101 30abcfc7 edgar_igl
        int cc_x_uptodate;  /* 1 - ccs, 2 - known | X_FLAG. 0 not uptodate.  */
102 30abcfc7 edgar_igl
        int flags_uptodate; /* Wether or not $ccs is uptodate.  */
103 30abcfc7 edgar_igl
        int flagx_known; /* Wether or not flags_x has the x flag known at
104 30abcfc7 edgar_igl
                            translation time.  */
105 8170028d ths
        int flags_x;
106 8170028d ths
107 30abcfc7 edgar_igl
        int clear_x; /* Clear x after this insn?  */
108 2a44f7f1 edgar_igl
        int cpustate_changed;
109 2a44f7f1 edgar_igl
        unsigned int tb_flags; /* tb dependent flags.  */
110 8170028d ths
        int is_jmp;
111 8170028d ths
112 2a44f7f1 edgar_igl
#define JMP_NOJMP    0
113 2a44f7f1 edgar_igl
#define JMP_DIRECT   1
114 2a44f7f1 edgar_igl
#define JMP_INDIRECT 2
115 2a44f7f1 edgar_igl
        int jmp; /* 0=nojmp, 1=direct, 2=indirect.  */ 
116 2a44f7f1 edgar_igl
        uint32_t jmp_pc;
117 2a44f7f1 edgar_igl
118 8170028d ths
        int delayed_branch;
119 8170028d ths
120 8170028d ths
        struct TranslationBlock *tb;
121 8170028d ths
        int singlestep_enabled;
122 8170028d ths
} DisasContext;
123 8170028d ths
124 8170028d ths
static void gen_BUG(DisasContext *dc, char *file, int line)
125 8170028d ths
{
126 8170028d ths
        printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
127 8170028d ths
        fprintf (logfile, "BUG: pc=%x %s %d\n", dc->pc, file, line);
128 cf1d97f0 edgar_igl
        cpu_abort(dc->env, "%s:%d\n", file, line);
129 8170028d ths
}
130 8170028d ths
131 a825e703 edgar_igl
const char *regnames[] =
132 a825e703 edgar_igl
{
133 a825e703 edgar_igl
        "$r0", "$r1", "$r2", "$r3",
134 a825e703 edgar_igl
        "$r4", "$r5", "$r6", "$r7",
135 a825e703 edgar_igl
        "$r8", "$r9", "$r10", "$r11",
136 a825e703 edgar_igl
        "$r12", "$r13", "$sp", "$acr",
137 a825e703 edgar_igl
};
138 a825e703 edgar_igl
const char *pregnames[] =
139 a825e703 edgar_igl
{
140 a825e703 edgar_igl
        "$bz", "$vr", "$pid", "$srs",
141 a825e703 edgar_igl
        "$wz", "$exs", "$eda", "$mof",
142 a825e703 edgar_igl
        "$dz", "$ebp", "$erp", "$srp",
143 a825e703 edgar_igl
        "$nrp", "$ccs", "$usp", "$spc",
144 a825e703 edgar_igl
};
145 a825e703 edgar_igl
146 05ba7d5f edgar_igl
/* We need this table to handle preg-moves with implicit width.  */
147 05ba7d5f edgar_igl
int preg_sizes[] = {
148 05ba7d5f edgar_igl
        1, /* bz.  */
149 05ba7d5f edgar_igl
        1, /* vr.  */
150 05ba7d5f edgar_igl
        4, /* pid.  */
151 05ba7d5f edgar_igl
        1, /* srs.  */
152 05ba7d5f edgar_igl
        2, /* wz.  */
153 05ba7d5f edgar_igl
        4, 4, 4,
154 05ba7d5f edgar_igl
        4, 4, 4, 4,
155 05ba7d5f edgar_igl
        4, 4, 4, 4,
156 05ba7d5f edgar_igl
};
157 05ba7d5f edgar_igl
158 05ba7d5f edgar_igl
#define t_gen_mov_TN_env(tn, member) \
159 3157a0a9 edgar_igl
 _t_gen_mov_TN_env((tn), offsetof(CPUState, member))
160 05ba7d5f edgar_igl
#define t_gen_mov_env_TN(member, tn) \
161 3157a0a9 edgar_igl
 _t_gen_mov_env_TN(offsetof(CPUState, member), (tn))
162 05ba7d5f edgar_igl
163 b41f7df0 edgar_igl
static inline void t_gen_mov_TN_reg(TCGv tn, int r)
164 b41f7df0 edgar_igl
{
165 b41f7df0 edgar_igl
        if (r < 0 || r > 15)
166 b41f7df0 edgar_igl
                fprintf(stderr, "wrong register read $r%d\n", r);
167 b41f7df0 edgar_igl
        tcg_gen_mov_tl(tn, cpu_R[r]);
168 b41f7df0 edgar_igl
}
169 b41f7df0 edgar_igl
static inline void t_gen_mov_reg_TN(int r, TCGv tn)
170 b41f7df0 edgar_igl
{
171 b41f7df0 edgar_igl
        if (r < 0 || r > 15)
172 b41f7df0 edgar_igl
                fprintf(stderr, "wrong register write $r%d\n", r);
173 b41f7df0 edgar_igl
        tcg_gen_mov_tl(cpu_R[r], tn);
174 b41f7df0 edgar_igl
}
175 05ba7d5f edgar_igl
176 05ba7d5f edgar_igl
static inline void _t_gen_mov_TN_env(TCGv tn, int offset)
177 05ba7d5f edgar_igl
{
178 b41f7df0 edgar_igl
        if (offset > sizeof (CPUState))
179 b41f7df0 edgar_igl
                fprintf(stderr, "wrong load from env from off=%d\n", offset);
180 05ba7d5f edgar_igl
        tcg_gen_ld_tl(tn, cpu_env, offset);
181 05ba7d5f edgar_igl
}
182 05ba7d5f edgar_igl
static inline void _t_gen_mov_env_TN(int offset, TCGv tn)
183 05ba7d5f edgar_igl
{
184 b41f7df0 edgar_igl
        if (offset > sizeof (CPUState))
185 b41f7df0 edgar_igl
                fprintf(stderr, "wrong store to env at off=%d\n", offset);
186 05ba7d5f edgar_igl
        tcg_gen_st_tl(tn, cpu_env, offset);
187 05ba7d5f edgar_igl
}
188 05ba7d5f edgar_igl
189 05ba7d5f edgar_igl
static inline void t_gen_mov_TN_preg(TCGv tn, int r)
190 05ba7d5f edgar_igl
{
191 b41f7df0 edgar_igl
        if (r < 0 || r > 15)
192 b41f7df0 edgar_igl
                fprintf(stderr, "wrong register read $p%d\n", r);
193 05ba7d5f edgar_igl
        if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
194 3157a0a9 edgar_igl
                tcg_gen_mov_tl(tn, tcg_const_tl(0));
195 05ba7d5f edgar_igl
        else if (r == PR_VR)
196 3157a0a9 edgar_igl
                tcg_gen_mov_tl(tn, tcg_const_tl(32));
197 b41f7df0 edgar_igl
        else if (r == PR_EXS) {
198 b41f7df0 edgar_igl
                printf("read from EXS!\n");
199 b41f7df0 edgar_igl
                tcg_gen_mov_tl(tn, cpu_PR[r]);
200 b41f7df0 edgar_igl
        }
201 b41f7df0 edgar_igl
        else if (r == PR_EDA) {
202 b41f7df0 edgar_igl
                printf("read from EDA!\n");
203 b41f7df0 edgar_igl
                tcg_gen_mov_tl(tn, cpu_PR[r]);
204 b41f7df0 edgar_igl
        }
205 05ba7d5f edgar_igl
        else
206 a825e703 edgar_igl
                tcg_gen_mov_tl(tn, cpu_PR[r]);
207 05ba7d5f edgar_igl
}
208 cf1d97f0 edgar_igl
static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
209 05ba7d5f edgar_igl
{
210 b41f7df0 edgar_igl
        if (r < 0 || r > 15)
211 b41f7df0 edgar_igl
                fprintf(stderr, "wrong register write $p%d\n", r);
212 05ba7d5f edgar_igl
        if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
213 05ba7d5f edgar_igl
                return;
214 b41f7df0 edgar_igl
        else if (r == PR_SRS)
215 b41f7df0 edgar_igl
                tcg_gen_andi_tl(cpu_PR[r], tn, 3);
216 b41f7df0 edgar_igl
        else {
217 a825e703 edgar_igl
                tcg_gen_mov_tl(cpu_PR[r], tn);
218 2a44f7f1 edgar_igl
                if (r == PR_PID) 
219 cf1d97f0 edgar_igl
                        tcg_gen_helper_0_1(helper_tlb_flush_pid, tn);
220 2a44f7f1 edgar_igl
                else if (r == PR_CCS)
221 2a44f7f1 edgar_igl
                        dc->cpustate_changed = 1;
222 b41f7df0 edgar_igl
        }
223 05ba7d5f edgar_igl
}
224 05ba7d5f edgar_igl
225 dceaf394 edgar_igl
static inline void t_gen_raise_exception(uint32_t index)
226 05ba7d5f edgar_igl
{
227 dceaf394 edgar_igl
        tcg_gen_helper_0_1(helper_raise_exception, tcg_const_tl(index));
228 05ba7d5f edgar_igl
}
229 05ba7d5f edgar_igl
230 05ba7d5f edgar_igl
static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
231 05ba7d5f edgar_igl
{
232 05ba7d5f edgar_igl
        int l1;
233 05ba7d5f edgar_igl
234 05ba7d5f edgar_igl
        l1 = gen_new_label();
235 05ba7d5f edgar_igl
        /* Speculative shift. */
236 05ba7d5f edgar_igl
        tcg_gen_shl_tl(d, a, b);
237 cb63669a pbrook
        tcg_gen_brcondi_tl(TCG_COND_LEU, b, 31, l1);
238 05ba7d5f edgar_igl
        /* Clear dst if shift operands were to large.  */
239 05ba7d5f edgar_igl
        tcg_gen_movi_tl(d, 0);
240 05ba7d5f edgar_igl
        gen_set_label(l1);
241 05ba7d5f edgar_igl
}
242 05ba7d5f edgar_igl
243 05ba7d5f edgar_igl
static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
244 05ba7d5f edgar_igl
{
245 05ba7d5f edgar_igl
        int l1;
246 05ba7d5f edgar_igl
247 05ba7d5f edgar_igl
        l1 = gen_new_label();
248 05ba7d5f edgar_igl
        /* Speculative shift. */
249 05ba7d5f edgar_igl
        tcg_gen_shr_tl(d, a, b);
250 cb63669a pbrook
        tcg_gen_brcondi_tl(TCG_COND_LEU, b, 31, l1);
251 05ba7d5f edgar_igl
        /* Clear dst if shift operands were to large.  */
252 05ba7d5f edgar_igl
        tcg_gen_movi_tl(d, 0);
253 05ba7d5f edgar_igl
        gen_set_label(l1);
254 05ba7d5f edgar_igl
}
255 05ba7d5f edgar_igl
256 05ba7d5f edgar_igl
static void t_gen_asr(TCGv d, TCGv a, TCGv b)
257 05ba7d5f edgar_igl
{
258 05ba7d5f edgar_igl
        int l1;
259 05ba7d5f edgar_igl
260 05ba7d5f edgar_igl
        l1 = gen_new_label();
261 05ba7d5f edgar_igl
        /* Speculative shift. */
262 05ba7d5f edgar_igl
        tcg_gen_sar_tl(d, a, b);
263 cb63669a pbrook
        tcg_gen_brcondi_tl(TCG_COND_LEU, b, 31, l1);
264 05ba7d5f edgar_igl
        /* Clear dst if shift operands were to large.  */
265 b41f7df0 edgar_igl
        tcg_gen_sar_tl(d, a, tcg_const_tl(30));
266 05ba7d5f edgar_igl
        gen_set_label(l1);
267 05ba7d5f edgar_igl
}
268 05ba7d5f edgar_igl
269 3157a0a9 edgar_igl
/* 64-bit signed mul, lower result in d and upper in d2.  */
270 3157a0a9 edgar_igl
static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
271 3157a0a9 edgar_igl
{
272 3157a0a9 edgar_igl
        TCGv t0, t1;
273 3157a0a9 edgar_igl
274 3157a0a9 edgar_igl
        t0 = tcg_temp_new(TCG_TYPE_I64);
275 3157a0a9 edgar_igl
        t1 = tcg_temp_new(TCG_TYPE_I64);
276 3157a0a9 edgar_igl
277 3157a0a9 edgar_igl
        tcg_gen_ext32s_i64(t0, a);
278 3157a0a9 edgar_igl
        tcg_gen_ext32s_i64(t1, b);
279 3157a0a9 edgar_igl
        tcg_gen_mul_i64(t0, t0, t1);
280 3157a0a9 edgar_igl
281 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d, t0);
282 3157a0a9 edgar_igl
        tcg_gen_shri_i64(t0, t0, 32);
283 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d2, t0);
284 b41f7df0 edgar_igl
285 30abcfc7 edgar_igl
        tcg_temp_free(t0);
286 30abcfc7 edgar_igl
        tcg_temp_free(t1);
287 3157a0a9 edgar_igl
}
288 3157a0a9 edgar_igl
289 3157a0a9 edgar_igl
/* 64-bit unsigned muls, lower result in d and upper in d2.  */
290 3157a0a9 edgar_igl
static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
291 3157a0a9 edgar_igl
{
292 3157a0a9 edgar_igl
        TCGv t0, t1;
293 3157a0a9 edgar_igl
294 3157a0a9 edgar_igl
        t0 = tcg_temp_new(TCG_TYPE_I64);
295 3157a0a9 edgar_igl
        t1 = tcg_temp_new(TCG_TYPE_I64);
296 3157a0a9 edgar_igl
297 3157a0a9 edgar_igl
        tcg_gen_extu_i32_i64(t0, a);
298 3157a0a9 edgar_igl
        tcg_gen_extu_i32_i64(t1, b);
299 3157a0a9 edgar_igl
        tcg_gen_mul_i64(t0, t0, t1);
300 3157a0a9 edgar_igl
301 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d, t0);
302 3157a0a9 edgar_igl
        tcg_gen_shri_i64(t0, t0, 32);
303 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d2, t0);
304 b41f7df0 edgar_igl
305 30abcfc7 edgar_igl
        tcg_temp_free(t0);
306 30abcfc7 edgar_igl
        tcg_temp_free(t1);
307 3157a0a9 edgar_igl
}
308 3157a0a9 edgar_igl
309 d059c172 edgar_igl
/* 32bit branch-free binary search for counting leading zeros.  */
310 d059c172 edgar_igl
static void t_gen_lz_i32(TCGv d, TCGv x)
311 d059c172 edgar_igl
{
312 d059c172 edgar_igl
        TCGv y, m, n;
313 d059c172 edgar_igl
314 d059c172 edgar_igl
        y = tcg_temp_new(TCG_TYPE_I32);
315 d059c172 edgar_igl
        m = tcg_temp_new(TCG_TYPE_I32);
316 d059c172 edgar_igl
        n = tcg_temp_new(TCG_TYPE_I32);
317 d059c172 edgar_igl
318 d059c172 edgar_igl
        /* y = -(x >> 16)  */
319 d059c172 edgar_igl
        tcg_gen_shri_i32(y, x, 16);
320 390efc54 pbrook
        tcg_gen_neg_i32(y, y);
321 d059c172 edgar_igl
322 d059c172 edgar_igl
        /* m = (y >> 16) & 16  */
323 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
324 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 16);
325 d059c172 edgar_igl
326 d059c172 edgar_igl
        /* n = 16 - m  */
327 d059c172 edgar_igl
        tcg_gen_sub_i32(n, tcg_const_i32(16), m);
328 d059c172 edgar_igl
        /* x = x >> m  */
329 d059c172 edgar_igl
        tcg_gen_shr_i32(x, x, m);
330 d059c172 edgar_igl
331 d059c172 edgar_igl
        /* y = x - 0x100  */
332 d059c172 edgar_igl
        tcg_gen_subi_i32(y, x, 0x100);
333 d059c172 edgar_igl
        /* m = (y >> 16) & 8  */
334 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
335 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 8);
336 d059c172 edgar_igl
        /* n = n + m  */
337 d059c172 edgar_igl
        tcg_gen_add_i32(n, n, m);
338 d059c172 edgar_igl
        /* x = x << m  */
339 d059c172 edgar_igl
        tcg_gen_shl_i32(x, x, m);
340 d059c172 edgar_igl
341 d059c172 edgar_igl
        /* y = x - 0x1000  */
342 d059c172 edgar_igl
        tcg_gen_subi_i32(y, x, 0x1000);
343 d059c172 edgar_igl
        /* m = (y >> 16) & 4  */
344 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
345 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 4);
346 d059c172 edgar_igl
        /* n = n + m  */
347 d059c172 edgar_igl
        tcg_gen_add_i32(n, n, m);
348 d059c172 edgar_igl
        /* x = x << m  */
349 d059c172 edgar_igl
        tcg_gen_shl_i32(x, x, m);
350 d059c172 edgar_igl
351 d059c172 edgar_igl
        /* y = x - 0x4000  */
352 d059c172 edgar_igl
        tcg_gen_subi_i32(y, x, 0x4000);
353 d059c172 edgar_igl
        /* m = (y >> 16) & 2  */
354 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
355 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 2);
356 d059c172 edgar_igl
        /* n = n + m  */
357 d059c172 edgar_igl
        tcg_gen_add_i32(n, n, m);
358 d059c172 edgar_igl
        /* x = x << m  */
359 d059c172 edgar_igl
        tcg_gen_shl_i32(x, x, m);
360 d059c172 edgar_igl
361 d059c172 edgar_igl
        /* y = x >> 14  */
362 d059c172 edgar_igl
        tcg_gen_shri_i32(y, x, 14);
363 d059c172 edgar_igl
        /* m = y & ~(y >> 1)  */
364 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 1);
365 d1896336 edgar_igl
        tcg_gen_not_i32(m, m);
366 d059c172 edgar_igl
        tcg_gen_and_i32(m, m, y);
367 d059c172 edgar_igl
368 d059c172 edgar_igl
        /* d = n + 2 - m  */
369 d059c172 edgar_igl
        tcg_gen_addi_i32(d, n, 2);
370 d059c172 edgar_igl
        tcg_gen_sub_i32(d, d, m);
371 d059c172 edgar_igl
372 30abcfc7 edgar_igl
        tcg_temp_free(y);
373 30abcfc7 edgar_igl
        tcg_temp_free(m);
374 30abcfc7 edgar_igl
        tcg_temp_free(n);
375 d059c172 edgar_igl
}
376 d059c172 edgar_igl
377 30abcfc7 edgar_igl
static void t_gen_btst(TCGv d, TCGv a, TCGv b)
378 dceaf394 edgar_igl
{
379 dceaf394 edgar_igl
        TCGv sbit;
380 dceaf394 edgar_igl
        TCGv bset;
381 30abcfc7 edgar_igl
        TCGv t0;
382 dceaf394 edgar_igl
        int l1;
383 dceaf394 edgar_igl
384 dceaf394 edgar_igl
        /* des ref:
385 dceaf394 edgar_igl
           The N flag is set according to the selected bit in the dest reg.
386 dceaf394 edgar_igl
           The Z flag is set if the selected bit and all bits to the right are
387 dceaf394 edgar_igl
           zero.
388 dceaf394 edgar_igl
           The X flag is cleared.
389 dceaf394 edgar_igl
           Other flags are left untouched.
390 dceaf394 edgar_igl
           The destination reg is not affected.
391 dceaf394 edgar_igl

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

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

400 dceaf394 edgar_igl
        // Clear the X, N and Z flags.
401 dceaf394 edgar_igl
        T0 = env->pregs[PR_CCS] & ~(X_FLAG | N_FLAG | Z_FLAG);
402 dceaf394 edgar_igl
        // Set the N and Z flags accordingly.
403 dceaf394 edgar_igl
        T0 |= (bset << 3) | (fz << 2);
404 dceaf394 edgar_igl
        */
405 dceaf394 edgar_igl
406 dceaf394 edgar_igl
        l1 = gen_new_label();
407 dceaf394 edgar_igl
        sbit = tcg_temp_new(TCG_TYPE_TL);
408 dceaf394 edgar_igl
        bset = tcg_temp_new(TCG_TYPE_TL);
409 30abcfc7 edgar_igl
        t0 = tcg_temp_new(TCG_TYPE_TL);
410 dceaf394 edgar_igl
411 dceaf394 edgar_igl
        /* Compute bset and sbit.  */
412 30abcfc7 edgar_igl
        tcg_gen_andi_tl(sbit, b, 31);
413 30abcfc7 edgar_igl
        tcg_gen_shl_tl(t0, tcg_const_tl(1), sbit);
414 30abcfc7 edgar_igl
        tcg_gen_and_tl(bset, a, t0);
415 dceaf394 edgar_igl
        tcg_gen_shr_tl(bset, bset, sbit);
416 dceaf394 edgar_igl
        /* Displace to N_FLAG.  */
417 dceaf394 edgar_igl
        tcg_gen_shli_tl(bset, bset, 3);
418 dceaf394 edgar_igl
419 dceaf394 edgar_igl
        tcg_gen_shl_tl(sbit, tcg_const_tl(2), sbit);
420 dceaf394 edgar_igl
        tcg_gen_subi_tl(sbit, sbit, 1);
421 30abcfc7 edgar_igl
        tcg_gen_and_tl(sbit, a, sbit);
422 dceaf394 edgar_igl
423 dceaf394 edgar_igl
        tcg_gen_andi_tl(d, cpu_PR[PR_CCS], ~(X_FLAG | N_FLAG | Z_FLAG));
424 dceaf394 edgar_igl
        /* or in the N_FLAG.  */
425 dceaf394 edgar_igl
        tcg_gen_or_tl(d, d, bset);
426 cb63669a pbrook
        tcg_gen_brcondi_tl(TCG_COND_NE, sbit, 0, l1);
427 dceaf394 edgar_igl
        /* or in the Z_FLAG.  */
428 dceaf394 edgar_igl
        tcg_gen_ori_tl(d, d, Z_FLAG);
429 dceaf394 edgar_igl
        gen_set_label(l1);
430 dceaf394 edgar_igl
431 30abcfc7 edgar_igl
        tcg_temp_free(sbit);
432 30abcfc7 edgar_igl
        tcg_temp_free(bset);
433 dceaf394 edgar_igl
}
434 dceaf394 edgar_igl
435 30abcfc7 edgar_igl
static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
436 aae6b32a edgar_igl
{
437 aae6b32a edgar_igl
        int l1;
438 aae6b32a edgar_igl
439 aae6b32a edgar_igl
        l1 = gen_new_label();
440 aae6b32a edgar_igl
441 aae6b32a edgar_igl
        /* 
442 aae6b32a edgar_igl
         * d <<= 1
443 aae6b32a edgar_igl
         * if (d >= s)
444 aae6b32a edgar_igl
         *    d -= s;
445 aae6b32a edgar_igl
         */
446 30abcfc7 edgar_igl
        tcg_gen_shli_tl(d, a, 1);
447 30abcfc7 edgar_igl
        tcg_gen_brcond_tl(TCG_COND_LTU, d, b, l1);
448 30abcfc7 edgar_igl
        tcg_gen_sub_tl(d, d, b);
449 aae6b32a edgar_igl
        gen_set_label(l1);
450 aae6b32a edgar_igl
}
451 aae6b32a edgar_igl
452 3157a0a9 edgar_igl
/* Extended arithmetics on CRIS.  */
453 3157a0a9 edgar_igl
static inline void t_gen_add_flag(TCGv d, int flag)
454 3157a0a9 edgar_igl
{
455 3157a0a9 edgar_igl
        TCGv c;
456 3157a0a9 edgar_igl
457 3157a0a9 edgar_igl
        c = tcg_temp_new(TCG_TYPE_TL);
458 3157a0a9 edgar_igl
        t_gen_mov_TN_preg(c, PR_CCS);
459 3157a0a9 edgar_igl
        /* Propagate carry into d.  */
460 3157a0a9 edgar_igl
        tcg_gen_andi_tl(c, c, 1 << flag);
461 3157a0a9 edgar_igl
        if (flag)
462 3157a0a9 edgar_igl
                tcg_gen_shri_tl(c, c, flag);
463 3157a0a9 edgar_igl
        tcg_gen_add_tl(d, d, c);
464 30abcfc7 edgar_igl
        tcg_temp_free(c);
465 3157a0a9 edgar_igl
}
466 3157a0a9 edgar_igl
467 30abcfc7 edgar_igl
static inline void t_gen_addx_carry(DisasContext *dc, TCGv d)
468 3157a0a9 edgar_igl
{
469 30abcfc7 edgar_igl
        if (dc->flagx_known) {
470 30abcfc7 edgar_igl
                if (dc->flags_x) {
471 30abcfc7 edgar_igl
                        TCGv c;
472 30abcfc7 edgar_igl
            
473 30abcfc7 edgar_igl
                        c = tcg_temp_new(TCG_TYPE_TL);
474 30abcfc7 edgar_igl
                        t_gen_mov_TN_preg(c, PR_CCS);
475 30abcfc7 edgar_igl
                        /* C flag is already at bit 0.  */
476 30abcfc7 edgar_igl
                        tcg_gen_andi_tl(c, c, C_FLAG);
477 30abcfc7 edgar_igl
                        tcg_gen_add_tl(d, d, c);
478 30abcfc7 edgar_igl
                        tcg_temp_free(c);
479 30abcfc7 edgar_igl
                }
480 30abcfc7 edgar_igl
        } else {
481 30abcfc7 edgar_igl
                TCGv x, c;
482 3157a0a9 edgar_igl
483 30abcfc7 edgar_igl
                x = tcg_temp_new(TCG_TYPE_TL);
484 30abcfc7 edgar_igl
                c = tcg_temp_new(TCG_TYPE_TL);
485 30abcfc7 edgar_igl
                t_gen_mov_TN_preg(x, PR_CCS);
486 30abcfc7 edgar_igl
                tcg_gen_mov_tl(c, x);
487 3157a0a9 edgar_igl
488 30abcfc7 edgar_igl
                /* Propagate carry into d if X is set. Branch free.  */
489 30abcfc7 edgar_igl
                tcg_gen_andi_tl(c, c, C_FLAG);
490 30abcfc7 edgar_igl
                tcg_gen_andi_tl(x, x, X_FLAG);
491 30abcfc7 edgar_igl
                tcg_gen_shri_tl(x, x, 4);
492 3157a0a9 edgar_igl
493 30abcfc7 edgar_igl
                tcg_gen_and_tl(x, x, c);
494 30abcfc7 edgar_igl
                tcg_gen_add_tl(d, d, x);        
495 30abcfc7 edgar_igl
                tcg_temp_free(x);
496 30abcfc7 edgar_igl
                tcg_temp_free(c);
497 30abcfc7 edgar_igl
        }
498 3157a0a9 edgar_igl
}
499 3157a0a9 edgar_igl
500 a39f8f3a edgar_igl
static inline void t_gen_subx_carry(DisasContext *dc, TCGv d)
501 3157a0a9 edgar_igl
{
502 30abcfc7 edgar_igl
        if (dc->flagx_known) {
503 30abcfc7 edgar_igl
                if (dc->flags_x) {
504 30abcfc7 edgar_igl
                        TCGv c;
505 30abcfc7 edgar_igl
            
506 30abcfc7 edgar_igl
                        c = tcg_temp_new(TCG_TYPE_TL);
507 30abcfc7 edgar_igl
                        t_gen_mov_TN_preg(c, PR_CCS);
508 30abcfc7 edgar_igl
                        /* C flag is already at bit 0.  */
509 30abcfc7 edgar_igl
                        tcg_gen_andi_tl(c, c, C_FLAG);
510 30abcfc7 edgar_igl
                        tcg_gen_sub_tl(d, d, c);
511 30abcfc7 edgar_igl
                        tcg_temp_free(c);
512 30abcfc7 edgar_igl
                }
513 30abcfc7 edgar_igl
        } else {
514 a39f8f3a edgar_igl
                TCGv x, c;
515 a39f8f3a edgar_igl
516 a39f8f3a edgar_igl
                x = tcg_temp_new(TCG_TYPE_TL);
517 a39f8f3a edgar_igl
                c = tcg_temp_new(TCG_TYPE_TL);
518 a39f8f3a edgar_igl
                t_gen_mov_TN_preg(x, PR_CCS);
519 a39f8f3a edgar_igl
                tcg_gen_mov_tl(c, x);
520 a39f8f3a edgar_igl
521 a39f8f3a edgar_igl
                /* Propagate carry into d if X is set. Branch free.  */
522 a39f8f3a edgar_igl
                tcg_gen_andi_tl(c, c, C_FLAG);
523 a39f8f3a edgar_igl
                tcg_gen_andi_tl(x, x, X_FLAG);
524 a39f8f3a edgar_igl
                tcg_gen_shri_tl(x, x, 4);
525 a39f8f3a edgar_igl
526 a39f8f3a edgar_igl
                tcg_gen_and_tl(x, x, c);
527 a39f8f3a edgar_igl
                tcg_gen_sub_tl(d, d, x);
528 30abcfc7 edgar_igl
                tcg_temp_free(x);
529 30abcfc7 edgar_igl
                tcg_temp_free(c);
530 a39f8f3a edgar_igl
        }
531 3157a0a9 edgar_igl
}
532 3157a0a9 edgar_igl
533 3157a0a9 edgar_igl
/* Swap the two bytes within each half word of the s operand.
534 3157a0a9 edgar_igl
   T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff)  */
535 3157a0a9 edgar_igl
static inline void t_gen_swapb(TCGv d, TCGv s)
536 3157a0a9 edgar_igl
{
537 3157a0a9 edgar_igl
        TCGv t, org_s;
538 3157a0a9 edgar_igl
539 3157a0a9 edgar_igl
        t = tcg_temp_new(TCG_TYPE_TL);
540 3157a0a9 edgar_igl
        org_s = tcg_temp_new(TCG_TYPE_TL);
541 3157a0a9 edgar_igl
542 3157a0a9 edgar_igl
        /* d and s may refer to the same object.  */
543 3157a0a9 edgar_igl
        tcg_gen_mov_tl(org_s, s);
544 3157a0a9 edgar_igl
        tcg_gen_shli_tl(t, org_s, 8);
545 3157a0a9 edgar_igl
        tcg_gen_andi_tl(d, t, 0xff00ff00);
546 3157a0a9 edgar_igl
        tcg_gen_shri_tl(t, org_s, 8);
547 3157a0a9 edgar_igl
        tcg_gen_andi_tl(t, t, 0x00ff00ff);
548 3157a0a9 edgar_igl
        tcg_gen_or_tl(d, d, t);
549 30abcfc7 edgar_igl
        tcg_temp_free(t);
550 30abcfc7 edgar_igl
        tcg_temp_free(org_s);
551 3157a0a9 edgar_igl
}
552 3157a0a9 edgar_igl
553 3157a0a9 edgar_igl
/* Swap the halfwords of the s operand.  */
554 3157a0a9 edgar_igl
static inline void t_gen_swapw(TCGv d, TCGv s)
555 3157a0a9 edgar_igl
{
556 3157a0a9 edgar_igl
        TCGv t;
557 3157a0a9 edgar_igl
        /* d and s refer the same object.  */
558 3157a0a9 edgar_igl
        t = tcg_temp_new(TCG_TYPE_TL);
559 3157a0a9 edgar_igl
        tcg_gen_mov_tl(t, s);
560 3157a0a9 edgar_igl
        tcg_gen_shli_tl(d, t, 16);
561 3157a0a9 edgar_igl
        tcg_gen_shri_tl(t, t, 16);
562 3157a0a9 edgar_igl
        tcg_gen_or_tl(d, d, t);
563 30abcfc7 edgar_igl
        tcg_temp_free(t);
564 3157a0a9 edgar_igl
}
565 3157a0a9 edgar_igl
566 3157a0a9 edgar_igl
/* Reverse the within each byte.
567 3157a0a9 edgar_igl
   T0 = (((T0 << 7) & 0x80808080) |
568 3157a0a9 edgar_igl
   ((T0 << 5) & 0x40404040) |
569 3157a0a9 edgar_igl
   ((T0 << 3) & 0x20202020) |
570 3157a0a9 edgar_igl
   ((T0 << 1) & 0x10101010) |
571 3157a0a9 edgar_igl
   ((T0 >> 1) & 0x08080808) |
572 3157a0a9 edgar_igl
   ((T0 >> 3) & 0x04040404) |
573 3157a0a9 edgar_igl
   ((T0 >> 5) & 0x02020202) |
574 3157a0a9 edgar_igl
   ((T0 >> 7) & 0x01010101));
575 3157a0a9 edgar_igl
 */
576 3157a0a9 edgar_igl
static inline void t_gen_swapr(TCGv d, TCGv s)
577 3157a0a9 edgar_igl
{
578 3157a0a9 edgar_igl
        struct {
579 3157a0a9 edgar_igl
                int shift; /* LSL when positive, LSR when negative.  */
580 3157a0a9 edgar_igl
                uint32_t mask;
581 3157a0a9 edgar_igl
        } bitrev [] = {
582 3157a0a9 edgar_igl
                {7, 0x80808080},
583 3157a0a9 edgar_igl
                {5, 0x40404040},
584 3157a0a9 edgar_igl
                {3, 0x20202020},
585 3157a0a9 edgar_igl
                {1, 0x10101010},
586 3157a0a9 edgar_igl
                {-1, 0x08080808},
587 3157a0a9 edgar_igl
                {-3, 0x04040404},
588 3157a0a9 edgar_igl
                {-5, 0x02020202},
589 3157a0a9 edgar_igl
                {-7, 0x01010101}
590 3157a0a9 edgar_igl
        };
591 3157a0a9 edgar_igl
        int i;
592 3157a0a9 edgar_igl
        TCGv t, org_s;
593 3157a0a9 edgar_igl
594 3157a0a9 edgar_igl
        /* d and s refer the same object.  */
595 3157a0a9 edgar_igl
        t = tcg_temp_new(TCG_TYPE_TL);
596 3157a0a9 edgar_igl
        org_s = tcg_temp_new(TCG_TYPE_TL);
597 3157a0a9 edgar_igl
        tcg_gen_mov_tl(org_s, s);
598 3157a0a9 edgar_igl
599 3157a0a9 edgar_igl
        tcg_gen_shli_tl(t, org_s,  bitrev[0].shift);
600 3157a0a9 edgar_igl
        tcg_gen_andi_tl(d, t,  bitrev[0].mask);
601 3157a0a9 edgar_igl
        for (i = 1; i < sizeof bitrev / sizeof bitrev[0]; i++) {
602 3157a0a9 edgar_igl
                if (bitrev[i].shift >= 0) {
603 3157a0a9 edgar_igl
                        tcg_gen_shli_tl(t, org_s,  bitrev[i].shift);
604 3157a0a9 edgar_igl
                } else {
605 3157a0a9 edgar_igl
                        tcg_gen_shri_tl(t, org_s,  -bitrev[i].shift);
606 3157a0a9 edgar_igl
                }
607 3157a0a9 edgar_igl
                tcg_gen_andi_tl(t, t,  bitrev[i].mask);
608 3157a0a9 edgar_igl
                tcg_gen_or_tl(d, d, t);
609 3157a0a9 edgar_igl
        }
610 30abcfc7 edgar_igl
        tcg_temp_free(t);
611 30abcfc7 edgar_igl
        tcg_temp_free(org_s);
612 3157a0a9 edgar_igl
}
613 3157a0a9 edgar_igl
614 cf1d97f0 edgar_igl
static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
615 17ac9754 edgar_igl
{
616 17ac9754 edgar_igl
        TCGv btaken;
617 17ac9754 edgar_igl
        int l1;
618 17ac9754 edgar_igl
619 17ac9754 edgar_igl
        l1 = gen_new_label();
620 17ac9754 edgar_igl
        btaken = tcg_temp_new(TCG_TYPE_TL);
621 17ac9754 edgar_igl
622 17ac9754 edgar_igl
        /* Conditional jmp.  */
623 2a44f7f1 edgar_igl
        tcg_gen_mov_tl(btaken, env_btaken);
624 cf1d97f0 edgar_igl
        tcg_gen_mov_tl(env_pc, pc_false);
625 cb63669a pbrook
        tcg_gen_brcondi_tl(TCG_COND_EQ, btaken, 0, l1);
626 cf1d97f0 edgar_igl
        tcg_gen_mov_tl(env_pc, pc_true);
627 17ac9754 edgar_igl
        gen_set_label(l1);
628 17ac9754 edgar_igl
629 30abcfc7 edgar_igl
        tcg_temp_free(btaken);
630 17ac9754 edgar_igl
}
631 17ac9754 edgar_igl
632 8170028d ths
static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
633 8170028d ths
{
634 8170028d ths
        TranslationBlock *tb;
635 8170028d ths
        tb = dc->tb;
636 8170028d ths
        if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
637 05ba7d5f edgar_igl
                tcg_gen_goto_tb(n);
638 50cfa95c edgar_igl
                tcg_gen_movi_tl(env_pc, dest);
639 05ba7d5f edgar_igl
                tcg_gen_exit_tb((long)tb + n);
640 8170028d ths
        } else {
641 2a44f7f1 edgar_igl
                tcg_gen_movi_tl(env_pc, dest);
642 05ba7d5f edgar_igl
                tcg_gen_exit_tb(0);
643 8170028d ths
        }
644 8170028d ths
}
645 8170028d ths
646 8170028d ths
/* Sign extend at translation time.  */
647 8170028d ths
static int sign_extend(unsigned int val, unsigned int width)
648 8170028d ths
{
649 8170028d ths
        int sval;
650 8170028d ths
651 8170028d ths
        /* LSL.  */
652 8170028d ths
        val <<= 31 - width;
653 8170028d ths
        sval = val;
654 8170028d ths
        /* ASR.  */
655 8170028d ths
        sval >>= 31 - width;
656 8170028d ths
        return sval;
657 8170028d ths
}
658 8170028d ths
659 05ba7d5f edgar_igl
static inline void cris_clear_x_flag(DisasContext *dc)
660 05ba7d5f edgar_igl
{
661 2a44f7f1 edgar_igl
        if (dc->flagx_known && dc->flags_x)
662 2a44f7f1 edgar_igl
                dc->flags_uptodate = 0;
663 2a44f7f1 edgar_igl
664 30abcfc7 edgar_igl
        dc->flagx_known = 1;
665 b41f7df0 edgar_igl
        dc->flags_x = 0;
666 05ba7d5f edgar_igl
}
667 05ba7d5f edgar_igl
668 30abcfc7 edgar_igl
static void cris_flush_cc_state(DisasContext *dc)
669 8170028d ths
{
670 30abcfc7 edgar_igl
        if (dc->cc_size_uptodate != dc->cc_size) {
671 b41f7df0 edgar_igl
                tcg_gen_movi_tl(cc_size, dc->cc_size);
672 30abcfc7 edgar_igl
                dc->cc_size_uptodate = dc->cc_size;
673 30abcfc7 edgar_igl
        }
674 30abcfc7 edgar_igl
        tcg_gen_movi_tl(cc_op, dc->cc_op);
675 30abcfc7 edgar_igl
        tcg_gen_movi_tl(cc_mask, dc->cc_mask);
676 30abcfc7 edgar_igl
}
677 30abcfc7 edgar_igl
678 30abcfc7 edgar_igl
static void cris_evaluate_flags(DisasContext *dc)
679 30abcfc7 edgar_igl
{
680 30abcfc7 edgar_igl
        if (!dc->flags_uptodate) {
681 30abcfc7 edgar_igl
                cris_flush_cc_state(dc);
682 b41f7df0 edgar_igl
683 8170028d ths
                switch (dc->cc_op)
684 8170028d ths
                {
685 8170028d ths
                        case CC_OP_MCP:
686 b41f7df0 edgar_igl
                                tcg_gen_helper_0_0(helper_evaluate_flags_mcp);
687 8170028d ths
                                break;
688 8170028d ths
                        case CC_OP_MULS:
689 b41f7df0 edgar_igl
                                tcg_gen_helper_0_0(helper_evaluate_flags_muls);
690 8170028d ths
                                break;
691 8170028d ths
                        case CC_OP_MULU:
692 b41f7df0 edgar_igl
                                tcg_gen_helper_0_0(helper_evaluate_flags_mulu);
693 8170028d ths
                                break;
694 8170028d ths
                        case CC_OP_MOVE:
695 30abcfc7 edgar_igl
                        case CC_OP_AND:
696 30abcfc7 edgar_igl
                        case CC_OP_OR:
697 30abcfc7 edgar_igl
                        case CC_OP_XOR:
698 30abcfc7 edgar_igl
                        case CC_OP_ASR:
699 30abcfc7 edgar_igl
                        case CC_OP_LSR:
700 30abcfc7 edgar_igl
                        case CC_OP_LSL:
701 8170028d ths
                                switch (dc->cc_size)
702 8170028d ths
                                {
703 8170028d ths
                                        case 4:
704 b41f7df0 edgar_igl
                                                tcg_gen_helper_0_0(helper_evaluate_flags_move_4);
705 8170028d ths
                                                break;
706 8170028d ths
                                        case 2:
707 b41f7df0 edgar_igl
                                                tcg_gen_helper_0_0(helper_evaluate_flags_move_2);
708 8170028d ths
                                                break;
709 8170028d ths
                                        default:
710 b41f7df0 edgar_igl
                                                tcg_gen_helper_0_0(helper_evaluate_flags);
711 8170028d ths
                                                break;
712 8170028d ths
                                }
713 8170028d ths
                                break;
714 b41f7df0 edgar_igl
                        case CC_OP_FLAGS:
715 b41f7df0 edgar_igl
                                /* live.  */
716 b41f7df0 edgar_igl
                                break;
717 8170028d ths
                        default:
718 8170028d ths
                        {
719 8170028d ths
                                switch (dc->cc_size)
720 8170028d ths
                                {
721 8170028d ths
                                        case 4:
722 b41f7df0 edgar_igl
                                                tcg_gen_helper_0_0(helper_evaluate_flags_alu_4);
723 8170028d ths
                                                break;
724 8170028d ths
                                        default:
725 b41f7df0 edgar_igl
                                                tcg_gen_helper_0_0(helper_evaluate_flags);
726 8170028d ths
                                                break;
727 8170028d ths
                                }
728 8170028d ths
                        }
729 8170028d ths
                        break;
730 8170028d ths
                }
731 2a44f7f1 edgar_igl
                if (dc->flagx_known) {
732 2a44f7f1 edgar_igl
                        if (dc->flags_x)
733 2a44f7f1 edgar_igl
                                tcg_gen_ori_tl(cpu_PR[PR_CCS], 
734 2a44f7f1 edgar_igl
                                               cpu_PR[PR_CCS], X_FLAG);
735 2a44f7f1 edgar_igl
                        else
736 2a44f7f1 edgar_igl
                                tcg_gen_andi_tl(cpu_PR[PR_CCS], 
737 2a44f7f1 edgar_igl
                                                cpu_PR[PR_CCS], ~X_FLAG);
738 2a44f7f1 edgar_igl
        }
739 2a44f7f1 edgar_igl
740 30abcfc7 edgar_igl
                dc->flags_uptodate = 1;
741 8170028d ths
        }
742 8170028d ths
}
743 8170028d ths
744 8170028d ths
static void cris_cc_mask(DisasContext *dc, unsigned int mask)
745 8170028d ths
{
746 8170028d ths
        uint32_t ovl;
747 8170028d ths
748 2a44f7f1 edgar_igl
        if (!mask) {
749 2a44f7f1 edgar_igl
                dc->update_cc = 0;
750 2a44f7f1 edgar_igl
                return;
751 2a44f7f1 edgar_igl
        }        
752 2a44f7f1 edgar_igl
753 fd56059f balrog
        /* Check if we need to evaluate the condition codes due to 
754 fd56059f balrog
           CC overlaying.  */
755 8170028d ths
        ovl = (dc->cc_mask ^ mask) & ~mask;
756 8170028d ths
        if (ovl) {
757 8170028d ths
                /* TODO: optimize this case. It trigs all the time.  */
758 8170028d ths
                cris_evaluate_flags (dc);
759 8170028d ths
        }
760 8170028d ths
        dc->cc_mask = mask;
761 8170028d ths
        dc->update_cc = 1;
762 8170028d ths
}
763 8170028d ths
764 b41f7df0 edgar_igl
static void cris_update_cc_op(DisasContext *dc, int op, int size)
765 8170028d ths
{
766 8170028d ths
        dc->cc_op = op;
767 8170028d ths
        dc->cc_size = size;
768 30abcfc7 edgar_igl
        dc->flags_uptodate = 0;
769 8170028d ths
}
770 8170028d ths
771 30abcfc7 edgar_igl
static inline void cris_update_cc_x(DisasContext *dc)
772 30abcfc7 edgar_igl
{
773 30abcfc7 edgar_igl
        /* Save the x flag state at the time of the cc snapshot.  */
774 30abcfc7 edgar_igl
        if (dc->flagx_known) {
775 30abcfc7 edgar_igl
                if (dc->cc_x_uptodate == (2 | dc->flags_x))
776 30abcfc7 edgar_igl
                        return;
777 30abcfc7 edgar_igl
                tcg_gen_movi_tl(cc_x, dc->flags_x);
778 30abcfc7 edgar_igl
                dc->cc_x_uptodate = 2 | dc->flags_x;
779 30abcfc7 edgar_igl
        }
780 30abcfc7 edgar_igl
        else {
781 30abcfc7 edgar_igl
                tcg_gen_andi_tl(cc_x, cpu_PR[PR_CCS], X_FLAG);
782 30abcfc7 edgar_igl
                dc->cc_x_uptodate = 1;
783 30abcfc7 edgar_igl
        }
784 30abcfc7 edgar_igl
}
785 30abcfc7 edgar_igl
786 30abcfc7 edgar_igl
/* Update cc prior to executing ALU op. Needs source operands untouched.  */
787 30abcfc7 edgar_igl
static void cris_pre_alu_update_cc(DisasContext *dc, int op, 
788 30abcfc7 edgar_igl
                                   TCGv dst, TCGv src, int size)
789 8170028d ths
{
790 8170028d ths
        if (dc->update_cc) {
791 b41f7df0 edgar_igl
                cris_update_cc_op(dc, op, size);
792 30abcfc7 edgar_igl
                tcg_gen_mov_tl(cc_src, src);
793 30abcfc7 edgar_igl
794 30abcfc7 edgar_igl
                if (op != CC_OP_MOVE
795 30abcfc7 edgar_igl
                    && op != CC_OP_AND
796 30abcfc7 edgar_igl
                    && op != CC_OP_OR
797 30abcfc7 edgar_igl
                    && op != CC_OP_XOR
798 30abcfc7 edgar_igl
                    && op != CC_OP_ASR
799 30abcfc7 edgar_igl
                    && op != CC_OP_LSR
800 30abcfc7 edgar_igl
                    && op != CC_OP_LSL)
801 30abcfc7 edgar_igl
                        tcg_gen_mov_tl(cc_dest, dst);
802 30abcfc7 edgar_igl
803 30abcfc7 edgar_igl
                cris_update_cc_x(dc);
804 30abcfc7 edgar_igl
        }
805 30abcfc7 edgar_igl
}
806 3157a0a9 edgar_igl
807 30abcfc7 edgar_igl
/* Update cc after executing ALU op. needs the result.  */
808 30abcfc7 edgar_igl
static inline void cris_update_result(DisasContext *dc, TCGv res)
809 30abcfc7 edgar_igl
{
810 30abcfc7 edgar_igl
        if (dc->update_cc) {
811 30abcfc7 edgar_igl
                if (dc->cc_size == 4 && 
812 30abcfc7 edgar_igl
                    (dc->cc_op == CC_OP_SUB
813 30abcfc7 edgar_igl
                     || dc->cc_op == CC_OP_ADD))
814 30abcfc7 edgar_igl
                        return;
815 30abcfc7 edgar_igl
                tcg_gen_mov_tl(cc_result, res);
816 8170028d ths
        }
817 30abcfc7 edgar_igl
}
818 8170028d ths
819 30abcfc7 edgar_igl
/* Returns one if the write back stage should execute.  */
820 30abcfc7 edgar_igl
static void cris_alu_op_exec(DisasContext *dc, int op, 
821 30abcfc7 edgar_igl
                               TCGv dst, TCGv a, TCGv b, int size)
822 30abcfc7 edgar_igl
{
823 8170028d ths
        /* Emit the ALU insns.  */
824 8170028d ths
        switch (op)
825 8170028d ths
        {
826 8170028d ths
                case CC_OP_ADD:
827 30abcfc7 edgar_igl
                        tcg_gen_add_tl(dst, a, b);
828 8170028d ths
                        /* Extended arithmetics.  */
829 30abcfc7 edgar_igl
                        t_gen_addx_carry(dc, dst);
830 8170028d ths
                        break;
831 8170028d ths
                case CC_OP_ADDC:
832 30abcfc7 edgar_igl
                        tcg_gen_add_tl(dst, a, b);
833 30abcfc7 edgar_igl
                        t_gen_add_flag(dst, 0); /* C_FLAG.  */
834 8170028d ths
                        break;
835 8170028d ths
                case CC_OP_MCP:
836 30abcfc7 edgar_igl
                        tcg_gen_add_tl(dst, a, b);
837 30abcfc7 edgar_igl
                        t_gen_add_flag(dst, 8); /* R_FLAG.  */
838 8170028d ths
                        break;
839 8170028d ths
                case CC_OP_SUB:
840 30abcfc7 edgar_igl
                        tcg_gen_sub_tl(dst, a, b);
841 8170028d ths
                        /* Extended arithmetics.  */
842 30abcfc7 edgar_igl
                        t_gen_subx_carry(dc, dst);
843 8170028d ths
                        break;
844 8170028d ths
                case CC_OP_MOVE:
845 30abcfc7 edgar_igl
                        tcg_gen_mov_tl(dst, b);
846 8170028d ths
                        break;
847 8170028d ths
                case CC_OP_OR:
848 30abcfc7 edgar_igl
                        tcg_gen_or_tl(dst, a, b);
849 8170028d ths
                        break;
850 8170028d ths
                case CC_OP_AND:
851 30abcfc7 edgar_igl
                        tcg_gen_and_tl(dst, a, b);
852 8170028d ths
                        break;
853 8170028d ths
                case CC_OP_XOR:
854 30abcfc7 edgar_igl
                        tcg_gen_xor_tl(dst, a, b);
855 8170028d ths
                        break;
856 8170028d ths
                case CC_OP_LSL:
857 30abcfc7 edgar_igl
                        t_gen_lsl(dst, a, b);
858 8170028d ths
                        break;
859 8170028d ths
                case CC_OP_LSR:
860 30abcfc7 edgar_igl
                        t_gen_lsr(dst, a, b);
861 8170028d ths
                        break;
862 8170028d ths
                case CC_OP_ASR:
863 30abcfc7 edgar_igl
                        t_gen_asr(dst, a, b);
864 8170028d ths
                        break;
865 8170028d ths
                case CC_OP_NEG:
866 30abcfc7 edgar_igl
                        tcg_gen_neg_tl(dst, b);
867 8170028d ths
                        /* Extended arithmetics.  */
868 30abcfc7 edgar_igl
                        t_gen_subx_carry(dc, dst);
869 8170028d ths
                        break;
870 8170028d ths
                case CC_OP_LZ:
871 30abcfc7 edgar_igl
                        t_gen_lz_i32(dst, b);
872 8170028d ths
                        break;
873 8170028d ths
                case CC_OP_BTST:
874 30abcfc7 edgar_igl
                        t_gen_btst(dst, a, b);
875 8170028d ths
                        break;
876 8170028d ths
                case CC_OP_MULS:
877 30abcfc7 edgar_igl
                        t_gen_muls(dst, cpu_PR[PR_MOF], a, b);
878 30abcfc7 edgar_igl
                        break;
879 8170028d ths
                case CC_OP_MULU:
880 30abcfc7 edgar_igl
                        t_gen_mulu(dst, cpu_PR[PR_MOF], a, b);
881 30abcfc7 edgar_igl
                        break;
882 8170028d ths
                case CC_OP_DSTEP:
883 30abcfc7 edgar_igl
                        t_gen_cris_dstep(dst, a, b);
884 8170028d ths
                        break;
885 8170028d ths
                case CC_OP_BOUND:
886 3157a0a9 edgar_igl
                {
887 3157a0a9 edgar_igl
                        int l1;
888 3157a0a9 edgar_igl
                        l1 = gen_new_label();
889 30abcfc7 edgar_igl
                        tcg_gen_mov_tl(dst, a);
890 30abcfc7 edgar_igl
                        tcg_gen_brcond_tl(TCG_COND_LEU, a, b, l1);
891 30abcfc7 edgar_igl
                        tcg_gen_mov_tl(dst, b);
892 3157a0a9 edgar_igl
                        gen_set_label(l1);
893 3157a0a9 edgar_igl
                }
894 3157a0a9 edgar_igl
                break;
895 8170028d ths
                case CC_OP_CMP:
896 30abcfc7 edgar_igl
                        tcg_gen_sub_tl(dst, a, b);
897 8170028d ths
                        /* Extended arithmetics.  */
898 30abcfc7 edgar_igl
                        t_gen_subx_carry(dc, dst);
899 8170028d ths
                        break;
900 8170028d ths
                default:
901 8170028d ths
                        fprintf (logfile, "illegal ALU op.\n");
902 8170028d ths
                        BUG();
903 8170028d ths
                        break;
904 8170028d ths
        }
905 8170028d ths
906 8170028d ths
        if (size == 1)
907 30abcfc7 edgar_igl
                tcg_gen_andi_tl(dst, dst, 0xff);
908 8170028d ths
        else if (size == 2)
909 30abcfc7 edgar_igl
                tcg_gen_andi_tl(dst, dst, 0xffff);
910 30abcfc7 edgar_igl
}
911 30abcfc7 edgar_igl
912 30abcfc7 edgar_igl
static void cris_alu(DisasContext *dc, int op,
913 30abcfc7 edgar_igl
                               TCGv d, TCGv op_a, TCGv op_b, int size)
914 30abcfc7 edgar_igl
{
915 30abcfc7 edgar_igl
        TCGv tmp;
916 30abcfc7 edgar_igl
        int writeback;
917 30abcfc7 edgar_igl
918 30abcfc7 edgar_igl
        writeback = 1;
919 30abcfc7 edgar_igl
        tmp = cpu_T[0];
920 30abcfc7 edgar_igl
        if (op == CC_OP_CMP)
921 30abcfc7 edgar_igl
                writeback = 0;
922 30abcfc7 edgar_igl
        else if (size == 4) {
923 30abcfc7 edgar_igl
                tmp = d;
924 30abcfc7 edgar_igl
                writeback = 0;
925 30abcfc7 edgar_igl
        }
926 30abcfc7 edgar_igl
927 30abcfc7 edgar_igl
        cris_pre_alu_update_cc(dc, op, op_a, op_b, size);
928 30abcfc7 edgar_igl
        cris_alu_op_exec(dc, op, tmp, op_a, op_b, size);
929 30abcfc7 edgar_igl
        cris_update_result(dc, tmp);
930 05ba7d5f edgar_igl
931 8170028d ths
        /* Writeback.  */
932 8170028d ths
        if (writeback) {
933 30abcfc7 edgar_igl
                if (size == 1)
934 30abcfc7 edgar_igl
                        tcg_gen_andi_tl(d, d, ~0xff);
935 30abcfc7 edgar_igl
                else
936 30abcfc7 edgar_igl
                        tcg_gen_andi_tl(d, d, ~0xffff);
937 30abcfc7 edgar_igl
                tcg_gen_or_tl(d, d, tmp);
938 8170028d ths
        }
939 8170028d ths
}
940 8170028d ths
941 8170028d ths
static int arith_cc(DisasContext *dc)
942 8170028d ths
{
943 8170028d ths
        if (dc->update_cc) {
944 8170028d ths
                switch (dc->cc_op) {
945 30abcfc7 edgar_igl
                        case CC_OP_ADDC: return 1;
946 8170028d ths
                        case CC_OP_ADD: return 1;
947 8170028d ths
                        case CC_OP_SUB: return 1;
948 30abcfc7 edgar_igl
                        case CC_OP_DSTEP: return 1;
949 8170028d ths
                        case CC_OP_LSL: return 1;
950 8170028d ths
                        case CC_OP_LSR: return 1;
951 8170028d ths
                        case CC_OP_ASR: return 1;
952 8170028d ths
                        case CC_OP_CMP: return 1;
953 30abcfc7 edgar_igl
                        case CC_OP_NEG: return 1;
954 30abcfc7 edgar_igl
                        case CC_OP_OR: return 1;
955 30abcfc7 edgar_igl
                        case CC_OP_XOR: return 1;
956 30abcfc7 edgar_igl
                        case CC_OP_MULU: return 1;
957 30abcfc7 edgar_igl
                        case CC_OP_MULS: return 1;
958 8170028d ths
                        default:
959 8170028d ths
                                return 0;
960 8170028d ths
                }
961 8170028d ths
        }
962 8170028d ths
        return 0;
963 8170028d ths
}
964 8170028d ths
965 8170028d ths
static void gen_tst_cc (DisasContext *dc, int cond)
966 8170028d ths
{
967 2a44f7f1 edgar_igl
        int arith_opt, move_opt;
968 8170028d ths
969 8170028d ths
        /* TODO: optimize more condition codes.  */
970 dceaf394 edgar_igl
971 dceaf394 edgar_igl
        /*
972 dceaf394 edgar_igl
         * If the flags are live, we've gotta look into the bits of CCS.
973 dceaf394 edgar_igl
         * Otherwise, if we just did an arithmetic operation we try to
974 dceaf394 edgar_igl
         * evaluate the condition code faster.
975 dceaf394 edgar_igl
         *
976 dceaf394 edgar_igl
         * When this function is done, T0 should be non-zero if the condition
977 dceaf394 edgar_igl
         * code is true.
978 dceaf394 edgar_igl
         */
979 30abcfc7 edgar_igl
        arith_opt = arith_cc(dc) && !dc->flags_uptodate;
980 2a44f7f1 edgar_igl
        move_opt = (dc->cc_op == CC_OP_MOVE) && !dc->flags_uptodate;
981 8170028d ths
        switch (cond) {
982 8170028d ths
                case CC_EQ:
983 2a44f7f1 edgar_igl
                        if (arith_opt || move_opt) {
984 dceaf394 edgar_igl
                                /* If cc_result is zero, T0 should be 
985 dceaf394 edgar_igl
                                   non-zero otherwise T0 should be zero.  */
986 dceaf394 edgar_igl
                                int l1;
987 dceaf394 edgar_igl
                                l1 = gen_new_label();
988 dceaf394 edgar_igl
                                tcg_gen_movi_tl(cpu_T[0], 0);
989 cb63669a pbrook
                                tcg_gen_brcondi_tl(TCG_COND_NE, cc_result, 
990 cb63669a pbrook
                                                   0, l1);
991 dceaf394 edgar_igl
                                tcg_gen_movi_tl(cpu_T[0], 1);
992 dceaf394 edgar_igl
                                gen_set_label(l1);
993 dceaf394 edgar_igl
                        }
994 8170028d ths
                        else {
995 8170028d ths
                                cris_evaluate_flags(dc);
996 dceaf394 edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], 
997 dceaf394 edgar_igl
                                                cpu_PR[PR_CCS], Z_FLAG);
998 8170028d ths
                        }
999 8170028d ths
                        break;
1000 8170028d ths
                case CC_NE:
1001 2a44f7f1 edgar_igl
                        if (arith_opt || move_opt)
1002 dceaf394 edgar_igl
                                tcg_gen_mov_tl(cpu_T[0], cc_result);
1003 8170028d ths
                        else {
1004 8170028d ths
                                cris_evaluate_flags(dc);
1005 dceaf394 edgar_igl
                                tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS],
1006 dceaf394 edgar_igl
                                                Z_FLAG);
1007 dceaf394 edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], Z_FLAG);
1008 8170028d ths
                        }
1009 8170028d ths
                        break;
1010 8170028d ths
                case CC_CS:
1011 8170028d ths
                        cris_evaluate_flags(dc);
1012 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], C_FLAG);
1013 8170028d ths
                        break;
1014 8170028d ths
                case CC_CC:
1015 8170028d ths
                        cris_evaluate_flags(dc);
1016 2a44f7f1 edgar_igl
                        tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS], C_FLAG);
1017 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], C_FLAG);
1018 8170028d ths
                        break;
1019 8170028d ths
                case CC_VS:
1020 8170028d ths
                        cris_evaluate_flags(dc);
1021 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], V_FLAG);
1022 8170028d ths
                        break;
1023 8170028d ths
                case CC_VC:
1024 8170028d ths
                        cris_evaluate_flags(dc);
1025 dceaf394 edgar_igl
                        tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS],
1026 dceaf394 edgar_igl
                                        V_FLAG);
1027 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], V_FLAG);
1028 8170028d ths
                        break;
1029 8170028d ths
                case CC_PL:
1030 2a44f7f1 edgar_igl
                        if (arith_opt || move_opt) {
1031 2a44f7f1 edgar_igl
                                int bits = 31;
1032 2a44f7f1 edgar_igl
1033 2a44f7f1 edgar_igl
                                if (dc->cc_size == 1)
1034 2a44f7f1 edgar_igl
                                        bits = 7;
1035 2a44f7f1 edgar_igl
                                else if (dc->cc_size == 2)
1036 2a44f7f1 edgar_igl
                                        bits = 15;        
1037 2a44f7f1 edgar_igl
1038 2a44f7f1 edgar_igl
                                tcg_gen_shri_tl(cpu_T[0], cc_result, bits);
1039 2a44f7f1 edgar_igl
                                tcg_gen_xori_tl(cpu_T[0], cpu_T[0], 1);
1040 2a44f7f1 edgar_igl
                        } else {
1041 8170028d ths
                                cris_evaluate_flags(dc);
1042 dceaf394 edgar_igl
                                tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS],
1043 dceaf394 edgar_igl
                                                N_FLAG);
1044 dceaf394 edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], N_FLAG);
1045 8170028d ths
                        }
1046 8170028d ths
                        break;
1047 8170028d ths
                case CC_MI:
1048 2a44f7f1 edgar_igl
                        if (arith_opt || move_opt) {
1049 2a44f7f1 edgar_igl
                                int bits = 31;
1050 2a44f7f1 edgar_igl
1051 2a44f7f1 edgar_igl
                                if (dc->cc_size == 1)
1052 2a44f7f1 edgar_igl
                                        bits = 7;
1053 2a44f7f1 edgar_igl
                                else if (dc->cc_size == 2)
1054 2a44f7f1 edgar_igl
                                        bits = 15;        
1055 2a44f7f1 edgar_igl
1056 2a44f7f1 edgar_igl
                                tcg_gen_shri_tl(cpu_T[0], cc_result, 31);
1057 dceaf394 edgar_igl
                        }
1058 8170028d ths
                        else {
1059 8170028d ths
                                cris_evaluate_flags(dc);
1060 dceaf394 edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS],
1061 dceaf394 edgar_igl
                                                N_FLAG);
1062 8170028d ths
                        }
1063 8170028d ths
                        break;
1064 8170028d ths
                case CC_LS:
1065 8170028d ths
                        cris_evaluate_flags(dc);
1066 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS],
1067 dceaf394 edgar_igl
                                        C_FLAG | Z_FLAG);
1068 8170028d ths
                        break;
1069 8170028d ths
                case CC_HI:
1070 8170028d ths
                        cris_evaluate_flags(dc);
1071 dceaf394 edgar_igl
                        {
1072 dceaf394 edgar_igl
                                TCGv tmp;
1073 dceaf394 edgar_igl
1074 dceaf394 edgar_igl
                                tmp = tcg_temp_new(TCG_TYPE_TL);
1075 dceaf394 edgar_igl
                                tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS],
1076 dceaf394 edgar_igl
                                                C_FLAG | Z_FLAG);
1077 dceaf394 edgar_igl
                                /* Overlay the C flag on top of the Z.  */
1078 dceaf394 edgar_igl
                                tcg_gen_shli_tl(cpu_T[0], tmp, 2);
1079 dceaf394 edgar_igl
                                tcg_gen_and_tl(cpu_T[0], tmp, cpu_T[0]);
1080 dceaf394 edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], Z_FLAG);
1081 dceaf394 edgar_igl
1082 30abcfc7 edgar_igl
                                tcg_temp_free(tmp);
1083 dceaf394 edgar_igl
                        }
1084 8170028d ths
                        break;
1085 8170028d ths
                case CC_GE:
1086 8170028d ths
                        cris_evaluate_flags(dc);
1087 dceaf394 edgar_igl
                        /* Overlay the V flag on top of the N.  */
1088 dceaf394 edgar_igl
                        tcg_gen_shli_tl(cpu_T[0], cpu_PR[PR_CCS], 2);
1089 dceaf394 edgar_igl
                        tcg_gen_xor_tl(cpu_T[0],
1090 dceaf394 edgar_igl
                                       cpu_PR[PR_CCS], cpu_T[0]);
1091 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], N_FLAG);
1092 dceaf394 edgar_igl
                        tcg_gen_xori_tl(cpu_T[0], cpu_T[0], N_FLAG);
1093 8170028d ths
                        break;
1094 8170028d ths
                case CC_LT:
1095 8170028d ths
                        cris_evaluate_flags(dc);
1096 dceaf394 edgar_igl
                        /* Overlay the V flag on top of the N.  */
1097 dceaf394 edgar_igl
                        tcg_gen_shli_tl(cpu_T[0], cpu_PR[PR_CCS], 2);
1098 dceaf394 edgar_igl
                        tcg_gen_xor_tl(cpu_T[0],
1099 dceaf394 edgar_igl
                                       cpu_PR[PR_CCS], cpu_T[0]);
1100 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], N_FLAG);
1101 8170028d ths
                        break;
1102 8170028d ths
                case CC_GT:
1103 8170028d ths
                        cris_evaluate_flags(dc);
1104 dceaf394 edgar_igl
                        {
1105 dceaf394 edgar_igl
                                TCGv n, z;
1106 dceaf394 edgar_igl
1107 dceaf394 edgar_igl
                                n = tcg_temp_new(TCG_TYPE_TL);
1108 dceaf394 edgar_igl
                                z = tcg_temp_new(TCG_TYPE_TL);
1109 dceaf394 edgar_igl
1110 dceaf394 edgar_igl
                                /* To avoid a shift we overlay everything on
1111 dceaf394 edgar_igl
                                   the V flag.  */
1112 dceaf394 edgar_igl
                                tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1113 dceaf394 edgar_igl
                                tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1114 dceaf394 edgar_igl
                                /* invert Z.  */
1115 dceaf394 edgar_igl
                                tcg_gen_xori_tl(z, z, 2);
1116 dceaf394 edgar_igl
1117 dceaf394 edgar_igl
                                tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1118 dceaf394 edgar_igl
                                tcg_gen_xori_tl(n, n, 2);
1119 dceaf394 edgar_igl
                                tcg_gen_and_tl(cpu_T[0], z, n);
1120 dceaf394 edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 2);
1121 dceaf394 edgar_igl
1122 30abcfc7 edgar_igl
                                tcg_temp_free(n);
1123 30abcfc7 edgar_igl
                                tcg_temp_free(z);
1124 dceaf394 edgar_igl
                        }
1125 8170028d ths
                        break;
1126 8170028d ths
                case CC_LE:
1127 8170028d ths
                        cris_evaluate_flags(dc);
1128 dceaf394 edgar_igl
                        {
1129 dceaf394 edgar_igl
                                TCGv n, z;
1130 dceaf394 edgar_igl
1131 dceaf394 edgar_igl
                                n = tcg_temp_new(TCG_TYPE_TL);
1132 dceaf394 edgar_igl
                                z = tcg_temp_new(TCG_TYPE_TL);
1133 dceaf394 edgar_igl
1134 dceaf394 edgar_igl
                                /* To avoid a shift we overlay everything on
1135 dceaf394 edgar_igl
                                   the V flag.  */
1136 dceaf394 edgar_igl
                                tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1137 dceaf394 edgar_igl
                                tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1138 dceaf394 edgar_igl
1139 dceaf394 edgar_igl
                                tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1140 dceaf394 edgar_igl
                                tcg_gen_or_tl(cpu_T[0], z, n);
1141 dceaf394 edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 2);
1142 dceaf394 edgar_igl
1143 30abcfc7 edgar_igl
                                tcg_temp_free(n);
1144 30abcfc7 edgar_igl
                                tcg_temp_free(z);
1145 dceaf394 edgar_igl
                        }
1146 8170028d ths
                        break;
1147 8170028d ths
                case CC_P:
1148 8170028d ths
                        cris_evaluate_flags(dc);
1149 dceaf394 edgar_igl
                        tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], P_FLAG);
1150 8170028d ths
                        break;
1151 8170028d ths
                case CC_A:
1152 17ac9754 edgar_igl
                        tcg_gen_movi_tl(cpu_T[0], 1);
1153 8170028d ths
                        break;
1154 8170028d ths
                default:
1155 8170028d ths
                        BUG();
1156 8170028d ths
                        break;
1157 8170028d ths
        };
1158 8170028d ths
}
1159 8170028d ths
1160 2a44f7f1 edgar_igl
static void cris_store_direct_jmp(DisasContext *dc)
1161 2a44f7f1 edgar_igl
{
1162 2a44f7f1 edgar_igl
        /* Store the direct jmp state into the cpu-state.  */
1163 2a44f7f1 edgar_igl
        if (dc->jmp == JMP_DIRECT) {
1164 2a44f7f1 edgar_igl
                tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1165 2a44f7f1 edgar_igl
                tcg_gen_movi_tl(env_btaken, 1);
1166 2a44f7f1 edgar_igl
        }
1167 2a44f7f1 edgar_igl
}
1168 2a44f7f1 edgar_igl
1169 2a44f7f1 edgar_igl
static void cris_prepare_cc_branch (DisasContext *dc, 
1170 2a44f7f1 edgar_igl
                                    int offset, int cond)
1171 8170028d ths
{
1172 8170028d ths
        /* This helps us re-schedule the micro-code to insns in delay-slots
1173 8170028d ths
           before the actual jump.  */
1174 8170028d ths
        dc->delayed_branch = 2;
1175 2a44f7f1 edgar_igl
        dc->jmp_pc = dc->pc + offset;
1176 2a44f7f1 edgar_igl
1177 8170028d ths
        if (cond != CC_A)
1178 8170028d ths
        {
1179 2a44f7f1 edgar_igl
                dc->jmp = JMP_INDIRECT;
1180 8170028d ths
                gen_tst_cc (dc, cond);
1181 2a44f7f1 edgar_igl
                tcg_gen_mov_tl(env_btaken, cpu_T[0]);
1182 2a44f7f1 edgar_igl
                tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1183 2a44f7f1 edgar_igl
        } else {
1184 2a44f7f1 edgar_igl
                /* Allow chaining.  */
1185 2a44f7f1 edgar_igl
                dc->jmp = JMP_DIRECT;
1186 2a44f7f1 edgar_igl
        }
1187 8170028d ths
}
1188 8170028d ths
1189 b41f7df0 edgar_igl
1190 2a44f7f1 edgar_igl
/* jumps, when the dest is in a live reg for example. Direct should be set
1191 2a44f7f1 edgar_igl
   when the dest addr is constant to allow tb chaining.  */
1192 2a44f7f1 edgar_igl
static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
1193 8170028d ths
{
1194 8170028d ths
        /* This helps us re-schedule the micro-code to insns in delay-slots
1195 8170028d ths
           before the actual jump.  */
1196 8170028d ths
        dc->delayed_branch = 2;
1197 2a44f7f1 edgar_igl
        dc->jmp = type;
1198 2a44f7f1 edgar_igl
        if (type == JMP_INDIRECT)
1199 2a44f7f1 edgar_igl
                tcg_gen_movi_tl(env_btaken, 1);
1200 8170028d ths
}
1201 8170028d ths
1202 b41f7df0 edgar_igl
void gen_load(DisasContext *dc, TCGv dst, TCGv addr, 
1203 b41f7df0 edgar_igl
              unsigned int size, int sign)
1204 8170028d ths
{
1205 b41f7df0 edgar_igl
        int mem_index = cpu_mmu_index(dc->env);
1206 b41f7df0 edgar_igl
1207 2a44f7f1 edgar_igl
        /* If we get a fault on a delayslot we must keep the jmp state in
1208 2a44f7f1 edgar_igl
           the cpu-state to be able to re-execute the jmp.  */
1209 2a44f7f1 edgar_igl
        if (dc->delayed_branch == 1)
1210 2a44f7f1 edgar_igl
                cris_store_direct_jmp(dc);
1211 2a44f7f1 edgar_igl
1212 8170028d ths
        if (size == 1) {
1213 8170028d ths
                if (sign)
1214 b41f7df0 edgar_igl
                        tcg_gen_qemu_ld8s(dst, addr, mem_index);
1215 8170028d ths
                else
1216 b41f7df0 edgar_igl
                        tcg_gen_qemu_ld8u(dst, addr, mem_index);
1217 8170028d ths
        }
1218 8170028d ths
        else if (size == 2) {
1219 8170028d ths
                if (sign)
1220 b41f7df0 edgar_igl
                        tcg_gen_qemu_ld16s(dst, addr, mem_index);
1221 8170028d ths
                else
1222 b41f7df0 edgar_igl
                        tcg_gen_qemu_ld16u(dst, addr, mem_index);
1223 8170028d ths
        }
1224 8170028d ths
        else {
1225 30abcfc7 edgar_igl
                tcg_gen_qemu_ld32u(dst, addr, mem_index);
1226 8170028d ths
        }
1227 8170028d ths
}
1228 8170028d ths
1229 17ac9754 edgar_igl
void gen_store (DisasContext *dc, TCGv addr, TCGv val,
1230 17ac9754 edgar_igl
                unsigned int size)
1231 8170028d ths
{
1232 b41f7df0 edgar_igl
        int mem_index = cpu_mmu_index(dc->env);
1233 b41f7df0 edgar_igl
1234 2a44f7f1 edgar_igl
        /* If we get a fault on a delayslot we must keep the jmp state in
1235 2a44f7f1 edgar_igl
           the cpu-state to be able to re-execute the jmp.  */
1236 2a44f7f1 edgar_igl
        if (dc->delayed_branch == 1)
1237 2a44f7f1 edgar_igl
                 cris_store_direct_jmp(dc);
1238 2a44f7f1 edgar_igl
1239 2a44f7f1 edgar_igl
1240 2a44f7f1 edgar_igl
        /* Conditional writes. We only support the kind were X and P are known
1241 2a44f7f1 edgar_igl
           at translation time.  */
1242 2a44f7f1 edgar_igl
        if (dc->flagx_known && dc->flags_x && (dc->tb_flags & P_FLAG)) {
1243 2a44f7f1 edgar_igl
                dc->postinc = 0;
1244 2a44f7f1 edgar_igl
                cris_evaluate_flags(dc);
1245 2a44f7f1 edgar_igl
                tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
1246 2a44f7f1 edgar_igl
                return;
1247 2a44f7f1 edgar_igl
        }
1248 2a44f7f1 edgar_igl
1249 8170028d ths
        /* Remember, operands are flipped. CRIS has reversed order.  */
1250 b41f7df0 edgar_igl
        if (size == 1)
1251 17ac9754 edgar_igl
                tcg_gen_qemu_st8(val, addr, mem_index);
1252 b41f7df0 edgar_igl
        else if (size == 2)
1253 17ac9754 edgar_igl
                tcg_gen_qemu_st16(val, addr, mem_index);
1254 8170028d ths
        else
1255 17ac9754 edgar_igl
                tcg_gen_qemu_st32(val, addr, mem_index);
1256 2a44f7f1 edgar_igl
1257 2a44f7f1 edgar_igl
        if (dc->flagx_known && dc->flags_x) {
1258 2a44f7f1 edgar_igl
                cris_evaluate_flags(dc);
1259 2a44f7f1 edgar_igl
                tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
1260 2a44f7f1 edgar_igl
        }
1261 8170028d ths
}
1262 8170028d ths
1263 05ba7d5f edgar_igl
static inline void t_gen_sext(TCGv d, TCGv s, int size)
1264 8170028d ths
{
1265 8170028d ths
        if (size == 1)
1266 05ba7d5f edgar_igl
                tcg_gen_ext8s_i32(d, s);
1267 8170028d ths
        else if (size == 2)
1268 05ba7d5f edgar_igl
                tcg_gen_ext16s_i32(d, s);
1269 30abcfc7 edgar_igl
        else if(d != s)
1270 50cfa95c edgar_igl
                tcg_gen_mov_tl(d, s);
1271 8170028d ths
}
1272 8170028d ths
1273 05ba7d5f edgar_igl
static inline void t_gen_zext(TCGv d, TCGv s, int size)
1274 8170028d ths
{
1275 8170028d ths
        if (size == 1)
1276 86831435 pbrook
                tcg_gen_ext8u_i32(d, s);
1277 8170028d ths
        else if (size == 2)
1278 86831435 pbrook
                tcg_gen_ext16u_i32(d, s);
1279 30abcfc7 edgar_igl
        else if (d != s)
1280 50cfa95c edgar_igl
                tcg_gen_mov_tl(d, s);
1281 8170028d ths
}
1282 8170028d ths
1283 8170028d ths
#if DISAS_CRIS
1284 8170028d ths
static char memsize_char(int size)
1285 8170028d ths
{
1286 8170028d ths
        switch (size)
1287 8170028d ths
        {
1288 8170028d ths
                case 1: return 'b';  break;
1289 8170028d ths
                case 2: return 'w';  break;
1290 8170028d ths
                case 4: return 'd';  break;
1291 8170028d ths
                default:
1292 8170028d ths
                        return 'x';
1293 8170028d ths
                        break;
1294 8170028d ths
        }
1295 8170028d ths
}
1296 8170028d ths
#endif
1297 8170028d ths
1298 30abcfc7 edgar_igl
static inline unsigned int memsize_z(DisasContext *dc)
1299 8170028d ths
{
1300 8170028d ths
        return dc->zsize + 1;
1301 8170028d ths
}
1302 8170028d ths
1303 30abcfc7 edgar_igl
static inline unsigned int memsize_zz(DisasContext *dc)
1304 8170028d ths
{
1305 8170028d ths
        switch (dc->zzsize)
1306 8170028d ths
        {
1307 8170028d ths
                case 0: return 1;
1308 8170028d ths
                case 1: return 2;
1309 8170028d ths
                default:
1310 8170028d ths
                        return 4;
1311 8170028d ths
        }
1312 8170028d ths
}
1313 8170028d ths
1314 c7d05695 edgar_igl
static inline void do_postinc (DisasContext *dc, int size)
1315 8170028d ths
{
1316 c7d05695 edgar_igl
        if (dc->postinc)
1317 c7d05695 edgar_igl
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
1318 8170028d ths
}
1319 8170028d ths
1320 30abcfc7 edgar_igl
static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
1321 30abcfc7 edgar_igl
                            int size, int s_ext, TCGv dst)
1322 8170028d ths
{
1323 8170028d ths
        if (s_ext)
1324 30abcfc7 edgar_igl
                t_gen_sext(dst, cpu_R[rs], size);
1325 8170028d ths
        else
1326 30abcfc7 edgar_igl
                t_gen_zext(dst, cpu_R[rs], size);
1327 8170028d ths
}
1328 8170028d ths
1329 8170028d ths
/* Prepare T0 and T1 for a register alu operation.
1330 8170028d ths
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1331 8170028d ths
   needed.  */
1332 8170028d ths
static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
1333 8170028d ths
                          int size, int s_ext)
1334 8170028d ths
{
1335 30abcfc7 edgar_igl
        dec_prep_move_r(dc, rs, rd, size, s_ext, cpu_T[1]);
1336 8170028d ths
1337 8170028d ths
        if (s_ext)
1338 50cfa95c edgar_igl
                t_gen_sext(cpu_T[0], cpu_R[rd], size);
1339 8170028d ths
        else
1340 50cfa95c edgar_igl
                t_gen_zext(cpu_T[0], cpu_R[rd], size);
1341 8170028d ths
}
1342 8170028d ths
1343 30abcfc7 edgar_igl
static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize,
1344 30abcfc7 edgar_igl
                           TCGv dst)
1345 8170028d ths
{
1346 8170028d ths
        unsigned int rs, rd;
1347 8170028d ths
        uint32_t imm;
1348 8170028d ths
        int is_imm;
1349 8170028d ths
        int insn_len = 2;
1350 8170028d ths
1351 8170028d ths
        rs = dc->op1;
1352 8170028d ths
        rd = dc->op2;
1353 8170028d ths
        is_imm = rs == 15 && dc->postinc;
1354 8170028d ths
1355 8170028d ths
        /* Load [$rs] onto T1.  */
1356 8170028d ths
        if (is_imm) {
1357 8170028d ths
                insn_len = 2 + memsize;
1358 8170028d ths
                if (memsize == 1)
1359 8170028d ths
                        insn_len++;
1360 8170028d ths
1361 8170028d ths
                if (memsize != 4) {
1362 8170028d ths
                        if (s_ext) {
1363 17ac9754 edgar_igl
                                if (memsize == 1)
1364 17ac9754 edgar_igl
                                        imm = ldsb_code(dc->pc + 2);
1365 17ac9754 edgar_igl
                                else
1366 17ac9754 edgar_igl
                                        imm = ldsw_code(dc->pc + 2);
1367 8170028d ths
                        } else {
1368 8170028d ths
                                if (memsize == 1)
1369 17ac9754 edgar_igl
                                        imm = ldub_code(dc->pc + 2);
1370 8170028d ths
                                else
1371 17ac9754 edgar_igl
                                        imm = lduw_code(dc->pc + 2);
1372 8170028d ths
                        }
1373 17ac9754 edgar_igl
                } else
1374 17ac9754 edgar_igl
                        imm = ldl_code(dc->pc + 2);
1375 17ac9754 edgar_igl
                        
1376 8170028d ths
                DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n",
1377 cf1d97f0 edgar_igl
                             imm, rd, s_ext, memsize));
1378 30abcfc7 edgar_igl
                tcg_gen_movi_tl(dst, imm);
1379 8170028d ths
                dc->postinc = 0;
1380 8170028d ths
        } else {
1381 30abcfc7 edgar_igl
                cris_flush_cc_state(dc);
1382 30abcfc7 edgar_igl
                gen_load(dc, dst, cpu_R[rs], memsize, 0);
1383 8170028d ths
                if (s_ext)
1384 30abcfc7 edgar_igl
                        t_gen_sext(dst, dst, memsize);
1385 8170028d ths
                else
1386 30abcfc7 edgar_igl
                        t_gen_zext(dst, dst, memsize);
1387 8170028d ths
        }
1388 cf1d97f0 edgar_igl
        return insn_len;
1389 cf1d97f0 edgar_igl
}
1390 cf1d97f0 edgar_igl
1391 cf1d97f0 edgar_igl
/* Prepare T0 and T1 for a memory + alu operation.
1392 cf1d97f0 edgar_igl
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1393 cf1d97f0 edgar_igl
   needed.  */
1394 cf1d97f0 edgar_igl
static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
1395 cf1d97f0 edgar_igl
{
1396 cf1d97f0 edgar_igl
        int insn_len;
1397 cf1d97f0 edgar_igl
1398 30abcfc7 edgar_igl
        insn_len = dec_prep_move_m(dc, s_ext, memsize, cpu_T[1]);
1399 8170028d ths
1400 8170028d ths
        /* put dest in T0.  */
1401 cf1d97f0 edgar_igl
        tcg_gen_mov_tl(cpu_T[0], cpu_R[dc->op2]);
1402 8170028d ths
        return insn_len;
1403 8170028d ths
}
1404 8170028d ths
1405 8170028d ths
#if DISAS_CRIS
1406 8170028d ths
static const char *cc_name(int cc)
1407 8170028d ths
{
1408 8170028d ths
        static char *cc_names[16] = {
1409 8170028d ths
                "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1410 8170028d ths
                "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1411 8170028d ths
        };
1412 8170028d ths
        assert(cc < 16);
1413 8170028d ths
        return cc_names[cc];
1414 8170028d ths
}
1415 8170028d ths
#endif
1416 8170028d ths
1417 b41f7df0 edgar_igl
/* Start of insn decoders.  */
1418 b41f7df0 edgar_igl
1419 8170028d ths
static unsigned int dec_bccq(DisasContext *dc)
1420 8170028d ths
{
1421 8170028d ths
        int32_t offset;
1422 8170028d ths
        int sign;
1423 8170028d ths
        uint32_t cond = dc->op2;
1424 8170028d ths
        int tmp;
1425 8170028d ths
1426 8170028d ths
        offset = EXTRACT_FIELD (dc->ir, 1, 7);
1427 8170028d ths
        sign = EXTRACT_FIELD(dc->ir, 0, 0);
1428 8170028d ths
1429 8170028d ths
        offset *= 2;
1430 8170028d ths
        offset |= sign << 8;
1431 8170028d ths
        tmp = offset;
1432 8170028d ths
        offset = sign_extend(offset, 8);
1433 8170028d ths
1434 2a44f7f1 edgar_igl
        DIS(fprintf (logfile, "b%s %x\n", cc_name(cond), dc->pc + offset));
1435 2a44f7f1 edgar_igl
1436 8170028d ths
        /* op2 holds the condition-code.  */
1437 8170028d ths
        cris_cc_mask(dc, 0);
1438 8170028d ths
        cris_prepare_cc_branch (dc, offset, cond);
1439 8170028d ths
        return 2;
1440 8170028d ths
}
1441 8170028d ths
static unsigned int dec_addoq(DisasContext *dc)
1442 8170028d ths
{
1443 b41f7df0 edgar_igl
        int32_t imm;
1444 8170028d ths
1445 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1446 8170028d ths
        imm = sign_extend(dc->op1, 7);
1447 8170028d ths
1448 8170028d ths
        DIS(fprintf (logfile, "addoq %d, $r%u\n", imm, dc->op2));
1449 8170028d ths
        cris_cc_mask(dc, 0);
1450 8170028d ths
        /* Fetch register operand,  */
1451 b41f7df0 edgar_igl
        tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
1452 8170028d ths
        return 2;
1453 8170028d ths
}
1454 8170028d ths
static unsigned int dec_addq(DisasContext *dc)
1455 8170028d ths
{
1456 8170028d ths
        DIS(fprintf (logfile, "addq %u, $r%u\n", dc->op1, dc->op2));
1457 8170028d ths
1458 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1459 8170028d ths
1460 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1461 30abcfc7 edgar_igl
1462 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_ADD,
1463 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1464 8170028d ths
        return 2;
1465 8170028d ths
}
1466 8170028d ths
static unsigned int dec_moveq(DisasContext *dc)
1467 8170028d ths
{
1468 8170028d ths
        uint32_t imm;
1469 8170028d ths
1470 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1471 8170028d ths
        imm = sign_extend(dc->op1, 5);
1472 8170028d ths
        DIS(fprintf (logfile, "moveq %d, $r%u\n", imm, dc->op2));
1473 8170028d ths
1474 a39f8f3a edgar_igl
        tcg_gen_mov_tl(cpu_R[dc->op2], tcg_const_tl(imm));
1475 8170028d ths
        return 2;
1476 8170028d ths
}
1477 8170028d ths
static unsigned int dec_subq(DisasContext *dc)
1478 8170028d ths
{
1479 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1480 8170028d ths
1481 8170028d ths
        DIS(fprintf (logfile, "subq %u, $r%u\n", dc->op1, dc->op2));
1482 8170028d ths
1483 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1484 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_SUB,
1485 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1486 8170028d ths
        return 2;
1487 8170028d ths
}
1488 8170028d ths
static unsigned int dec_cmpq(DisasContext *dc)
1489 8170028d ths
{
1490 8170028d ths
        uint32_t imm;
1491 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1492 8170028d ths
        imm = sign_extend(dc->op1, 5);
1493 8170028d ths
1494 8170028d ths
        DIS(fprintf (logfile, "cmpq %d, $r%d\n", imm, dc->op2));
1495 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1496 30abcfc7 edgar_igl
1497 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_CMP,
1498 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1499 8170028d ths
        return 2;
1500 8170028d ths
}
1501 8170028d ths
static unsigned int dec_andq(DisasContext *dc)
1502 8170028d ths
{
1503 8170028d ths
        uint32_t imm;
1504 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1505 8170028d ths
        imm = sign_extend(dc->op1, 5);
1506 8170028d ths
1507 8170028d ths
        DIS(fprintf (logfile, "andq %d, $r%d\n", imm, dc->op2));
1508 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1509 30abcfc7 edgar_igl
1510 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_AND,
1511 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1512 8170028d ths
        return 2;
1513 8170028d ths
}
1514 8170028d ths
static unsigned int dec_orq(DisasContext *dc)
1515 8170028d ths
{
1516 8170028d ths
        uint32_t imm;
1517 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1518 8170028d ths
        imm = sign_extend(dc->op1, 5);
1519 8170028d ths
        DIS(fprintf (logfile, "orq %d, $r%d\n", imm, dc->op2));
1520 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1521 30abcfc7 edgar_igl
1522 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_OR,
1523 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1524 8170028d ths
        return 2;
1525 8170028d ths
}
1526 8170028d ths
static unsigned int dec_btstq(DisasContext *dc)
1527 8170028d ths
{
1528 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1529 8170028d ths
        DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2));
1530 17ac9754 edgar_igl
1531 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1532 8170028d ths
1533 30abcfc7 edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1534 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_BTST,
1535 30abcfc7 edgar_igl
                    cpu_T[0], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1536 b41f7df0 edgar_igl
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1537 cf1d97f0 edgar_igl
        t_gen_mov_preg_TN(dc, PR_CCS, cpu_T[0]);
1538 30abcfc7 edgar_igl
        dc->flags_uptodate = 1;
1539 8170028d ths
        return 2;
1540 8170028d ths
}
1541 8170028d ths
static unsigned int dec_asrq(DisasContext *dc)
1542 8170028d ths
{
1543 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1544 8170028d ths
        DIS(fprintf (logfile, "asrq %u, $r%d\n", dc->op1, dc->op2));
1545 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1546 30abcfc7 edgar_igl
1547 2a44f7f1 edgar_igl
        tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1548 2a44f7f1 edgar_igl
        cris_alu(dc, CC_OP_MOVE,
1549 30abcfc7 edgar_igl
                    cpu_R[dc->op2],
1550 2a44f7f1 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], 4);
1551 8170028d ths
        return 2;
1552 8170028d ths
}
1553 8170028d ths
static unsigned int dec_lslq(DisasContext *dc)
1554 8170028d ths
{
1555 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1556 8170028d ths
        DIS(fprintf (logfile, "lslq %u, $r%d\n", dc->op1, dc->op2));
1557 8170028d ths
1558 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1559 30abcfc7 edgar_igl
1560 2a44f7f1 edgar_igl
        tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1561 2a44f7f1 edgar_igl
1562 2a44f7f1 edgar_igl
        cris_alu(dc, CC_OP_MOVE,
1563 30abcfc7 edgar_igl
                    cpu_R[dc->op2],
1564 2a44f7f1 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], 4);
1565 8170028d ths
        return 2;
1566 8170028d ths
}
1567 8170028d ths
static unsigned int dec_lsrq(DisasContext *dc)
1568 8170028d ths
{
1569 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1570 8170028d ths
        DIS(fprintf (logfile, "lsrq %u, $r%d\n", dc->op1, dc->op2));
1571 8170028d ths
1572 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1573 30abcfc7 edgar_igl
1574 2a44f7f1 edgar_igl
        tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1575 2a44f7f1 edgar_igl
        cris_alu(dc, CC_OP_MOVE,
1576 30abcfc7 edgar_igl
                    cpu_R[dc->op2],
1577 2a44f7f1 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], 4);
1578 8170028d ths
        return 2;
1579 8170028d ths
}
1580 8170028d ths
1581 8170028d ths
static unsigned int dec_move_r(DisasContext *dc)
1582 8170028d ths
{
1583 8170028d ths
        int size = memsize_zz(dc);
1584 8170028d ths
1585 8170028d ths
        DIS(fprintf (logfile, "move.%c $r%u, $r%u\n",
1586 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1587 8170028d ths
1588 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1589 30abcfc7 edgar_igl
        if (size == 4) {
1590 30abcfc7 edgar_igl
                dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
1591 30abcfc7 edgar_igl
                cris_cc_mask(dc, CC_MASK_NZ);
1592 30abcfc7 edgar_igl
                cris_update_cc_op(dc, CC_OP_MOVE, 4);
1593 30abcfc7 edgar_igl
                cris_update_cc_x(dc);
1594 30abcfc7 edgar_igl
                cris_update_result(dc, cpu_R[dc->op2]);
1595 30abcfc7 edgar_igl
        }
1596 30abcfc7 edgar_igl
        else {
1597 30abcfc7 edgar_igl
                dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_T[1]);
1598 30abcfc7 edgar_igl
                cris_alu(dc, CC_OP_MOVE,
1599 30abcfc7 edgar_igl
                         cpu_R[dc->op2],
1600 30abcfc7 edgar_igl
                         cpu_R[dc->op2], cpu_T[1], size);
1601 30abcfc7 edgar_igl
        }
1602 8170028d ths
        return 2;
1603 8170028d ths
}
1604 8170028d ths
1605 8170028d ths
static unsigned int dec_scc_r(DisasContext *dc)
1606 8170028d ths
{
1607 8170028d ths
        int cond = dc->op2;
1608 8170028d ths
1609 8170028d ths
        DIS(fprintf (logfile, "s%s $r%u\n",
1610 8170028d ths
                    cc_name(cond), dc->op1));
1611 8170028d ths
1612 8170028d ths
        if (cond != CC_A)
1613 8170028d ths
        {
1614 dceaf394 edgar_igl
                int l1;
1615 dceaf394 edgar_igl
1616 8170028d ths
                gen_tst_cc (dc, cond);
1617 dceaf394 edgar_igl
1618 dceaf394 edgar_igl
                l1 = gen_new_label();
1619 dceaf394 edgar_igl
                tcg_gen_movi_tl(cpu_R[dc->op1], 0);
1620 cb63669a pbrook
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1621 dceaf394 edgar_igl
                tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1622 dceaf394 edgar_igl
                gen_set_label(l1);
1623 8170028d ths
        }
1624 8170028d ths
        else
1625 dceaf394 edgar_igl
                tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1626 8170028d ths
1627 8170028d ths
        cris_cc_mask(dc, 0);
1628 8170028d ths
        return 2;
1629 8170028d ths
}
1630 8170028d ths
1631 8170028d ths
static unsigned int dec_and_r(DisasContext *dc)
1632 8170028d ths
{
1633 8170028d ths
        int size = memsize_zz(dc);
1634 8170028d ths
1635 8170028d ths
        DIS(fprintf (logfile, "and.%c $r%u, $r%u\n",
1636 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1637 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1638 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1639 30abcfc7 edgar_igl
1640 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_AND,
1641 30abcfc7 edgar_igl
                    cpu_R[dc->op2],
1642 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_T[1], size);
1643 8170028d ths
        return 2;
1644 8170028d ths
}
1645 8170028d ths
1646 8170028d ths
static unsigned int dec_lz_r(DisasContext *dc)
1647 8170028d ths
{
1648 8170028d ths
        DIS(fprintf (logfile, "lz $r%u, $r%u\n",
1649 8170028d ths
                    dc->op1, dc->op2));
1650 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1651 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1652 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_LZ,
1653 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4);
1654 8170028d ths
        return 2;
1655 8170028d ths
}
1656 8170028d ths
1657 8170028d ths
static unsigned int dec_lsl_r(DisasContext *dc)
1658 8170028d ths
{
1659 8170028d ths
        int size = memsize_zz(dc);
1660 8170028d ths
1661 8170028d ths
        DIS(fprintf (logfile, "lsl.%c $r%u, $r%u\n",
1662 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1663 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1664 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1665 05ba7d5f edgar_igl
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
1666 30abcfc7 edgar_igl
1667 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_LSL,
1668 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_T[0], cpu_T[1], size);
1669 8170028d ths
        return 2;
1670 8170028d ths
}
1671 8170028d ths
1672 8170028d ths
static unsigned int dec_lsr_r(DisasContext *dc)
1673 8170028d ths
{
1674 8170028d ths
        int size = memsize_zz(dc);
1675 8170028d ths
1676 8170028d ths
        DIS(fprintf (logfile, "lsr.%c $r%u, $r%u\n",
1677 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1678 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1679 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1680 05ba7d5f edgar_igl
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
1681 30abcfc7 edgar_igl
1682 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_LSR,
1683 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_T[0], cpu_T[1], size);
1684 8170028d ths
        return 2;
1685 8170028d ths
}
1686 8170028d ths
1687 8170028d ths
static unsigned int dec_asr_r(DisasContext *dc)
1688 8170028d ths
{
1689 8170028d ths
        int size = memsize_zz(dc);
1690 8170028d ths
1691 8170028d ths
        DIS(fprintf (logfile, "asr.%c $r%u, $r%u\n",
1692 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1693 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1694 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
1695 05ba7d5f edgar_igl
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
1696 30abcfc7 edgar_igl
1697 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_ASR,
1698 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_T[0], cpu_T[1], size);
1699 8170028d ths
        return 2;
1700 8170028d ths
}
1701 8170028d ths
1702 8170028d ths
static unsigned int dec_muls_r(DisasContext *dc)
1703 8170028d ths
{
1704 8170028d ths
        int size = memsize_zz(dc);
1705 8170028d ths
1706 8170028d ths
        DIS(fprintf (logfile, "muls.%c $r%u, $r%u\n",
1707 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1708 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZV);
1709 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
1710 30abcfc7 edgar_igl
1711 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_MULS,
1712 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4);
1713 8170028d ths
        return 2;
1714 8170028d ths
}
1715 8170028d ths
1716 8170028d ths
static unsigned int dec_mulu_r(DisasContext *dc)
1717 8170028d ths
{
1718 8170028d ths
        int size = memsize_zz(dc);
1719 8170028d ths
1720 8170028d ths
        DIS(fprintf (logfile, "mulu.%c $r%u, $r%u\n",
1721 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1722 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZV);
1723 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1724 30abcfc7 edgar_igl
1725 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_MULU,
1726 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4);
1727 8170028d ths
        return 2;
1728 8170028d ths
}
1729 8170028d ths
1730 8170028d ths
1731 8170028d ths
static unsigned int dec_dstep_r(DisasContext *dc)
1732 8170028d ths
{
1733 8170028d ths
        DIS(fprintf (logfile, "dstep $r%u, $r%u\n", dc->op1, dc->op2));
1734 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1735 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_DSTEP,
1736 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1737 8170028d ths
        return 2;
1738 8170028d ths
}
1739 8170028d ths
1740 8170028d ths
static unsigned int dec_xor_r(DisasContext *dc)
1741 8170028d ths
{
1742 8170028d ths
        int size = memsize_zz(dc);
1743 8170028d ths
        DIS(fprintf (logfile, "xor.%c $r%u, $r%u\n",
1744 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1745 8170028d ths
        BUG_ON(size != 4); /* xor is dword.  */
1746 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1747 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1748 30abcfc7 edgar_igl
1749 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_XOR,
1750 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4);
1751 8170028d ths
        return 2;
1752 8170028d ths
}
1753 8170028d ths
1754 8170028d ths
static unsigned int dec_bound_r(DisasContext *dc)
1755 8170028d ths
{
1756 8170028d ths
        int size = memsize_zz(dc);
1757 8170028d ths
        DIS(fprintf (logfile, "bound.%c $r%u, $r%u\n",
1758 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1759 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1760 30abcfc7 edgar_igl
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_T[1]);
1761 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_BOUND,
1762 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4);
1763 8170028d ths
        return 2;
1764 8170028d ths
}
1765 8170028d ths
1766 8170028d ths
static unsigned int dec_cmp_r(DisasContext *dc)
1767 8170028d ths
{
1768 8170028d ths
        int size = memsize_zz(dc);
1769 8170028d ths
        DIS(fprintf (logfile, "cmp.%c $r%u, $r%u\n",
1770 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1771 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1772 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1773 30abcfc7 edgar_igl
1774 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_CMP,
1775 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_T[0], cpu_T[1], size);
1776 8170028d ths
        return 2;
1777 8170028d ths
}
1778 8170028d ths
1779 8170028d ths
static unsigned int dec_abs_r(DisasContext *dc)
1780 8170028d ths
{
1781 3157a0a9 edgar_igl
        int l1;
1782 3157a0a9 edgar_igl
1783 8170028d ths
        DIS(fprintf (logfile, "abs $r%u, $r%u\n",
1784 8170028d ths
                    dc->op1, dc->op2));
1785 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1786 30abcfc7 edgar_igl
        dec_prep_move_r(dc, dc->op1, dc->op2, 4, 0, cpu_T[1]);
1787 3157a0a9 edgar_igl
1788 3157a0a9 edgar_igl
        /* TODO: consider a branch free approach.  */
1789 3157a0a9 edgar_igl
        l1 = gen_new_label();
1790 cb63669a pbrook
        tcg_gen_brcondi_tl(TCG_COND_GE, cpu_T[1], 0, l1);
1791 390efc54 pbrook
        tcg_gen_neg_tl(cpu_T[1], cpu_T[1]);
1792 3157a0a9 edgar_igl
        gen_set_label(l1);
1793 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_MOVE,
1794 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4);
1795 8170028d ths
        return 2;
1796 8170028d ths
}
1797 8170028d ths
1798 8170028d ths
static unsigned int dec_add_r(DisasContext *dc)
1799 8170028d ths
{
1800 8170028d ths
        int size = memsize_zz(dc);
1801 8170028d ths
        DIS(fprintf (logfile, "add.%c $r%u, $r%u\n",
1802 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1803 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1804 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1805 30abcfc7 edgar_igl
1806 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_ADD,
1807 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_T[0], cpu_T[1], size);
1808 8170028d ths
        return 2;
1809 8170028d ths
}
1810 8170028d ths
1811 8170028d ths
static unsigned int dec_addc_r(DisasContext *dc)
1812 8170028d ths
{
1813 8170028d ths
        DIS(fprintf (logfile, "addc $r%u, $r%u\n",
1814 8170028d ths
                    dc->op1, dc->op2));
1815 8170028d ths
        cris_evaluate_flags(dc);
1816 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1817 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1818 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_ADDC,
1819 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4);
1820 8170028d ths
        return 2;
1821 8170028d ths
}
1822 8170028d ths
1823 8170028d ths
static unsigned int dec_mcp_r(DisasContext *dc)
1824 8170028d ths
{
1825 8170028d ths
        DIS(fprintf (logfile, "mcp $p%u, $r%u\n",
1826 8170028d ths
                     dc->op2, dc->op1));
1827 8170028d ths
        cris_evaluate_flags(dc);
1828 8170028d ths
        cris_cc_mask(dc, CC_MASK_RNZV);
1829 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_MCP,
1830 30abcfc7 edgar_igl
                    cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
1831 8170028d ths
        return 2;
1832 8170028d ths
}
1833 8170028d ths
1834 8170028d ths
#if DISAS_CRIS
1835 8170028d ths
static char * swapmode_name(int mode, char *modename) {
1836 8170028d ths
        int i = 0;
1837 8170028d ths
        if (mode & 8)
1838 8170028d ths
                modename[i++] = 'n';
1839 8170028d ths
        if (mode & 4)
1840 8170028d ths
                modename[i++] = 'w';
1841 8170028d ths
        if (mode & 2)
1842 8170028d ths
                modename[i++] = 'b';
1843 8170028d ths
        if (mode & 1)
1844 8170028d ths
                modename[i++] = 'r';
1845 8170028d ths
        modename[i++] = 0;
1846 8170028d ths
        return modename;
1847 8170028d ths
}
1848 8170028d ths
#endif
1849 8170028d ths
1850 8170028d ths
static unsigned int dec_swap_r(DisasContext *dc)
1851 8170028d ths
{
1852 cf1d97f0 edgar_igl
#if DISAS_CRIS
1853 cf1d97f0 edgar_igl
        char modename[4];
1854 cf1d97f0 edgar_igl
#endif
1855 8170028d ths
        DIS(fprintf (logfile, "swap%s $r%u\n",
1856 8170028d ths
                     swapmode_name(dc->op2, modename), dc->op1));
1857 8170028d ths
1858 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1859 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1860 8170028d ths
        if (dc->op2 & 8)
1861 d1896336 edgar_igl
                tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
1862 8170028d ths
        if (dc->op2 & 4)
1863 3157a0a9 edgar_igl
                t_gen_swapw(cpu_T[0], cpu_T[0]);
1864 8170028d ths
        if (dc->op2 & 2)
1865 3157a0a9 edgar_igl
                t_gen_swapb(cpu_T[0], cpu_T[0]);
1866 8170028d ths
        if (dc->op2 & 1)
1867 3157a0a9 edgar_igl
                t_gen_swapr(cpu_T[0], cpu_T[0]);
1868 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_MOVE,
1869 30abcfc7 edgar_igl
                    cpu_R[dc->op1], cpu_R[dc->op1], cpu_T[0], 4);
1870 30abcfc7 edgar_igl
1871 8170028d ths
        return 2;
1872 8170028d ths
}
1873 8170028d ths
1874 8170028d ths
static unsigned int dec_or_r(DisasContext *dc)
1875 8170028d ths
{
1876 8170028d ths
        int size = memsize_zz(dc);
1877 8170028d ths
        DIS(fprintf (logfile, "or.%c $r%u, $r%u\n",
1878 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1879 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1880 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1881 30abcfc7 edgar_igl
1882 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_OR,
1883 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_T[0], cpu_T[1], size);
1884 8170028d ths
        return 2;
1885 8170028d ths
}
1886 8170028d ths
1887 8170028d ths
static unsigned int dec_addi_r(DisasContext *dc)
1888 8170028d ths
{
1889 8170028d ths
        DIS(fprintf (logfile, "addi.%c $r%u, $r%u\n",
1890 8170028d ths
                    memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1891 8170028d ths
        cris_cc_mask(dc, 0);
1892 30abcfc7 edgar_igl
        tcg_gen_shl_tl(cpu_T[0], cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1893 30abcfc7 edgar_igl
        tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], cpu_T[0]);
1894 8170028d ths
        return 2;
1895 8170028d ths
}
1896 8170028d ths
1897 8170028d ths
static unsigned int dec_addi_acr(DisasContext *dc)
1898 8170028d ths
{
1899 8170028d ths
        DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n",
1900 b41f7df0 edgar_igl
                  memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1901 8170028d ths
        cris_cc_mask(dc, 0);
1902 30abcfc7 edgar_igl
        tcg_gen_shl_tl(cpu_T[0], cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1903 30abcfc7 edgar_igl
        tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], cpu_T[0]);
1904 8170028d ths
        return 2;
1905 8170028d ths
}
1906 8170028d ths
1907 8170028d ths
static unsigned int dec_neg_r(DisasContext *dc)
1908 8170028d ths
{
1909 8170028d ths
        int size = memsize_zz(dc);
1910 8170028d ths
        DIS(fprintf (logfile, "neg.%c $r%u, $r%u\n",
1911 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1912 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1913 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1914 30abcfc7 edgar_igl
1915 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_NEG,
1916 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_T[0], cpu_T[1], size);
1917 8170028d ths
        return 2;
1918 8170028d ths
}
1919 8170028d ths
1920 8170028d ths
static unsigned int dec_btst_r(DisasContext *dc)
1921 8170028d ths
{
1922 8170028d ths
        DIS(fprintf (logfile, "btst $r%u, $r%u\n",
1923 8170028d ths
                    dc->op1, dc->op2));
1924 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1925 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1926 8170028d ths
1927 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_BTST,
1928 30abcfc7 edgar_igl
                    cpu_T[0], cpu_T[0], cpu_T[1], 4);
1929 b41f7df0 edgar_igl
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1930 cf1d97f0 edgar_igl
        t_gen_mov_preg_TN(dc, PR_CCS, cpu_T[0]);
1931 30abcfc7 edgar_igl
        dc->flags_uptodate = 1;
1932 8170028d ths
        return 2;
1933 8170028d ths
}
1934 8170028d ths
1935 8170028d ths
static unsigned int dec_sub_r(DisasContext *dc)
1936 8170028d ths
{
1937 8170028d ths
        int size = memsize_zz(dc);
1938 8170028d ths
        DIS(fprintf (logfile, "sub.%c $r%u, $r%u\n",
1939 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1940 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1941 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1942 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_SUB,
1943 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_T[0], cpu_T[1], size);
1944 8170028d ths
        return 2;
1945 8170028d ths
}
1946 8170028d ths
1947 8170028d ths
/* Zero extension. From size to dword.  */
1948 8170028d ths
static unsigned int dec_movu_r(DisasContext *dc)
1949 8170028d ths
{
1950 8170028d ths
        int size = memsize_z(dc);
1951 8170028d ths
        DIS(fprintf (logfile, "movu.%c $r%u, $r%u\n",
1952 8170028d ths
                    memsize_char(size),
1953 8170028d ths
                    dc->op1, dc->op2));
1954 8170028d ths
1955 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1956 30abcfc7 edgar_igl
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_T[1]);
1957 30abcfc7 edgar_igl
        cris_alu(dc, CC_OP_MOVE,
1958 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4);
1959 8170028d ths
        return 2;
1960 8170028d ths
}
1961 8170028d ths
1962 8170028d ths
/* Sign extension. From size to dword.  */
1963 8170028d ths
static unsigned int dec_movs_r(DisasContext *dc)
1964 8170028d ths
{
1965 8170028d ths
        int size = memsize_z(dc);
1966 8170028d ths
        DIS(fprintf (logfile, "movs.%c $r%u, $r%u\n",
1967 8170028d ths
                    memsize_char(size),
1968 8170028d ths
                    dc->op1, dc->op2));
1969 8170028d ths
1970 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1971 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
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 30abcfc7 edgar_igl
                    cpu_R[dc->op2], cpu_T[0], 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 8170028d ths
                        BUG();
2792 8170028d ths
                        break;
2793 8170028d ths
                case 6:
2794 8170028d ths
                        /* break.  */
2795 2a44f7f1 edgar_igl
                        tcg_gen_movi_tl(env_pc, dc->pc);
2796 8170028d ths
                        /* Breaks start at 16 in the exception vector.  */
2797 dceaf394 edgar_igl
                        t_gen_mov_env_TN(trap_vector, 
2798 dceaf394 edgar_igl
                                         tcg_const_tl(dc->op1 + 16));
2799 dceaf394 edgar_igl
                        t_gen_raise_exception(EXCP_BREAK);
2800 b41f7df0 edgar_igl
                        dc->is_jmp = DISAS_UPDATE;
2801 8170028d ths
                        break;
2802 8170028d ths
                default:
2803 8170028d ths
                        printf ("op2=%x\n", dc->op2);
2804 8170028d ths
                        BUG();
2805 8170028d ths
                        break;
2806 8170028d ths
2807 8170028d ths
        }
2808 8170028d ths
        return 2;
2809 8170028d ths
}
2810 8170028d ths
2811 5d4a534d edgar_igl
static unsigned int dec_ftag_fidx_d_m(DisasContext *dc)
2812 5d4a534d edgar_igl
{
2813 5d4a534d edgar_igl
        /* Ignore D-cache flushes.  */
2814 5d4a534d edgar_igl
        return 2;
2815 5d4a534d edgar_igl
}
2816 5d4a534d edgar_igl
2817 5d4a534d edgar_igl
static unsigned int dec_ftag_fidx_i_m(DisasContext *dc)
2818 5d4a534d edgar_igl
{
2819 5d4a534d edgar_igl
        /* Ignore I-cache flushes.  */
2820 5d4a534d edgar_igl
        return 2;
2821 5d4a534d edgar_igl
}
2822 5d4a534d edgar_igl
2823 8170028d ths
static unsigned int dec_null(DisasContext *dc)
2824 8170028d ths
{
2825 8170028d ths
        printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2826 8170028d ths
                dc->pc, dc->opcode, dc->op1, dc->op2);
2827 8170028d ths
        fflush(NULL);
2828 8170028d ths
        BUG();
2829 8170028d ths
        return 2;
2830 8170028d ths
}
2831 8170028d ths
2832 8170028d ths
struct decoder_info {
2833 8170028d ths
        struct {
2834 8170028d ths
                uint32_t bits;
2835 8170028d ths
                uint32_t mask;
2836 8170028d ths
        };
2837 8170028d ths
        unsigned int (*dec)(DisasContext *dc);
2838 8170028d ths
} decinfo[] = {
2839 8170028d ths
        /* Order matters here.  */
2840 8170028d ths
        {DEC_MOVEQ, dec_moveq},
2841 8170028d ths
        {DEC_BTSTQ, dec_btstq},
2842 8170028d ths
        {DEC_CMPQ, dec_cmpq},
2843 8170028d ths
        {DEC_ADDOQ, dec_addoq},
2844 8170028d ths
        {DEC_ADDQ, dec_addq},
2845 8170028d ths
        {DEC_SUBQ, dec_subq},
2846 8170028d ths
        {DEC_ANDQ, dec_andq},
2847 8170028d ths
        {DEC_ORQ, dec_orq},
2848 8170028d ths
        {DEC_ASRQ, dec_asrq},
2849 8170028d ths
        {DEC_LSLQ, dec_lslq},
2850 8170028d ths
        {DEC_LSRQ, dec_lsrq},
2851 8170028d ths
        {DEC_BCCQ, dec_bccq},
2852 8170028d ths
2853 8170028d ths
        {DEC_BCC_IM, dec_bcc_im},
2854 8170028d ths
        {DEC_JAS_IM, dec_jas_im},
2855 8170028d ths
        {DEC_JAS_R, dec_jas_r},
2856 8170028d ths
        {DEC_JASC_IM, dec_jasc_im},
2857 8170028d ths
        {DEC_JASC_R, dec_jasc_r},
2858 8170028d ths
        {DEC_BAS_IM, dec_bas_im},
2859 8170028d ths
        {DEC_BASC_IM, dec_basc_im},
2860 8170028d ths
        {DEC_JUMP_P, dec_jump_p},
2861 8170028d ths
        {DEC_LAPC_IM, dec_lapc_im},
2862 8170028d ths
        {DEC_LAPCQ, dec_lapcq},
2863 8170028d ths
2864 8170028d ths
        {DEC_RFE_ETC, dec_rfe_etc},
2865 8170028d ths
        {DEC_ADDC_MR, dec_addc_mr},
2866 8170028d ths
2867 8170028d ths
        {DEC_MOVE_MP, dec_move_mp},
2868 8170028d ths
        {DEC_MOVE_PM, dec_move_pm},
2869 8170028d ths
        {DEC_MOVEM_MR, dec_movem_mr},
2870 8170028d ths
        {DEC_MOVEM_RM, dec_movem_rm},
2871 8170028d ths
        {DEC_MOVE_PR, dec_move_pr},
2872 8170028d ths
        {DEC_SCC_R, dec_scc_r},
2873 8170028d ths
        {DEC_SETF, dec_setclrf},
2874 8170028d ths
        {DEC_CLEARF, dec_setclrf},
2875 8170028d ths
2876 8170028d ths
        {DEC_MOVE_SR, dec_move_sr},
2877 8170028d ths
        {DEC_MOVE_RP, dec_move_rp},
2878 8170028d ths
        {DEC_SWAP_R, dec_swap_r},
2879 8170028d ths
        {DEC_ABS_R, dec_abs_r},
2880 8170028d ths
        {DEC_LZ_R, dec_lz_r},
2881 8170028d ths
        {DEC_MOVE_RS, dec_move_rs},
2882 8170028d ths
        {DEC_BTST_R, dec_btst_r},
2883 8170028d ths
        {DEC_ADDC_R, dec_addc_r},
2884 8170028d ths
2885 8170028d ths
        {DEC_DSTEP_R, dec_dstep_r},
2886 8170028d ths
        {DEC_XOR_R, dec_xor_r},
2887 8170028d ths
        {DEC_MCP_R, dec_mcp_r},
2888 8170028d ths
        {DEC_CMP_R, dec_cmp_r},
2889 8170028d ths
2890 8170028d ths
        {DEC_ADDI_R, dec_addi_r},
2891 8170028d ths
        {DEC_ADDI_ACR, dec_addi_acr},
2892 8170028d ths
2893 8170028d ths
        {DEC_ADD_R, dec_add_r},
2894 8170028d ths
        {DEC_SUB_R, dec_sub_r},
2895 8170028d ths
2896 8170028d ths
        {DEC_ADDU_R, dec_addu_r},
2897 8170028d ths
        {DEC_ADDS_R, dec_adds_r},
2898 8170028d ths
        {DEC_SUBU_R, dec_subu_r},
2899 8170028d ths
        {DEC_SUBS_R, dec_subs_r},
2900 8170028d ths
        {DEC_LSL_R, dec_lsl_r},
2901 8170028d ths
2902 8170028d ths
        {DEC_AND_R, dec_and_r},
2903 8170028d ths
        {DEC_OR_R, dec_or_r},
2904 8170028d ths
        {DEC_BOUND_R, dec_bound_r},
2905 8170028d ths
        {DEC_ASR_R, dec_asr_r},
2906 8170028d ths
        {DEC_LSR_R, dec_lsr_r},
2907 8170028d ths
2908 8170028d ths
        {DEC_MOVU_R, dec_movu_r},
2909 8170028d ths
        {DEC_MOVS_R, dec_movs_r},
2910 8170028d ths
        {DEC_NEG_R, dec_neg_r},
2911 8170028d ths
        {DEC_MOVE_R, dec_move_r},
2912 8170028d ths
2913 5d4a534d edgar_igl
        {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
2914 5d4a534d edgar_igl
        {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
2915 8170028d ths
2916 8170028d ths
        {DEC_MULS_R, dec_muls_r},
2917 8170028d ths
        {DEC_MULU_R, dec_mulu_r},
2918 8170028d ths
2919 8170028d ths
        {DEC_ADDU_M, dec_addu_m},
2920 8170028d ths
        {DEC_ADDS_M, dec_adds_m},
2921 8170028d ths
        {DEC_SUBU_M, dec_subu_m},
2922 8170028d ths
        {DEC_SUBS_M, dec_subs_m},
2923 8170028d ths
2924 8170028d ths
        {DEC_CMPU_M, dec_cmpu_m},
2925 8170028d ths
        {DEC_CMPS_M, dec_cmps_m},
2926 8170028d ths
        {DEC_MOVU_M, dec_movu_m},
2927 8170028d ths
        {DEC_MOVS_M, dec_movs_m},
2928 8170028d ths
2929 8170028d ths
        {DEC_CMP_M, dec_cmp_m},
2930 8170028d ths
        {DEC_ADDO_M, dec_addo_m},
2931 8170028d ths
        {DEC_BOUND_M, dec_bound_m},
2932 8170028d ths
        {DEC_ADD_M, dec_add_m},
2933 8170028d ths
        {DEC_SUB_M, dec_sub_m},
2934 8170028d ths
        {DEC_AND_M, dec_and_m},
2935 8170028d ths
        {DEC_OR_M, dec_or_m},
2936 8170028d ths
        {DEC_MOVE_RM, dec_move_rm},
2937 8170028d ths
        {DEC_TEST_M, dec_test_m},
2938 8170028d ths
        {DEC_MOVE_MR, dec_move_mr},
2939 8170028d ths
2940 8170028d ths
        {{0, 0}, dec_null}
2941 8170028d ths
};
2942 8170028d ths
2943 8170028d ths
static inline unsigned int
2944 8170028d ths
cris_decoder(DisasContext *dc)
2945 8170028d ths
{
2946 8170028d ths
        unsigned int insn_len = 2;
2947 8170028d ths
        int i;
2948 8170028d ths
2949 8170028d ths
        /* Load a halfword onto the instruction register.  */
2950 17ac9754 edgar_igl
        dc->ir = lduw_code(dc->pc);
2951 8170028d ths
2952 8170028d ths
        /* Now decode it.  */
2953 8170028d ths
        dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
2954 8170028d ths
        dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
2955 8170028d ths
        dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
2956 8170028d ths
        dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
2957 8170028d ths
        dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
2958 8170028d ths
        dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
2959 8170028d ths
2960 8170028d ths
        /* Large switch for all insns.  */
2961 8170028d ths
        for (i = 0; i < sizeof decinfo / sizeof decinfo[0]; i++) {
2962 8170028d ths
                if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
2963 8170028d ths
                {
2964 8170028d ths
                        insn_len = decinfo[i].dec(dc);
2965 8170028d ths
                        break;
2966 8170028d ths
                }
2967 8170028d ths
        }
2968 8170028d ths
2969 8170028d ths
        return insn_len;
2970 8170028d ths
}
2971 8170028d ths
2972 8170028d ths
static void check_breakpoint(CPUState *env, DisasContext *dc)
2973 8170028d ths
{
2974 8170028d ths
        int j;
2975 8170028d ths
        if (env->nb_breakpoints > 0) {
2976 8170028d ths
                for(j = 0; j < env->nb_breakpoints; j++) {
2977 8170028d ths
                        if (env->breakpoints[j] == dc->pc) {
2978 8170028d ths
                                cris_evaluate_flags (dc);
2979 2a44f7f1 edgar_igl
                                tcg_gen_movi_tl(env_pc, dc->pc);
2980 dceaf394 edgar_igl
                                t_gen_raise_exception(EXCP_DEBUG);
2981 8170028d ths
                                dc->is_jmp = DISAS_UPDATE;
2982 8170028d ths
                        }
2983 8170028d ths
                }
2984 8170028d ths
        }
2985 8170028d ths
}
2986 8170028d ths
2987 cf1d97f0 edgar_igl
2988 cf1d97f0 edgar_igl
/*
2989 cf1d97f0 edgar_igl
 * Delay slots on QEMU/CRIS.
2990 cf1d97f0 edgar_igl
 *
2991 cf1d97f0 edgar_igl
 * If an exception hits on a delayslot, the core will let ERP (the Exception
2992 cf1d97f0 edgar_igl
 * Return Pointer) point to the branch (the previous) insn and set the lsb to
2993 cf1d97f0 edgar_igl
 * to give SW a hint that the exception actually hit on the dslot.
2994 cf1d97f0 edgar_igl
 *
2995 cf1d97f0 edgar_igl
 * CRIS expects all PC addresses to be 16-bit aligned. The lsb is ignored by
2996 cf1d97f0 edgar_igl
 * the core and any jmp to an odd addresses will mask off that lsb. It is 
2997 cf1d97f0 edgar_igl
 * simply there to let sw know there was an exception on a dslot.
2998 cf1d97f0 edgar_igl
 *
2999 cf1d97f0 edgar_igl
 * When the software returns from an exception, the branch will re-execute.
3000 cf1d97f0 edgar_igl
 * On QEMU care needs to be taken when a branch+delayslot sequence is broken
3001 cf1d97f0 edgar_igl
 * and the branch and delayslot dont share pages.
3002 cf1d97f0 edgar_igl
 *
3003 cf1d97f0 edgar_igl
 * The TB contaning the branch insn will set up env->btarget and evaluate 
3004 cf1d97f0 edgar_igl
 * env->btaken. When the translation loop exits we will note that the branch 
3005 cf1d97f0 edgar_igl
 * sequence is broken and let env->dslot be the size of the branch insn (those
3006 cf1d97f0 edgar_igl
 * vary in length).
3007 cf1d97f0 edgar_igl
 *
3008 cf1d97f0 edgar_igl
 * The TB contaning the delayslot will have the PC of its real insn (i.e no lsb
3009 cf1d97f0 edgar_igl
 * set). It will also expect to have env->dslot setup with the size of the 
3010 cf1d97f0 edgar_igl
 * delay slot so that env->pc - env->dslot point to the branch insn. This TB 
3011 cf1d97f0 edgar_igl
 * will execute the dslot and take the branch, either to btarget or just one 
3012 cf1d97f0 edgar_igl
 * insn ahead.
3013 cf1d97f0 edgar_igl
 *
3014 cf1d97f0 edgar_igl
 * When exceptions occur, we check for env->dslot in do_interrupt to detect 
3015 cf1d97f0 edgar_igl
 * broken branch sequences and setup $erp accordingly (i.e let it point to the
3016 cf1d97f0 edgar_igl
 * branch and set lsb). Then env->dslot gets cleared so that the exception 
3017 cf1d97f0 edgar_igl
 * handler can enter. When returning from exceptions (jump $erp) the lsb gets
3018 cf1d97f0 edgar_igl
 * masked off and we will reexecute the branch insn.
3019 cf1d97f0 edgar_igl
 *
3020 cf1d97f0 edgar_igl
 */
3021 cf1d97f0 edgar_igl
3022 8170028d ths
/* generate intermediate code for basic block 'tb'.  */
3023 8170028d ths
static int
3024 8170028d ths
gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
3025 8170028d ths
                               int search_pc)
3026 8170028d ths
{
3027 8170028d ths
        uint16_t *gen_opc_end;
3028 8170028d ths
           uint32_t pc_start;
3029 8170028d ths
        unsigned int insn_len;
3030 8170028d ths
        int j, lj;
3031 cf1d97f0 edgar_igl
        struct DisasContext ctx;
3032 8170028d ths
        struct DisasContext *dc = &ctx;
3033 8170028d ths
        uint32_t next_page_start;
3034 2a44f7f1 edgar_igl
        target_ulong npc;
3035 8170028d ths
3036 a825e703 edgar_igl
        if (!logfile)
3037 a825e703 edgar_igl
                logfile = stderr;
3038 a825e703 edgar_igl
3039 73e51723 edgar_igl
        /* Odd PC indicates that branch is rexecuting due to exception in the
3040 73e51723 edgar_igl
         * delayslot, like in real hw.
3041 73e51723 edgar_igl
         */
3042 73e51723 edgar_igl
        pc_start = tb->pc & ~1;
3043 8170028d ths
        dc->env = env;
3044 8170028d ths
        dc->tb = tb;
3045 8170028d ths
3046 8170028d ths
        gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3047 8170028d ths
3048 8170028d ths
        dc->is_jmp = DISAS_NEXT;
3049 b41f7df0 edgar_igl
        dc->ppc = pc_start;
3050 8170028d ths
        dc->pc = pc_start;
3051 8170028d ths
        dc->singlestep_enabled = env->singlestep_enabled;
3052 30abcfc7 edgar_igl
        dc->flags_uptodate = 1;
3053 30abcfc7 edgar_igl
        dc->flagx_known = 1;
3054 30abcfc7 edgar_igl
        dc->flags_x = tb->flags & X_FLAG;
3055 30abcfc7 edgar_igl
        dc->cc_x_uptodate = 0;
3056 b41f7df0 edgar_igl
        dc->cc_mask = 0;
3057 cf1d97f0 edgar_igl
        dc->update_cc = 0;
3058 30abcfc7 edgar_igl
3059 b41f7df0 edgar_igl
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
3060 30abcfc7 edgar_igl
        dc->cc_size_uptodate = -1;
3061 b41f7df0 edgar_igl
3062 cf1d97f0 edgar_igl
        /* Decode TB flags.  */
3063 2a44f7f1 edgar_igl
        dc->tb_flags = tb->flags & (P_FLAG | U_FLAG | X_FLAG);
3064 cf1d97f0 edgar_igl
        dc->delayed_branch = !!(tb->flags & 7);
3065 2a44f7f1 edgar_igl
        if (dc->delayed_branch)
3066 2a44f7f1 edgar_igl
                dc->jmp = JMP_INDIRECT;
3067 2a44f7f1 edgar_igl
        else
3068 2a44f7f1 edgar_igl
                dc->jmp = JMP_NOJMP;
3069 2a44f7f1 edgar_igl
3070 2a44f7f1 edgar_igl
        dc->cpustate_changed = 0;
3071 b41f7df0 edgar_igl
3072 b41f7df0 edgar_igl
        if (loglevel & CPU_LOG_TB_IN_ASM) {
3073 b41f7df0 edgar_igl
                fprintf(logfile,
3074 2a44f7f1 edgar_igl
                        "srch=%d pc=%x %x flg=%llx bt=%x ds=%lld ccs=%x\n"
3075 30abcfc7 edgar_igl
                        "pid=%x usp=%x\n"
3076 b41f7df0 edgar_igl
                        "%x.%x.%x.%x\n"
3077 b41f7df0 edgar_igl
                        "%x.%x.%x.%x\n"
3078 b41f7df0 edgar_igl
                        "%x.%x.%x.%x\n"
3079 b41f7df0 edgar_igl
                        "%x.%x.%x.%x\n",
3080 2a44f7f1 edgar_igl
                        search_pc, dc->pc, dc->ppc, tb->flags,
3081 cf1d97f0 edgar_igl
                        env->btarget, tb->flags & 7,
3082 cf1d97f0 edgar_igl
                        env->pregs[PR_CCS], 
3083 b41f7df0 edgar_igl
                        env->pregs[PR_PID], env->pregs[PR_USP],
3084 b41f7df0 edgar_igl
                        env->regs[0], env->regs[1], env->regs[2], env->regs[3],
3085 b41f7df0 edgar_igl
                        env->regs[4], env->regs[5], env->regs[6], env->regs[7],
3086 b41f7df0 edgar_igl
                        env->regs[8], env->regs[9],
3087 b41f7df0 edgar_igl
                        env->regs[10], env->regs[11],
3088 b41f7df0 edgar_igl
                        env->regs[12], env->regs[13],
3089 b41f7df0 edgar_igl
                        env->regs[14], env->regs[15]);
3090 b41f7df0 edgar_igl
                
3091 b41f7df0 edgar_igl
        }
3092 3157a0a9 edgar_igl
3093 8170028d ths
        next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
3094 8170028d ths
        lj = -1;
3095 8170028d ths
        do
3096 8170028d ths
        {
3097 8170028d ths
                check_breakpoint(env, dc);
3098 8170028d ths
3099 8170028d ths
                if (search_pc) {
3100 8170028d ths
                        j = gen_opc_ptr - gen_opc_buf;
3101 8170028d ths
                        if (lj < j) {
3102 8170028d ths
                                lj++;
3103 8170028d ths
                                while (lj < j)
3104 8170028d ths
                                        gen_opc_instr_start[lj++] = 0;
3105 8170028d ths
                        }
3106 cf1d97f0 edgar_igl
                        if (dc->delayed_branch == 1)
3107 b41f7df0 edgar_igl
                                gen_opc_pc[lj] = dc->ppc | 1;
3108 cf1d97f0 edgar_igl
                        else
3109 b41f7df0 edgar_igl
                                gen_opc_pc[lj] = dc->pc;
3110 cf1d97f0 edgar_igl
                        gen_opc_instr_start[lj] = 1;
3111 cf1d97f0 edgar_igl
                }
3112 cf1d97f0 edgar_igl
3113 cf1d97f0 edgar_igl
                /* Pretty disas.  */
3114 cf1d97f0 edgar_igl
                DIS(fprintf(logfile, "%x ", dc->pc));
3115 cf1d97f0 edgar_igl
                if (search_pc) {
3116 cf1d97f0 edgar_igl
                        DIS(fprintf(logfile, "%x ", dc->pc));
3117 8170028d ths
                }
3118 8170028d ths
3119 b41f7df0 edgar_igl
                dc->clear_x = 1;
3120 30abcfc7 edgar_igl
                if (unlikely(loglevel & CPU_LOG_TB_OP))
3121 30abcfc7 edgar_igl
                        tcg_gen_debug_insn_start(dc->pc);
3122 8170028d ths
                insn_len = cris_decoder(dc);
3123 b41f7df0 edgar_igl
                dc->ppc = dc->pc;
3124 8170028d ths
                dc->pc += insn_len;
3125 b41f7df0 edgar_igl
                if (dc->clear_x)
3126 b41f7df0 edgar_igl
                        cris_clear_x_flag(dc);
3127 8170028d ths
3128 8170028d ths
                /* Check for delayed branches here. If we do it before
3129 8170028d ths
                   actually genereating any host code, the simulator will just
3130 8170028d ths
                   loop doing nothing for on this program location.  */
3131 8170028d ths
                if (dc->delayed_branch) {
3132 8170028d ths
                        dc->delayed_branch--;
3133 8170028d ths
                        if (dc->delayed_branch == 0)
3134 8170028d ths
                        {
3135 2a44f7f1 edgar_igl
                                if (tb->flags & 7)
3136 2a44f7f1 edgar_igl
                                        t_gen_mov_env_TN(dslot, 
3137 2a44f7f1 edgar_igl
                                                tcg_const_tl(0));
3138 2a44f7f1 edgar_igl
                                if (dc->jmp == JMP_DIRECT) {
3139 2a44f7f1 edgar_igl
                                        dc->is_jmp = DISAS_NEXT;
3140 2a44f7f1 edgar_igl
                                } else {
3141 2a44f7f1 edgar_igl
                                        t_gen_cc_jmp(env_btarget, 
3142 2a44f7f1 edgar_igl
                                                     tcg_const_tl(dc->pc));
3143 2a44f7f1 edgar_igl
                                        dc->is_jmp = DISAS_JUMP;
3144 2a44f7f1 edgar_igl
                                }
3145 2a44f7f1 edgar_igl
                                break;
3146 8170028d ths
                        }
3147 8170028d ths
                }
3148 8170028d ths
3149 73e51723 edgar_igl
                /* If we are rexecuting a branch due to exceptions on
3150 73e51723 edgar_igl
                   delay slots dont break.  */
3151 73e51723 edgar_igl
                if (!(tb->pc & 1) && env->singlestep_enabled)
3152 8170028d ths
                        break;
3153 8170028d ths
        } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end
3154 cf1d97f0 edgar_igl
                 && (dc->pc < next_page_start));
3155 b41f7df0 edgar_igl
3156 2a44f7f1 edgar_igl
        npc = dc->pc;
3157 2a44f7f1 edgar_igl
        if (dc->jmp == JMP_DIRECT && !dc->delayed_branch)
3158 2a44f7f1 edgar_igl
                npc = dc->jmp_pc;
3159 2a44f7f1 edgar_igl
3160 2a44f7f1 edgar_igl
        /* Force an update if the per-tb cpu state has changed.  */
3161 2a44f7f1 edgar_igl
        if (dc->is_jmp == DISAS_NEXT
3162 2a44f7f1 edgar_igl
            && (dc->cpustate_changed || !dc->flagx_known 
3163 2a44f7f1 edgar_igl
            || (dc->flags_x != (tb->flags & X_FLAG)))) {
3164 2a44f7f1 edgar_igl
                dc->is_jmp = DISAS_UPDATE;
3165 2a44f7f1 edgar_igl
                tcg_gen_movi_tl(env_pc, npc);
3166 2a44f7f1 edgar_igl
        }
3167 cf1d97f0 edgar_igl
        /* Broken branch+delayslot sequence.  */
3168 b41f7df0 edgar_igl
        if (dc->delayed_branch == 1) {
3169 cf1d97f0 edgar_igl
                /* Set env->dslot to the size of the branch insn.  */
3170 cf1d97f0 edgar_igl
                t_gen_mov_env_TN(dslot, tcg_const_tl(dc->pc - dc->ppc));
3171 2a44f7f1 edgar_igl
                cris_store_direct_jmp(dc);
3172 8170028d ths
        }
3173 8170028d ths
3174 8170028d ths
        cris_evaluate_flags (dc);
3175 2a44f7f1 edgar_igl
3176 8170028d ths
        if (__builtin_expect(env->singlestep_enabled, 0)) {
3177 2a44f7f1 edgar_igl
                tcg_gen_movi_tl(env_pc, npc);
3178 dceaf394 edgar_igl
                t_gen_raise_exception(EXCP_DEBUG);
3179 8170028d ths
        } else {
3180 8170028d ths
                switch(dc->is_jmp) {
3181 8170028d ths
                        case DISAS_NEXT:
3182 2a44f7f1 edgar_igl
                                gen_goto_tb(dc, 1, npc);
3183 8170028d ths
                                break;
3184 8170028d ths
                        default:
3185 8170028d ths
                        case DISAS_JUMP:
3186 8170028d ths
                        case DISAS_UPDATE:
3187 8170028d ths
                                /* indicate that the hash table must be used
3188 8170028d ths
                                   to find the next TB */
3189 57fec1fe bellard
                                tcg_gen_exit_tb(0);
3190 8170028d ths
                                break;
3191 4f400ab5 edgar_igl
                        case DISAS_SWI:
3192 8170028d ths
                        case DISAS_TB_JUMP:
3193 8170028d ths
                                /* nothing more to generate */
3194 8170028d ths
                                break;
3195 8170028d ths
                }
3196 8170028d ths
        }
3197 8170028d ths
        *gen_opc_ptr = INDEX_op_end;
3198 8170028d ths
        if (search_pc) {
3199 8170028d ths
                j = gen_opc_ptr - gen_opc_buf;
3200 8170028d ths
                lj++;
3201 8170028d ths
                while (lj <= j)
3202 8170028d ths
                        gen_opc_instr_start[lj++] = 0;
3203 8170028d ths
        } else {
3204 8170028d ths
                tb->size = dc->pc - pc_start;
3205 8170028d ths
        }
3206 8170028d ths
3207 8170028d ths
#ifdef DEBUG_DISAS
3208 8170028d ths
        if (loglevel & CPU_LOG_TB_IN_ASM) {
3209 8170028d ths
                fprintf(logfile, "--------------\n");
3210 8170028d ths
                fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
3211 17ac9754 edgar_igl
                target_disas(logfile, pc_start, dc->pc - pc_start, 0);
3212 b41f7df0 edgar_igl
                fprintf(logfile, "\nisize=%d osize=%d\n", 
3213 b41f7df0 edgar_igl
                        dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
3214 8170028d ths
        }
3215 8170028d ths
#endif
3216 8170028d ths
        return 0;
3217 8170028d ths
}
3218 8170028d ths
3219 8170028d ths
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
3220 8170028d ths
{
3221 8170028d ths
    return gen_intermediate_code_internal(env, tb, 0);
3222 8170028d ths
}
3223 8170028d ths
3224 8170028d ths
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
3225 8170028d ths
{
3226 8170028d ths
    return gen_intermediate_code_internal(env, tb, 1);
3227 8170028d ths
}
3228 8170028d ths
3229 8170028d ths
void cpu_dump_state (CPUState *env, FILE *f,
3230 8170028d ths
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
3231 8170028d ths
                     int flags)
3232 8170028d ths
{
3233 8170028d ths
        int i;
3234 8170028d ths
        uint32_t srs;
3235 8170028d ths
3236 8170028d ths
        if (!env || !f)
3237 8170028d ths
                return;
3238 8170028d ths
3239 8170028d ths
        cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
3240 30abcfc7 edgar_igl
                    "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
3241 9004627f edgar_igl
                    env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
3242 8170028d ths
                    env->cc_op,
3243 30abcfc7 edgar_igl
                    env->cc_src, env->cc_dest, env->cc_result, env->cc_mask);
3244 30abcfc7 edgar_igl
3245 8170028d ths
3246 8170028d ths
        for (i = 0; i < 16; i++) {
3247 8170028d ths
                cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
3248 8170028d ths
                if ((i + 1) % 4 == 0)
3249 8170028d ths
                        cpu_fprintf(f, "\n");
3250 8170028d ths
        }
3251 8170028d ths
        cpu_fprintf(f, "\nspecial regs:\n");
3252 8170028d ths
        for (i = 0; i < 16; i++) {
3253 8170028d ths
                cpu_fprintf(f, "p%2.2d=%8.8x ", i, env->pregs[i]);
3254 8170028d ths
                if ((i + 1) % 4 == 0)
3255 8170028d ths
                        cpu_fprintf(f, "\n");
3256 8170028d ths
        }
3257 9004627f edgar_igl
        srs = env->pregs[PR_SRS];
3258 b41f7df0 edgar_igl
        cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
3259 8170028d ths
        if (srs < 256) {
3260 8170028d ths
                for (i = 0; i < 16; i++) {
3261 8170028d ths
                        cpu_fprintf(f, "s%2.2d=%8.8x ",
3262 8170028d ths
                                    i, env->sregs[srs][i]);
3263 8170028d ths
                        if ((i + 1) % 4 == 0)
3264 8170028d ths
                                cpu_fprintf(f, "\n");
3265 8170028d ths
                }
3266 8170028d ths
        }
3267 8170028d ths
        cpu_fprintf(f, "\n\n");
3268 8170028d ths
3269 8170028d ths
}
3270 8170028d ths
3271 aaed909a bellard
CPUCRISState *cpu_cris_init (const char *cpu_model)
3272 8170028d ths
{
3273 8170028d ths
        CPUCRISState *env;
3274 a825e703 edgar_igl
        int i;
3275 8170028d ths
3276 8170028d ths
        env = qemu_mallocz(sizeof(CPUCRISState));
3277 8170028d ths
        if (!env)
3278 8170028d ths
                return NULL;
3279 8170028d ths
        cpu_exec_init(env);
3280 05ba7d5f edgar_igl
3281 05ba7d5f edgar_igl
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
3282 05ba7d5f edgar_igl
#if TARGET_LONG_BITS > HOST_LONG_BITS
3283 05ba7d5f edgar_igl
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, 
3284 05ba7d5f edgar_igl
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
3285 05ba7d5f edgar_igl
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
3286 05ba7d5f edgar_igl
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
3287 05ba7d5f edgar_igl
#else
3288 05ba7d5f edgar_igl
        cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
3289 05ba7d5f edgar_igl
        cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
3290 05ba7d5f edgar_igl
#endif
3291 05ba7d5f edgar_igl
3292 30abcfc7 edgar_igl
        cc_x = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
3293 30abcfc7 edgar_igl
                                  offsetof(CPUState, cc_x), "cc_x");
3294 30abcfc7 edgar_igl
        cc_src = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
3295 a825e703 edgar_igl
                                    offsetof(CPUState, cc_src), "cc_src");
3296 30abcfc7 edgar_igl
        cc_dest = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
3297 30abcfc7 edgar_igl
                                     offsetof(CPUState, cc_dest),
3298 a825e703 edgar_igl
                                     "cc_dest");
3299 30abcfc7 edgar_igl
        cc_result = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
3300 30abcfc7 edgar_igl
                                       offsetof(CPUState, cc_result),
3301 a825e703 edgar_igl
                                       "cc_result");
3302 30abcfc7 edgar_igl
        cc_op = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
3303 a825e703 edgar_igl
                                   offsetof(CPUState, cc_op), "cc_op");
3304 30abcfc7 edgar_igl
        cc_size = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
3305 30abcfc7 edgar_igl
                                     offsetof(CPUState, cc_size),
3306 a825e703 edgar_igl
                                     "cc_size");
3307 30abcfc7 edgar_igl
        cc_mask = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
3308 a825e703 edgar_igl
                                     offsetof(CPUState, cc_mask),
3309 a825e703 edgar_igl
                                     "cc_mask");
3310 a825e703 edgar_igl
3311 b41f7df0 edgar_igl
        env_pc = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
3312 30abcfc7 edgar_igl
                                    offsetof(CPUState, pc),
3313 30abcfc7 edgar_igl
                                    "pc");
3314 30abcfc7 edgar_igl
        env_btarget = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
3315 30abcfc7 edgar_igl
                                         offsetof(CPUState, btarget),
3316 30abcfc7 edgar_igl
                                         "btarget");
3317 2a44f7f1 edgar_igl
        env_btaken = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
3318 2a44f7f1 edgar_igl
                                         offsetof(CPUState, btaken),
3319 2a44f7f1 edgar_igl
                                         "btaken");
3320 a825e703 edgar_igl
        for (i = 0; i < 16; i++) {
3321 30abcfc7 edgar_igl
                cpu_R[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
3322 30abcfc7 edgar_igl
                                              offsetof(CPUState, regs[i]),
3323 a825e703 edgar_igl
                                              regnames[i]);
3324 a825e703 edgar_igl
        }
3325 a825e703 edgar_igl
        for (i = 0; i < 16; i++) {
3326 30abcfc7 edgar_igl
                cpu_PR[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
3327 30abcfc7 edgar_igl
                                               offsetof(CPUState, pregs[i]),
3328 a825e703 edgar_igl
                                               pregnames[i]);
3329 a825e703 edgar_igl
        }
3330 a825e703 edgar_igl
3331 dceaf394 edgar_igl
        TCG_HELPER(helper_raise_exception);
3332 b41f7df0 edgar_igl
        TCG_HELPER(helper_store);
3333 b41f7df0 edgar_igl
        TCG_HELPER(helper_dump);
3334 b41f7df0 edgar_igl
        TCG_HELPER(helper_dummy);
3335 b41f7df0 edgar_igl
3336 cf1d97f0 edgar_igl
        TCG_HELPER(helper_tlb_flush_pid);
3337 dceaf394 edgar_igl
        TCG_HELPER(helper_movl_sreg_reg);
3338 dceaf394 edgar_igl
        TCG_HELPER(helper_movl_reg_sreg);
3339 dceaf394 edgar_igl
        TCG_HELPER(helper_rfe);
3340 dceaf394 edgar_igl
3341 b41f7df0 edgar_igl
        TCG_HELPER(helper_evaluate_flags_muls);
3342 b41f7df0 edgar_igl
        TCG_HELPER(helper_evaluate_flags_mulu);
3343 b41f7df0 edgar_igl
        TCG_HELPER(helper_evaluate_flags_mcp);
3344 b41f7df0 edgar_igl
        TCG_HELPER(helper_evaluate_flags_alu_4);
3345 b41f7df0 edgar_igl
        TCG_HELPER(helper_evaluate_flags_move_4);
3346 b41f7df0 edgar_igl
        TCG_HELPER(helper_evaluate_flags_move_2);
3347 b41f7df0 edgar_igl
        TCG_HELPER(helper_evaluate_flags);
3348 30abcfc7 edgar_igl
        TCG_HELPER(helper_top_evaluate_flags);
3349 b41f7df0 edgar_igl
3350 8170028d ths
        cpu_reset(env);
3351 8170028d ths
        return env;
3352 8170028d ths
}
3353 8170028d ths
3354 8170028d ths
void cpu_reset (CPUCRISState *env)
3355 8170028d ths
{
3356 8170028d ths
        memset(env, 0, offsetof(CPUCRISState, breakpoints));
3357 8170028d ths
        tlb_flush(env, 1);
3358 b41f7df0 edgar_igl
3359 b41f7df0 edgar_igl
#if defined(CONFIG_USER_ONLY)
3360 b41f7df0 edgar_igl
        /* start in user mode with interrupts enabled.  */
3361 b41f7df0 edgar_igl
        env->pregs[PR_CCS] |= U_FLAG | I_FLAG;
3362 b41f7df0 edgar_igl
#else
3363 b41f7df0 edgar_igl
        env->pregs[PR_CCS] = 0;
3364 b41f7df0 edgar_igl
#endif
3365 8170028d ths
}
3366 d2856f1a aurel32
3367 d2856f1a aurel32
void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
3368 d2856f1a aurel32
                 unsigned long searched_pc, int pc_pos, void *puc)
3369 d2856f1a aurel32
{
3370 17ac9754 edgar_igl
        env->pc = gen_opc_pc[pc_pos];
3371 d2856f1a aurel32
}