Statistics
| Branch: | Revision:

root / target-cris / translate.c @ 79f85c3a

History | View | Annotate | Download (83.7 kB)

1 8170028d ths
/*
2 8170028d ths
 *  CRIS emulation for qemu: main translation routines.
3 8170028d ths
 *
4 05ba7d5f edgar_igl
 *  Copyright (c) 2008 AXIS Communications AB
5 8170028d ths
 *  Written by Edgar E. Iglesias.
6 8170028d ths
 *
7 8170028d ths
 * This library is free software; you can redistribute it and/or
8 8170028d ths
 * modify it under the terms of the GNU Lesser General Public
9 8170028d ths
 * License as published by the Free Software Foundation; either
10 8170028d ths
 * version 2 of the License, or (at your option) any later version.
11 8170028d ths
 *
12 8170028d ths
 * This library is distributed in the hope that it will be useful,
13 8170028d ths
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 8170028d ths
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 8170028d ths
 * Lesser General Public License for more details.
16 8170028d ths
 *
17 8170028d ths
 * You should have received a copy of the GNU Lesser General Public
18 8170028d ths
 * License along with this library; if not, write to the Free Software
19 fad6cb1a aurel32
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 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 a7812ae4 pbrook
#define GEN_HELPER 1
43 a7812ae4 pbrook
#include "helper.h"
44 a7812ae4 pbrook
45 8170028d ths
#define DISAS_CRIS 0
46 8170028d ths
#if DISAS_CRIS
47 a1aebcb8 edgar_igl
#define DIS(x) if (loglevel & CPU_LOG_TB_IN_ASM) x
48 8170028d ths
#else
49 8170028d ths
#define DIS(x)
50 8170028d ths
#endif
51 8170028d ths
52 b41f7df0 edgar_igl
#define D(x)
53 8170028d ths
#define BUG() (gen_BUG(dc, __FILE__, __LINE__))
54 8170028d ths
#define BUG_ON(x) ({if (x) BUG();})
55 8170028d ths
56 4f400ab5 edgar_igl
#define DISAS_SWI 5
57 4f400ab5 edgar_igl
58 8170028d ths
/* Used by the decoder.  */
59 8170028d ths
#define EXTRACT_FIELD(src, start, end) \
60 8170028d ths
            (((src) >> start) & ((1 << (end - start + 1)) - 1))
