Statistics
| Branch: | Revision:

root / target-cris / translate.c @ 5d12aa63

History | View | Annotate | Download (93.1 kB)

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