Statistics
| Branch: | Revision:

root / target-cris / translate.c @ 298e01b6

History | View | Annotate | Download (63.2 kB)

1 8170028d ths
/*
2 8170028d ths
 *  CRIS emulation for qemu: main translation routines.
3 8170028d ths
 *
4 05ba7d5f edgar_igl
 *  Copyright (c) 2008 AXIS Communications AB
5 8170028d ths
 *  Written by Edgar E. Iglesias.
6 8170028d ths
 *
7 8170028d ths
 * This library is free software; you can redistribute it and/or
8 8170028d ths
 * modify it under the terms of the GNU Lesser General Public
9 8170028d ths
 * License as published by the Free Software Foundation; either
10 8170028d ths
 * version 2 of the License, or (at your option) any later version.
11 8170028d ths
 *
12 8170028d ths
 * This library is distributed in the hope that it will be useful,
13 8170028d ths
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 8170028d ths
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 8170028d ths
 * Lesser General Public License for more details.
16 8170028d ths
 *
17 8170028d ths
 * You should have received a copy of the GNU Lesser General Public
18 8170028d ths
 * License along with this library; if not, write to the Free Software
19 8170028d ths
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 8170028d ths
 */
21 8170028d ths
22 8170028d ths
#include <stdarg.h>
23 8170028d ths
#include <stdlib.h>
24 8170028d ths
#include <stdio.h>
25 8170028d ths
#include <string.h>
26 8170028d ths
#include <inttypes.h>
27 8170028d ths
#include <assert.h>
28 8170028d ths
29 8170028d ths
#include "cpu.h"
30 8170028d ths
#include "exec-all.h"
31 8170028d ths
#include "disas.h"
32 57fec1fe bellard
#include "tcg-op.h"
33 05ba7d5f edgar_igl
#include "helper.h"
34 8170028d ths
#include "crisv32-decode.h"
35 8170028d ths
36 8170028d ths
#define CRIS_STATS 0
37 8170028d ths
#if CRIS_STATS
38 8170028d ths
#define STATS(x) x
39 8170028d ths
#else
40 8170028d ths
#define STATS(x)
41 8170028d ths
#endif
42 8170028d ths
43 8170028d ths
#define DISAS_CRIS 0
44 8170028d ths
#if DISAS_CRIS
45 8170028d ths
#define DIS(x) x
46 8170028d ths
#else
47 8170028d ths
#define DIS(x)
48 8170028d ths
#endif
49 8170028d ths
50 8170028d ths
#define BUG() (gen_BUG(dc, __FILE__, __LINE__))
51 8170028d ths
#define BUG_ON(x) ({if (x) BUG();})
52 8170028d ths
53 4f400ab5 edgar_igl
#define DISAS_SWI 5
54 4f400ab5 edgar_igl
55 8170028d ths
/* Used by the decoder.  */
56 8170028d ths
#define EXTRACT_FIELD(src, start, end) \
57 8170028d ths
            (((src) >> start) & ((1 << (end - start + 1)) - 1))
58 8170028d ths
59 8170028d ths
#define CC_MASK_NZ 0xc
60 8170028d ths
#define CC_MASK_NZV 0xe
61 8170028d ths
#define CC_MASK_NZVC 0xf
62 8170028d ths
#define CC_MASK_RNZV 0x10e
63 8170028d ths
64 a825e703 edgar_igl
TCGv cpu_env;
65 a825e703 edgar_igl
TCGv cpu_T[2];
66 a825e703 edgar_igl
TCGv cpu_R[16];
67 a825e703 edgar_igl
TCGv cpu_PR[16];
68 a825e703 edgar_igl
TCGv cc_src;
69 a825e703 edgar_igl
TCGv cc_dest;
70 a825e703 edgar_igl
TCGv cc_result;
71 a825e703 edgar_igl
TCGv cc_op;
72 a825e703 edgar_igl
TCGv cc_size;
73 a825e703 edgar_igl
TCGv cc_mask;
74 05ba7d5f edgar_igl
75 8170028d ths
/* This is the state at translation time.  */
76 8170028d ths
typedef struct DisasContext {
77 8170028d ths
        CPUState *env;
78 8170028d ths
        target_ulong pc, insn_pc;
79 8170028d ths
80 8170028d ths
        /* Decoder.  */
81 8170028d ths
        uint32_t ir;
82 8170028d ths
        uint32_t opcode;
83 8170028d ths
        unsigned int op1;
84 8170028d ths
        unsigned int op2;
85 8170028d ths
        unsigned int zsize, zzsize;
86 8170028d ths
        unsigned int mode;
87 8170028d ths
        unsigned int postinc;
88 8170028d ths
89 8170028d ths
        int update_cc;
90 8170028d ths
        int cc_op;
91 8170028d ths
        int cc_size;
92 8170028d ths
        uint32_t cc_mask;
93 8170028d ths
        int flags_live;
94 8170028d ths
        int flagx_live;
95 8170028d ths
        int flags_x;
96 8170028d ths
        uint32_t tb_entry_flags;
97 8170028d ths
98 8170028d ths
        int memidx; /* user or kernel mode.  */
99 8170028d ths
        int is_jmp;
100 8170028d ths
        int dyn_jmp;
101 8170028d ths
102 8170028d ths
        uint32_t delayed_pc;
103 8170028d ths
        int delayed_branch;
104 8170028d ths
        int bcc;
105 8170028d ths
        uint32_t condlabel;
106 8170028d ths
107 8170028d ths
        struct TranslationBlock *tb;
108 8170028d ths
        int singlestep_enabled;
109 8170028d ths
} DisasContext;
110 8170028d ths
111 8170028d ths
void cris_prepare_jmp (DisasContext *dc, uint32_t dst);
112 8170028d ths
static void gen_BUG(DisasContext *dc, char *file, int line)
113 8170028d ths
{
114 8170028d ths
        printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
115 8170028d ths
        fprintf (logfile, "BUG: pc=%x %s %d\n", dc->pc, file, line);
116 8170028d ths
        cpu_dump_state (dc->env, stdout, fprintf, 0);
117 8170028d ths
        fflush(NULL);
118 8170028d ths
        cris_prepare_jmp (dc, 0x70000000 + line);
119 8170028d ths
}
120 8170028d ths
121 8170028d ths
#ifdef CONFIG_USER_ONLY
122 8170028d ths
#define GEN_OP_LD(width, reg) \
123 8170028d ths
  void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
124 8170028d ths
    gen_op_ld##width##_T0_##reg##_raw(); \
125 8170028d ths
  }
126 8170028d ths
#define GEN_OP_ST(width, reg) \
127 8170028d ths
  void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
128 8170028d ths
    gen_op_st##width##_##reg##_T1_raw(); \
129 8170028d ths
  }
130 8170028d ths
#else
131 8170028d ths
#define GEN_OP_LD(width, reg) \
132 8170028d ths
  void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
133 8170028d ths
    if (dc->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
134 8170028d ths
    else gen_op_ld##width##_T0_##reg##_user();\
135 8170028d ths
  }
136 8170028d ths
#define GEN_OP_ST(width, reg) \
137 8170028d ths
  void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
138 8170028d ths
    if (dc->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
139 8170028d ths
    else gen_op_st##width##_##reg##_T1_user();\
140 8170028d ths
  }
141 8170028d ths
#endif
142 8170028d ths
143 8170028d ths
GEN_OP_LD(ub, T0)
144 8170028d ths
GEN_OP_LD(b, T0)
145 8170028d ths
GEN_OP_ST(b, T0)
146 8170028d ths
GEN_OP_LD(uw, T0)
147 8170028d ths
GEN_OP_LD(w, T0)
148 8170028d ths
GEN_OP_ST(w, T0)
149 8170028d ths
GEN_OP_LD(l, T0)
150 8170028d ths
GEN_OP_ST(l, T0)
151 8170028d ths
152 a825e703 edgar_igl
const char *regnames[] =
153 a825e703 edgar_igl
{
154 a825e703 edgar_igl
        "$r0", "$r1", "$r2", "$r3",
155 a825e703 edgar_igl
        "$r4", "$r5", "$r6", "$r7",
156 a825e703 edgar_igl
        "$r8", "$r9", "$r10", "$r11",
157 a825e703 edgar_igl
        "$r12", "$r13", "$sp", "$acr",
158 a825e703 edgar_igl
};
159 a825e703 edgar_igl
const char *pregnames[] =
160 a825e703 edgar_igl
{
161 a825e703 edgar_igl
        "$bz", "$vr", "$pid", "$srs",
162 a825e703 edgar_igl
        "$wz", "$exs", "$eda", "$mof",
163 a825e703 edgar_igl
        "$dz", "$ebp", "$erp", "$srp",
164 a825e703 edgar_igl
        "$nrp", "$ccs", "$usp", "$spc",
165 a825e703 edgar_igl
};
166 a825e703 edgar_igl
167 05ba7d5f edgar_igl
/* We need this table to handle preg-moves with implicit width.  */
168 05ba7d5f edgar_igl
int preg_sizes[] = {
169 05ba7d5f edgar_igl
        1, /* bz.  */
170 05ba7d5f edgar_igl
        1, /* vr.  */
171 05ba7d5f edgar_igl
        4, /* pid.  */
172 05ba7d5f edgar_igl
        1, /* srs.  */
173 05ba7d5f edgar_igl
        2, /* wz.  */
174 05ba7d5f edgar_igl
        4, 4, 4,
175 05ba7d5f edgar_igl
        4, 4, 4, 4,
176 05ba7d5f edgar_igl
        4, 4, 4, 4,
177 05ba7d5f edgar_igl
};
178 05ba7d5f edgar_igl
179 05ba7d5f edgar_igl
#define t_gen_mov_TN_env(tn, member) \
180 3157a0a9 edgar_igl
 _t_gen_mov_TN_env((tn), offsetof(CPUState, member))
181 05ba7d5f edgar_igl
#define t_gen_mov_env_TN(member, tn) \
182 3157a0a9 edgar_igl
 _t_gen_mov_env_TN(offsetof(CPUState, member), (tn))
183 05ba7d5f edgar_igl
184 05ba7d5f edgar_igl
#define t_gen_mov_TN_reg(tn, regno) \
185 a825e703 edgar_igl
 tcg_gen_mov_tl(tn, cpu_R[regno])
186 05ba7d5f edgar_igl
#define t_gen_mov_reg_TN(regno, tn) \
187 a825e703 edgar_igl
 tcg_gen_mov_tl(cpu_R[regno], tn)
188 05ba7d5f edgar_igl
189 05ba7d5f edgar_igl
static inline void _t_gen_mov_TN_env(TCGv tn, int offset)
190 05ba7d5f edgar_igl
{
191 05ba7d5f edgar_igl
        tcg_gen_ld_tl(tn, cpu_env, offset);
192 05ba7d5f edgar_igl
}
193 05ba7d5f edgar_igl
static inline void _t_gen_mov_env_TN(int offset, TCGv tn)
194 05ba7d5f edgar_igl
{
195 05ba7d5f edgar_igl
        tcg_gen_st_tl(tn, cpu_env, offset);
196 05ba7d5f edgar_igl
}
197 05ba7d5f edgar_igl
198 05ba7d5f edgar_igl
static inline void t_gen_mov_TN_preg(TCGv tn, int r)
199 05ba7d5f edgar_igl
{
200 05ba7d5f edgar_igl
        if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
201 3157a0a9 edgar_igl
                tcg_gen_mov_tl(tn, tcg_const_tl(0));
202 05ba7d5f edgar_igl
        else if (r == PR_VR)
203 3157a0a9 edgar_igl
                tcg_gen_mov_tl(tn, tcg_const_tl(32));
204 05ba7d5f edgar_igl
        else
205 a825e703 edgar_igl
                tcg_gen_mov_tl(tn, cpu_PR[r]);
206 05ba7d5f edgar_igl
}
207 05ba7d5f edgar_igl
static inline void t_gen_mov_preg_TN(int r, TCGv tn)
208 05ba7d5f edgar_igl
{
209 05ba7d5f edgar_igl
        if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
210 05ba7d5f edgar_igl
                return;
211 05ba7d5f edgar_igl
        else
212 a825e703 edgar_igl
                tcg_gen_mov_tl(cpu_PR[r], tn);
213 05ba7d5f edgar_igl
}
214 05ba7d5f edgar_igl
215 05ba7d5f edgar_igl
static inline void t_gen_mov_TN_im(TCGv tn, int32_t val)
216 05ba7d5f edgar_igl
{
217 05ba7d5f edgar_igl
        tcg_gen_movi_tl(tn, val);
218 05ba7d5f edgar_igl
}
219 05ba7d5f edgar_igl
220 05ba7d5f edgar_igl
static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
221 05ba7d5f edgar_igl
{
222 05ba7d5f edgar_igl
        int l1;
223 05ba7d5f edgar_igl
224 05ba7d5f edgar_igl
        l1 = gen_new_label();
225 05ba7d5f edgar_igl
        /* Speculative shift. */
226 05ba7d5f edgar_igl
        tcg_gen_shl_tl(d, a, b);
227 3157a0a9 edgar_igl
        tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_tl(31), l1);
228 05ba7d5f edgar_igl
        /* Clear dst if shift operands were to large.  */
229 05ba7d5f edgar_igl
        tcg_gen_movi_tl(d, 0);
230 05ba7d5f edgar_igl
        gen_set_label(l1);
231 05ba7d5f edgar_igl
}
232 05ba7d5f edgar_igl
233 05ba7d5f edgar_igl
static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
234 05ba7d5f edgar_igl
{
235 05ba7d5f edgar_igl
        int l1;
236 05ba7d5f edgar_igl
237 05ba7d5f edgar_igl
        l1 = gen_new_label();
238 05ba7d5f edgar_igl
        /* Speculative shift. */
239 05ba7d5f edgar_igl
        tcg_gen_shr_tl(d, a, b);
240 3157a0a9 edgar_igl
        tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_tl(31), l1);
241 05ba7d5f edgar_igl
        /* Clear dst if shift operands were to large.  */
242 05ba7d5f edgar_igl
        tcg_gen_movi_tl(d, 0);
243 05ba7d5f edgar_igl
        gen_set_label(l1);
244 05ba7d5f edgar_igl
}
245 05ba7d5f edgar_igl
246 05ba7d5f edgar_igl
static void t_gen_asr(TCGv d, TCGv a, TCGv b)
247 05ba7d5f edgar_igl
{
248 05ba7d5f edgar_igl
        int l1;
249 05ba7d5f edgar_igl
250 05ba7d5f edgar_igl
        l1 = gen_new_label();
251 05ba7d5f edgar_igl
        /* Speculative shift. */
252 05ba7d5f edgar_igl
        tcg_gen_sar_tl(d, a, b);
253 3157a0a9 edgar_igl
        tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_tl(31), l1);
254 05ba7d5f edgar_igl
        /* Clear dst if shift operands were to large.  */
255 05ba7d5f edgar_igl
        tcg_gen_movi_tl(d, 0);
256 3157a0a9 edgar_igl
        tcg_gen_brcond_tl(TCG_COND_LT, b, tcg_const_tl(0x80000000), l1);
257 05ba7d5f edgar_igl
        tcg_gen_movi_tl(d, 0xffffffff);
258 05ba7d5f edgar_igl
        gen_set_label(l1);
259 05ba7d5f edgar_igl
}
260 05ba7d5f edgar_igl
261 3157a0a9 edgar_igl
/* 64-bit signed mul, lower result in d and upper in d2.  */
262 3157a0a9 edgar_igl
static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
263 3157a0a9 edgar_igl
{
264 3157a0a9 edgar_igl
        TCGv t0, t1;
265 3157a0a9 edgar_igl
266 3157a0a9 edgar_igl
        t0 = tcg_temp_new(TCG_TYPE_I64);
267 3157a0a9 edgar_igl
        t1 = tcg_temp_new(TCG_TYPE_I64);
268 3157a0a9 edgar_igl
269 3157a0a9 edgar_igl
        tcg_gen_ext32s_i64(t0, a);
270 3157a0a9 edgar_igl
        tcg_gen_ext32s_i64(t1, b);
271 3157a0a9 edgar_igl
        tcg_gen_mul_i64(t0, t0, t1);
272 3157a0a9 edgar_igl
273 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d, t0);
274 3157a0a9 edgar_igl
        tcg_gen_shri_i64(t0, t0, 32);
275 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d2, t0);
276 3157a0a9 edgar_igl
}
277 3157a0a9 edgar_igl
278 3157a0a9 edgar_igl
/* 64-bit unsigned muls, lower result in d and upper in d2.  */
279 3157a0a9 edgar_igl
static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
280 3157a0a9 edgar_igl
{
281 3157a0a9 edgar_igl
        TCGv t0, t1;
282 3157a0a9 edgar_igl
283 3157a0a9 edgar_igl
        t0 = tcg_temp_new(TCG_TYPE_I64);
284 3157a0a9 edgar_igl
        t1 = tcg_temp_new(TCG_TYPE_I64);
285 3157a0a9 edgar_igl
286 3157a0a9 edgar_igl
        tcg_gen_extu_i32_i64(t0, a);
287 3157a0a9 edgar_igl
        tcg_gen_extu_i32_i64(t1, b);
288 3157a0a9 edgar_igl
        tcg_gen_mul_i64(t0, t0, t1);
289 3157a0a9 edgar_igl
290 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d, t0);
291 3157a0a9 edgar_igl
        tcg_gen_shri_i64(t0, t0, 32);
292 3157a0a9 edgar_igl
        tcg_gen_trunc_i64_i32(d2, t0);