61 8170028d ths
62 8170028d ths
#define CC_MASK_NZ 0xc
63 8170028d ths
#define CC_MASK_NZV 0xe
64 8170028d ths
#define CC_MASK_NZVC 0xf
65 8170028d ths
#define CC_MASK_RNZV 0x10e
66 8170028d ths
67 a7812ae4 pbrook
static TCGv_ptr cpu_env;
68 9b32fbf8 edgar_igl
static TCGv cpu_R[16];
69 9b32fbf8 edgar_igl
static TCGv cpu_PR[16];
70 9b32fbf8 edgar_igl
static TCGv cc_x;
71 9b32fbf8 edgar_igl
static TCGv cc_src;
72 9b32fbf8 edgar_igl
static TCGv cc_dest;
73 9b32fbf8 edgar_igl
static TCGv cc_result;
74 9b32fbf8 edgar_igl
static TCGv cc_op;
75 9b32fbf8 edgar_igl
static TCGv cc_size;
76 9b32fbf8 edgar_igl
static TCGv cc_mask;
77 9b32fbf8 edgar_igl
78 9b32fbf8 edgar_igl
static TCGv env_btaken;
79 9b32fbf8 edgar_igl
static TCGv env_btarget;
80 9b32fbf8 edgar_igl
static TCGv env_pc;
81 b41f7df0 edgar_igl
82 2e70f6ef pbrook
#include "gen-icount.h"
83 2e70f6ef pbrook
84 8170028d ths
/* This is the state at translation time.  */
85 8170028d ths
typedef struct DisasContext {
86 8170028d ths
        CPUState *env;
87 b41f7df0 edgar_igl
        target_ulong pc, ppc;
88 8170028d ths
89 8170028d ths
        /* Decoder.  */
90 8170028d ths
        uint32_t ir;
91 8170028d ths
        uint32_t opcode;
92 8170028d ths
        unsigned int op1;
93 8170028d ths
        unsigned int op2;
94 8170028d ths
        unsigned int zsize, zzsize;
95 8170028d ths
        unsigned int mode;
96 8170028d ths
        unsigned int postinc;
97 8170028d ths
98 8170028d ths
        int update_cc;
99 8170028d ths
        int cc_op;
100 8170028d ths
        int cc_size;
101 8170028d ths
        uint32_t cc_mask;
102 30abcfc7 edgar_igl
103 30abcfc7 edgar_igl
        int cc_size_uptodate; /* -1 invalid or last written value.  */
104 30abcfc7 edgar_igl
105 30abcfc7 edgar_igl
        int cc_x_uptodate;  /* 1 - ccs, 2 - known | X_FLAG. 0 not uptodate.  */
106 30abcfc7 edgar_igl
        int flags_uptodate; /* Wether or not $ccs is uptodate.  */
107 30abcfc7 edgar_igl
        int flagx_known; /* Wether or not flags_x has the x flag known at
108 30abcfc7 edgar_igl
                            translation time.  */
109 8170028d ths
        int flags_x;
110 8170028d ths
111 30abcfc7 edgar_igl
        int clear_x; /* Clear x after this insn?  */
112 2a44f7f1 edgar_igl
        int cpustate_changed;
113 2a44f7f1 edgar_igl
        unsigned int tb_flags; /* tb dependent flags.  */
114 8170028d ths
        int is_jmp;
115 8170028d ths
116 2a44f7f1 edgar_igl
#define JMP_NOJMP    0
117 2a44f7f1 edgar_igl
#define JMP_DIRECT   1
118 2a44f7f1 edgar_igl
#define JMP_INDIRECT 2
119 2a44f7f1 edgar_igl
        int jmp; /* 0=nojmp, 1=direct, 2=indirect.  */ 
120 2a44f7f1 edgar_igl
        uint32_t jmp_pc;
121 2a44f7f1 edgar_igl
122 8170028d ths
        int delayed_branch;
123 8170028d ths
124 8170028d ths
        struct TranslationBlock *tb;
125 8170028d ths
        int singlestep_enabled;
126 8170028d ths
} DisasContext;
127 8170028d ths
128 7ccfb2eb blueswir1
static void gen_BUG(DisasContext *dc, const char *file, int line)
129 8170028d ths
{
130 8170028d ths
        printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
131 8170028d ths
        fprintf (logfile, "BUG: pc=%x %s %d\n", dc->pc, file, line);
132 cf1d97f0 edgar_igl
        cpu_abort(dc->env, "%s:%d\n", file, line);
133 8170028d ths
}
134 8170028d ths
135 9b32fbf8 edgar_igl
static const char *regnames[] =
136 a825e703 edgar_igl
{
137 a825e703 edgar_igl
        "$r0", "$r1", "$r2", "$r3",
138 a825e703 edgar_igl
        "$r4", "$r5", "$r6", "$r7",
139 a825e703 edgar_igl
        "$r8", "$r9", "$r10", "$r11",
140 a825e703 edgar_igl
        "$r12", "$r13", "$sp", "$acr",
141 a825e703 edgar_igl
};
142 9b32fbf8 edgar_igl
static const char *pregnames[] =
143 a825e703 edgar_igl
{
144 a825e703 edgar_igl
        "$bz", "$vr", "$pid", "$srs",
145 a825e703 edgar_igl
        "$wz", "$exs", "$eda", "$mof",
146 a825e703 edgar_igl
        "$dz", "$ebp", "$erp", "$srp",
147 a825e703 edgar_igl
        "$nrp", "$ccs", "$usp", "$spc",
148 a825e703 edgar_igl
};
149 a825e703 edgar_igl
150 05ba7d5f edgar_igl
/* We need this table to handle preg-moves with implicit width.  */
151 9b32fbf8 edgar_igl
static int preg_sizes[] = {
152 05ba7d5f edgar_igl
        1, /* bz.  */
153 05ba7d5f edgar_igl
        1, /* vr.  */
154 05ba7d5f edgar_igl
        4, /* pid.  */
155 05ba7d5f edgar_igl
        1, /* srs.  */
156 05ba7d5f edgar_igl
        2, /* wz.  */
157 05ba7d5f edgar_igl
        4, 4, 4,
158 05ba7d5f edgar_igl
        4, 4, 4, 4,
159 05ba7d5f edgar_igl
        4, 4, 4, 4,
160 05ba7d5f edgar_igl
};
161 05ba7d5f edgar_igl
162 05ba7d5f edgar_igl
#define t_gen_mov_TN_env(tn, member) \
163 3157a0a9 edgar_igl
 _t_gen_mov_TN_env((tn), offsetof(CPUState, member))
