Statistics
| Branch: | Revision:

root / target-cris / translate.c @ ac72472b

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