293 3157a0a9 edgar_igl
}
294 3157a0a9 edgar_igl
295 3157a0a9 edgar_igl
/* Extended arithmetics on CRIS.  */
296 3157a0a9 edgar_igl
static inline void t_gen_add_flag(TCGv d, int flag)
297 3157a0a9 edgar_igl
{
298 3157a0a9 edgar_igl
        TCGv c;
299 3157a0a9 edgar_igl
300 3157a0a9 edgar_igl
        c = tcg_temp_new(TCG_TYPE_TL);
301 3157a0a9 edgar_igl
        t_gen_mov_TN_preg(c, PR_CCS);
302 3157a0a9 edgar_igl
        /* Propagate carry into d.  */
303 3157a0a9 edgar_igl
        tcg_gen_andi_tl(c, c, 1 << flag);
304 3157a0a9 edgar_igl
        if (flag)
305 3157a0a9 edgar_igl
                tcg_gen_shri_tl(c, c, flag);
306 3157a0a9 edgar_igl
        tcg_gen_add_tl(d, d, c);
307 3157a0a9 edgar_igl
}
308 3157a0a9 edgar_igl
309 3157a0a9 edgar_igl
static inline void t_gen_addx_carry(TCGv d)
310 3157a0a9 edgar_igl
{
311 3157a0a9 edgar_igl
        TCGv x, c;
312 3157a0a9 edgar_igl
313 3157a0a9 edgar_igl
        x = tcg_temp_new(TCG_TYPE_TL);
314 3157a0a9 edgar_igl
        c = tcg_temp_new(TCG_TYPE_TL);
315 3157a0a9 edgar_igl
        t_gen_mov_TN_preg(x, PR_CCS);
316 3157a0a9 edgar_igl
        tcg_gen_mov_tl(c, x);
317 3157a0a9 edgar_igl
318 3157a0a9 edgar_igl
        /* Propagate carry into d if X is set. Branch free.  */
319 3157a0a9 edgar_igl
        tcg_gen_andi_tl(c, c, C_FLAG);
320 3157a0a9 edgar_igl
        tcg_gen_andi_tl(x, x, X_FLAG);
321 3157a0a9 edgar_igl
        tcg_gen_shri_tl(x, x, 4);
322 3157a0a9 edgar_igl
323 3157a0a9 edgar_igl
        tcg_gen_and_tl(x, x, c);
324 3157a0a9 edgar_igl
        tcg_gen_add_tl(d, d, x);        
325 3157a0a9 edgar_igl
}
326 3157a0a9 edgar_igl
327 3157a0a9 edgar_igl
static inline void t_gen_subx_carry(TCGv d)
328 3157a0a9 edgar_igl
{
329 3157a0a9 edgar_igl
        TCGv x, c;
330 3157a0a9 edgar_igl
331 3157a0a9 edgar_igl
        x = tcg_temp_new(TCG_TYPE_TL);
332 3157a0a9 edgar_igl
        c = tcg_temp_new(TCG_TYPE_TL);
333 3157a0a9 edgar_igl
        t_gen_mov_TN_preg(x, PR_CCS);
334 3157a0a9 edgar_igl
        tcg_gen_mov_tl(c, x);
335 3157a0a9 edgar_igl
336 3157a0a9 edgar_igl
        /* Propagate carry into d if X is set. Branch free.  */
337 3157a0a9 edgar_igl
        tcg_gen_andi_tl(c, c, C_FLAG);
338 3157a0a9 edgar_igl
        tcg_gen_andi_tl(x, x, X_FLAG);
339 3157a0a9 edgar_igl
        tcg_gen_shri_tl(x, x, 4);
340 3157a0a9 edgar_igl
341 3157a0a9 edgar_igl
        tcg_gen_and_tl(x, x, c);
342 3157a0a9 edgar_igl
        tcg_gen_sub_tl(d, d, x);
343 3157a0a9 edgar_igl
}
344 3157a0a9 edgar_igl
345 3157a0a9 edgar_igl
/* Swap the two bytes within each half word of the s operand.
346 3157a0a9 edgar_igl
   T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff)  */
347 3157a0a9 edgar_igl
static inline void t_gen_swapb(TCGv d, TCGv s)
348 3157a0a9 edgar_igl
{
349 3157a0a9 edgar_igl
        TCGv t, org_s;
350 3157a0a9 edgar_igl
351 3157a0a9 edgar_igl
        t = tcg_temp_new(TCG_TYPE_TL);
352 3157a0a9 edgar_igl
        org_s = tcg_temp_new(TCG_TYPE_TL);
353 3157a0a9 edgar_igl
354 3157a0a9 edgar_igl
        /* d and s may refer to the same object.  */
355 3157a0a9 edgar_igl
        tcg_gen_mov_tl(org_s, s);
356 3157a0a9 edgar_igl
        tcg_gen_shli_tl(t, org_s, 8);
357 3157a0a9 edgar_igl
        tcg_gen_andi_tl(d, t, 0xff00ff00);
358 3157a0a9 edgar_igl
        tcg_gen_shri_tl(t, org_s, 8);
359 3157a0a9 edgar_igl
        tcg_gen_andi_tl(t, t, 0x00ff00ff);
360 3157a0a9 edgar_igl
        tcg_gen_or_tl(d, d, t);
361 3157a0a9 edgar_igl
}
362 3157a0a9 edgar_igl
363 3157a0a9 edgar_igl
/* Swap the halfwords of the s operand.  */
364 3157a0a9 edgar_igl
static inline void t_gen_swapw(TCGv d, TCGv s)
365 3157a0a9 edgar_igl
{
366 3157a0a9 edgar_igl
        TCGv t;
367 3157a0a9 edgar_igl
        /* d and s refer the same object.  */
368 3157a0a9 edgar_igl
        t = tcg_temp_new(TCG_TYPE_TL);
369 3157a0a9 edgar_igl
        tcg_gen_mov_tl(t, s);
370 3157a0a9 edgar_igl
        tcg_gen_shli_tl(d, t, 16);
371 3157a0a9 edgar_igl
        tcg_gen_shri_tl(t, t, 16);
372 3157a0a9 edgar_igl
        tcg_gen_or_tl(d, d, t);
373 3157a0a9 edgar_igl
}
374 3157a0a9 edgar_igl
375 3157a0a9 edgar_igl
/* Reverse the within each byte.
376 3157a0a9 edgar_igl
   T0 = (((T0 << 7) & 0x80808080) |
377 3157a0a9 edgar_igl
   ((T0 << 5) & 0x40404040) |
378 3157a0a9 edgar_igl
   ((T0 << 3) & 0x20202020) |
379 3157a0a9 edgar_igl
   ((T0 << 1) & 0x10101010) |
380 3157a0a9 edgar_igl
   ((T0 >> 1) & 0x08080808) |
381 3157a0a9 edgar_igl
   ((T0 >> 3) & 0x04040404) |
382 3157a0a9 edgar_igl
   ((T0 >> 5) & 0x02020202) |
383 3157a0a9 edgar_igl
   ((T0 >> 7) & 0x01010101));
384 3157a0a9 edgar_igl
 */
385 3157a0a9 edgar_igl
static inline void t_gen_swapr(TCGv d, TCGv s)
386 3157a0a9 edgar_igl
{
387 3157a0a9 edgar_igl
        struct {
388 3157a0a9 edgar_igl
                int shift; /* LSL when positive, LSR when negative.  */
389 3157a0a9 edgar_igl
                uint32_t mask;
390 3157a0a9 edgar_igl
        } bitrev [] = {
391 3157a0a9 edgar_igl
                {7, 0x80808080},
392 3157a0a9 edgar_igl
                {5, 0x40404040},
393 3157a0a9 edgar_igl
                {3, 0x20202020},
394 3157a0a9 edgar_igl
                {1, 0x10101010},
395 3157a0a9 edgar_igl
                {-1, 0x08080808},
396 3157a0a9 edgar_igl
                {-3, 0x04040404},
397 3157a0a9 edgar_igl
                {-5, 0x02020202},
398 3157a0a9 edgar_igl
                {-7, 0x01010101}
399 3157a0a9 edgar_igl
        };
400 3157a0a9 edgar_igl
        int i;
401 3157a0a9 edgar_igl
        TCGv t, org_s;
402 3157a0a9 edgar_igl
403 3157a0a9 edgar_igl
        /* d and s refer the same object.  */
404 3157a0a9 edgar_igl
        t = tcg_temp_new(TCG_TYPE_TL);
405 3157a0a9 edgar_igl
        org_s = tcg_temp_new(TCG_TYPE_TL);
406 3157a0a9 edgar_igl
        tcg_gen_mov_tl(org_s, s);
407 3157a0a9 edgar_igl
408 3157a0a9 edgar_igl
        tcg_gen_shli_tl(t, org_s,  bitrev[0].shift);
409 3157a0a9 edgar_igl
        tcg_gen_andi_tl(d, t,  bitrev[0].mask);
410 3157a0a9 edgar_igl
        for (i = 1; i < sizeof bitrev / sizeof bitrev[0]; i++) {
411 3157a0a9 edgar_igl
                if (bitrev[i].shift >= 0) {
412 3157a0a9 edgar_igl
                        tcg_gen_shli_tl(t, org_s,  bitrev[i].shift);
413 3157a0a9 edgar_igl
                } else {
414 3157a0a9 edgar_igl
                        tcg_gen_shri_tl(t, org_s,  -bitrev[i].shift);
415 3157a0a9 edgar_igl
                }
416 3157a0a9 edgar_igl
                tcg_gen_andi_tl(t, t,  bitrev[i].mask);
417 3157a0a9 edgar_igl
                tcg_gen_or_tl(d, d, t);
418 3157a0a9 edgar_igl
        }
419 3157a0a9 edgar_igl
}
420 3157a0a9 edgar_igl
421 8170028d ths
static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
422 8170028d ths
{
423 8170028d ths
        TranslationBlock *tb;
424 8170028d ths
        tb = dc->tb;
425 8170028d ths
        if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
426 05ba7d5f edgar_igl
                tcg_gen_goto_tb(n);
427 05ba7d5f edgar_igl
                tcg_gen_movi_tl(cpu_T[0], dest);
428 3157a0a9 edgar_igl
                t_gen_mov_env_TN(pc, cpu_T[0]);
429 05ba7d5f edgar_igl
                tcg_gen_exit_tb((long)tb + n);
430 8170028d ths
        } else {
431 3157a0a9 edgar_igl
                t_gen_mov_env_TN(pc, cpu_T[0]);
432 05ba7d5f edgar_igl
                tcg_gen_exit_tb(0);
433 8170028d ths
        }
434 8170028d ths
}
435 8170028d ths
436 8170028d ths
/* Sign extend at translation time.  */
437 8170028d ths
static int sign_extend(unsigned int val, unsigned int width)
438 8170028d ths
{
439 8170028d ths
        int sval;
440 8170028d ths
441 8170028d ths
        /* LSL.  */
442 8170028d ths
        val <<= 31 - width;
443 8170028d ths
        sval = val;
444 8170028d ths
        /* ASR.  */
445 8170028d ths
        sval >>= 31 - width;
446 8170028d ths
        return sval;
447 8170028d ths
}
448 8170028d ths
449 05ba7d5f edgar_igl
static inline void cris_clear_x_flag(DisasContext *dc)
450 05ba7d5f edgar_igl
{
451 a825e703 edgar_igl
        if (!dc->flagx_live || dc->cc_op != CC_OP_FLAGS) {
452 a825e703 edgar_igl
                t_gen_mov_TN_preg(cpu_T[0], PR_CCS);
453 a825e703 edgar_igl
                tcg_gen_andi_i32(cpu_T[0], cpu_T[0], ~X_FLAG);
454 a825e703 edgar_igl
                t_gen_mov_preg_TN(PR_CCS, cpu_T[0]);
455 a825e703 edgar_igl
                dc->flagx_live = 1;
456 a825e703 edgar_igl
                dc->flags_x = 0;
457 a825e703 edgar_igl
        }
458 05ba7d5f edgar_igl
}
459 05ba7d5f edgar_igl
460 8170028d ths
static void cris_evaluate_flags(DisasContext *dc)
461 8170028d ths
{
462 8170028d ths
        if (!dc->flags_live) {
463 8170028d ths
                switch (dc->cc_op)
464 8170028d ths
                {
465 8170028d ths
                        case CC_OP_MCP:
466 8170028d ths
                                gen_op_evaluate_flags_mcp ();
467 8170028d ths
                                break;
468 8170028d ths
                        case CC_OP_MULS:
469 8170028d ths
                                gen_op_evaluate_flags_muls ();
470 8170028d ths
                                break;
471 8170028d ths
                        case CC_OP_MULU:
472 8170028d ths
                                gen_op_evaluate_flags_mulu ();
473 8170028d ths
                                break;
474 8170028d ths
                        case CC_OP_MOVE:
475 8170028d ths
                                switch (dc->cc_size)
476 8170028d ths
                                {
477 8170028d ths
                                        case 4:
478 8170028d ths
                                                gen_op_evaluate_flags_move_4();
479 8170028d ths
                                                break;
480 8170028d ths
                                        case 2:
481 8170028d ths
                                                gen_op_evaluate_flags_move_2();
482 8170028d ths
                                                break;
483 8170028d ths
                                        default:
484 8170028d ths
                                                gen_op_evaluate_flags ();
485 8170028d ths
                                                break;
486 8170028d ths
                                }
487 8170028d ths
                                break;
488 8170028d ths
489 8170028d ths
                        default:
490 8170028d ths
                        {
491 8170028d ths
                                switch (dc->cc_size)
492 8170028d ths
                                {
493 8170028d ths
                                        case 4:
494 8170028d ths
                                                gen_op_evaluate_flags_alu_4 ();
495 8170028d ths
                                                break;
496 8170028d ths
                                        default:
497 8170028d ths
                                                gen_op_evaluate_flags ();
498 8170028d ths
                                                break;
499 8170028d ths
                                }
500 8170028d ths
                        }
501 8170028d ths
                        break;
502 8170028d ths
                }
503 8170028d ths
                dc->flags_live = 1;
504 8170028d ths
        }
505 8170028d ths
}
506 8170028d ths
507 8170028d ths
static void cris_cc_mask(DisasContext *dc, unsigned int mask)
508 8170028d ths
{
509 8170028d ths
        uint32_t ovl;
510 8170028d ths
511 fd56059f balrog
        /* Check if we need to evaluate the condition codes due to 
512 fd56059f balrog
           CC overlaying.  */
513 8170028d ths
        ovl = (dc->cc_mask ^ mask) & ~mask;
514 8170028d ths
        if (ovl) {
515 8170028d ths
                /* TODO: optimize this case. It trigs all the time.  */
516 8170028d ths
                cris_evaluate_flags (dc);
517 8170028d ths
        }
518 8170028d ths
        dc->cc_mask = mask;
519 8170028d ths
        dc->update_cc = 1;
520 a825e703 edgar_igl
521 8170028d ths
        if (mask == 0)
522 8170028d ths
                dc->update_cc = 0;
523 a825e703 edgar_igl
        else
524 8170028d ths
                dc->flags_live = 0;
525 8170028d ths
}
526 8170028d ths
527 8170028d ths
static void cris_update_cc_op(DisasContext *dc, int op)
528 8170028d ths
{
529 8170028d ths
        dc->cc_op = op;
530 8170028d ths
        dc->flags_live = 0;
531 a825e703 edgar_igl
        tcg_gen_movi_tl(cc_op, op);
532 8170028d ths
}
533 8170028d ths
static void cris_update_cc_size(DisasContext *dc, int size)
534 8170028d ths
{
535 8170028d ths
        dc->cc_size = size;
536 a825e703 edgar_igl
        tcg_gen_movi_tl(cc_size, size);
537 8170028d ths
}
538 8170028d ths
539 8170028d ths
/* op is the operation.
540 8170028d ths
   T0, T1 are the operands.
541 8170028d ths
   dst is the destination reg.
542 8170028d ths
*/
543 8170028d ths
static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
544 8170028d ths
{
545 8170028d ths
        int writeback = 1;
546 8170028d ths
        if (dc->update_cc) {
547 8170028d ths
                cris_update_cc_op(dc, op);
548 8170028d ths
                cris_update_cc_size(dc, size);
549 a825e703 edgar_igl
                tcg_gen_mov_tl(cc_dest, cpu_T[0]);
550 a825e703 edgar_igl
                tcg_gen_movi_tl(cc_mask, dc->cc_mask);
551 3157a0a9 edgar_igl
552 3157a0a9 edgar_igl
                /* FIXME: This shouldn't be needed. But we don't pass the
553 3157a0a9 edgar_igl
                 tests without it. Investigate.  */
554 3157a0a9 edgar_igl
                t_gen_mov_env_TN(cc_x_live, tcg_const_tl(dc->flagx_live));
555 3157a0a9 edgar_igl
                t_gen_mov_env_TN(cc_x, tcg_const_tl(dc->flags_x));
556 8170028d ths
        }
557 8170028d ths
558 8170028d ths
        /* Emit the ALU insns.  */
559 8170028d ths
        switch (op)
560 8170028d ths
        {
561 8170028d ths
                case CC_OP_ADD:
562 05ba7d5f edgar_igl
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
563 8170028d ths
                        /* Extended arithmetics.  */
564 3157a0a9 edgar_igl
                        t_gen_addx_carry(cpu_T[0]);
565 8170028d ths
                        break;
566 8170028d ths
                case CC_OP_ADDC:
567 05ba7d5f edgar_igl
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
568 3157a0a9 edgar_igl
                        t_gen_add_flag(cpu_T[0], 0); /* C_FLAG.  */
569 8170028d ths
                        break;
570 8170028d ths
                case CC_OP_MCP:
571 05ba7d5f edgar_igl
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
572 3157a0a9 edgar_igl
                        t_gen_add_flag(cpu_T[0], 8); /* R_FLAG.  */
573 8170028d ths
                        break;
574 8170028d ths
                case CC_OP_SUB:
575 3157a0a9 edgar_igl
                        tcg_gen_sub_tl(cpu_T[1], tcg_const_tl(0), cpu_T[1]);
576 05ba7d5f edgar_igl
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
577 3157a0a9 edgar_igl
                        tcg_gen_sub_tl(cpu_T[1], tcg_const_tl(0), cpu_T[1]);
578 8170028d ths
                        /* CRIS flag evaluation needs ~src.  */
579 3157a0a9 edgar_igl
                        tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
580 8170028d ths
581 8170028d ths
                        /* Extended arithmetics.  */
582 3157a0a9 edgar_igl
                        t_gen_subx_carry(cpu_T[0]);
583 8170028d ths
                        break;
584 8170028d ths
                case CC_OP_MOVE:
585 05ba7d5f edgar_igl
                        tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
586 8170028d ths
                        break;
587 8170028d ths
                case CC_OP_OR:
588 05ba7d5f edgar_igl
                        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
589 8170028d ths
                        break;
590 8170028d ths
                case CC_OP_AND:
591 05ba7d5f edgar_igl
                        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
592 8170028d ths
                        break;
593 8170028d ths
                case CC_OP_XOR:
594 05ba7d5f edgar_igl
                        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
595 8170028d ths
                        break;
596 8170028d ths
                case CC_OP_LSL:
597 05ba7d5f edgar_igl
                        t_gen_lsl(cpu_T[0], cpu_T[0], cpu_T[1]);
598 8170028d ths
                        break;
599 8170028d ths
                case CC_OP_LSR:
600 05ba7d5f edgar_igl
                        t_gen_lsr(cpu_T[0], cpu_T[0], cpu_T[1]);
601 8170028d ths
                        break;
602 8170028d ths
                case CC_OP_ASR:
603 05ba7d5f edgar_igl
                        t_gen_asr(cpu_T[0], cpu_T[0], cpu_T[1]);
604 8170028d ths
                        break;
605 8170028d ths
                case CC_OP_NEG:
606 3157a0a9 edgar_igl
                        /* Hopefully the TCG backend recognizes this pattern
607 3157a0a9 edgar_igl
                           and makes a real neg out of it.  */
608 3157a0a9 edgar_igl
                        tcg_gen_sub_tl(cpu_T[0], tcg_const_tl(0), cpu_T[1]);
609 8170028d ths
                        /* Extended arithmetics.  */
610 3157a0a9 edgar_igl
                        t_gen_subx_carry(cpu_T[0]);
611 8170028d ths
                        break;
612 8170028d ths
                case CC_OP_LZ:
613 8170028d ths
                        gen_op_lz_T0_T1();
614 8170028d ths
                        break;
615 8170028d ths
                case CC_OP_BTST:
616 8170028d ths
                        gen_op_btst_T0_T1();
617 8170028d ths
                        writeback = 0;
618 8170028d ths
                        break;
619 8170028d ths
                case CC_OP_MULS:
620 3157a0a9 edgar_igl
                {
621 3157a0a9 edgar_igl
                        TCGv mof;
622 3157a0a9 edgar_igl
                        mof = tcg_temp_new(TCG_TYPE_TL);
623 3157a0a9 edgar_igl
                        t_gen_muls(cpu_T[0], mof, cpu_T[0], cpu_T[1]);
624 3157a0a9 edgar_igl
                        t_gen_mov_preg_TN(PR_MOF, mof);
625 3157a0a9 edgar_igl
                }
626 3157a0a9 edgar_igl
                break;
627 8170028d ths
                case CC_OP_MULU:
628 3157a0a9 edgar_igl
                {
629 3157a0a9 edgar_igl
                        TCGv mof;
630 3157a0a9 edgar_igl
                        mof = tcg_temp_new(TCG_TYPE_TL);
631 3157a0a9 edgar_igl
                        t_gen_mulu(cpu_T[0], mof, cpu_T[0], cpu_T[1]);
632 3157a0a9 edgar_igl
                        t_gen_mov_preg_TN(PR_MOF, mof);
633 3157a0a9 edgar_igl
                }
634 3157a0a9 edgar_igl
                break;
635 8170028d ths
                case CC_OP_DSTEP:
636 8170028d ths
                        gen_op_dstep_T0_T1();
637 8170028d ths
                        break;
638 8170028d ths
                case CC_OP_BOUND:
639 3157a0a9 edgar_igl
                {
640 3157a0a9 edgar_igl
                        int l1;
641 3157a0a9 edgar_igl
                        l1 = gen_new_label();
642 3157a0a9 edgar_igl
                        tcg_gen_brcond_tl(TCG_COND_LEU, 
643 3157a0a9 edgar_igl
                                          cpu_T[0], cpu_T[1], l1);
644 3157a0a9 edgar_igl
                        tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
645 3157a0a9 edgar_igl
                        gen_set_label(l1);
646 3157a0a9 edgar_igl
                }
647 3157a0a9 edgar_igl
                break;
648 8170028d ths
                case CC_OP_CMP:
649 3157a0a9 edgar_igl
                        tcg_gen_sub_tl(cpu_T[1], tcg_const_tl(0), cpu_T[1]);
650 05ba7d5f edgar_igl
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
651 05ba7d5f edgar_igl
                        /* CRIS flag evaluation needs ~src.  */
652 3157a0a9 edgar_igl
                        tcg_gen_sub_tl(cpu_T[1], tcg_const_tl(0), cpu_T[1]);
653 8170028d ths
                        /* CRIS flag evaluation needs ~src.  */
654 3157a0a9 edgar_igl
                        tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
655 8170028d ths
656 8170028d ths
                        /* Extended arithmetics.  */
657 3157a0a9 edgar_igl
                        t_gen_subx_carry(cpu_T[0]);
658 8170028d ths
                        writeback = 0;
659 8170028d ths
                        break;
660 8170028d ths
                default:
661 8170028d ths
                        fprintf (logfile, "illegal ALU op.\n");
662 8170028d ths
                        BUG();
663 8170028d ths
                        break;
664 8170028d ths
        }
665 8170028d ths
666 8170028d ths
        if (dc->update_cc)
667 a825e703 edgar_igl
                tcg_gen_mov_tl(cc_src, cpu_T[1]);
668 8170028d ths
669 8170028d ths
        if (size == 1)
670 05ba7d5f edgar_igl
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
671 8170028d ths
        else if (size == 2)
672 05ba7d5f edgar_igl
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
673 05ba7d5f edgar_igl
674 8170028d ths
        /* Writeback.  */
675 8170028d ths
        if (writeback) {
676 8170028d ths
                if (size == 4)
677 05ba7d5f edgar_igl
                        t_gen_mov_reg_TN(rd, cpu_T[0]);
678 8170028d ths
                else {
679 05ba7d5f edgar_igl
                        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
680 05ba7d5f edgar_igl
                        t_gen_mov_TN_reg(cpu_T[0], rd);
681 8170028d ths
                        if (size == 1)
682 05ba7d5f edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~0xff);
683 8170028d ths
                        else
684 05ba7d5f edgar_igl
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~0xffff);
685 05ba7d5f edgar_igl
                        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
686 05ba7d5f edgar_igl
                        t_gen_mov_reg_TN(rd, cpu_T[0]);
687 05ba7d5f edgar_igl
                        tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
688 8170028d ths
                }