164 05ba7d5f edgar_igl
#define t_gen_mov_env_TN(member, tn) \
165 3157a0a9 edgar_igl
 _t_gen_mov_env_TN(offsetof(CPUState, member), (tn))
166 05ba7d5f edgar_igl
167 b41f7df0 edgar_igl
static inline void t_gen_mov_TN_reg(TCGv tn, int r)
168 b41f7df0 edgar_igl
{
169 b41f7df0 edgar_igl
        if (r < 0 || r > 15)
170 b41f7df0 edgar_igl
                fprintf(stderr, "wrong register read $r%d\n", r);
171 b41f7df0 edgar_igl
        tcg_gen_mov_tl(tn, cpu_R[r]);
172 b41f7df0 edgar_igl
}
173 b41f7df0 edgar_igl
static inline void t_gen_mov_reg_TN(int r, TCGv tn)
174 b41f7df0 edgar_igl
{
175 b41f7df0 edgar_igl
        if (r < 0 || r > 15)
176 b41f7df0 edgar_igl
                fprintf(stderr, "wrong register write $r%d\n", r);
177 b41f7df0 edgar_igl
        tcg_gen_mov_tl(cpu_R[r], tn);
178 b41f7df0 edgar_igl
}
179 05ba7d5f edgar_igl
180 05ba7d5f edgar_igl
static inline void _t_gen_mov_TN_env(TCGv tn, int offset)
181 05ba7d5f edgar_igl
{
182 b41f7df0 edgar_igl
        if (offset > sizeof (CPUState))
183 b41f7df0 edgar_igl
                fprintf(stderr, "wrong load from env from off=%d\n", offset);
184 05ba7d5f edgar_igl
        tcg_gen_ld_tl(tn, cpu_env, offset);
185 05ba7d5f edgar_igl
}
186 05ba7d5f edgar_igl
static inline void _t_gen_mov_env_TN(int offset, TCGv tn)
187 05ba7d5f edgar_igl
{
188 b41f7df0 edgar_igl
        if (offset > sizeof (CPUState))
189 b41f7df0 edgar_igl
                fprintf(stderr, "wrong store to env at off=%d\n", offset);
190 05ba7d5f edgar_igl
        tcg_gen_st_tl(tn, cpu_env, offset);
191 05ba7d5f edgar_igl
}
192 05ba7d5f edgar_igl
193 05ba7d5f edgar_igl
static inline void t_gen_mov_TN_preg(TCGv tn, int r)
194 05ba7d5f edgar_igl
{
195 b41f7df0 edgar_igl
        if (r < 0 || r > 15)
196 b41f7df0 edgar_igl
                fprintf(stderr, "wrong register read $p%d\n", r);
197 05ba7d5f edgar_igl
        if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
198 3157a0a9 edgar_igl
                tcg_gen_mov_tl(tn, tcg_const_tl(0));
199 05ba7d5f edgar_igl
        else if (r == PR_VR)
200 3157a0a9 edgar_igl
                tcg_gen_mov_tl(tn, tcg_const_tl(32));
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 2a44f7f1 edgar_igl
                if (r == PR_PID) 
218 a7812ae4 pbrook
                        gen_helper_tlb_flush_pid(tn);
219 a1aebcb8 edgar_igl
                if (dc->tb_flags & S_FLAG && r == PR_SPC) 
220 a7812ae4 pbrook
                        gen_helper_spc_write(tn);
221 2a44f7f1 edgar_igl
                else if (r == PR_CCS)
222 2a44f7f1 edgar_igl
                        dc->cpustate_changed = 1;
223 28de16da edgar_igl
                tcg_gen_mov_tl(cpu_PR[r], tn);
224 b41f7df0 edgar_igl
        }
