Statistics
| Branch: | Revision:

root / target-cris / translate.c @ 0d84be5b

History | View | Annotate | Download (82.1 kB)

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