689 8170028d ths
        }
690 8170028d ths
        if (dc->update_cc)
691 a825e703 edgar_igl
                tcg_gen_mov_tl(cc_result, cpu_T[0]);
692 8170028d ths
693 8170028d ths
        {
694 8170028d ths
                /* TODO: Optimize this.  */
695 8170028d ths
                if (!dc->flagx_live)
696 8170028d ths
                        cris_evaluate_flags(dc);
697 8170028d ths
        }
698 8170028d ths
}
699 8170028d ths
700 8170028d ths
static int arith_cc(DisasContext *dc)
701 8170028d ths
{
702 8170028d ths
        if (dc->update_cc) {
703 8170028d ths
                switch (dc->cc_op) {
704 8170028d ths
                        case CC_OP_ADD: return 1;
705 8170028d ths
                        case CC_OP_SUB: return 1;
706 8170028d ths
                        case CC_OP_LSL: return 1;
707 8170028d ths
                        case CC_OP_LSR: return 1;
708 8170028d ths
                        case CC_OP_ASR: return 1;
709 8170028d ths
                        case CC_OP_CMP: return 1;
710 8170028d ths
                        default:
711 8170028d ths
                                return 0;
712 8170028d ths
                }
713 8170028d ths
        }
714 8170028d ths
        return 0;
715 8170028d ths
}
716 8170028d ths
717 8170028d ths
static void gen_tst_cc (DisasContext *dc, int cond)
718 8170028d ths
{
719 8170028d ths
        int arith_opt;
720 8170028d ths
721 8170028d ths
        /* TODO: optimize more condition codes.  */
722 8170028d ths
        arith_opt = arith_cc(dc) && !dc->flags_live;
723 8170028d ths
        switch (cond) {
724 8170028d ths
                case CC_EQ:
725 8170028d ths
                        if (arith_opt)
726 8170028d ths
                                gen_op_tst_cc_eq_fast ();
727 8170028d ths
                        else {
728 8170028d ths
                                cris_evaluate_flags(dc);
729 8170028d ths
                                gen_op_tst_cc_eq ();
730 8170028d ths
                        }
731 8170028d ths
                        break;
732 8170028d ths
                case CC_NE:
733 8170028d ths
                        if (arith_opt)
734 8170028d ths
                                gen_op_tst_cc_ne_fast ();
735 8170028d ths
                        else {
736 8170028d ths
                                cris_evaluate_flags(dc);
737 8170028d ths
                                gen_op_tst_cc_ne ();
738 8170028d ths
                        }
739 8170028d ths
                        break;
740 8170028d ths
                case CC_CS:
741 8170028d ths
                        cris_evaluate_flags(dc);
742 8170028d ths
                        gen_op_tst_cc_cs ();
743 8170028d ths
                        break;
744 8170028d ths
                case CC_CC:
745 8170028d ths
                        cris_evaluate_flags(dc);
746 8170028d ths
                        gen_op_tst_cc_cc ();
747 8170028d ths
                        break;
748 8170028d ths
                case CC_VS:
749 8170028d ths
                        cris_evaluate_flags(dc);
750 8170028d ths
                        gen_op_tst_cc_vs ();
751 8170028d ths
                        break;
752 8170028d ths
                case CC_VC:
753 8170028d ths
                        cris_evaluate_flags(dc);
754 8170028d ths
                        gen_op_tst_cc_vc ();
755 8170028d ths
                        break;
756 8170028d ths
                case CC_PL:
757 8170028d ths
                        if (arith_opt)
758 8170028d ths
                                gen_op_tst_cc_pl_fast ();
759 8170028d ths
                        else {
760 8170028d ths
                                cris_evaluate_flags(dc);
761 8170028d ths
                                gen_op_tst_cc_pl ();
762 8170028d ths
                        }
763 8170028d ths
                        break;
764 8170028d ths
                case CC_MI:
765 8170028d ths
                        if (arith_opt)
766 8170028d ths
                                gen_op_tst_cc_mi_fast ();
767 8170028d ths
                        else {
768 8170028d ths
                                cris_evaluate_flags(dc);
769 8170028d ths
                                gen_op_tst_cc_mi ();
770 8170028d ths
                        }
771 8170028d ths
                        break;
772 8170028d ths
                case CC_LS:
773 8170028d ths
                        cris_evaluate_flags(dc);
774 8170028d ths
                        gen_op_tst_cc_ls ();
775 8170028d ths
                        break;
776 8170028d ths
                case CC_HI:
777 8170028d ths
                        cris_evaluate_flags(dc);
778 8170028d ths
                        gen_op_tst_cc_hi ();
779 8170028d ths
                        break;
780 8170028d ths
                case CC_GE:
781 8170028d ths
                        cris_evaluate_flags(dc);
782 8170028d ths
                        gen_op_tst_cc_ge ();
783 8170028d ths
                        break;
784 8170028d ths
                case CC_LT:
785 8170028d ths
                        cris_evaluate_flags(dc);
786 8170028d ths
                        gen_op_tst_cc_lt ();
787 8170028d ths
                        break;
788 8170028d ths
                case CC_GT:
789 8170028d ths
                        cris_evaluate_flags(dc);
790 8170028d ths
                        gen_op_tst_cc_gt ();
791 8170028d ths
                        break;
792 8170028d ths
                case CC_LE:
793 8170028d ths
                        cris_evaluate_flags(dc);
794 8170028d ths
                        gen_op_tst_cc_le ();
795 8170028d ths
                        break;
796 8170028d ths
                case CC_P:
797 8170028d ths
                        cris_evaluate_flags(dc);
798 8170028d ths
                        gen_op_tst_cc_p ();
799 8170028d ths
                        break;
800 8170028d ths
                case CC_A:
801 8170028d ths
                        cris_evaluate_flags(dc);
802 8170028d ths
                        gen_op_movl_T0_im (1);
803 8170028d ths
                        break;
804 8170028d ths
                default:
805 8170028d ths
                        BUG();
806 8170028d ths
                        break;
807 8170028d ths
        };
808 8170028d ths
}
809 8170028d ths
810 8170028d ths
static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond)
811 8170028d ths
{
812 8170028d ths
        /* This helps us re-schedule the micro-code to insns in delay-slots
813 8170028d ths
           before the actual jump.  */
814 8170028d ths
        dc->delayed_branch = 2;
815 8170028d ths
        dc->delayed_pc = dc->pc + offset;
816 8170028d ths
        dc->bcc = cond;
817 8170028d ths
        if (cond != CC_A)
818 8170028d ths
        {
819 8170028d ths
                gen_tst_cc (dc, cond);
820 8170028d ths
                gen_op_evaluate_bcc ();
821 8170028d ths
        }
822 3157a0a9 edgar_igl
        tcg_gen_movi_tl(cpu_T[0], dc->delayed_pc);
823 3157a0a9 edgar_igl
        t_gen_mov_env_TN(btarget, cpu_T[0]);
824 8170028d ths
}
825 8170028d ths
826 8170028d ths
/* Dynamic jumps, when the dest is in a live reg for example.  */
827 8170028d ths
void cris_prepare_dyn_jmp (DisasContext *dc)
828 8170028d ths
{
829 8170028d ths
        /* This helps us re-schedule the micro-code to insns in delay-slots
830 8170028d ths
           before the actual jump.  */
831 8170028d ths
        dc->delayed_branch = 2;
832 8170028d ths
        dc->dyn_jmp = 1;
833 8170028d ths
        dc->bcc = CC_A;
834 8170028d ths
}
835 8170028d ths
836 8170028d ths
void cris_prepare_jmp (DisasContext *dc, uint32_t dst)
837 8170028d ths
{
838 8170028d ths
        /* This helps us re-schedule the micro-code to insns in delay-slots
839 8170028d ths
           before the actual jump.  */
840 8170028d ths
        dc->delayed_branch = 2;
841 8170028d ths
        dc->delayed_pc = dst;
842 8170028d ths
        dc->dyn_jmp = 0;
843 8170028d ths
        dc->bcc = CC_A;
844 8170028d ths
}
845 8170028d ths
846 8170028d ths
void gen_load_T0_T0 (DisasContext *dc, unsigned int size, int sign)
847 8170028d ths
{
848 8170028d ths
        if (size == 1) {
849 8170028d ths
                if (sign)
850 8170028d ths
                        gen_op_ldb_T0_T0(dc);
851 8170028d ths
                else
852 8170028d ths
                        gen_op_ldub_T0_T0(dc);
853 8170028d ths
        }
854 8170028d ths
        else if (size == 2) {
855 8170028d ths
                if (sign)
856 8170028d ths
                        gen_op_ldw_T0_T0(dc);
857 8170028d ths
                else
858 8170028d ths
                        gen_op_lduw_T0_T0(dc);
859 8170028d ths
        }
860 8170028d ths
        else {
861 8170028d ths
                gen_op_ldl_T0_T0(dc);
862 8170028d ths
        }
863 8170028d ths
}
864 8170028d ths
865 8170028d ths
void gen_store_T0_T1 (DisasContext *dc, unsigned int size)
866 8170028d ths
{
867 8170028d ths
        /* Remember, operands are flipped. CRIS has reversed order.  */
868 8170028d ths
        if (size == 1) {
869 8170028d ths
                gen_op_stb_T0_T1(dc);
870 8170028d ths
        }
871 8170028d ths
        else if (size == 2) {
872 8170028d ths
                gen_op_stw_T0_T1(dc);
873 8170028d ths
        }
874 8170028d ths
        else
875 8170028d ths
                gen_op_stl_T0_T1(dc);
876 8170028d ths
}
877 8170028d ths
878 05ba7d5f edgar_igl
static inline void t_gen_sext(TCGv d, TCGv s, int size)
879 8170028d ths
{
880 8170028d ths
        if (size == 1)
881 05ba7d5f edgar_igl
                tcg_gen_ext8s_i32(d, s);
882 8170028d ths
        else if (size == 2)
883 05ba7d5f edgar_igl
                tcg_gen_ext16s_i32(d, s);
884 8170028d ths
}
885 8170028d ths
886 05ba7d5f edgar_igl
static inline void t_gen_zext(TCGv d, TCGv s, int size)
887 8170028d ths
{
888 05ba7d5f edgar_igl
        /* TCG-FIXME: this is not optimal. Many archs have fast zext insns.  */
889 8170028d ths
        if (size == 1)
890 05ba7d5f edgar_igl
                tcg_gen_andi_i32(d, s, 0xff);
891 8170028d ths
        else if (size == 2)
892 05ba7d5f edgar_igl
                tcg_gen_andi_i32(d, s, 0xffff);
893 8170028d ths
}
894 8170028d ths
895 8170028d ths
#if DISAS_CRIS
896 8170028d ths
static char memsize_char(int size)
897 8170028d ths
{
898 8170028d ths
        switch (size)
899 8170028d ths
        {
900 8170028d ths
                case 1: return 'b';  break;
901 8170028d ths
                case 2: return 'w';  break;
902 8170028d ths
                case 4: return 'd';  break;
903 8170028d ths
                default:
904 8170028d ths
                        return 'x';
905 8170028d ths
                        break;
906 8170028d ths
        }
907 8170028d ths
}
908 8170028d ths
#endif
909 8170028d ths
910 8170028d ths
static unsigned int memsize_z(DisasContext *dc)
911 8170028d ths
{
912 8170028d ths
        return dc->zsize + 1;
913 8170028d ths
}
914 8170028d ths
915 8170028d ths
static unsigned int memsize_zz(DisasContext *dc)
916 8170028d ths
{
917 8170028d ths
        switch (dc->zzsize)
918 8170028d ths
        {
919 8170028d ths
                case 0: return 1;
920 8170028d ths
                case 1: return 2;
921 8170028d ths
                default:
922 8170028d ths
                        return 4;
923 8170028d ths
        }
924 8170028d ths
}
925 8170028d ths
926 8170028d ths
static void do_postinc (DisasContext *dc, int size)
927 8170028d ths
{
928 8170028d ths
        if (!dc->postinc)
929 8170028d ths
                return;
930 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
931 3157a0a9 edgar_igl
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], size);
932 05ba7d5f edgar_igl
        t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
933 8170028d ths
}
934 8170028d ths
935 8170028d ths
936 8170028d ths
static void dec_prep_move_r(DisasContext *dc, int rs, int rd,
937 8170028d ths
                            int size, int s_ext)