225 05ba7d5f edgar_igl
}
226 05ba7d5f edgar_igl
227 dceaf394 edgar_igl
static inline void t_gen_raise_exception(uint32_t index)
228 05ba7d5f edgar_igl
{
229 a7812ae4 pbrook
        TCGv_i32 tmp = tcg_const_i32(index);
230 a7812ae4 pbrook
        gen_helper_raise_exception(tmp);
231 a7812ae4 pbrook
        tcg_temp_free_i32(tmp);
232 05ba7d5f edgar_igl
}
233 05ba7d5f edgar_igl
234 05ba7d5f edgar_igl
static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
235 05ba7d5f edgar_igl
{
236 7dcfb089 edgar_igl
        TCGv t0, t_31;
237 05ba7d5f edgar_igl
238 a7812ae4 pbrook
        t0 = tcg_temp_new();
239 44696296 edgar_igl
        t_31 = tcg_const_tl(31);
240 05ba7d5f edgar_igl
        tcg_gen_shl_tl(d, a, b);
241 7dcfb089 edgar_igl
242 7dcfb089 edgar_igl
        tcg_gen_sub_tl(t0, t_31, b);
243 7dcfb089 edgar_igl
        tcg_gen_sar_tl(t0, t0, t_31);
244 7dcfb089 edgar_igl
        tcg_gen_and_tl(t0, t0, d);
245 7dcfb089 edgar_igl
        tcg_gen_xor_tl(d, d, t0);
246 7dcfb089 edgar_igl
        tcg_temp_free(t0);
247 7dcfb089 edgar_igl
        tcg_temp_free(t_31);
248 05ba7d5f edgar_igl
}
249 05ba7d5f edgar_igl
250 05ba7d5f edgar_igl
static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
251 05ba7d5f edgar_igl
{
252 7dcfb089 edgar_igl
        TCGv t0, t_31;
253 05ba7d5f edgar_igl
254 a7812ae4 pbrook
        t0 = tcg_temp_new();
255 a7812ae4 pbrook
        t_31 = tcg_temp_new();
256 05ba7d5f edgar_igl
        tcg_gen_shr_tl(d, a, b);
257 7dcfb089 edgar_igl
258 7dcfb089 edgar_igl
        tcg_gen_movi_tl(t_31, 31);
259 7dcfb089 edgar_igl
        tcg_gen_sub_tl(t0, t_31, b);
260 7dcfb089 edgar_igl
        tcg_gen_sar_tl(t0, t0, t_31);
261 7dcfb089 edgar_igl
        tcg_gen_and_tl(t0, t0, d);
262 7dcfb089 edgar_igl
        tcg_gen_xor_tl(d, d, t0);
263 7dcfb089 edgar_igl
        tcg_temp_free(t0);
264 7dcfb089 edgar_igl
        tcg_temp_free(t_31);
265 05ba7d5f edgar_igl
}
266 05ba7d5f edgar_igl
267 05ba7d5f edgar_igl
static void t_gen_asr(TCGv d, TCGv a, TCGv b)
268 05ba7d5f edgar_igl
{
269 7dcfb089 edgar_igl
        TCGv t0, t_31;
270 05ba7d5f edgar_igl
271 a7812ae4 pbrook
        t0 = tcg_temp_new();
272 a7812ae4 pbrook
        t_31 = tcg_temp_new();
273 05ba7d5f edgar_igl
        tcg_gen_sar_tl(d, a, b);
274 7dcfb089 edgar_igl
275 7dcfb089 edgar_igl
        tcg_gen_movi_tl(t_31, 31);
276 7dcfb089 edgar_igl
        tcg_gen_sub_tl(t0, t_31, b);
277 7dcfb089 edgar_igl
        tcg_gen_sar_tl(t0, t0, t_31);
278 7dcfb089 edgar_igl
        tcg_gen_or_tl(d, d, t0);
279 7dcfb089 edgar_igl
        tcg_temp_free(t0);
280 7dcfb089 edgar_igl
        tcg_temp_free(t_31);
281 05ba7d5f edgar_igl
}
282 05ba7d5f edgar_igl
283 3157a0a9 edgar_igl
/* 64-bit signed mul, lower result in d and upper in d2.  */
284 3157a0a9 edgar_igl
static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
285 3157a0a9 edgar_igl
{
286 a7812ae4 pbrook
        TCGv_i64 t0, t1;
287 3157a0a9 edgar_igl
288 a7812ae4 pbrook
        t0 = tcg_temp_new_i64();
289 a7812ae4 pbrook
        t1 = tcg_temp_new_i64();
290 3157a0a9 edgar_igl
291 a7812ae4 pbrook
        tcg_gen_ext_i32_i64(t0, a);
292 a7812ae4 pbrook
        tcg_gen_ext_i32_i64(t1, b);
293 3157a0a9 edgar_igl
        tcg_gen_mul_i64(t0, t0, t1);
294 3157a0a9 edgar_igl
295 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d, t0);
296 3157a0a9 edgar_igl
        tcg_gen_shri_i64(t0, t0, 32);
