Statistics
| Branch: | Revision:

root / target-cris / translate.c @ 14899cdf

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