938 8170028d ths
{
939 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[1], rs);
940 8170028d ths
        if (s_ext)
941 05ba7d5f edgar_igl
                t_gen_sext(cpu_T[1], cpu_T[1], size);
942 8170028d ths
        else
943 05ba7d5f edgar_igl
                t_gen_zext(cpu_T[1], cpu_T[1], size);
944 8170028d ths
}
945 8170028d ths
946 8170028d ths
/* Prepare T0 and T1 for a register alu operation.
947 8170028d ths
   s_ext decides if the operand1 should be sign-extended or zero-extended when
948 8170028d ths
   needed.  */
949 8170028d ths
static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
950 8170028d ths
                          int size, int s_ext)
951 8170028d ths
{
952 8170028d ths
        dec_prep_move_r(dc, rs, rd, size, s_ext);
953 8170028d ths
954 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], rd);
955 8170028d ths
        if (s_ext)
956 05ba7d5f edgar_igl
                t_gen_sext(cpu_T[0], cpu_T[0], size);
957 8170028d ths
        else
958 05ba7d5f edgar_igl
                t_gen_zext(cpu_T[0], cpu_T[0], size);
959 8170028d ths
}
960 8170028d ths
961 8170028d ths
/* Prepare T0 and T1 for a memory + alu operation.
962 8170028d ths
   s_ext decides if the operand1 should be sign-extended or zero-extended when
963 8170028d ths
   needed.  */
964 8170028d ths
static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
965 8170028d ths
{
966 8170028d ths
        unsigned int rs, rd;
967 8170028d ths
        uint32_t imm;
968 8170028d ths
        int is_imm;
969 8170028d ths
        int insn_len = 2;
970 8170028d ths
971 8170028d ths
        rs = dc->op1;
972 8170028d ths
        rd = dc->op2;
973 8170028d ths
        is_imm = rs == 15 && dc->postinc;
974 8170028d ths
975 8170028d ths
        /* Load [$rs] onto T1.  */
976 8170028d ths
        if (is_imm) {
977 8170028d ths
                insn_len = 2 + memsize;
978 8170028d ths
                if (memsize == 1)
979 8170028d ths
                        insn_len++;
980 8170028d ths
981 8170028d ths
                imm = ldl_code(dc->pc + 2);
982 8170028d ths
                if (memsize != 4) {
983 8170028d ths
                        if (s_ext) {
984 8170028d ths
                                imm = sign_extend(imm, (memsize * 8) - 1);
985 8170028d ths
                        } else {
986 8170028d ths
                                if (memsize == 1)
987 8170028d ths
                                        imm &= 0xff;
988 8170028d ths
                                else
989 8170028d ths
                                        imm &= 0xffff;
990 8170028d ths
                        }
991 8170028d ths
                }
992 8170028d ths
                DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n",
993 8170028d ths
                            imm, rd, s_ext, memsize));
994 05ba7d5f edgar_igl
                tcg_gen_movi_tl(cpu_T[1], imm);
995 8170028d ths
                dc->postinc = 0;
996 8170028d ths
        } else {
997 05ba7d5f edgar_igl
                t_gen_mov_TN_reg(cpu_T[0], rs);
998 8170028d ths
                gen_load_T0_T0(dc, memsize, 0);
999 05ba7d5f edgar_igl
                tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1000 8170028d ths
                if (s_ext)
1001 05ba7d5f edgar_igl
                        t_gen_sext(cpu_T[1], cpu_T[1], memsize);
1002 8170028d ths
                else
1003 05ba7d5f edgar_igl
                        t_gen_zext(cpu_T[1], cpu_T[1], memsize);
1004 8170028d ths
        }
1005 8170028d ths
1006 8170028d ths
        /* put dest in T0.  */
1007 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], rd);
1008 8170028d ths
        return insn_len;
1009 8170028d ths
}
1010 8170028d ths
1011 8170028d ths
#if DISAS_CRIS
1012 8170028d ths
static const char *cc_name(int cc)
1013 8170028d ths
{
1014 8170028d ths
        static char *cc_names[16] = {
1015 8170028d ths
                "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1016 8170028d ths
                "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1017 8170028d ths
        };
1018 8170028d ths
        assert(cc < 16);
1019 8170028d ths
        return cc_names[cc];
1020 8170028d ths
}
1021 8170028d ths
#endif
1022 8170028d ths
1023 8170028d ths
static unsigned int dec_bccq(DisasContext *dc)
1024 8170028d ths
{
1025 8170028d ths
        int32_t offset;
1026 8170028d ths
        int sign;
1027 8170028d ths
        uint32_t cond = dc->op2;
1028 8170028d ths
        int tmp;
1029 8170028d ths
1030 8170028d ths
        offset = EXTRACT_FIELD (dc->ir, 1, 7);
1031 8170028d ths
        sign = EXTRACT_FIELD(dc->ir, 0, 0);
1032 8170028d ths
1033 8170028d ths
        offset *= 2;
1034 8170028d ths
        offset |= sign << 8;
1035 8170028d ths
        tmp = offset;
1036 8170028d ths
        offset = sign_extend(offset, 8);
1037 8170028d ths
1038 8170028d ths
        /* op2 holds the condition-code.  */
1039 8170028d ths
        cris_cc_mask(dc, 0);
1040 8170028d ths
        cris_prepare_cc_branch (dc, offset, cond);
1041 8170028d ths
        return 2;
1042 8170028d ths
}
1043 8170028d ths
static unsigned int dec_addoq(DisasContext *dc)
1044 8170028d ths
{
1045 8170028d ths
        uint32_t imm;
1046 8170028d ths
1047 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1048 8170028d ths
        imm = sign_extend(dc->op1, 7);
1049 8170028d ths
1050 8170028d ths
        DIS(fprintf (logfile, "addoq %d, $r%u\n", imm, dc->op2));
1051 8170028d ths
        cris_cc_mask(dc, 0);
1052 8170028d ths
        /* Fetch register operand,  */
1053 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1054 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[1], imm);
1055 9004627f edgar_igl
        crisv32_alu_op(dc, CC_OP_ADD, R_ACR, 4);
1056 8170028d ths
        return 2;
1057 8170028d ths
}
1058 8170028d ths
static unsigned int dec_addq(DisasContext *dc)
1059 8170028d ths
{
1060 8170028d ths
        DIS(fprintf (logfile, "addq %u, $r%u\n", dc->op1, dc->op2));
1061 8170028d ths
1062 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1063 8170028d ths
1064 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1065 8170028d ths
        /* Fetch register operand,  */
1066 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1067 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[1], dc->op1);
1068 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1069 8170028d ths
        return 2;
1070 8170028d ths
}
1071 8170028d ths
static unsigned int dec_moveq(DisasContext *dc)
1072 8170028d ths
{
1073 8170028d ths
        uint32_t imm;
1074 8170028d ths
1075 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1076 8170028d ths
        imm = sign_extend(dc->op1, 5);
1077 8170028d ths
        DIS(fprintf (logfile, "moveq %d, $r%u\n", imm, dc->op2));
1078 8170028d ths
1079 3157a0a9 edgar_igl
        t_gen_mov_reg_TN(dc->op2, tcg_const_tl(imm));
1080 8170028d ths
        return 2;
1081 8170028d ths
}
1082 8170028d ths
static unsigned int dec_subq(DisasContext *dc)
1083 8170028d ths
{
1084 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1085 8170028d ths
1086 8170028d ths
        DIS(fprintf (logfile, "subq %u, $r%u\n", dc->op1, dc->op2));
1087 8170028d ths
1088 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1089 8170028d ths
        /* Fetch register operand,  */
1090 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1091 05ba7d5f edgar_igl
        t_gen_mov_TN_im(cpu_T[1], dc->op1);
1092 8170028d ths
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1093 8170028d ths
        return 2;
1094 8170028d ths
}
1095 8170028d ths
static unsigned int dec_cmpq(DisasContext *dc)
1096 8170028d ths
{
1097 8170028d ths
        uint32_t imm;
1098 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1099 8170028d ths
        imm = sign_extend(dc->op1, 5);
1100 8170028d ths
1101 8170028d ths
        DIS(fprintf (logfile, "cmpq %d, $r%d\n", imm, dc->op2));
1102 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1103 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1104 05ba7d5f edgar_igl
        t_gen_mov_TN_im(cpu_T[1], imm);
1105 8170028d ths
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
1106 8170028d ths
        return 2;
1107 8170028d ths
}
1108 8170028d ths
static unsigned int dec_andq(DisasContext *dc)
1109 8170028d ths
{
1110 8170028d ths
        uint32_t imm;
1111 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1112 8170028d ths
        imm = sign_extend(dc->op1, 5);
1113 8170028d ths
1114 8170028d ths
        DIS(fprintf (logfile, "andq %d, $r%d\n", imm, dc->op2));
1115 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1116 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1117 05ba7d5f edgar_igl
        t_gen_mov_TN_im(cpu_T[1], imm);
1118 8170028d ths
        crisv32_alu_op(dc, CC_OP_AND, dc->op2, 4);
1119 8170028d ths
        return 2;
1120 8170028d ths
}
1121 8170028d ths
static unsigned int dec_orq(DisasContext *dc)
1122 8170028d ths
{
1123 8170028d ths
        uint32_t imm;
1124 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1125 8170028d ths
        imm = sign_extend(dc->op1, 5);
1126 8170028d ths
        DIS(fprintf (logfile, "orq %d, $r%d\n", imm, dc->op2));
1127 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1128 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1129 05ba7d5f edgar_igl
        t_gen_mov_TN_im(cpu_T[1], imm);
1130 8170028d ths
        crisv32_alu_op(dc, CC_OP_OR, dc->op2, 4);
1131 8170028d ths
        return 2;
1132 8170028d ths
}
1133 8170028d ths
static unsigned int dec_btstq(DisasContext *dc)
1134 8170028d ths
{
1135 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1136 8170028d ths
        DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2));
1137 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1138 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1139 05ba7d5f edgar_igl
        t_gen_mov_TN_im(cpu_T[1], dc->op1);
1140 8170028d ths
        crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
1141 8170028d ths
1142 8170028d ths
        cris_update_cc_op(dc, CC_OP_FLAGS);
1143 3157a0a9 edgar_igl
        t_gen_mov_preg_TN(PR_CCS, cpu_T[0]);
1144 8170028d ths
        dc->flags_live = 1;
1145 8170028d ths
        return 2;
