Statistics
| Branch: | Revision:

root / target-cris / translate.c @ d12d51d5

History | View | Annotate | Download (80 kB)

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