297 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d2, t0);
298 b41f7df0 edgar_igl
299 a7812ae4 pbrook
        tcg_temp_free_i64(t0);
300 a7812ae4 pbrook
        tcg_temp_free_i64(t1);
301 3157a0a9 edgar_igl
}
302 3157a0a9 edgar_igl
303 3157a0a9 edgar_igl
/* 64-bit unsigned muls, lower result in d and upper in d2.  */
304 3157a0a9 edgar_igl
static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
305 3157a0a9 edgar_igl
{
306 a7812ae4 pbrook
        TCGv_i64 t0, t1;
307 3157a0a9 edgar_igl
308 a7812ae4 pbrook
        t0 = tcg_temp_new_i64();
309 a7812ae4 pbrook
        t1 = tcg_temp_new_i64();
310 3157a0a9 edgar_igl
311 3157a0a9 edgar_igl
        tcg_gen_extu_i32_i64(t0, a);
312 3157a0a9 edgar_igl
        tcg_gen_extu_i32_i64(t1, b);
313 3157a0a9 edgar_igl
        tcg_gen_mul_i64(t0, t0, t1);
314 3157a0a9 edgar_igl
315 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d, t0);
316 3157a0a9 edgar_igl
        tcg_gen_shri_i64(t0, t0, 32);
317 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d2, t0);
318 b41f7df0 edgar_igl
319 a7812ae4 pbrook
        tcg_temp_free_i64(t0);
320 a7812ae4 pbrook
        tcg_temp_free_i64(t1);
321 3157a0a9 edgar_igl
}
322 3157a0a9 edgar_igl
323 d059c172 edgar_igl
/* 32bit branch-free binary search for counting leading zeros.  */
324 d059c172 edgar_igl
static void t_gen_lz_i32(TCGv d, TCGv x)
325 d059c172 edgar_igl
{
326 a7812ae4 pbrook
        TCGv_i32 y, m, n;
327 d059c172 edgar_igl
328 a7812ae4 pbrook
        y = tcg_temp_new_i32();
329 a7812ae4 pbrook
        m = tcg_temp_new_i32();
330 a7812ae4 pbrook
        n = tcg_temp_new_i32();
331 d059c172 edgar_igl
332 d059c172 edgar_igl
        /* y = -(x >> 16)  */
333 d059c172 edgar_igl
        tcg_gen_shri_i32(y, x, 16);
334 390efc54 pbrook
        tcg_gen_neg_i32(y, y);
335 d059c172 edgar_igl
336 d059c172 edgar_igl
        /* m = (y >> 16) & 16  */
337 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
338 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 16);
339 d059c172 edgar_igl
340 d059c172 edgar_igl
        /* n = 16 - m  */
341 d059c172 edgar_igl
        tcg_gen_sub_i32(n, tcg_const_i32(16), m);
342 d059c172 edgar_igl
        /* x = x >> m  */
343 d059c172 edgar_igl
        tcg_gen_shr_i32(x, x, m);
344 d059c172 edgar_igl
345 d059c172 edgar_igl
        /* y = x - 0x100  */
346 d059c172 edgar_igl
        tcg_gen_subi_i32(y, x, 0x100);
347 d059c172 edgar_igl
        /* m = (y >> 16) & 8  */
348 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
349 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 8);
350 d059c172 edgar_igl
        /* n = n + m  */