1146 8170028d ths
}
1147 8170028d ths
static unsigned int dec_asrq(DisasContext *dc)
1148 8170028d ths
{
1149 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1150 8170028d ths
        DIS(fprintf (logfile, "asrq %u, $r%d\n", dc->op1, dc->op2));
1151 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1152 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1153 05ba7d5f edgar_igl
        t_gen_mov_TN_im(cpu_T[1], dc->op1);
1154 8170028d ths
        crisv32_alu_op(dc, CC_OP_ASR, dc->op2, 4);
1155 8170028d ths
        return 2;
1156 8170028d ths
}
1157 8170028d ths
static unsigned int dec_lslq(DisasContext *dc)
1158 8170028d ths
{
1159 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1160 8170028d ths
        DIS(fprintf (logfile, "lslq %u, $r%d\n", dc->op1, dc->op2));
1161 8170028d ths
1162 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1163 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1164 05ba7d5f edgar_igl
        t_gen_mov_TN_im(cpu_T[1], dc->op1);
1165 8170028d ths
        crisv32_alu_op(dc, CC_OP_LSL, dc->op2, 4);
1166 8170028d ths
        return 2;
1167 8170028d ths
}
1168 8170028d ths
static unsigned int dec_lsrq(DisasContext *dc)
1169 8170028d ths
{
1170 8170028d ths
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1171 8170028d ths
        DIS(fprintf (logfile, "lsrq %u, $r%d\n", dc->op1, dc->op2));
1172 8170028d ths
1173 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1174 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1175 05ba7d5f edgar_igl
        t_gen_mov_TN_im(cpu_T[1], dc->op1);
1176 8170028d ths
        crisv32_alu_op(dc, CC_OP_LSR, dc->op2, 4);
1177 8170028d ths
        return 2;
1178 8170028d ths
}
1179 8170028d ths
1180 8170028d ths
static unsigned int dec_move_r(DisasContext *dc)
1181 8170028d ths
{
1182 8170028d ths
        int size = memsize_zz(dc);
1183 8170028d ths
1184 8170028d ths
        DIS(fprintf (logfile, "move.%c $r%u, $r%u\n",
1185 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1186 8170028d ths
1187 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1188 8170028d ths
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
1189 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, size);
1190 8170028d ths
        return 2;
1191 8170028d ths
}
1192 8170028d ths
1193 8170028d ths
static unsigned int dec_scc_r(DisasContext *dc)
1194 8170028d ths
{
1195 8170028d ths
        int cond = dc->op2;
1196 8170028d ths
1197 8170028d ths
        DIS(fprintf (logfile, "s%s $r%u\n",
1198 8170028d ths
                    cc_name(cond), dc->op1));
1199 8170028d ths
1200 8170028d ths
        if (cond != CC_A)
1201 8170028d ths
        {
1202 8170028d ths
                gen_tst_cc (dc, cond);
1203 3157a0a9 edgar_igl
                tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1204 8170028d ths
        }
1205 8170028d ths
        else
1206 3157a0a9 edgar_igl
                tcg_gen_movi_tl(cpu_T[1], 1);
1207 8170028d ths
1208 8170028d ths
        cris_cc_mask(dc, 0);
1209 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1210 8170028d ths
        return 2;
1211 8170028d ths
}
1212 8170028d ths
1213 8170028d ths
static unsigned int dec_and_r(DisasContext *dc)
1214 8170028d ths
{
1215 8170028d ths
        int size = memsize_zz(dc);
1216 8170028d ths
1217 8170028d ths
        DIS(fprintf (logfile, "and.%c $r%u, $r%u\n",
1218 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1219 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1220 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1221 8170028d ths
        crisv32_alu_op(dc, CC_OP_AND, dc->op2, size);
1222 8170028d ths
        return 2;
1223 8170028d ths
}
1224 8170028d ths
1225 8170028d ths
static unsigned int dec_lz_r(DisasContext *dc)
1226 8170028d ths
{
1227 8170028d ths
        DIS(fprintf (logfile, "lz $r%u, $r%u\n",
1228 8170028d ths
                    dc->op1, dc->op2));
1229 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1230 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1231 8170028d ths
        crisv32_alu_op(dc, CC_OP_LZ, dc->op2, 4);
1232 8170028d ths
        return 2;
1233 8170028d ths
}
1234 8170028d ths
1235 8170028d ths
static unsigned int dec_lsl_r(DisasContext *dc)
1236 8170028d ths
{
1237 8170028d ths
        int size = memsize_zz(dc);
1238 8170028d ths
1239 8170028d ths
        DIS(fprintf (logfile, "lsl.%c $r%u, $r%u\n",
1240 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1241 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1242 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1243 05ba7d5f edgar_igl
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
1244 8170028d ths
        crisv32_alu_op(dc, CC_OP_LSL, dc->op2, size);
1245 8170028d ths
        return 2;
1246 8170028d ths
}
1247 8170028d ths
1248 8170028d ths
static unsigned int dec_lsr_r(DisasContext *dc)
1249 8170028d ths
{
1250 8170028d ths
        int size = memsize_zz(dc);
1251 8170028d ths
1252 8170028d ths
        DIS(fprintf (logfile, "lsr.%c $r%u, $r%u\n",
1253 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1254 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1255 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1256 05ba7d5f edgar_igl
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
1257 8170028d ths
        crisv32_alu_op(dc, CC_OP_LSR, dc->op2, size);
1258 8170028d ths
        return 2;
1259 8170028d ths
}
1260 8170028d ths
1261 8170028d ths
static unsigned int dec_asr_r(DisasContext *dc)
1262 8170028d ths
{
1263 8170028d ths
        int size = memsize_zz(dc);
1264 8170028d ths
1265 8170028d ths
        DIS(fprintf (logfile, "asr.%c $r%u, $r%u\n",
1266 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1267 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1268 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
1269 05ba7d5f edgar_igl
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
1270 8170028d ths
        crisv32_alu_op(dc, CC_OP_ASR, dc->op2, size);
1271 8170028d ths
        return 2;
1272 8170028d ths
}
1273 8170028d ths
1274 8170028d ths
static unsigned int dec_muls_r(DisasContext *dc)
1275 8170028d ths
{
1276 8170028d ths
        int size = memsize_zz(dc);
1277 8170028d ths
1278 8170028d ths
        DIS(fprintf (logfile, "muls.%c $r%u, $r%u\n",
1279 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1280 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZV);
1281 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
1282 05ba7d5f edgar_igl
        t_gen_sext(cpu_T[0], cpu_T[0], size);
1283 8170028d ths
        crisv32_alu_op(dc, CC_OP_MULS, dc->op2, 4);
1284 8170028d ths
        return 2;
1285 8170028d ths
}
1286 8170028d ths
1287 8170028d ths
static unsigned int dec_mulu_r(DisasContext *dc)
1288 8170028d ths
{
1289 8170028d ths
        int size = memsize_zz(dc);
1290 8170028d ths
1291 8170028d ths
        DIS(fprintf (logfile, "mulu.%c $r%u, $r%u\n",
1292 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1293 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZV);
1294 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1295 05ba7d5f edgar_igl
        t_gen_zext(cpu_T[0], cpu_T[0], size);
1296 8170028d ths
        crisv32_alu_op(dc, CC_OP_MULU, dc->op2, 4);
1297 8170028d ths
        return 2;
1298 8170028d ths
}
1299 8170028d ths
1300 8170028d ths
1301 8170028d ths
static unsigned int dec_dstep_r(DisasContext *dc)
1302 8170028d ths
{
1303 8170028d ths
        DIS(fprintf (logfile, "dstep $r%u, $r%u\n", dc->op1, dc->op2));
1304 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1305 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1306 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1307 8170028d ths
        crisv32_alu_op(dc, CC_OP_DSTEP, dc->op2, 4);
1308 8170028d ths
        return 2;
1309 8170028d ths
}
1310 8170028d ths
1311 8170028d ths
static unsigned int dec_xor_r(DisasContext *dc)
1312 8170028d ths
{
1313 8170028d ths
        int size = memsize_zz(dc);
1314 8170028d ths
        DIS(fprintf (logfile, "xor.%c $r%u, $r%u\n",
1315 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1316 8170028d ths
        BUG_ON(size != 4); /* xor is dword.  */
1317 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1318 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1319 8170028d ths
        crisv32_alu_op(dc, CC_OP_XOR, dc->op2, 4);
1320 8170028d ths
        return 2;
1321 8170028d ths
}
1322 8170028d ths
1323 8170028d ths
static unsigned int dec_bound_r(DisasContext *dc)
1324 8170028d ths
{
1325 8170028d ths
        int size = memsize_zz(dc);
1326 8170028d ths
        DIS(fprintf (logfile, "bound.%c $r%u, $r%u\n",
1327 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1328 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1329 8170028d ths
        /* TODO: needs optmimization.  */
1330 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1331 8170028d ths
        /* rd should be 4.  */
1332 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1333 8170028d ths
        crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
1334 8170028d ths
        return 2;
1335 8170028d ths
}
1336 8170028d ths
1337 8170028d ths
static unsigned int dec_cmp_r(DisasContext *dc)
1338 8170028d ths
{
1339 8170028d ths
        int size = memsize_zz(dc);
1340 8170028d ths
        DIS(fprintf (logfile, "cmp.%c $r%u, $r%u\n",
1341 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1342 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1343 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1344 8170028d ths
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, size);
1345 8170028d ths
        return 2;
1346 8170028d ths
}
1347 8170028d ths
1348 8170028d ths
static unsigned int dec_abs_r(DisasContext *dc)
1349 8170028d ths
{
1350 3157a0a9 edgar_igl
        int l1;
1351 3157a0a9 edgar_igl
1352 8170028d ths
        DIS(fprintf (logfile, "abs $r%u, $r%u\n",
1353 8170028d ths
                    dc->op1, dc->op2));
1354 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1355 8170028d ths
        dec_prep_move_r(dc, dc->op1, dc->op2, 4, 0);
1356 3157a0a9 edgar_igl
1357 3157a0a9 edgar_igl
        /* TODO: consider a branch free approach.  */
1358 3157a0a9 edgar_igl
        l1 = gen_new_label();
1359 3157a0a9 edgar_igl
        tcg_gen_brcond_tl(TCG_COND_GE, cpu_T[1], tcg_const_tl(0), l1);
1360 3157a0a9 edgar_igl
        tcg_gen_sub_tl(cpu_T[1], tcg_const_tl(0), cpu_T[1]);
1361 3157a0a9 edgar_igl
        gen_set_label(l1);
1362 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1363 8170028d ths
        return 2;
1364 8170028d ths
}
1365 8170028d ths
1366 8170028d ths
static unsigned int dec_add_r(DisasContext *dc)
1367 8170028d ths
{
1368 8170028d ths
        int size = memsize_zz(dc);
1369 8170028d ths
        DIS(fprintf (logfile, "add.%c $r%u, $r%u\n",
1370 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1371 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1372 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1373 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, size);
1374 8170028d ths
        return 2;
1375 8170028d ths
}
1376 8170028d ths
1377 8170028d ths
static unsigned int dec_addc_r(DisasContext *dc)
1378 8170028d ths
{
1379 8170028d ths
        DIS(fprintf (logfile, "addc $r%u, $r%u\n",
1380 8170028d ths
                    dc->op1, dc->op2));
1381 8170028d ths
        cris_evaluate_flags(dc);
1382 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1383 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1384 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
1385 8170028d ths
        return 2;
1386 8170028d ths
}
1387 8170028d ths
1388 8170028d ths
static unsigned int dec_mcp_r(DisasContext *dc)
1389 8170028d ths
{
1390 8170028d ths
        DIS(fprintf (logfile, "mcp $p%u, $r%u\n",
1391 8170028d ths
                     dc->op2, dc->op1));
1392 8170028d ths
        cris_evaluate_flags(dc);
1393 8170028d ths
        cris_cc_mask(dc, CC_MASK_RNZV);
1394 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1395 05ba7d5f edgar_igl
        t_gen_mov_TN_preg(cpu_T[1], dc->op2);
1396 8170028d ths
        crisv32_alu_op(dc, CC_OP_MCP, dc->op1, 4);
1397 8170028d ths
        return 2;
1398 8170028d ths
}
1399 8170028d ths
1400 8170028d ths
#if DISAS_CRIS
1401 8170028d ths
static char * swapmode_name(int mode, char *modename) {
1402 8170028d ths
        int i = 0;
1403 8170028d ths
        if (mode & 8)
1404 8170028d ths
                modename[i++] = 'n';
1405 8170028d ths
        if (mode & 4)
1406 8170028d ths
                modename[i++] = 'w';
1407 8170028d ths
        if (mode & 2)
1408 8170028d ths
                modename[i++] = 'b';
1409 8170028d ths
        if (mode & 1)
1410 8170028d ths
                modename[i++] = 'r';
1411 8170028d ths
        modename[i++] = 0;
1412 8170028d ths
        return modename;
1413 8170028d ths
}
1414 8170028d ths
#endif
1415 8170028d ths
1416 8170028d ths
static unsigned int dec_swap_r(DisasContext *dc)
1417 8170028d ths
{
1418 8170028d ths
        DIS(char modename[4]);
1419 8170028d ths
        DIS(fprintf (logfile, "swap%s $r%u\n",
1420 8170028d ths
                     swapmode_name(dc->op2, modename), dc->op1));
1421 8170028d ths
1422 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1423 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1424 8170028d ths
        if (dc->op2 & 8)
1425 3157a0a9 edgar_igl
                tcg_gen_xori_tl(cpu_T[0], cpu_T[0], -1);
1426 8170028d ths
        if (dc->op2 & 4)
1427 3157a0a9 edgar_igl
                t_gen_swapw(cpu_T[0], cpu_T[0]);
1428 8170028d ths
        if (dc->op2 & 2)
1429 3157a0a9 edgar_igl
                t_gen_swapb(cpu_T[0], cpu_T[0]);
1430 8170028d ths
        if (dc->op2 & 1)
1431 3157a0a9 edgar_igl
                t_gen_swapr(cpu_T[0], cpu_T[0]);
1432 3157a0a9 edgar_igl
        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1433 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1434 8170028d ths
        return 2;
1435 8170028d ths
}
1436 8170028d ths
1437 8170028d ths
static unsigned int dec_or_r(DisasContext *dc)
1438 8170028d ths
{
1439 8170028d ths
        int size = memsize_zz(dc);
1440 8170028d ths
        DIS(fprintf (logfile, "or.%c $r%u, $r%u\n",
1441 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1442 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1443 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1444 8170028d ths
        crisv32_alu_op(dc, CC_OP_OR, dc->op2, size);
1445 8170028d ths
        return 2;
1446 8170028d ths
}
1447 8170028d ths
1448 8170028d ths
static unsigned int dec_addi_r(DisasContext *dc)
1449 8170028d ths
{
1450 8170028d ths
        DIS(fprintf (logfile, "addi.%c $r%u, $r%u\n",
1451 8170028d ths
                    memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1452 8170028d ths
        cris_cc_mask(dc, 0);
1453 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1454 3157a0a9 edgar_igl
        t_gen_lsl(cpu_T[0], cpu_T[0], tcg_const_tl(dc->zzsize));
1455 05ba7d5f edgar_igl
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1456 05ba7d5f edgar_igl
        t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
1457 8170028d ths
        return 2;
1458 8170028d ths
}
1459 8170028d ths
1460 8170028d ths
static unsigned int dec_addi_acr(DisasContext *dc)
1461 8170028d ths
{
1462 8170028d ths
        DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n",
1463 8170028d ths
                    memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1464 8170028d ths
        cris_cc_mask(dc, 0);
1465 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1466 3157a0a9 edgar_igl
        t_gen_lsl(cpu_T[0], cpu_T[0], tcg_const_tl(dc->zzsize));
1467 05ba7d5f edgar_igl
1468 05ba7d5f edgar_igl
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1469 05ba7d5f edgar_igl
        t_gen_mov_reg_TN(R_ACR, cpu_T[0]);
1470 8170028d ths
        return 2;
1471 8170028d ths
}
1472 8170028d ths
1473 8170028d ths
static unsigned int dec_neg_r(DisasContext *dc)
1474 8170028d ths
{
1475 8170028d ths
        int size = memsize_zz(dc);
1476 8170028d ths
        DIS(fprintf (logfile, "neg.%c $r%u, $r%u\n",
1477 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1478 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1479 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1480 8170028d ths
        crisv32_alu_op(dc, CC_OP_NEG, dc->op2, size);
1481 8170028d ths
        return 2;
1482 8170028d ths
}
1483 8170028d ths
1484 8170028d ths
static unsigned int dec_btst_r(DisasContext *dc)
1485 8170028d ths
{
1486 8170028d ths
        DIS(fprintf (logfile, "btst $r%u, $r%u\n",
1487 8170028d ths
                    dc->op1, dc->op2));
1488 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1489 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1490 8170028d ths
        crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
1491 8170028d ths
1492 8170028d ths
        cris_update_cc_op(dc, CC_OP_FLAGS);
1493 3157a0a9 edgar_igl
        t_gen_mov_preg_TN(PR_CCS, cpu_T[0]);
1494 8170028d ths
        dc->flags_live = 1;
1495 8170028d ths
        return 2;
1496 8170028d ths
}
1497 8170028d ths
1498 8170028d ths
static unsigned int dec_sub_r(DisasContext *dc)
1499 8170028d ths
{
1500 8170028d ths
        int size = memsize_zz(dc);
1501 8170028d ths
        DIS(fprintf (logfile, "sub.%c $r%u, $r%u\n",
1502 8170028d ths
                    memsize_char(size), dc->op1, dc->op2));
1503 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1504 8170028d ths
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1505 8170028d ths
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, size);
1506 8170028d ths
        return 2;
1507 8170028d ths
}
1508 8170028d ths
1509 8170028d ths
/* Zero extension. From size to dword.  */
1510 8170028d ths
static unsigned int dec_movu_r(DisasContext *dc)
1511 8170028d ths
{
1512 8170028d ths
        int size = memsize_z(dc);
1513 8170028d ths
        DIS(fprintf (logfile, "movu.%c $r%u, $r%u\n",
1514 8170028d ths
                    memsize_char(size),
1515 8170028d ths
                    dc->op1, dc->op2));
1516 8170028d ths
1517 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1518 8170028d ths
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
1519 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1520 8170028d ths
        return 2;
1521 8170028d ths
}
1522 8170028d ths
1523 8170028d ths
/* Sign extension. From size to dword.  */
1524 8170028d ths
static unsigned int dec_movs_r(DisasContext *dc)
1525 8170028d ths
{
1526 8170028d ths
        int size = memsize_z(dc);
1527 8170028d ths
        DIS(fprintf (logfile, "movs.%c $r%u, $r%u\n",
1528 8170028d ths
                    memsize_char(size),
1529 8170028d ths
                    dc->op1, dc->op2));
1530 8170028d ths
1531 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1532 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1533 8170028d ths
        /* Size can only be qi or hi.  */
1534 05ba7d5f edgar_igl
        t_gen_sext(cpu_T[1], cpu_T[0], size);
1535 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1536 8170028d ths
        return 2;
1537 8170028d ths
}
1538 8170028d ths
1539 8170028d ths
/* zero extension. From size to dword.  */
1540 8170028d ths
static unsigned int dec_addu_r(DisasContext *dc)
1541 8170028d ths
{
1542 8170028d ths
        int size = memsize_z(dc);
1543 8170028d ths
        DIS(fprintf (logfile, "addu.%c $r%u, $r%u\n",
1544 8170028d ths
                    memsize_char(size),
1545 8170028d ths
                    dc->op1, dc->op2));
1546 8170028d ths
1547 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1548 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1549 8170028d ths
        /* Size can only be qi or hi.  */
1550 05ba7d5f edgar_igl
        t_gen_zext(cpu_T[1], cpu_T[1], size);
1551 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1552 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1553 8170028d ths
        return 2;
1554 8170028d ths
}
1555 05ba7d5f edgar_igl
1556 8170028d ths
/* Sign extension. From size to dword.  */
1557 8170028d ths
static unsigned int dec_adds_r(DisasContext *dc)
1558 8170028d ths
{
1559 8170028d ths
        int size = memsize_z(dc);
1560 8170028d ths
        DIS(fprintf (logfile, "adds.%c $r%u, $r%u\n",
1561 8170028d ths
                    memsize_char(size),
1562 8170028d ths
                    dc->op1, dc->op2));
1563 8170028d ths
1564 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1565 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1566 8170028d ths
        /* Size can only be qi or hi.  */
1567 05ba7d5f edgar_igl
        t_gen_sext(cpu_T[1], cpu_T[1], size);
1568 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1569 05ba7d5f edgar_igl
1570 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1571 8170028d ths
        return 2;
1572 8170028d ths
}
1573 8170028d ths
1574 8170028d ths
/* Zero extension. From size to dword.  */
1575 8170028d ths
static unsigned int dec_subu_r(DisasContext *dc)
1576 8170028d ths
{
1577 8170028d ths
        int size = memsize_z(dc);
1578 8170028d ths
        DIS(fprintf (logfile, "subu.%c $r%u, $r%u\n",
1579 8170028d ths
                    memsize_char(size),
1580 8170028d ths
                    dc->op1, dc->op2));
1581 8170028d ths
1582 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1583 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1584 8170028d ths
        /* Size can only be qi or hi.  */
1585 05ba7d5f edgar_igl
        t_gen_zext(cpu_T[1], cpu_T[1], size);
1586 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1587 8170028d ths
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1588 8170028d ths
        return 2;
1589 8170028d ths
}
1590 8170028d ths
1591 8170028d ths
/* Sign extension. From size to dword.  */
1592 8170028d ths
static unsigned int dec_subs_r(DisasContext *dc)
1593 8170028d ths
{
1594 8170028d ths
        int size = memsize_z(dc);
1595 8170028d ths
        DIS(fprintf (logfile, "subs.%c $r%u, $r%u\n",
1596 8170028d ths
                    memsize_char(size),
1597 8170028d ths
                    dc->op1, dc->op2));
1598 8170028d ths
1599 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1600 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1601 8170028d ths
        /* Size can only be qi or hi.  */
1602 05ba7d5f edgar_igl
        t_gen_sext(cpu_T[1], cpu_T[1], size);
1603 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1604 8170028d ths
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1605 8170028d ths
        return 2;
1606 8170028d ths
}
1607 8170028d ths
1608 8170028d ths
static unsigned int dec_setclrf(DisasContext *dc)
1609 8170028d ths
{
1610 8170028d ths
        uint32_t flags;
1611 8170028d ths
        int set = (~dc->opcode >> 2) & 1;
1612 8170028d ths
1613 8170028d ths
        flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
1614 8170028d ths
                | EXTRACT_FIELD(dc->ir, 0, 3);
1615 8170028d ths
        DIS(fprintf (logfile, "set=%d flags=%x\n", set, flags));
1616 8170028d ths
        if (set && flags == 0)
1617 8170028d ths
                DIS(fprintf (logfile, "nop\n"));
1618 8170028d ths
        else if (!set && (flags & 0x20))
1619 8170028d ths
                DIS(fprintf (logfile, "di\n"));
1620 8170028d ths
        else
1621 8170028d ths
                DIS(fprintf (logfile, "%sf %x\n",
1622 8170028d ths
                            set ? "set" : "clr",
1623 8170028d ths
                            flags));
1624 8170028d ths
1625 8170028d ths
        if (set && (flags & X_FLAG)) {
1626 8170028d ths
                dc->flagx_live = 1;
1627 8170028d ths
                dc->flags_x = 1;
1628 8170028d ths
        }
1629 8170028d ths
1630 8170028d ths
        /* Simply decode the flags.  */
1631 8170028d ths
        cris_evaluate_flags (dc);
1632 8170028d ths
        cris_update_cc_op(dc, CC_OP_FLAGS);
1633 8170028d ths
        if (set)
1634 a825e703 edgar_igl
                gen_op_setf(flags);
1635 8170028d ths
        else
1636 a825e703 edgar_igl
                gen_op_clrf(flags);
1637 8170028d ths
        dc->flags_live = 1;
1638 8170028d ths
        return 2;
1639 8170028d ths
}
1640 8170028d ths
1641 8170028d ths
static unsigned int dec_move_rs(DisasContext *dc)
1642 8170028d ths
{
1643 8170028d ths
        DIS(fprintf (logfile, "move $r%u, $s%u\n", dc->op1, dc->op2));
1644 8170028d ths
        cris_cc_mask(dc, 0);
1645 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1646 8170028d ths
        gen_op_movl_sreg_T0(dc->op2);
1647 8170028d ths
1648 05ba7d5f edgar_igl
#if !defined(CONFIG_USER_ONLY)
1649 05ba7d5f edgar_igl
        if (dc->op2 == 6)
1650 05ba7d5f edgar_igl
                gen_op_movl_tlb_hi_T0();
1651 05ba7d5f edgar_igl
        else if (dc->op2 == 5) { /* srs is checked at runtime.  */
1652 05ba7d5f edgar_igl
                tcg_gen_helper_0_1(helper_tlb_update, cpu_T[0]);
1653 8170028d ths
                gen_op_movl_tlb_lo_T0();
1654 05ba7d5f edgar_igl
        }
1655 05ba7d5f edgar_igl
#endif
1656 8170028d ths
        return 2;
1657 8170028d ths
}
1658 8170028d ths
static unsigned int dec_move_sr(DisasContext *dc)
1659 8170028d ths
{
1660 05ba7d5f edgar_igl
        DIS(fprintf (logfile, "move $s%u, $r%u\n", dc->op2, dc->op1));
1661 8170028d ths
        cris_cc_mask(dc, 0);
1662 05ba7d5f edgar_igl
        gen_op_movl_T0_sreg(dc->op2);
1663 05ba7d5f edgar_igl
        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1664 05ba7d5f edgar_igl
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1665 8170028d ths
        return 2;
1666 8170028d ths
}
1667 8170028d ths
static unsigned int dec_move_rp(DisasContext *dc)
1668 8170028d ths
{
1669 8170028d ths
        DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2));
1670 8170028d ths
        cris_cc_mask(dc, 0);
1671 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1672 05ba7d5f edgar_igl
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
1673 8170028d ths
        return 2;
1674 8170028d ths
}
1675 8170028d ths
static unsigned int dec_move_pr(DisasContext *dc)
1676 8170028d ths
{
1677 8170028d ths
        DIS(fprintf (logfile, "move $p%u, $r%u\n", dc->op1, dc->op2));
1678 8170028d ths
        cris_cc_mask(dc, 0);
1679 fd56059f balrog
        /* Support register 0 is hardwired to zero. 
1680 fd56059f balrog
           Treat it specially. */
1681 fd56059f balrog
        if (dc->op2 == 0)
1682 05ba7d5f edgar_igl
                tcg_gen_movi_tl(cpu_T[1], 0);
1683 05ba7d5f edgar_igl
        else
1684 05ba7d5f edgar_igl
                t_gen_mov_TN_preg(cpu_T[1], dc->op2);
1685 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, preg_sizes[dc->op2]);
1686 8170028d ths
        return 2;
1687 8170028d ths
}
1688 8170028d ths
1689 8170028d ths
static unsigned int dec_move_mr(DisasContext *dc)
1690 8170028d ths
{
1691 8170028d ths
        int memsize = memsize_zz(dc);
1692 8170028d ths
        int insn_len;
1693 8170028d ths
        DIS(fprintf (logfile, "move.%c [$r%u%s, $r%u\n",
1694 8170028d ths
                    memsize_char(memsize),
1695 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1696 8170028d ths
                    dc->op2));
1697 8170028d ths
1698 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1699 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1700 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, memsize);
1701 8170028d ths
        do_postinc(dc, memsize);
1702 8170028d ths
        return insn_len;
1703 8170028d ths
}
1704 8170028d ths
1705 8170028d ths
static unsigned int dec_movs_m(DisasContext *dc)
1706 8170028d ths
{
1707 8170028d ths
        int memsize = memsize_z(dc);
1708 8170028d ths
        int insn_len;
1709 8170028d ths
        DIS(fprintf (logfile, "movs.%c [$r%u%s, $r%u\n",
1710 8170028d ths
                    memsize_char(memsize),
1711 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1712 8170028d ths
                    dc->op2));
1713 8170028d ths
1714 8170028d ths
        /* sign extend.  */
1715 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1716 8170028d ths
        insn_len = dec_prep_alu_m(dc, 1, memsize);
1717 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1718 8170028d ths
        do_postinc(dc, memsize);
1719 8170028d ths
        return insn_len;
1720 8170028d ths
}
1721 8170028d ths
1722 8170028d ths
static unsigned int dec_addu_m(DisasContext *dc)
1723 8170028d ths
{
1724 8170028d ths
        int memsize = memsize_z(dc);
1725 8170028d ths
        int insn_len;
1726 8170028d ths
        DIS(fprintf (logfile, "addu.%c [$r%u%s, $r%u\n",
1727 8170028d ths
                    memsize_char(memsize),
1728 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1729 8170028d ths
                    dc->op2));
1730 8170028d ths
1731 8170028d ths
        /* sign extend.  */
1732 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1733 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1734 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1735 8170028d ths
        do_postinc(dc, memsize);
1736 8170028d ths
        return insn_len;
1737 8170028d ths
}
1738 8170028d ths
1739 8170028d ths
static unsigned int dec_adds_m(DisasContext *dc)
1740 8170028d ths
{
1741 8170028d ths
        int memsize = memsize_z(dc);
1742 8170028d ths
        int insn_len;
1743 8170028d ths
        DIS(fprintf (logfile, "adds.%c [$r%u%s, $r%u\n",
1744 8170028d ths
                    memsize_char(memsize),
1745 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1746 8170028d ths
                    dc->op2));
1747 8170028d ths
1748 8170028d ths
        /* sign extend.  */
1749 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1750 8170028d ths
        insn_len = dec_prep_alu_m(dc, 1, memsize);
1751 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1752 8170028d ths
        do_postinc(dc, memsize);
1753 8170028d ths
        return insn_len;
1754 8170028d ths
}
1755 8170028d ths
1756 8170028d ths
static unsigned int dec_subu_m(DisasContext *dc)
1757 8170028d ths
{
1758 8170028d ths
        int memsize = memsize_z(dc);
1759 8170028d ths
        int insn_len;
1760 8170028d ths
        DIS(fprintf (logfile, "subu.%c [$r%u%s, $r%u\n",
1761 8170028d ths
                    memsize_char(memsize),
1762 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1763 8170028d ths
                    dc->op2));
1764 8170028d ths
1765 8170028d ths
        /* sign extend.  */
1766 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1767 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1768 8170028d ths
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1769 8170028d ths
        do_postinc(dc, memsize);
1770 8170028d ths
        return insn_len;
1771 8170028d ths
}
1772 8170028d ths
1773 8170028d ths
static unsigned int dec_subs_m(DisasContext *dc)
1774 8170028d ths
{
1775 8170028d ths
        int memsize = memsize_z(dc);
1776 8170028d ths
        int insn_len;
1777 8170028d ths
        DIS(fprintf (logfile, "subs.%c [$r%u%s, $r%u\n",
1778 8170028d ths
                    memsize_char(memsize),
1779 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1780 8170028d ths
                    dc->op2));
1781 8170028d ths
1782 8170028d ths
        /* sign extend.  */
1783 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1784 8170028d ths
        insn_len = dec_prep_alu_m(dc, 1, memsize);
1785 8170028d ths
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1786 8170028d ths
        do_postinc(dc, memsize);
1787 8170028d ths
        return insn_len;
1788 8170028d ths
}
1789 8170028d ths
1790 8170028d ths
static unsigned int dec_movu_m(DisasContext *dc)
1791 8170028d ths
{
1792 8170028d ths
        int memsize = memsize_z(dc);
1793 8170028d ths
        int insn_len;
1794 8170028d ths
1795 8170028d ths
        DIS(fprintf (logfile, "movu.%c [$r%u%s, $r%u\n",
1796 8170028d ths
                    memsize_char(memsize),
1797 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1798 8170028d ths
                    dc->op2));
1799 8170028d ths
1800 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1801 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1802 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1803 8170028d ths
        do_postinc(dc, memsize);
1804 8170028d ths
        return insn_len;
1805 8170028d ths
}
1806 8170028d ths
1807 8170028d ths
static unsigned int dec_cmpu_m(DisasContext *dc)
1808 8170028d ths
{
1809 8170028d ths
        int memsize = memsize_z(dc);
1810 8170028d ths
        int insn_len;
1811 8170028d ths
        DIS(fprintf (logfile, "cmpu.%c [$r%u%s, $r%u\n",
1812 8170028d ths
                    memsize_char(memsize),
1813 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1814 8170028d ths
                    dc->op2));
1815 8170028d ths
1816 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1817 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1818 8170028d ths
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
1819 8170028d ths
        do_postinc(dc, memsize);
1820 8170028d ths
        return insn_len;
1821 8170028d ths
}
1822 8170028d ths
1823 8170028d ths
static unsigned int dec_cmps_m(DisasContext *dc)
1824 8170028d ths
{
1825 8170028d ths
        int memsize = memsize_z(dc);
1826 8170028d ths
        int insn_len;
1827 8170028d ths
        DIS(fprintf (logfile, "cmps.%c [$r%u%s, $r%u\n",
1828 8170028d ths
                    memsize_char(memsize),
1829 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1830 8170028d ths
                    dc->op2));
1831 8170028d ths
1832 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1833 8170028d ths
        insn_len = dec_prep_alu_m(dc, 1, memsize);
1834 8170028d ths
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1835 8170028d ths
        do_postinc(dc, memsize);
1836 8170028d ths
        return insn_len;
1837 8170028d ths
}
1838 8170028d ths
1839 8170028d ths
static unsigned int dec_cmp_m(DisasContext *dc)
1840 8170028d ths
{
1841 8170028d ths
        int memsize = memsize_zz(dc);
1842 8170028d ths
        int insn_len;
1843 8170028d ths
        DIS(fprintf (logfile, "cmp.%c [$r%u%s, $r%u\n",
1844 8170028d ths
                    memsize_char(memsize),
1845 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1846 8170028d ths
                    dc->op2));
1847 8170028d ths
1848 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1849 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1850 8170028d ths
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1851 8170028d ths
        do_postinc(dc, memsize);
1852 8170028d ths
        return insn_len;
1853 8170028d ths
}
1854 8170028d ths
1855 8170028d ths
static unsigned int dec_test_m(DisasContext *dc)
1856 8170028d ths
{
1857 8170028d ths
        int memsize = memsize_zz(dc);
1858 8170028d ths
        int insn_len;
1859 8170028d ths
        DIS(fprintf (logfile, "test.%d [$r%u%s] op2=%x\n",
1860 8170028d ths
                    memsize_char(memsize),
1861 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1862 8170028d ths
                    dc->op2));
1863 8170028d ths
1864 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1865 8170028d ths
        gen_op_clrf(3);
1866 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1867 05ba7d5f edgar_igl
        tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1868 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[1], 0);
1869 8170028d ths
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1870 8170028d ths
        do_postinc(dc, memsize);
1871 8170028d ths
        return insn_len;
1872 8170028d ths
}
1873 8170028d ths
1874 8170028d ths
static unsigned int dec_and_m(DisasContext *dc)
1875 8170028d ths
{
1876 8170028d ths
        int memsize = memsize_zz(dc);
1877 8170028d ths
        int insn_len;
1878 8170028d ths
        DIS(fprintf (logfile, "and.%d [$r%u%s, $r%u\n",
1879 8170028d ths
                    memsize_char(memsize),
1880 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1881 8170028d ths
                    dc->op2));
1882 8170028d ths
1883 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1884 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1885 8170028d ths
        crisv32_alu_op(dc, CC_OP_AND, dc->op2, memsize_zz(dc));
1886 8170028d ths
        do_postinc(dc, memsize);
1887 8170028d ths
        return insn_len;
1888 8170028d ths
}
1889 8170028d ths
1890 8170028d ths
static unsigned int dec_add_m(DisasContext *dc)
1891 8170028d ths
{
1892 8170028d ths
        int memsize = memsize_zz(dc);
1893 8170028d ths
        int insn_len;
1894 8170028d ths
        DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
1895 8170028d ths
                    memsize_char(memsize),
1896 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1897 8170028d ths
                    dc->op2));
1898 8170028d ths
1899 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1900 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1901 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, memsize_zz(dc));
1902 8170028d ths
        do_postinc(dc, memsize);
1903 8170028d ths
        return insn_len;
1904 8170028d ths
}
1905 8170028d ths
1906 8170028d ths
static unsigned int dec_addo_m(DisasContext *dc)
1907 8170028d ths
{
1908 8170028d ths
        int memsize = memsize_zz(dc);
1909 8170028d ths
        int insn_len;
1910 8170028d ths
        DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
1911 8170028d ths
                    memsize_char(memsize),
1912 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1913 8170028d ths
                    dc->op2));
1914 8170028d ths
1915 8170028d ths
        cris_cc_mask(dc, 0);
1916 8170028d ths
        insn_len = dec_prep_alu_m(dc, 1, memsize);
1917 9004627f edgar_igl
        crisv32_alu_op(dc, CC_OP_ADD, R_ACR, 4);
1918 8170028d ths
        do_postinc(dc, memsize);
1919 8170028d ths
        return insn_len;
1920 8170028d ths
}
1921 8170028d ths
1922 8170028d ths
static unsigned int dec_bound_m(DisasContext *dc)
1923 8170028d ths
{
1924 8170028d ths
        int memsize = memsize_zz(dc);
1925 8170028d ths
        int insn_len;
1926 8170028d ths
        DIS(fprintf (logfile, "bound.%d [$r%u%s, $r%u\n",
1927 8170028d ths
                    memsize_char(memsize),
1928 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1929 8170028d ths
                    dc->op2));
1930 8170028d ths
1931 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1932 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1933 8170028d ths
        crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
1934 8170028d ths
        do_postinc(dc, memsize);
1935 8170028d ths
        return insn_len;
1936 8170028d ths
}
1937 8170028d ths
1938 8170028d ths
static unsigned int dec_addc_mr(DisasContext *dc)
1939 8170028d ths
{
1940 8170028d ths
        int insn_len = 2;
1941 8170028d ths
        DIS(fprintf (logfile, "addc [$r%u%s, $r%u\n",
1942 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1943 8170028d ths
                    dc->op2));
1944 8170028d ths
1945 8170028d ths
        cris_evaluate_flags(dc);
1946 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1947 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, 4);
1948 8170028d ths
        crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
1949 8170028d ths
        do_postinc(dc, 4);
1950 8170028d ths
        return insn_len;
1951 8170028d ths
}
1952 8170028d ths
1953 8170028d ths
static unsigned int dec_sub_m(DisasContext *dc)
1954 8170028d ths
{
1955 8170028d ths
        int memsize = memsize_zz(dc);
1956 8170028d ths
        int insn_len;
1957 8170028d ths
        DIS(fprintf (logfile, "sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
1958 8170028d ths
                    memsize_char(memsize),
1959 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1960 8170028d ths
                    dc->op2, dc->ir, dc->zzsize));
1961 8170028d ths
1962 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZVC);
1963 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1964 8170028d ths
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, memsize);
1965 8170028d ths
        do_postinc(dc, memsize);
1966 8170028d ths
        return insn_len;
1967 8170028d ths
}
1968 8170028d ths
1969 8170028d ths
static unsigned int dec_or_m(DisasContext *dc)
1970 8170028d ths
{
1971 8170028d ths
        int memsize = memsize_zz(dc);
1972 8170028d ths
        int insn_len;
1973 8170028d ths
        DIS(fprintf (logfile, "or.%d [$r%u%s, $r%u pc=%x\n",
1974 8170028d ths
                    memsize_char(memsize),
1975 8170028d ths
                    dc->op1, dc->postinc ? "+]" : "]",
1976 8170028d ths
                    dc->op2, dc->pc));
1977 8170028d ths
1978 8170028d ths
        cris_cc_mask(dc, CC_MASK_NZ);
1979 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1980 8170028d ths
        crisv32_alu_op(dc, CC_OP_OR, dc->op2, memsize_zz(dc));
1981 8170028d ths
        do_postinc(dc, memsize);
1982 8170028d ths
        return insn_len;
1983 8170028d ths
}
1984 8170028d ths
1985 8170028d ths
static unsigned int dec_move_mp(DisasContext *dc)
1986 8170028d ths
{
1987 8170028d ths
        int memsize = memsize_zz(dc);
1988 8170028d ths
        int insn_len = 2;
1989 8170028d ths
1990 8170028d ths
        DIS(fprintf (logfile, "move.%c [$r%u%s, $p%u\n",
1991 8170028d ths
                    memsize_char(memsize),
1992 8170028d ths
                    dc->op1,
1993 8170028d ths
                    dc->postinc ? "+]" : "]",
1994 8170028d ths
                    dc->op2));
1995 8170028d ths
1996 8170028d ths
        cris_cc_mask(dc, 0);
1997 8170028d ths
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1998 05ba7d5f edgar_igl
        t_gen_mov_preg_TN(dc->op2, cpu_T[1]);
1999 8170028d ths
2000 8170028d ths
        do_postinc(dc, memsize);
2001 8170028d ths
        return insn_len;
2002 8170028d ths
}
2003 8170028d ths
2004 8170028d ths
static unsigned int dec_move_pm(DisasContext *dc)
2005 8170028d ths
{
2006 8170028d ths
        int memsize;
2007 8170028d ths
2008 8170028d ths
        memsize = preg_sizes[dc->op2];
2009 8170028d ths
2010 fd56059f balrog
        DIS(fprintf (logfile, "move.%c $p%u, [$r%u%s\n",
2011 fd56059f balrog
                     memsize_char(memsize), 
2012 fd56059f balrog
                     dc->op2, dc->op1, dc->postinc ? "+]" : "]"));
2013 8170028d ths
2014 8170028d ths
        cris_cc_mask(dc, 0);
2015 fd56059f balrog
        /* prepare store. Address in T0, value in T1.  */
2016 05ba7d5f edgar_igl
        t_gen_mov_TN_preg(cpu_T[1], dc->op2);
2017 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2018 8170028d ths
        gen_store_T0_T1(dc, memsize);
2019 8170028d ths
        if (dc->postinc)
2020 8170028d ths
        {
2021 05ba7d5f edgar_igl
                tcg_gen_addi_tl(cpu_T[0], cpu_T[0], memsize);
2022 05ba7d5f edgar_igl
                t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
2023 8170028d ths
        }
2024 8170028d ths
        return 2;
2025 8170028d ths
}
2026 8170028d ths
2027 8170028d ths
static unsigned int dec_movem_mr(DisasContext *dc)
2028 8170028d ths
{
2029 8170028d ths
        int i;
2030 8170028d ths
2031 8170028d ths
        DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1,
2032 8170028d ths
                    dc->postinc ? "+]" : "]", dc->op2));
2033 8170028d ths
2034 8170028d ths
        cris_cc_mask(dc, 0);
2035 05ba7d5f edgar_igl
        /* fetch the address into T0 and T1.  */
2036 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
2037 8170028d ths
        for (i = 0; i <= dc->op2; i++) {
2038 8170028d ths
                /* Perform the load onto regnum i. Always dword wide.  */
2039 05ba7d5f edgar_igl
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
2040 8170028d ths
                gen_load_T0_T0(dc, 4, 0);
2041 05ba7d5f edgar_igl
                t_gen_mov_reg_TN(i, cpu_T[0]);
2042 05ba7d5f edgar_igl
                tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 4);
2043 8170028d ths
        }
2044 05ba7d5f edgar_igl
        /* writeback the updated pointer value.  */
2045 05ba7d5f edgar_igl
        if (dc->postinc)
2046 05ba7d5f edgar_igl
                t_gen_mov_reg_TN(dc->op1, cpu_T[1]);
2047 8170028d ths
        return 2;
2048 8170028d ths
}
2049 8170028d ths
2050 8170028d ths
static unsigned int dec_movem_rm(DisasContext *dc)
2051 8170028d ths
{
2052 8170028d ths
        int i;
2053 8170028d ths
2054 8170028d ths
        DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
2055 8170028d ths
                     dc->postinc ? "+]" : "]"));
2056 8170028d ths
2057 8170028d ths
        cris_cc_mask(dc, 0);
2058 8170028d ths
        for (i = 0; i <= dc->op2; i++) {
2059 8170028d ths
                /* Fetch register i into T1.  */
2060 05ba7d5f edgar_igl
                t_gen_mov_TN_reg(cpu_T[1], i);
2061 8170028d ths
                /* Fetch the address into T0.  */
2062 05ba7d5f edgar_igl
                t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2063 8170028d ths
                /* Displace it.  */
2064 05ba7d5f edgar_igl
                tcg_gen_addi_tl(cpu_T[0], cpu_T[0], i * 4);
2065 8170028d ths
                /* Perform the store.  */
2066 8170028d ths
                gen_store_T0_T1(dc, 4);
2067 8170028d ths
        }
2068 8170028d ths
        if (dc->postinc) {
2069 05ba7d5f edgar_igl
                /* T0 should point to the last written addr, advance one more
2070 05ba7d5f edgar_igl
                   step. */
2071 05ba7d5f edgar_igl
                tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 4);
2072 8170028d ths
                /* writeback the updated pointer value.  */
2073 05ba7d5f edgar_igl
                t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
2074 8170028d ths
        }
2075 8170028d ths
        return 2;
2076 8170028d ths
}
2077 8170028d ths
2078 8170028d ths
static unsigned int dec_move_rm(DisasContext *dc)
2079 8170028d ths
{
2080 8170028d ths
        int memsize;
2081 8170028d ths
2082 8170028d ths
        memsize = memsize_zz(dc);
2083 8170028d ths
2084 8170028d ths
        DIS(fprintf (logfile, "move.%d $r%u, [$r%u]\n",
2085 8170028d ths
                     memsize, dc->op2, dc->op1));
2086 8170028d ths
2087 8170028d ths
        cris_cc_mask(dc, 0);
2088 8170028d ths
        /* prepare store.  */
2089 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2090 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[1], dc->op2);
2091 8170028d ths
        gen_store_T0_T1(dc, memsize);
2092 8170028d ths
        if (dc->postinc)
2093 8170028d ths
        {
2094 05ba7d5f edgar_igl
                tcg_gen_addi_tl(cpu_T[0], cpu_T[0], memsize);
2095 05ba7d5f edgar_igl
                t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
2096 8170028d ths
        }
2097 8170028d ths
        return 2;
2098 8170028d ths
}
2099 8170028d ths
2100 8170028d ths
static unsigned int dec_lapcq(DisasContext *dc)
2101 8170028d ths
{
2102 8170028d ths
        DIS(fprintf (logfile, "lapcq %x, $r%u\n",
2103 8170028d ths
                    dc->pc + dc->op1*2, dc->op2));
2104 8170028d ths
        cris_cc_mask(dc, 0);
2105 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[1], dc->pc + dc->op1 * 2);
2106 8170028d ths
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
2107 8170028d ths
        return 2;
2108 8170028d ths
}
2109 8170028d ths
2110 8170028d ths
static unsigned int dec_lapc_im(DisasContext *dc)
2111 8170028d ths
{
2112 8170028d ths
        unsigned int rd;
2113 8170028d ths
        int32_t imm;
2114 8170028d ths
2115 8170028d ths
        rd = dc->op2;
2116 8170028d ths
2117 8170028d ths
        cris_cc_mask(dc, 0);
2118 8170028d ths
        imm = ldl_code(dc->pc + 2);
2119 8170028d ths
        DIS(fprintf (logfile, "lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2));
2120 3157a0a9 edgar_igl
        t_gen_mov_reg_TN(rd, tcg_const_tl(dc->pc + imm));
2121 05ba7d5f edgar_igl
        return 6;
2122 8170028d ths
}
2123 8170028d ths
2124 8170028d ths
/* Jump to special reg.  */
2125 8170028d ths
static unsigned int dec_jump_p(DisasContext *dc)
2126 8170028d ths
{
2127 8170028d ths
        DIS(fprintf (logfile, "jump $p%u\n", dc->op2));
2128 8170028d ths
        cris_cc_mask(dc, 0);
2129 8170028d ths
        /* Store the return address in Pd.  */
2130 05ba7d5f edgar_igl
        t_gen_mov_TN_preg(cpu_T[0], dc->op2);
2131 3157a0a9 edgar_igl
        t_gen_mov_env_TN(btarget, cpu_T[0]);
2132 8170028d ths
        cris_prepare_dyn_jmp(dc);
2133 8170028d ths
        return 2;
2134 8170028d ths
}
2135 8170028d ths
2136 8170028d ths
/* Jump and save.  */
2137 8170028d ths
static unsigned int dec_jas_r(DisasContext *dc)
2138 8170028d ths
{
2139 8170028d ths
        DIS(fprintf (logfile, "jas $r%u, $p%u\n", dc->op1, dc->op2));
2140 8170028d ths
        cris_cc_mask(dc, 0);
2141 8170028d ths
        /* Stor the return address in Pd.  */
2142 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2143 3157a0a9 edgar_igl
        t_gen_mov_env_TN(btarget, cpu_T[0]);
2144 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 4);
2145 05ba7d5f edgar_igl
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
2146 8170028d ths
        cris_prepare_dyn_jmp(dc);
2147 8170028d ths
        return 2;
2148 8170028d ths
}
2149 8170028d ths
2150 8170028d ths
static unsigned int dec_jas_im(DisasContext *dc)
2151 8170028d ths
{
2152 8170028d ths
        uint32_t imm;
2153 8170028d ths
2154 8170028d ths
        imm = ldl_code(dc->pc + 2);
2155 8170028d ths
2156 8170028d ths
        DIS(fprintf (logfile, "jas 0x%x\n", imm));
2157 8170028d ths
        cris_cc_mask(dc, 0);
2158 8170028d ths
        /* Stor the return address in Pd.  */
2159 a825e703 edgar_igl
        t_gen_mov_env_TN(btarget, tcg_const_tl(imm));
2160 a825e703 edgar_igl
        t_gen_mov_preg_TN(dc->op2, tcg_const_tl(dc->pc + 8));
2161 8170028d ths
        cris_prepare_dyn_jmp(dc);
2162 8170028d ths
        return 6;
2163 8170028d ths
}
2164 8170028d ths
2165 8170028d ths
static unsigned int dec_jasc_im(DisasContext *dc)
2166 8170028d ths
{
2167 8170028d ths
        uint32_t imm;
2168 8170028d ths
2169 8170028d ths
        imm = ldl_code(dc->pc + 2);
2170 8170028d ths
2171 8170028d ths
        DIS(fprintf (logfile, "jasc 0x%x\n", imm));
2172 8170028d ths
        cris_cc_mask(dc, 0);
2173 8170028d ths
        /* Stor the return address in Pd.  */
2174 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[0], imm);
2175 3157a0a9 edgar_igl
        t_gen_mov_env_TN(btarget, cpu_T[0]);
2176 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 8 + 4);
2177 05ba7d5f edgar_igl
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
2178 8170028d ths
        cris_prepare_dyn_jmp(dc);
2179 8170028d ths
        return 6;
2180 8170028d ths
}
2181 8170028d ths
2182 8170028d ths
static unsigned int dec_jasc_r(DisasContext *dc)
2183 8170028d ths
{
2184 8170028d ths
        DIS(fprintf (logfile, "jasc_r $r%u, $p%u\n", dc->op1, dc->op2));
2185 8170028d ths
        cris_cc_mask(dc, 0);
2186 8170028d ths
        /* Stor the return address in Pd.  */
2187 05ba7d5f edgar_igl
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2188 3157a0a9 edgar_igl
        t_gen_mov_env_TN(btarget, cpu_T[0]);
2189 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 4 + 4);
2190 05ba7d5f edgar_igl
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
2191 8170028d ths
        cris_prepare_dyn_jmp(dc);
2192 8170028d ths
        return 2;
2193 8170028d ths
}
2194 8170028d ths
2195 8170028d ths
static unsigned int dec_bcc_im(DisasContext *dc)
2196 8170028d ths
{
2197 8170028d ths
        int32_t offset;
2198 8170028d ths
        uint32_t cond = dc->op2;
2199 8170028d ths
2200 8170028d ths
        offset = ldl_code(dc->pc + 2);
2201 8170028d ths
        offset = sign_extend(offset, 15);
2202 8170028d ths
2203 8170028d ths
        DIS(fprintf (logfile, "b%s %d pc=%x dst=%x\n",
2204 8170028d ths
                    cc_name(cond), offset,
2205 8170028d ths
                    dc->pc, dc->pc + offset));
2206 8170028d ths
2207 8170028d ths
        cris_cc_mask(dc, 0);
2208 8170028d ths
        /* op2 holds the condition-code.  */
2209 8170028d ths
        cris_prepare_cc_branch (dc, offset, cond);
2210 8170028d ths
        return 4;
2211 8170028d ths
}
2212 8170028d ths
2213 8170028d ths
static unsigned int dec_bas_im(DisasContext *dc)
2214 8170028d ths
{
2215 8170028d ths
        int32_t simm;
2216 8170028d ths
2217 8170028d ths
2218 8170028d ths
        simm = ldl_code(dc->pc + 2);
2219 8170028d ths
2220 8170028d ths
        DIS(fprintf (logfile, "bas 0x%x, $p%u\n", dc->pc + simm, dc->op2));
2221 8170028d ths
        cris_cc_mask(dc, 0);
2222 8170028d ths
        /* Stor the return address in Pd.  */
2223 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[0], dc->pc + simm);
2224 3157a0a9 edgar_igl
        t_gen_mov_env_TN(btarget, cpu_T[0]);