351 d059c172 edgar_igl
        tcg_gen_add_i32(n, n, m);
352 d059c172 edgar_igl
        /* x = x << m  */
353 d059c172 edgar_igl
        tcg_gen_shl_i32(x, x, m);
354 d059c172 edgar_igl
355 d059c172 edgar_igl
        /* y = x - 0x1000  */
356 d059c172 edgar_igl
        tcg_gen_subi_i32(y, x, 0x1000);
357 d059c172 edgar_igl
        /* m = (y >> 16) & 4  */
358 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
359 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 4);
360 d059c172 edgar_igl
        /* n = n + m  */
361 d059c172 edgar_igl
        tcg_gen_add_i32(n, n, m);
362 d059c172 edgar_igl
        /* x = x << m  */
363 d059c172 edgar_igl
        tcg_gen_shl_i32(x, x, m);
364 d059c172 edgar_igl
365 d059c172 edgar_igl
        /* y = x - 0x4000  */
366 d059c172 edgar_igl
        tcg_gen_subi_i32(y, x, 0x4000);
367 d059c172 edgar_igl
        /* m = (y >> 16) & 2  */
368 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 16);
369 d059c172 edgar_igl
        tcg_gen_andi_i32(m, m, 2);
370 d059c172 edgar_igl
        /* n = n + m  */
371 d059c172 edgar_igl
        tcg_gen_add_i32(n, n, m);
372 d059c172 edgar_igl
        /* x = x << m  */
373 d059c172 edgar_igl
        tcg_gen_shl_i32(x, x, m);
374 d059c172 edgar_igl
375 d059c172 edgar_igl
        /* y = x >> 14  */
376 d059c172 edgar_igl
        tcg_gen_shri_i32(y, x, 14);
377 d059c172 edgar_igl
        /* m = y & ~(y >> 1)  */
378 d059c172 edgar_igl
        tcg_gen_sari_i32(m, y, 1);
379 d1896336 edgar_igl
        tcg_gen_not_i32(m, m);
380 d059c172 edgar_igl
        tcg_gen_and_i32(m, m, y);
381 d059c172 edgar_igl
382 d059c172 edgar_igl
        /* d = n + 2 - m  */
383 d059c172 edgar_igl
        tcg_gen_addi_i32(d, n, 2);
384 d059c172 edgar_igl
        tcg_gen_sub_i32(d, d, m);
385 d059c172 edgar_igl
386 30abcfc7 edgar_igl
        tcg_temp_free(y);
387 30abcfc7 edgar_igl
        tcg_temp_free(m);
388 30abcfc7 edgar_igl
        tcg_temp_free(n);
389 d059c172 edgar_igl
}
390 d059c172 edgar_igl
391 30abcfc7 edgar_igl
static void t_gen_btst(TCGv d, TCGv a, TCGv b)
392 dceaf394 edgar_igl
{
393 dceaf394 edgar_igl
        TCGv sbit;
394 dceaf394 edgar_igl
        TCGv bset;
395 30abcfc7 edgar_igl
        TCGv t0;
396 dceaf394 edgar_igl
        int l1;
397 dceaf394 edgar_igl
398 dceaf394 edgar_igl
        /* des ref:
399 dceaf394 edgar_igl
           The N flag is set according to the selected bit in the dest reg.
400 dceaf394 edgar_igl
           The Z flag is set if the selected bit and all bits to the right are
401 dceaf394 edgar_igl
           zero.
402 dceaf394 edgar_igl
           The X flag is cleared.
403 dceaf394 edgar_igl
           Other flags are left untouched.
404 dceaf394 edgar_igl
           The destination reg is not affected.
405 dceaf394 edgar_igl

406 dceaf394 edgar_igl
        unsigned int fz, sbit, bset, mask, masked_t0;
407 dceaf394 edgar_igl

408 dceaf394 edgar_igl
        sbit = T1 & 31;
409 dceaf394 edgar_igl
        bset = !!(T0 & (1 << sbit));
410 dceaf394 edgar_igl
        mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1;
411 dceaf394 edgar_igl
        masked_t0 = T0 & mask;
412 dceaf394 edgar_igl
        fz = !(masked_t0 | bset);
413 dceaf394 edgar_igl

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