2225 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 8);
2226 05ba7d5f edgar_igl
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
2227 8170028d ths
        cris_prepare_dyn_jmp(dc);
2228 8170028d ths
        return 6;
2229 8170028d ths
}
2230 8170028d ths
2231 8170028d ths
static unsigned int dec_basc_im(DisasContext *dc)
2232 8170028d ths
{
2233 8170028d ths
        int32_t simm;
2234 8170028d ths
        simm = ldl_code(dc->pc + 2);
2235 8170028d ths
2236 8170028d ths
        DIS(fprintf (logfile, "basc 0x%x, $p%u\n", dc->pc + simm, dc->op2));
2237 8170028d ths
        cris_cc_mask(dc, 0);
2238 8170028d ths
        /* Stor the return address in Pd.  */
2239 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[0], dc->pc + simm);
2240 3157a0a9 edgar_igl
        t_gen_mov_env_TN(btarget, cpu_T[0]);
2241 05ba7d5f edgar_igl
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 12);
2242 05ba7d5f edgar_igl
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
2243 8170028d ths
        cris_prepare_dyn_jmp(dc);
2244 8170028d ths
        return 6;
2245 8170028d ths
}
2246 8170028d ths
2247 8170028d ths
static unsigned int dec_rfe_etc(DisasContext *dc)
2248 8170028d ths
{
2249 8170028d ths
        DIS(fprintf (logfile, "rfe_etc opc=%x pc=0x%x op1=%d op2=%d\n",
2250 8170028d ths
                    dc->opcode, dc->pc, dc->op1, dc->op2));
2251 8170028d ths
2252 8170028d ths
        cris_cc_mask(dc, 0);
2253 8170028d ths
2254 8170028d ths
        if (dc->op2 == 15) /* ignore halt.  */
2255 05ba7d5f edgar_igl
                return 2;
2256 8170028d ths
2257 8170028d ths
        switch (dc->op2 & 7) {
2258 8170028d ths
                case 2:
2259 8170028d ths
                        /* rfe.  */
2260 8170028d ths
                        cris_evaluate_flags(dc);
2261 8170028d ths
                        gen_op_ccs_rshift();
2262 8170028d ths
                        break;
2263 8170028d ths
                case 5:
2264 8170028d ths
                        /* rfn.  */
2265 8170028d ths
                        BUG();
2266 8170028d ths
                        break;
2267 8170028d ths
                case 6:
2268 8170028d ths
                        /* break.  */
2269 05ba7d5f edgar_igl
                        tcg_gen_movi_tl(cpu_T[0], dc->pc);
2270 3157a0a9 edgar_igl
                        t_gen_mov_env_TN(pc, cpu_T[0]);
2271 8170028d ths
                        /* Breaks start at 16 in the exception vector.  */
2272 8170028d ths
                        gen_op_break_im(dc->op1 + 16);
2273 4f400ab5 edgar_igl
                        dc->is_jmp = DISAS_SWI;
2274 8170028d ths
                        break;
2275 8170028d ths
                default:
2276 8170028d ths
                        printf ("op2=%x\n", dc->op2);
2277 8170028d ths
                        BUG();
2278 8170028d ths
                        break;
2279 8170028d ths
2280 8170028d ths
        }
2281 8170028d ths
        return 2;
2282 8170028d ths
}
2283 8170028d ths
2284 5d4a534d edgar_igl
static unsigned int dec_ftag_fidx_d_m(DisasContext *dc)
2285 5d4a534d edgar_igl
{
2286 5d4a534d edgar_igl
        /* Ignore D-cache flushes.  */
2287 5d4a534d edgar_igl
        return 2;
2288 5d4a534d edgar_igl
}
2289 5d4a534d edgar_igl
2290 5d4a534d edgar_igl
static unsigned int dec_ftag_fidx_i_m(DisasContext *dc)
2291 5d4a534d edgar_igl
{
2292 5d4a534d edgar_igl
        /* Ignore I-cache flushes.  */
2293 5d4a534d edgar_igl
        return 2;
2294 5d4a534d edgar_igl
}
2295 5d4a534d edgar_igl
2296 8170028d ths
static unsigned int dec_null(DisasContext *dc)
2297 8170028d ths
{
2298 8170028d ths
        printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2299 8170028d ths
                dc->pc, dc->opcode, dc->op1, dc->op2);
2300 8170028d ths
        fflush(NULL);
2301 8170028d ths
        BUG();
2302 8170028d ths
        return 2;
2303 8170028d ths
}
2304 8170028d ths
2305 8170028d ths
struct decoder_info {
2306 8170028d ths
        struct {
2307 8170028d ths
                uint32_t bits;
2308 8170028d ths
                uint32_t mask;
2309 8170028d ths
        };
2310 8170028d ths
        unsigned int (*dec)(DisasContext *dc);
2311 8170028d ths
} decinfo[] = {
2312 8170028d ths
        /* Order matters here.  */
2313 8170028d ths
        {DEC_MOVEQ, dec_moveq},
2314 8170028d ths
        {DEC_BTSTQ, dec_btstq},
2315 8170028d ths
        {DEC_CMPQ, dec_cmpq},
2316 8170028d ths
        {DEC_ADDOQ, dec_addoq},
2317 8170028d ths
        {DEC_ADDQ, dec_addq},
2318 8170028d ths
        {DEC_SUBQ, dec_subq},
2319 8170028d ths
        {DEC_ANDQ, dec_andq},
2320 8170028d ths
        {DEC_ORQ, dec_orq},
2321 8170028d ths
        {DEC_ASRQ, dec_asrq},
2322 8170028d ths
        {DEC_LSLQ, dec_lslq},
2323 8170028d ths
        {DEC_LSRQ, dec_lsrq},
2324 8170028d ths
        {DEC_BCCQ, dec_bccq},
2325 8170028d ths
2326 8170028d ths
        {DEC_BCC_IM, dec_bcc_im},
2327 8170028d ths
        {DEC_JAS_IM, dec_jas_im},
2328 8170028d ths
        {DEC_JAS_R, dec_jas_r},
2329 8170028d ths
        {DEC_JASC_IM, dec_jasc_im},
2330 8170028d ths
        {DEC_JASC_R, dec_jasc_r},
2331 8170028d ths
        {DEC_BAS_IM, dec_bas_im},
2332 8170028d ths
        {DEC_BASC_IM, dec_basc_im},
2333 8170028d ths
        {DEC_JUMP_P, dec_jump_p},
2334 8170028d ths
        {DEC_LAPC_IM, dec_lapc_im},
2335 8170028d ths
        {DEC_LAPCQ, dec_lapcq},
2336 8170028d ths
2337 8170028d ths
        {DEC_RFE_ETC, dec_rfe_etc},
2338 8170028d ths
        {DEC_ADDC_MR, dec_addc_mr},
2339 8170028d ths
2340 8170028d ths
        {DEC_MOVE_MP, dec_move_mp},
2341 8170028d ths
        {DEC_MOVE_PM, dec_move_pm},
2342 8170028d ths
        {DEC_MOVEM_MR, dec_movem_mr},
2343 8170028d ths
        {DEC_MOVEM_RM, dec_movem_rm},
2344 8170028d ths
        {DEC_MOVE_PR, dec_move_pr},
2345 8170028d ths
        {DEC_SCC_R, dec_scc_r},
2346 8170028d ths
        {DEC_SETF, dec_setclrf},
2347 8170028d ths
        {DEC_CLEARF, dec_setclrf},
2348 8170028d ths
2349 8170028d ths
        {DEC_MOVE_SR, dec_move_sr},
2350 8170028d ths
        {DEC_MOVE_RP, dec_move_rp},
2351 8170028d ths
        {DEC_SWAP_R, dec_swap_r},
2352 8170028d ths
        {DEC_ABS_R, dec_abs_r},
2353 8170028d ths
        {DEC_LZ_R, dec_lz_r},
2354 8170028d ths
        {DEC_MOVE_RS, dec_move_rs},
2355 8170028d ths
        {DEC_BTST_R, dec_btst_r},
2356 8170028d ths
        {DEC_ADDC_R, dec_addc_r},
2357 8170028d ths
2358 8170028d ths
        {DEC_DSTEP_R, dec_dstep_r},
2359 8170028d ths
        {DEC_XOR_R, dec_xor_r},
2360 8170028d ths
        {DEC_MCP_R, dec_mcp_r},
2361 8170028d ths
        {DEC_CMP_R, dec_cmp_r},
2362 8170028d ths
2363 8170028d ths
        {DEC_ADDI_R, dec_addi_r},
2364 8170028d ths
        {DEC_ADDI_ACR, dec_addi_acr},
2365 8170028d ths
2366 8170028d ths
        {DEC_ADD_R, dec_add_r},
2367 8170028d ths
        {DEC_SUB_R, dec_sub_r},
2368 8170028d ths
2369 8170028d ths
        {DEC_ADDU_R, dec_addu_r},
2370 8170028d ths
        {DEC_ADDS_R, dec_adds_r},
2371 8170028d ths
        {DEC_SUBU_R, dec_subu_r},
2372 8170028d ths
        {DEC_SUBS_R, dec_subs_r},
2373 8170028d ths
        {DEC_LSL_R, dec_lsl_r},
2374 8170028d ths
2375 8170028d ths
        {DEC_AND_R, dec_and_r},
2376 8170028d ths
        {DEC_OR_R, dec_or_r},
2377 8170028d ths
        {DEC_BOUND_R, dec_bound_r},
2378 8170028d ths
        {DEC_ASR_R, dec_asr_r},
2379 8170028d ths
        {DEC_LSR_R, dec_lsr_r},
2380 8170028d ths
2381 8170028d ths
        {DEC_MOVU_R, dec_movu_r},
2382 8170028d ths
        {DEC_MOVS_R, dec_movs_r},
2383 8170028d ths
        {DEC_NEG_R, dec_neg_r},
2384 8170028d ths
        {DEC_MOVE_R, dec_move_r},
2385 8170028d ths
2386 5d4a534d edgar_igl
        {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
2387 5d4a534d edgar_igl
        {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
2388 8170028d ths
2389 8170028d ths
        {DEC_MULS_R, dec_muls_r},
2390 8170028d ths
        {DEC_MULU_R, dec_mulu_r},
2391 8170028d ths
2392 8170028d ths
        {DEC_ADDU_M, dec_addu_m},
2393 8170028d ths
        {DEC_ADDS_M, dec_adds_m},
2394 8170028d ths
        {DEC_SUBU_M, dec_subu_m},
2395 8170028d ths
        {DEC_SUBS_M, dec_subs_m},
2396 8170028d ths
2397 8170028d ths
        {DEC_CMPU_M, dec_cmpu_m},
2398 8170028d ths
        {DEC_CMPS_M, dec_cmps_m},
2399 8170028d ths
        {DEC_MOVU_M, dec_movu_m},
2400 8170028d ths
        {DEC_MOVS_M, dec_movs_m},
2401 8170028d ths
2402 8170028d ths
        {DEC_CMP_M, dec_cmp_m},
2403 8170028d ths
        {DEC_ADDO_M, dec_addo_m},
2404 8170028d ths
        {DEC_BOUND_M, dec_bound_m},
2405 8170028d ths
        {DEC_ADD_M, dec_add_m},
2406 8170028d ths
        {DEC_SUB_M, dec_sub_m},
2407 8170028d ths
        {DEC_AND_M, dec_and_m},
2408 8170028d ths
        {DEC_OR_M, dec_or_m},
2409 8170028d ths
        {DEC_MOVE_RM, dec_move_rm},
2410 8170028d ths
        {DEC_TEST_M, dec_test_m},
2411 8170028d ths
        {DEC_MOVE_MR, dec_move_mr},
2412 8170028d ths
2413 8170028d ths
        {{0, 0}, dec_null}
2414 8170028d ths
};
2415 8170028d ths
2416 8170028d ths
static inline unsigned int
2417 8170028d ths
cris_decoder(DisasContext *dc)
2418 8170028d ths
{
2419 8170028d ths
        unsigned int insn_len = 2;
2420 8170028d ths
        uint32_t tmp;
2421 8170028d ths
        int i;
2422 8170028d ths
2423 8170028d ths
        /* Load a halfword onto the instruction register.  */
2424 8170028d ths
        tmp = ldl_code(dc->pc);
2425 8170028d ths
        dc->ir = tmp & 0xffff;
2426 8170028d ths
2427 8170028d ths
        /* Now decode it.  */
2428 8170028d ths
        dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
2429 8170028d ths
        dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
2430 8170028d ths
        dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
2431 8170028d ths
        dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
2432 8170028d ths
        dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
2433 8170028d ths
        dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
2434 8170028d ths
2435 8170028d ths
        /* Large switch for all insns.  */
2436 8170028d ths
        for (i = 0; i < sizeof decinfo / sizeof decinfo[0]; i++) {
2437 8170028d ths
                if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
2438 8170028d ths
                {
2439 8170028d ths
                        insn_len = decinfo[i].dec(dc);
2440 8170028d ths
                        break;
2441 8170028d ths
                }
2442 8170028d ths
        }
2443 8170028d ths
2444 8170028d ths
        return insn_len;
2445 8170028d ths
}
2446 8170028d ths
2447 8170028d ths
static void check_breakpoint(CPUState *env, DisasContext *dc)
2448 8170028d ths
{
2449 8170028d ths
        int j;
2450 8170028d ths
        if (env->nb_breakpoints > 0) {
2451 8170028d ths
                for(j = 0; j < env->nb_breakpoints; j++) {
2452 8170028d ths
                        if (env->breakpoints[j] == dc->pc) {
2453 8170028d ths
                                cris_evaluate_flags (dc);
2454 05ba7d5f edgar_igl
                                tcg_gen_movi_tl(cpu_T[0], dc->pc);
2455 3157a0a9 edgar_igl
                                t_gen_mov_env_TN(pc, cpu_T[0]);
2456 8170028d ths
                                gen_op_debug();
2457 8170028d ths
                                dc->is_jmp = DISAS_UPDATE;
2458 8170028d ths
                        }
2459 8170028d ths
                }
2460 8170028d ths
        }
2461 8170028d ths
}
2462 8170028d ths
2463 8170028d ths
/* generate intermediate code for basic block 'tb'.  */
2464 8170028d ths
struct DisasContext ctx;
2465 8170028d ths
static int
2466 8170028d ths
gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2467 8170028d ths
                               int search_pc)
2468 8170028d ths
{
2469 8170028d ths
        uint16_t *gen_opc_end;
2470 8170028d ths
           uint32_t pc_start;
2471 8170028d ths
        unsigned int insn_len;
2472 8170028d ths
        int j, lj;
2473 8170028d ths
        struct DisasContext *dc = &ctx;
2474 8170028d ths
        uint32_t next_page_start;
2475 8170028d ths
2476 a825e703 edgar_igl
        if (!logfile)
2477 a825e703 edgar_igl
                logfile = stderr;
2478 a825e703 edgar_igl
2479 8170028d ths
        pc_start = tb->pc;
2480 8170028d ths
        dc->env = env;
2481 8170028d ths
        dc->tb = tb;
2482 8170028d ths
2483 8170028d ths
        gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2484 8170028d ths
2485 8170028d ths
        dc->is_jmp = DISAS_NEXT;
2486 8170028d ths
        dc->pc = pc_start;
2487 8170028d ths
        dc->singlestep_enabled = env->singlestep_enabled;
2488 8170028d ths
        dc->flagx_live = 0;
2489 8170028d ths
        dc->flags_x = 0;
2490 3157a0a9 edgar_igl
2491 8170028d ths
        next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
2492 8170028d ths
        lj = -1;
2493 8170028d ths
        do
2494 8170028d ths
        {
2495 8170028d ths
                check_breakpoint(env, dc);
2496 4f400ab5 edgar_igl
                if (dc->is_jmp == DISAS_JUMP
2497 4f400ab5 edgar_igl
                    || dc->is_jmp == DISAS_SWI)
2498 8170028d ths
                        goto done;
2499 8170028d ths
2500 8170028d ths
                if (search_pc) {
2501 8170028d ths
                        j = gen_opc_ptr - gen_opc_buf;
2502 8170028d ths
                        if (lj < j) {
2503 8170028d ths
                                lj++;
2504 8170028d ths
                                while (lj < j)
2505 8170028d ths
                                        gen_opc_instr_start[lj++] = 0;
2506 8170028d ths
                        }
2507 8170028d ths
                        gen_opc_pc[lj] = dc->pc;
2508 8170028d ths
                        gen_opc_instr_start[lj] = 1;
2509 8170028d ths
                }
2510 8170028d ths
2511 8170028d ths
                insn_len = cris_decoder(dc);
2512 8170028d ths
                STATS(gen_op_exec_insn());
2513 8170028d ths
                dc->pc += insn_len;
2514 a825e703 edgar_igl
                cris_clear_x_flag(dc);
2515 8170028d ths
2516 8170028d ths
                /* Check for delayed branches here. If we do it before
2517 8170028d ths
                   actually genereating any host code, the simulator will just
2518 8170028d ths
                   loop doing nothing for on this program location.  */
2519 8170028d ths
                if (dc->delayed_branch) {
2520 8170028d ths
                        dc->delayed_branch--;
2521 8170028d ths
                        if (dc->delayed_branch == 0)
2522 8170028d ths
                        {
2523 8170028d ths
                                if (dc->bcc == CC_A) {
2524 57fec1fe bellard
                                        gen_op_jmp1 ();
2525 8170028d ths
                                        dc->is_jmp = DISAS_UPDATE;
2526 8170028d ths
                                }
2527 8170028d ths
                                else {
2528 8170028d ths
                                        /* Conditional jmp.  */
2529 8170028d ths
                                        gen_op_cc_jmp (dc->delayed_pc, dc->pc);
2530 8170028d ths
                                        dc->is_jmp = DISAS_UPDATE;
2531 8170028d ths
                                }
2532 8170028d ths
                        }
2533 8170028d ths
                }
2534 8170028d ths
2535 8170028d ths
                if (env->singlestep_enabled)
2536 8170028d ths
                        break;
2537 8170028d ths
        } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end
2538 8170028d ths
                 && dc->pc < next_page_start);
2539 8170028d ths
2540 8170028d ths
        if (!dc->is_jmp) {
2541 3157a0a9 edgar_igl
                tcg_gen_movi_tl(cpu_T[0], dc->pc);
2542 3157a0a9 edgar_igl
                t_gen_mov_env_TN(pc, cpu_T[0]);
2543 8170028d ths
        }
2544 8170028d ths
2545 8170028d ths
        cris_evaluate_flags (dc);
2546 8170028d ths
  done:
2547 8170028d ths
        if (__builtin_expect(env->singlestep_enabled, 0)) {
2548 8170028d ths
                gen_op_debug();
2549 8170028d ths
        } else {
2550 8170028d ths
                switch(dc->is_jmp) {
2551 8170028d ths
                        case DISAS_NEXT:
2552 8170028d ths
                                gen_goto_tb(dc, 1, dc->pc);
2553 8170028d ths
                                break;
2554 8170028d ths
                        default:
2555 8170028d ths
                        case DISAS_JUMP:
2556 8170028d ths
                        case DISAS_UPDATE:
2557 8170028d ths
                                /* indicate that the hash table must be used
2558 8170028d ths
                                   to find the next TB */
2559 57fec1fe bellard
                                tcg_gen_exit_tb(0);
2560 8170028d ths
                                break;
2561 4f400ab5 edgar_igl
                        case DISAS_SWI:
2562 8170028d ths
                        case DISAS_TB_JUMP:
2563 8170028d ths
                                /* nothing more to generate */
2564 8170028d ths
                                break;
2565 8170028d ths
                }
2566 8170028d ths
        }
2567 8170028d ths
        *gen_opc_ptr = INDEX_op_end;
2568 8170028d ths
        if (search_pc) {
2569 8170028d ths
                j = gen_opc_ptr - gen_opc_buf;
2570 8170028d ths
                lj++;
2571 8170028d ths
                while (lj <= j)
2572 8170028d ths
                        gen_opc_instr_start[lj++] = 0;
2573 8170028d ths
        } else {
2574 8170028d ths
                tb->size = dc->pc - pc_start;
2575 8170028d ths
        }
2576 8170028d ths
2577 8170028d ths
#ifdef DEBUG_DISAS
2578 8170028d ths
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2579 8170028d ths
                fprintf(logfile, "--------------\n");
2580 8170028d ths
                fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2581 8170028d ths
                target_disas(logfile, pc_start, dc->pc + 4 - pc_start, 0);
2582 8170028d ths
                fprintf(logfile, "\n");
2583 8170028d ths
        }
2584 8170028d ths
#endif
2585 8170028d ths
        return 0;
2586 8170028d ths
}
2587 8170028d ths
2588 8170028d ths
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
2589 8170028d ths
{
2590 8170028d ths
    return gen_intermediate_code_internal(env, tb, 0);
2591 8170028d ths
}
2592 8170028d ths
2593 8170028d ths
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2594 8170028d ths
{
2595 8170028d ths
    return gen_intermediate_code_internal(env, tb, 1);
2596 8170028d ths
}
2597 8170028d ths
2598 8170028d ths
void cpu_dump_state (CPUState *env, FILE *f,
2599 8170028d ths
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
2600 8170028d ths
                     int flags)
2601 8170028d ths
{
2602 8170028d ths
        int i;
2603 8170028d ths
        uint32_t srs;
2604 8170028d ths
2605 8170028d ths
        if (!env || !f)
2606 8170028d ths
                return;
2607 8170028d ths
2608 8170028d ths
        cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
2609 8170028d ths
                    "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n"
2610 8170028d ths
                    "debug=%x %x %x\n",
2611 9004627f edgar_igl
                    env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
2612 8170028d ths
                    env->cc_op,
2613 8170028d ths
                    env->cc_src, env->cc_dest, env->cc_result, env->cc_mask,
2614 8170028d ths
                    env->debug1, env->debug2, env->debug3);
2615 8170028d ths
2616 8170028d ths
        for (i = 0; i < 16; i++) {
2617 8170028d ths
                cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
2618 8170028d ths
                if ((i + 1) % 4 == 0)
2619 8170028d ths
                        cpu_fprintf(f, "\n");
2620 8170028d ths
        }
2621 8170028d ths
        cpu_fprintf(f, "\nspecial regs:\n");
2622 8170028d ths
        for (i = 0; i < 16; i++) {
2623 8170028d ths
                cpu_fprintf(f, "p%2.2d=%8.8x ", i, env->pregs[i]);
2624 8170028d ths
                if ((i + 1) % 4 == 0)
2625 8170028d ths
                        cpu_fprintf(f, "\n");
2626 8170028d ths
        }
2627 9004627f edgar_igl
        srs = env->pregs[PR_SRS];
2628 8170028d ths
        cpu_fprintf(f, "\nsupport function regs bank %d:\n", srs);
2629 8170028d ths
        if (srs < 256) {
2630 8170028d ths
                for (i = 0; i < 16; i++) {
2631 8170028d ths
                        cpu_fprintf(f, "s%2.2d=%8.8x ",
2632 8170028d ths
                                    i, env->sregs[srs][i]);
2633 8170028d ths
                        if ((i + 1) % 4 == 0)
2634 8170028d ths
                                cpu_fprintf(f, "\n");
2635 8170028d ths
                }
2636 8170028d ths
        }
2637 8170028d ths
        cpu_fprintf(f, "\n\n");
2638 8170028d ths
2639 8170028d ths
}
2640 8170028d ths
2641 05ba7d5f edgar_igl
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
2642 05ba7d5f edgar_igl
{
2643 05ba7d5f edgar_igl
}
2644 05ba7d5f edgar_igl
2645 aaed909a bellard
CPUCRISState *cpu_cris_init (const char *cpu_model)
2646 8170028d ths
{
2647 8170028d ths
        CPUCRISState *env;
2648 a825e703 edgar_igl
        int i;
2649 8170028d ths
2650 8170028d ths
        env = qemu_mallocz(sizeof(CPUCRISState));
2651 8170028d ths
        if (!env)
2652 8170028d ths
                return NULL;
2653 8170028d ths
        cpu_exec_init(env);
2654 05ba7d5f edgar_igl
2655 05ba7d5f edgar_igl
        tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
2656 05ba7d5f edgar_igl
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
2657 05ba7d5f edgar_igl
#if TARGET_LONG_BITS > HOST_LONG_BITS
2658 05ba7d5f edgar_igl
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, 
2659 05ba7d5f edgar_igl
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
2660 05ba7d5f edgar_igl
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
2661 05ba7d5f edgar_igl
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
2662 05ba7d5f edgar_igl
#else
2663 05ba7d5f edgar_igl
        cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
2664 05ba7d5f edgar_igl
        cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
2665 05ba7d5f edgar_igl
#endif
2666 05ba7d5f edgar_igl
2667 a825e703 edgar_igl
        cc_src = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2668 a825e703 edgar_igl
                                    offsetof(CPUState, cc_src), "cc_src");
2669 a825e703 edgar_igl
        cc_dest = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2670 a825e703 edgar_igl
                                     offsetof(CPUState, cc_dest), 
2671 a825e703 edgar_igl
                                     "cc_dest");
2672 a825e703 edgar_igl
        cc_result = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2673 a825e703 edgar_igl
                                       offsetof(CPUState, cc_result), 
2674 a825e703 edgar_igl
                                       "cc_result");
2675 a825e703 edgar_igl
        cc_op = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2676 a825e703 edgar_igl
                                   offsetof(CPUState, cc_op), "cc_op");
2677 a825e703 edgar_igl
        cc_size = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2678 a825e703 edgar_igl
                                     offsetof(CPUState, cc_size), 
2679 a825e703 edgar_igl
                                     "cc_size");
2680 a825e703 edgar_igl
        cc_mask = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2681 a825e703 edgar_igl
                                     offsetof(CPUState, cc_mask),
2682 a825e703 edgar_igl
                                     "cc_mask");
2683 a825e703 edgar_igl
2684 a825e703 edgar_igl
        for (i = 0; i < 16; i++) {
2685 a825e703 edgar_igl
                cpu_R[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2686 a825e703 edgar_igl
                                              offsetof(CPUState, regs[i]), 
2687 a825e703 edgar_igl
                                              regnames[i]);
2688 a825e703 edgar_igl
        }
2689 a825e703 edgar_igl
        for (i = 0; i < 16; i++) {
2690 a825e703 edgar_igl
                cpu_PR[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2691 a825e703 edgar_igl
                                               offsetof(CPUState, pregs[i]), 
2692 a825e703 edgar_igl
                                               pregnames[i]);
2693 a825e703 edgar_igl
        }
2694 a825e703 edgar_igl
2695 8170028d ths
        cpu_reset(env);
2696 8170028d ths
        return env;
2697 8170028d ths
}
2698 8170028d ths
2699 8170028d ths
void cpu_reset (CPUCRISState *env)
2700 8170028d ths
{
2701 8170028d ths
        memset(env, 0, offsetof(CPUCRISState, breakpoints));
2702 8170028d ths
        tlb_flush(env, 1);
2703 8170028d ths
}