Statistics
| Branch: | Revision:

root / target-cris / translate.c @ 7fd2592d

History | View | Annotate | Download (93.6 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 4b4a72e5 Stefan Weil
                tcg_gen_exit_tb((tcg_target_long)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 7b5eff4d Evgeny Voevodin
    tcg_gen_qemu_ld64(dst, addr, mem_index);
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 7b5eff4d Evgeny Voevodin
    if (size == 1) {
1151 7b5eff4d Evgeny Voevodin
        if (sign) {
1152 7b5eff4d Evgeny Voevodin
            tcg_gen_qemu_ld8s(dst, addr, mem_index);
1153 7b5eff4d Evgeny Voevodin
        } else {
1154 7b5eff4d Evgeny Voevodin
            tcg_gen_qemu_ld8u(dst, addr, mem_index);
1155 7b5eff4d Evgeny Voevodin
        }
1156 7b5eff4d Evgeny Voevodin
    } else if (size == 2) {
1157 7b5eff4d Evgeny Voevodin
        if (sign) {
1158 7b5eff4d Evgeny Voevodin
            tcg_gen_qemu_ld16s(dst, addr, mem_index);
1159 7b5eff4d Evgeny Voevodin
        } else {
1160 7b5eff4d Evgeny Voevodin
            tcg_gen_qemu_ld16u(dst, addr, mem_index);
1161 7b5eff4d Evgeny Voevodin
        }
1162 7b5eff4d Evgeny Voevodin
    } else if (size == 4) {
1163 7b5eff4d Evgeny Voevodin
        tcg_gen_qemu_ld32u(dst, addr, mem_index);
1164 7b5eff4d Evgeny Voevodin
    } else {
1165 7b5eff4d Evgeny Voevodin
        abort();
1166 7b5eff4d Evgeny Voevodin
    }
1167 8170028d ths
}
1168 8170028d ths
1169 9b32fbf8 edgar_igl
static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
1170 7b5eff4d Evgeny Voevodin
               unsigned int size)
1171 8170028d ths
{
1172 7b5eff4d Evgeny Voevodin
    int mem_index = cpu_mmu_index(dc->env);
1173 b41f7df0 edgar_igl
1174 7b5eff4d Evgeny Voevodin
    /* If we get a fault on a delayslot we must keep the jmp state in
1175 7b5eff4d Evgeny Voevodin
       the cpu-state to be able to re-execute the jmp.  */
1176 7b5eff4d Evgeny Voevodin
    if (dc->delayed_branch == 1) {
1177 7b5eff4d Evgeny Voevodin
        cris_store_direct_jmp(dc);
1178 7b5eff4d Evgeny Voevodin
    }
1179 2a44f7f1 edgar_igl
1180 2a44f7f1 edgar_igl
1181 7b5eff4d Evgeny Voevodin
    /* Conditional writes. We only support the kind were X and P are known
1182 7b5eff4d Evgeny Voevodin
       at translation time.  */
1183 7b5eff4d Evgeny Voevodin
    if (dc->flagx_known && dc->flags_x && (dc->tb_flags & P_FLAG)) {
1184 7b5eff4d Evgeny Voevodin
        dc->postinc = 0;
1185 7b5eff4d Evgeny Voevodin
        cris_evaluate_flags(dc);
1186 7b5eff4d Evgeny Voevodin
        tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
1187 7b5eff4d Evgeny Voevodin
        return;
1188 7b5eff4d Evgeny Voevodin
    }
1189 2a44f7f1 edgar_igl
1190 7b5eff4d Evgeny Voevodin
    if (size == 1) {
1191 7b5eff4d Evgeny Voevodin
        tcg_gen_qemu_st8(val, addr, mem_index);
1192 7b5eff4d Evgeny Voevodin
    } else if (size == 2) {
1193 7b5eff4d Evgeny Voevodin
        tcg_gen_qemu_st16(val, addr, mem_index);
1194 7b5eff4d Evgeny Voevodin
    } else {
1195 7b5eff4d Evgeny Voevodin
        tcg_gen_qemu_st32(val, addr, mem_index);
1196 7b5eff4d Evgeny Voevodin
    }
1197 2a44f7f1 edgar_igl
1198 7b5eff4d Evgeny Voevodin
    if (dc->flagx_known && dc->flags_x) {
1199 7b5eff4d Evgeny Voevodin
        cris_evaluate_flags(dc);
1200 7b5eff4d Evgeny Voevodin
        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
1201 7b5eff4d Evgeny Voevodin
    }
1202 8170028d ths
}
1203 8170028d ths
1204 05ba7d5f edgar_igl
static inline void t_gen_sext(TCGv d, TCGv s, int size)
1205 8170028d ths
{
1206 7b5eff4d Evgeny Voevodin
    if (size == 1) {
1207 7b5eff4d Evgeny Voevodin
        tcg_gen_ext8s_i32(d, s);
1208 7b5eff4d Evgeny Voevodin
    } else if (size == 2) {
1209 7b5eff4d Evgeny Voevodin
        tcg_gen_ext16s_i32(d, s);
1210 7b5eff4d Evgeny Voevodin
    } else if (!TCGV_EQUAL(d, s)) {
1211 7b5eff4d Evgeny Voevodin
        tcg_gen_mov_tl(d, s);
1212 7b5eff4d Evgeny Voevodin
    }
1213 8170028d ths
}
1214 8170028d ths
1215 05ba7d5f edgar_igl
static inline void t_gen_zext(TCGv d, TCGv s, int size)
1216 8170028d ths
{
1217 7b5eff4d Evgeny Voevodin
    if (size == 1) {
1218 7b5eff4d Evgeny Voevodin
        tcg_gen_ext8u_i32(d, s);
1219 7b5eff4d Evgeny Voevodin
    } else if (size == 2) {
1220 7b5eff4d Evgeny Voevodin
        tcg_gen_ext16u_i32(d, s);
1221 7b5eff4d Evgeny Voevodin
    } else if (!TCGV_EQUAL(d, s)) {
1222 7b5eff4d Evgeny Voevodin
        tcg_gen_mov_tl(d, s);
1223 7b5eff4d Evgeny Voevodin
    }
1224 8170028d ths
}
1225 8170028d ths
1226 8170028d ths
#if DISAS_CRIS
1227 8170028d ths
static char memsize_char(int size)
1228 8170028d ths
{
1229 7b5eff4d Evgeny Voevodin
    switch (size) {
1230 7b5eff4d Evgeny Voevodin
    case 1: return 'b';  break;
1231 7b5eff4d Evgeny Voevodin
    case 2: return 'w';  break;
1232 7b5eff4d Evgeny Voevodin
    case 4: return 'd';  break;
1233 7b5eff4d Evgeny Voevodin
    default:
1234 7b5eff4d Evgeny Voevodin
        return 'x';
1235 7b5eff4d Evgeny Voevodin
        break;
1236 7b5eff4d Evgeny Voevodin
    }
1237 8170028d ths
}
1238 8170028d ths
#endif
1239 8170028d ths
1240 30abcfc7 edgar_igl
static inline unsigned int memsize_z(DisasContext *dc)
1241 8170028d ths
{
1242 7b5eff4d Evgeny Voevodin
    return dc->zsize + 1;
1243 8170028d ths
}
1244 8170028d ths
1245 30abcfc7 edgar_igl
static inline unsigned int memsize_zz(DisasContext *dc)
1246 8170028d ths
{
1247 7b5eff4d Evgeny Voevodin
    switch (dc->zzsize) {
1248 7b5eff4d Evgeny Voevodin
    case 0: return 1;
1249 7b5eff4d Evgeny Voevodin
    case 1: return 2;
1250 7b5eff4d Evgeny Voevodin
    default:
1251 7b5eff4d Evgeny Voevodin
        return 4;
1252 7b5eff4d Evgeny Voevodin
    }
1253 8170028d ths
}
1254 8170028d ths
1255 c7d05695 edgar_igl
static inline void do_postinc (DisasContext *dc, int size)
1256 8170028d ths
{
1257 7b5eff4d Evgeny Voevodin
    if (dc->postinc) {
1258 7b5eff4d Evgeny Voevodin
        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
1259 7b5eff4d Evgeny Voevodin
    }
1260 8170028d ths
}
1261 8170028d ths
1262 30abcfc7 edgar_igl
static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
1263 7b5eff4d Evgeny Voevodin
                   int size, int s_ext, TCGv dst)
1264 8170028d ths
{
1265 7b5eff4d Evgeny Voevodin
    if (s_ext) {
1266 7b5eff4d Evgeny Voevodin
        t_gen_sext(dst, cpu_R[rs], size);
1267 7b5eff4d Evgeny Voevodin
    } else {
1268 7b5eff4d Evgeny Voevodin
        t_gen_zext(dst, cpu_R[rs], size);
1269 7b5eff4d Evgeny Voevodin
    }
1270 8170028d ths
}
1271 8170028d ths
1272 8170028d ths
/* Prepare T0 and T1 for a register alu operation.
1273 8170028d ths
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1274 8170028d ths
   needed.  */
1275 8170028d ths
static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
1276 7b5eff4d Evgeny Voevodin
              int size, int s_ext, TCGv dst, TCGv src)
1277 8170028d ths
{
1278 7b5eff4d Evgeny Voevodin
    dec_prep_move_r(dc, rs, rd, size, s_ext, src);
1279 8170028d ths
1280 7b5eff4d Evgeny Voevodin
    if (s_ext) {
1281 7b5eff4d Evgeny Voevodin
        t_gen_sext(dst, cpu_R[rd], size);
1282 7b5eff4d Evgeny Voevodin
    } else {
1283 7b5eff4d Evgeny Voevodin
        t_gen_zext(dst, cpu_R[rd], size);
1284 7b5eff4d Evgeny Voevodin
    }
1285 8170028d ths
}
1286 8170028d ths
1287 cf7e0c80 Aurelien Jarno
static int dec_prep_move_m(CPUCRISState *env, DisasContext *dc,
1288 cf7e0c80 Aurelien Jarno
                           int s_ext, int memsize, TCGv dst)
1289 8170028d ths
{
1290 7b5eff4d Evgeny Voevodin
    unsigned int rs;
1291 7b5eff4d Evgeny Voevodin
    uint32_t imm;
1292 7b5eff4d Evgeny Voevodin
    int is_imm;
1293 7b5eff4d Evgeny Voevodin
    int insn_len = 2;
1294 7b5eff4d Evgeny Voevodin
1295 7b5eff4d Evgeny Voevodin
    rs = dc->op1;
1296 7b5eff4d Evgeny Voevodin
    is_imm = rs == 15 && dc->postinc;
1297 7b5eff4d Evgeny Voevodin
1298 7b5eff4d Evgeny Voevodin
    /* Load [$rs] onto T1.  */
1299 7b5eff4d Evgeny Voevodin
    if (is_imm) {
1300 7b5eff4d Evgeny Voevodin
        insn_len = 2 + memsize;
1301 7b5eff4d Evgeny Voevodin
        if (memsize == 1) {
1302 7b5eff4d Evgeny Voevodin
            insn_len++;
1303 7b5eff4d Evgeny Voevodin
        }
1304 7b5eff4d Evgeny Voevodin
1305 7b5eff4d Evgeny Voevodin
        imm = cris_fetch(env, dc, dc->pc + 2, memsize, s_ext);
1306 7b5eff4d Evgeny Voevodin
        tcg_gen_movi_tl(dst, imm);
1307 7b5eff4d Evgeny Voevodin
        dc->postinc = 0;
1308 7b5eff4d Evgeny Voevodin
    } else {
1309 7b5eff4d Evgeny Voevodin
        cris_flush_cc_state(dc);
1310 7b5eff4d Evgeny Voevodin
        gen_load(dc, dst, cpu_R[rs], memsize, 0);
1311 7b5eff4d Evgeny Voevodin
        if (s_ext) {
1312 7b5eff4d Evgeny Voevodin
            t_gen_sext(dst, dst, memsize);
1313 7b5eff4d Evgeny Voevodin
        } else {
1314 7b5eff4d Evgeny Voevodin
            t_gen_zext(dst, dst, memsize);
1315 7b5eff4d Evgeny Voevodin
        }
1316 7b5eff4d Evgeny Voevodin
    }
1317 7b5eff4d Evgeny Voevodin
    return insn_len;
1318 cf1d97f0 edgar_igl
}
1319 cf1d97f0 edgar_igl
1320 cf1d97f0 edgar_igl
/* Prepare T0 and T1 for a memory + alu operation.
1321 cf1d97f0 edgar_igl
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1322 cf1d97f0 edgar_igl
   needed.  */
1323 cf7e0c80 Aurelien Jarno
static int dec_prep_alu_m(CPUCRISState *env, DisasContext *dc,
1324 cf7e0c80 Aurelien Jarno
                          int s_ext, int memsize, TCGv dst, TCGv src)
1325 cf1d97f0 edgar_igl
{
1326 7b5eff4d Evgeny Voevodin
    int insn_len;
1327 cf1d97f0 edgar_igl
1328 7b5eff4d Evgeny Voevodin
    insn_len = dec_prep_move_m(env, dc, s_ext, memsize, src);
1329 7b5eff4d Evgeny Voevodin
    tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
1330 7b5eff4d Evgeny Voevodin
    return insn_len;
1331 8170028d ths
}
1332 8170028d ths
1333 8170028d ths
#if DISAS_CRIS
1334 8170028d ths
static const char *cc_name(int cc)
1335 8170028d ths
{
1336 7b5eff4d Evgeny Voevodin
    static const char *cc_names[16] = {
1337 7b5eff4d Evgeny Voevodin
        "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1338 7b5eff4d Evgeny Voevodin
        "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1339 7b5eff4d Evgeny Voevodin
    };
1340 7b5eff4d Evgeny Voevodin
    assert(cc < 16);
1341 7b5eff4d Evgeny Voevodin
    return cc_names[cc];
1342 8170028d ths
}
1343 8170028d ths
#endif
1344 8170028d ths
1345 b41f7df0 edgar_igl
/* Start of insn decoders.  */
1346 b41f7df0 edgar_igl
1347 cf7e0c80 Aurelien Jarno
static int dec_bccq(CPUCRISState *env, DisasContext *dc)
1348 8170028d ths
{
1349 7b5eff4d Evgeny Voevodin
    int32_t offset;
1350 7b5eff4d Evgeny Voevodin
    int sign;
1351 7b5eff4d Evgeny Voevodin
    uint32_t cond = dc->op2;
1352 8170028d ths
1353 7b5eff4d Evgeny Voevodin
    offset = EXTRACT_FIELD(dc->ir, 1, 7);
1354 7b5eff4d Evgeny Voevodin
    sign = EXTRACT_FIELD(dc->ir, 0, 0);
1355 8170028d ths
1356 7b5eff4d Evgeny Voevodin
    offset *= 2;
1357 7b5eff4d Evgeny Voevodin
    offset |= sign << 8;
1358 7b5eff4d Evgeny Voevodin
    offset = sign_extend(offset, 8);
1359 8170028d ths
1360 7b5eff4d Evgeny Voevodin
    LOG_DIS("b%s %x\n", cc_name(cond), dc->pc + offset);
1361 2a44f7f1 edgar_igl
1362 7b5eff4d Evgeny Voevodin
    /* op2 holds the condition-code.  */
1363 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
1364 7b5eff4d Evgeny Voevodin
    cris_prepare_cc_branch(dc, offset, cond);
1365 7b5eff4d Evgeny Voevodin
    return 2;
1366 8170028d ths
}
1367 cf7e0c80 Aurelien Jarno
static int dec_addoq(CPUCRISState *env, DisasContext *dc)
1368 8170028d ths
{
1369 7b5eff4d Evgeny Voevodin
    int32_t imm;
1370 8170028d ths
1371 7b5eff4d Evgeny Voevodin
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1372 7b5eff4d Evgeny Voevodin
    imm = sign_extend(dc->op1, 7);
1373 8170028d ths
1374 7b5eff4d Evgeny Voevodin
    LOG_DIS("addoq %d, $r%u\n", imm, dc->op2);
1375 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
1376 7b5eff4d Evgeny Voevodin
    /* Fetch register operand,  */
1377 7b5eff4d Evgeny Voevodin
    tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
1378 fb48f71b edgar_igl
1379 7b5eff4d Evgeny Voevodin
    return 2;
1380 8170028d ths
}
1381 cf7e0c80 Aurelien Jarno
static int dec_addq(CPUCRISState *env, DisasContext *dc)
1382 8170028d ths
{
1383 7b5eff4d Evgeny Voevodin
    LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
1384 8170028d ths
1385 7b5eff4d Evgeny Voevodin
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1386 8170028d ths
1387 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
1388 30abcfc7 edgar_igl
1389 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_ADD,
1390 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1391 7b5eff4d Evgeny Voevodin
    return 2;
1392 8170028d ths
}
1393 cf7e0c80 Aurelien Jarno
static int dec_moveq(CPUCRISState *env, DisasContext *dc)
1394 8170028d ths
{
1395 7b5eff4d Evgeny Voevodin
    uint32_t imm;
1396 8170028d ths
1397 7b5eff4d Evgeny Voevodin
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1398 7b5eff4d Evgeny Voevodin
    imm = sign_extend(dc->op1, 5);
1399 7b5eff4d Evgeny Voevodin
    LOG_DIS("moveq %d, $r%u\n", imm, dc->op2);
1400 8170028d ths
1401 7b5eff4d Evgeny Voevodin
    tcg_gen_movi_tl(cpu_R[dc->op2], imm);
1402 7b5eff4d Evgeny Voevodin
    return 2;
1403 8170028d ths
}
1404 cf7e0c80 Aurelien Jarno
static int dec_subq(CPUCRISState *env, DisasContext *dc)
1405 8170028d ths
{
1406 7b5eff4d Evgeny Voevodin
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1407 8170028d ths
1408 7b5eff4d Evgeny Voevodin
    LOG_DIS("subq %u, $r%u\n", dc->op1, dc->op2);
1409 8170028d ths
1410 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
1411 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_SUB,
1412 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1413 7b5eff4d Evgeny Voevodin
    return 2;
1414 8170028d ths
}
1415 cf7e0c80 Aurelien Jarno
static int dec_cmpq(CPUCRISState *env, DisasContext *dc)
1416 8170028d ths
{
1417 7b5eff4d Evgeny Voevodin
    uint32_t imm;
1418 7b5eff4d Evgeny Voevodin
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1419 7b5eff4d Evgeny Voevodin
    imm = sign_extend(dc->op1, 5);
1420 8170028d ths
1421 7b5eff4d Evgeny Voevodin
    LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2);
1422 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
1423 30abcfc7 edgar_igl
1424 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_CMP,
1425 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1426 7b5eff4d Evgeny Voevodin
    return 2;
1427 8170028d ths
}
1428 cf7e0c80 Aurelien Jarno
static int dec_andq(CPUCRISState *env, DisasContext *dc)
1429 8170028d ths
{
1430 7b5eff4d Evgeny Voevodin
    uint32_t imm;
1431 7b5eff4d Evgeny Voevodin
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1432 7b5eff4d Evgeny Voevodin
    imm = sign_extend(dc->op1, 5);
1433 8170028d ths
1434 7b5eff4d Evgeny Voevodin
    LOG_DIS("andq %d, $r%d\n", imm, dc->op2);
1435 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1436 30abcfc7 edgar_igl
1437 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_AND,
1438 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1439 7b5eff4d Evgeny Voevodin
    return 2;
1440 8170028d ths
}
1441 cf7e0c80 Aurelien Jarno
static int dec_orq(CPUCRISState *env, DisasContext *dc)
1442 8170028d ths
{
1443 7b5eff4d Evgeny Voevodin
    uint32_t imm;
1444 7b5eff4d Evgeny Voevodin
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1445 7b5eff4d Evgeny Voevodin
    imm = sign_extend(dc->op1, 5);
1446 7b5eff4d Evgeny Voevodin
    LOG_DIS("orq %d, $r%d\n", imm, dc->op2);
1447 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1448 30abcfc7 edgar_igl
1449 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_OR,
1450 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1451 7b5eff4d Evgeny Voevodin
    return 2;
1452 8170028d ths
}
1453 cf7e0c80 Aurelien Jarno
static int dec_btstq(CPUCRISState *env, DisasContext *dc)
1454 8170028d ths
{
1455 7b5eff4d Evgeny Voevodin
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1456 7b5eff4d Evgeny Voevodin
    LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);
1457 17ac9754 edgar_igl
1458 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1459 7b5eff4d Evgeny Voevodin
    cris_evaluate_flags(dc);
1460 febc9920 Aurelien Jarno
        gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
1461 7b5eff4d Evgeny Voevodin
            tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
1462 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_MOVE,
1463 7b5eff4d Evgeny Voevodin
         cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1464 7b5eff4d Evgeny Voevodin
    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1465 7b5eff4d Evgeny Voevodin
    dc->flags_uptodate = 1;
1466 7b5eff4d Evgeny Voevodin
    return 2;
1467 8170028d ths
}
1468 cf7e0c80 Aurelien Jarno
static int dec_asrq(CPUCRISState *env, DisasContext *dc)
1469 8170028d ths
{
1470 7b5eff4d Evgeny Voevodin
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1471 7b5eff4d Evgeny Voevodin
    LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
1472 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1473 30abcfc7 edgar_igl
1474 7b5eff4d Evgeny Voevodin
    tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1475 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_MOVE,
1476 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2],
1477 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op2], 4);
1478 7b5eff4d Evgeny Voevodin
    return 2;
1479 8170028d ths
}
1480 cf7e0c80 Aurelien Jarno
static int dec_lslq(CPUCRISState *env, DisasContext *dc)
1481 8170028d ths
{
1482 7b5eff4d Evgeny Voevodin
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1483 7b5eff4d Evgeny Voevodin
    LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
1484 8170028d ths
1485 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1486 30abcfc7 edgar_igl
1487 7b5eff4d Evgeny Voevodin
    tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1488 2a44f7f1 edgar_igl
1489 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_MOVE,
1490 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2],
1491 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op2], 4);
1492 7b5eff4d Evgeny Voevodin
    return 2;
1493 8170028d ths
}
1494 cf7e0c80 Aurelien Jarno
static int dec_lsrq(CPUCRISState *env, DisasContext *dc)
1495 8170028d ths
{
1496 7b5eff4d Evgeny Voevodin
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1497 7b5eff4d Evgeny Voevodin
    LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
1498 8170028d ths
1499 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1500 30abcfc7 edgar_igl
1501 7b5eff4d Evgeny Voevodin
    tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1502 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_MOVE,
1503 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2],
1504 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op2], 4);
1505 7b5eff4d Evgeny Voevodin
    return 2;
1506 8170028d ths
}
1507 8170028d ths
1508 cf7e0c80 Aurelien Jarno
static int dec_move_r(CPUCRISState *env, DisasContext *dc)
1509 8170028d ths
{
1510 7b5eff4d Evgeny Voevodin
    int size = memsize_zz(dc);
1511 7b5eff4d Evgeny Voevodin
1512 7b5eff4d Evgeny Voevodin
    LOG_DIS("move.%c $r%u, $r%u\n",
1513 7b5eff4d Evgeny Voevodin
            memsize_char(size), dc->op1, dc->op2);
1514 7b5eff4d Evgeny Voevodin
1515 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1516 7b5eff4d Evgeny Voevodin
    if (size == 4) {
1517 7b5eff4d Evgeny Voevodin
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
1518 7b5eff4d Evgeny Voevodin
        cris_cc_mask(dc, CC_MASK_NZ);
1519 7b5eff4d Evgeny Voevodin
        cris_update_cc_op(dc, CC_OP_MOVE, 4);
1520 7b5eff4d Evgeny Voevodin
        cris_update_cc_x(dc);
1521 7b5eff4d Evgeny Voevodin
        cris_update_result(dc, cpu_R[dc->op2]);
1522 7b5eff4d Evgeny Voevodin
    } else {
1523 7b5eff4d Evgeny Voevodin
        TCGv t0;
1524 7b5eff4d Evgeny Voevodin
1525 7b5eff4d Evgeny Voevodin
        t0 = tcg_temp_new();
1526 7b5eff4d Evgeny Voevodin
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1527 7b5eff4d Evgeny Voevodin
        cris_alu(dc, CC_OP_MOVE,
1528 7b5eff4d Evgeny Voevodin
             cpu_R[dc->op2],
1529 7b5eff4d Evgeny Voevodin
             cpu_R[dc->op2], t0, size);
1530 7b5eff4d Evgeny Voevodin
        tcg_temp_free(t0);
1531 7b5eff4d Evgeny Voevodin
    }
1532 7b5eff4d Evgeny Voevodin
    return 2;
1533 8170028d ths
}
1534 8170028d ths
1535 cf7e0c80 Aurelien Jarno
static int dec_scc_r(CPUCRISState *env, DisasContext *dc)
1536 8170028d ths
{
1537 7b5eff4d Evgeny Voevodin
    int cond = dc->op2;
1538 8170028d ths
1539 7b5eff4d Evgeny Voevodin
    LOG_DIS("s%s $r%u\n",
1540 7b5eff4d Evgeny Voevodin
            cc_name(cond), dc->op1);
1541 8170028d ths
1542 7b5eff4d Evgeny Voevodin
    if (cond != CC_A) {
1543 7b5eff4d Evgeny Voevodin
        int l1;
1544 dceaf394 edgar_igl
1545 7b5eff4d Evgeny Voevodin
        gen_tst_cc(dc, cpu_R[dc->op1], cond);
1546 7b5eff4d Evgeny Voevodin
        l1 = gen_new_label();
1547 7b5eff4d Evgeny Voevodin
        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->op1], 0, l1);
1548 7b5eff4d Evgeny Voevodin
        tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1549 7b5eff4d Evgeny Voevodin
        gen_set_label(l1);
1550 7b5eff4d Evgeny Voevodin
    } else {
1551 7b5eff4d Evgeny Voevodin
        tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1552 7b5eff4d Evgeny Voevodin
    }
1553 8170028d ths
1554 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
1555 7b5eff4d Evgeny Voevodin
    return 2;
1556 8170028d ths
}
1557 8170028d ths
1558 fb48f71b edgar_igl
static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t)
1559 fb48f71b edgar_igl
{
1560 7b5eff4d Evgeny Voevodin
    if (size == 4) {
1561 7b5eff4d Evgeny Voevodin
        t[0] = cpu_R[dc->op2];
1562 7b5eff4d Evgeny Voevodin
        t[1] = cpu_R[dc->op1];
1563 7b5eff4d Evgeny Voevodin
    } else {
1564 7b5eff4d Evgeny Voevodin
        t[0] = tcg_temp_new();
1565 7b5eff4d Evgeny Voevodin
        t[1] = tcg_temp_new();
1566 7b5eff4d Evgeny Voevodin
    }
1567 fb48f71b edgar_igl
}
1568 fb48f71b edgar_igl
1569 fb48f71b edgar_igl
static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
1570 fb48f71b edgar_igl
{
1571 7b5eff4d Evgeny Voevodin
    if (size != 4) {
1572 7b5eff4d Evgeny Voevodin
        tcg_temp_free(t[0]);
1573 7b5eff4d Evgeny Voevodin
        tcg_temp_free(t[1]);
1574 7b5eff4d Evgeny Voevodin
    }
1575 fb48f71b edgar_igl
}
1576 fb48f71b edgar_igl
1577 cf7e0c80 Aurelien Jarno
static int dec_and_r(CPUCRISState *env, DisasContext *dc)
1578 8170028d ths
{
1579 7b5eff4d Evgeny Voevodin
    TCGv t[2];
1580 7b5eff4d Evgeny Voevodin
    int size = memsize_zz(dc);
1581 8170028d ths
1582 7b5eff4d Evgeny Voevodin
    LOG_DIS("and.%c $r%u, $r%u\n",
1583 7b5eff4d Evgeny Voevodin
            memsize_char(size), dc->op1, dc->op2);
1584 fb48f71b edgar_igl
1585 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1586 30abcfc7 edgar_igl
1587 7b5eff4d Evgeny Voevodin
    cris_alu_alloc_temps(dc, size, t);
1588 7b5eff4d Evgeny Voevodin
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1589 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
1590 7b5eff4d Evgeny Voevodin
    cris_alu_free_temps(dc, size, t);
1591 7b5eff4d Evgeny Voevodin
    return 2;
1592 8170028d ths
}
1593 8170028d ths
1594 cf7e0c80 Aurelien Jarno
static int dec_lz_r(CPUCRISState *env, DisasContext *dc)
1595 8170028d ths
{
1596 7b5eff4d Evgeny Voevodin
    TCGv t0;
1597 7b5eff4d Evgeny Voevodin
    LOG_DIS("lz $r%u, $r%u\n",
1598 7b5eff4d Evgeny Voevodin
            dc->op1, dc->op2);
1599 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1600 7b5eff4d Evgeny Voevodin
    t0 = tcg_temp_new();
1601 7b5eff4d Evgeny Voevodin
    dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
1602 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1603 7b5eff4d Evgeny Voevodin
    tcg_temp_free(t0);
1604 7b5eff4d Evgeny Voevodin
    return 2;
1605 8170028d ths
}
1606 8170028d ths
1607 cf7e0c80 Aurelien Jarno
static int dec_lsl_r(CPUCRISState *env, DisasContext *dc)
1608 8170028d ths
{
1609 7b5eff4d Evgeny Voevodin
    TCGv t[2];
1610 7b5eff4d Evgeny Voevodin
    int size = memsize_zz(dc);
1611 8170028d ths
1612 7b5eff4d Evgeny Voevodin
    LOG_DIS("lsl.%c $r%u, $r%u\n",
1613 7b5eff4d Evgeny Voevodin
            memsize_char(size), dc->op1, dc->op2);
1614 30abcfc7 edgar_igl
1615 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1616 7b5eff4d Evgeny Voevodin
    cris_alu_alloc_temps(dc, size, t);
1617 7b5eff4d Evgeny Voevodin
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1618 7b5eff4d Evgeny Voevodin
    tcg_gen_andi_tl(t[1], t[1], 63);
1619 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size);
1620 7b5eff4d Evgeny Voevodin
    cris_alu_alloc_temps(dc, size, t);
1621 7b5eff4d Evgeny Voevodin
    return 2;
1622 8170028d ths
}
1623 8170028d ths
1624 cf7e0c80 Aurelien Jarno
static int dec_lsr_r(CPUCRISState *env, DisasContext *dc)
1625 8170028d ths
{
1626 7b5eff4d Evgeny Voevodin
    TCGv t[2];
1627 7b5eff4d Evgeny Voevodin
    int size = memsize_zz(dc);
1628 8170028d ths
1629 7b5eff4d Evgeny Voevodin
    LOG_DIS("lsr.%c $r%u, $r%u\n",
1630 7b5eff4d Evgeny Voevodin
            memsize_char(size), dc->op1, dc->op2);
1631 30abcfc7 edgar_igl
1632 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1633 7b5eff4d Evgeny Voevodin
    cris_alu_alloc_temps(dc, size, t);
1634 7b5eff4d Evgeny Voevodin
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1635 7b5eff4d Evgeny Voevodin
    tcg_gen_andi_tl(t[1], t[1], 63);
1636 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size);
1637 7b5eff4d Evgeny Voevodin
    cris_alu_free_temps(dc, size, t);
1638 7b5eff4d Evgeny Voevodin
    return 2;
1639 8170028d ths
}
1640 8170028d ths
1641 cf7e0c80 Aurelien Jarno
static int dec_asr_r(CPUCRISState *env, DisasContext *dc)
1642 8170028d ths
{
1643 7b5eff4d Evgeny Voevodin
    TCGv t[2];
1644 7b5eff4d Evgeny Voevodin
    int size = memsize_zz(dc);
1645 8170028d ths
1646 7b5eff4d Evgeny Voevodin
    LOG_DIS("asr.%c $r%u, $r%u\n",
1647 7b5eff4d Evgeny Voevodin
            memsize_char(size), dc->op1, dc->op2);
1648 30abcfc7 edgar_igl
1649 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1650 7b5eff4d Evgeny Voevodin
    cris_alu_alloc_temps(dc, size, t);
1651 7b5eff4d Evgeny Voevodin
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1652 7b5eff4d Evgeny Voevodin
    tcg_gen_andi_tl(t[1], t[1], 63);
1653 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
1654 7b5eff4d Evgeny Voevodin
    cris_alu_free_temps(dc, size, t);
1655 7b5eff4d Evgeny Voevodin
    return 2;
1656 8170028d ths
}
1657 8170028d ths
1658 cf7e0c80 Aurelien Jarno
static int dec_muls_r(CPUCRISState *env, DisasContext *dc)
1659 8170028d ths
{
1660 7b5eff4d Evgeny Voevodin
    TCGv t[2];
1661 7b5eff4d Evgeny Voevodin
    int size = memsize_zz(dc);
1662 8170028d ths
1663 7b5eff4d Evgeny Voevodin
    LOG_DIS("muls.%c $r%u, $r%u\n",
1664 7b5eff4d Evgeny Voevodin
            memsize_char(size), dc->op1, dc->op2);
1665 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZV);
1666 7b5eff4d Evgeny Voevodin
    cris_alu_alloc_temps(dc, size, t);
1667 7b5eff4d Evgeny Voevodin
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1668 30abcfc7 edgar_igl
1669 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
1670 7b5eff4d Evgeny Voevodin
    cris_alu_free_temps(dc, size, t);
1671 7b5eff4d Evgeny Voevodin
    return 2;
1672 8170028d ths
}
1673 8170028d ths
1674 cf7e0c80 Aurelien Jarno
static int dec_mulu_r(CPUCRISState *env, DisasContext *dc)
1675 8170028d ths
{
1676 7b5eff4d Evgeny Voevodin
    TCGv t[2];
1677 7b5eff4d Evgeny Voevodin
    int size = memsize_zz(dc);
1678 8170028d ths
1679 7b5eff4d Evgeny Voevodin
    LOG_DIS("mulu.%c $r%u, $r%u\n",
1680 7b5eff4d Evgeny Voevodin
            memsize_char(size), dc->op1, dc->op2);
1681 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZV);
1682 7b5eff4d Evgeny Voevodin
    cris_alu_alloc_temps(dc, size, t);
1683 7b5eff4d Evgeny Voevodin
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1684 30abcfc7 edgar_igl
1685 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
1686 7b5eff4d Evgeny Voevodin
    cris_alu_alloc_temps(dc, size, t);
1687 7b5eff4d Evgeny Voevodin
    return 2;
1688 8170028d ths
}
1689 8170028d ths
1690 8170028d ths
1691 cf7e0c80 Aurelien Jarno
static int dec_dstep_r(CPUCRISState *env, DisasContext *dc)
1692 8170028d ths
{
1693 7b5eff4d Evgeny Voevodin
    LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
1694 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1695 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_DSTEP,
1696 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1697 7b5eff4d Evgeny Voevodin
    return 2;
1698 8170028d ths
}
1699 8170028d ths
1700 cf7e0c80 Aurelien Jarno
static int dec_xor_r(CPUCRISState *env, DisasContext *dc)
1701 8170028d ths
{
1702 7b5eff4d Evgeny Voevodin
    TCGv t[2];
1703 7b5eff4d Evgeny Voevodin
    int size = memsize_zz(dc);
1704 7b5eff4d Evgeny Voevodin
    LOG_DIS("xor.%c $r%u, $r%u\n",
1705 7b5eff4d Evgeny Voevodin
            memsize_char(size), dc->op1, dc->op2);
1706 7b5eff4d Evgeny Voevodin
    BUG_ON(size != 4); /* xor is dword.  */
1707 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1708 7b5eff4d Evgeny Voevodin
    cris_alu_alloc_temps(dc, size, t);
1709 7b5eff4d Evgeny Voevodin
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1710 30abcfc7 edgar_igl
1711 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
1712 7b5eff4d Evgeny Voevodin
    cris_alu_free_temps(dc, size, t);
1713 7b5eff4d Evgeny Voevodin
    return 2;
1714 8170028d ths
}
1715 8170028d ths
1716 cf7e0c80 Aurelien Jarno
static int dec_bound_r(CPUCRISState *env, DisasContext *dc)
1717 8170028d ths
{
1718 7b5eff4d Evgeny Voevodin
    TCGv l0;
1719 7b5eff4d Evgeny Voevodin
    int size = memsize_zz(dc);
1720 7b5eff4d Evgeny Voevodin
    LOG_DIS("bound.%c $r%u, $r%u\n",
1721 7b5eff4d Evgeny Voevodin
            memsize_char(size), dc->op1, dc->op2);
1722 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1723 7b5eff4d Evgeny Voevodin
    l0 = tcg_temp_local_new();
1724 7b5eff4d Evgeny Voevodin
    dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
1725 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
1726 7b5eff4d Evgeny Voevodin
    tcg_temp_free(l0);
1727 7b5eff4d Evgeny Voevodin
    return 2;
1728 8170028d ths
}
1729 8170028d ths
1730 cf7e0c80 Aurelien Jarno
static int dec_cmp_r(CPUCRISState *env, DisasContext *dc)
1731 8170028d ths
{
1732 7b5eff4d Evgeny Voevodin
    TCGv t[2];
1733 7b5eff4d Evgeny Voevodin
    int size = memsize_zz(dc);
1734 7b5eff4d Evgeny Voevodin
    LOG_DIS("cmp.%c $r%u, $r%u\n",
1735 7b5eff4d Evgeny Voevodin
            memsize_char(size), dc->op1, dc->op2);
1736 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
1737 7b5eff4d Evgeny Voevodin
    cris_alu_alloc_temps(dc, size, t);
1738 7b5eff4d Evgeny Voevodin
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1739 30abcfc7 edgar_igl
1740 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
1741 7b5eff4d Evgeny Voevodin
    cris_alu_free_temps(dc, size, t);
1742 7b5eff4d Evgeny Voevodin
    return 2;
1743 8170028d ths
}
1744 8170028d ths
1745 cf7e0c80 Aurelien Jarno
static int dec_abs_r(CPUCRISState *env, DisasContext *dc)
1746 8170028d ths
{
1747 7b5eff4d Evgeny Voevodin
    TCGv t0;
1748 3157a0a9 edgar_igl
1749 7b5eff4d Evgeny Voevodin
    LOG_DIS("abs $r%u, $r%u\n",
1750 7b5eff4d Evgeny Voevodin
            dc->op1, dc->op2);
1751 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1752 3157a0a9 edgar_igl
1753 7b5eff4d Evgeny Voevodin
    t0 = tcg_temp_new();
1754 7b5eff4d Evgeny Voevodin
    tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31);
1755 7b5eff4d Evgeny Voevodin
    tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0);
1756 7b5eff4d Evgeny Voevodin
    tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0);
1757 7b5eff4d Evgeny Voevodin
    tcg_temp_free(t0);
1758 7dcfb089 edgar_igl
1759 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_MOVE,
1760 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1761 7b5eff4d Evgeny Voevodin
    return 2;
1762 8170028d ths
}
1763 8170028d ths
1764 cf7e0c80 Aurelien Jarno
static int dec_add_r(CPUCRISState *env, DisasContext *dc)
1765 8170028d ths
{
1766 7b5eff4d Evgeny Voevodin
    TCGv t[2];
1767 7b5eff4d Evgeny Voevodin
    int size = memsize_zz(dc);
1768 7b5eff4d Evgeny Voevodin
    LOG_DIS("add.%c $r%u, $r%u\n",
1769 7b5eff4d Evgeny Voevodin
            memsize_char(size), dc->op1, dc->op2);
1770 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
1771 7b5eff4d Evgeny Voevodin
    cris_alu_alloc_temps(dc, size, t);
1772 7b5eff4d Evgeny Voevodin
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1773 30abcfc7 edgar_igl
1774 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
1775 7b5eff4d Evgeny Voevodin
    cris_alu_free_temps(dc, size, t);
1776 7b5eff4d Evgeny Voevodin
    return 2;
1777 8170028d ths
}
1778 8170028d ths
1779 cf7e0c80 Aurelien Jarno
static int dec_addc_r(CPUCRISState *env, DisasContext *dc)
1780 8170028d ths
{
1781 7b5eff4d Evgeny Voevodin
    LOG_DIS("addc $r%u, $r%u\n",
1782 7b5eff4d Evgeny Voevodin
            dc->op1, dc->op2);
1783 7b5eff4d Evgeny Voevodin
    cris_evaluate_flags(dc);
1784 7b5eff4d Evgeny Voevodin
    /* Set for this insn.  */
1785 7b5eff4d Evgeny Voevodin
    dc->flagx_known = 1;
1786 7b5eff4d Evgeny Voevodin
    dc->flags_x = X_FLAG;
1787 a8cf66bb edgar_igl
1788 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
1789 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_ADDC,
1790 7b5eff4d Evgeny Voevodin
         cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1791 7b5eff4d Evgeny Voevodin
    return 2;
1792 8170028d ths
}
1793 8170028d ths
1794 cf7e0c80 Aurelien Jarno
static int dec_mcp_r(CPUCRISState *env, DisasContext *dc)
1795 8170028d ths
{
1796 7b5eff4d Evgeny Voevodin
    LOG_DIS("mcp $p%u, $r%u\n",
1797 7b5eff4d Evgeny Voevodin
             dc->op2, dc->op1);
1798 7b5eff4d Evgeny Voevodin
    cris_evaluate_flags(dc);
1799 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_RNZV);
1800 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_MCP,
1801 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
1802 7b5eff4d Evgeny Voevodin
    return 2;
1803 8170028d ths
}
1804 8170028d ths
1805 8170028d ths
#if DISAS_CRIS
1806 8170028d ths
static char * swapmode_name(int mode, char *modename) {
1807 7b5eff4d Evgeny Voevodin
    int i = 0;
1808 7b5eff4d Evgeny Voevodin
    if (mode & 8) {
1809 7b5eff4d Evgeny Voevodin
        modename[i++] = 'n';
1810 7b5eff4d Evgeny Voevodin
    }
1811 7b5eff4d Evgeny Voevodin
    if (mode & 4) {
1812 7b5eff4d Evgeny Voevodin
        modename[i++] = 'w';
1813 7b5eff4d Evgeny Voevodin
    }
1814 7b5eff4d Evgeny Voevodin
    if (mode & 2) {
1815 7b5eff4d Evgeny Voevodin
        modename[i++] = 'b';
1816 7b5eff4d Evgeny Voevodin
    }
1817 7b5eff4d Evgeny Voevodin
    if (mode & 1) {
1818 7b5eff4d Evgeny Voevodin
        modename[i++] = 'r';
1819 7b5eff4d Evgeny Voevodin
    }
1820 7b5eff4d Evgeny Voevodin
    modename[i++] = 0;
1821 7b5eff4d Evgeny Voevodin
    return modename;
1822 8170028d ths
}
1823 8170028d ths
#endif
1824 8170028d ths
1825 cf7e0c80 Aurelien Jarno
static int dec_swap_r(CPUCRISState *env, DisasContext *dc)
1826 8170028d ths
{
1827 7b5eff4d Evgeny Voevodin
    TCGv t0;
1828 cf1d97f0 edgar_igl
#if DISAS_CRIS
1829 7b5eff4d Evgeny Voevodin
    char modename[4];
1830 cf1d97f0 edgar_igl
#endif
1831 7b5eff4d Evgeny Voevodin
    LOG_DIS("swap%s $r%u\n",
1832 7b5eff4d Evgeny Voevodin
             swapmode_name(dc->op2, modename), dc->op1);
1833 7b5eff4d Evgeny Voevodin
1834 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1835 7b5eff4d Evgeny Voevodin
    t0 = tcg_temp_new();
1836 7b5eff4d Evgeny Voevodin
    t_gen_mov_TN_reg(t0, dc->op1);
1837 7b5eff4d Evgeny Voevodin
    if (dc->op2 & 8) {
1838 7b5eff4d Evgeny Voevodin
        tcg_gen_not_tl(t0, t0);
1839 7b5eff4d Evgeny Voevodin
    }
1840 7b5eff4d Evgeny Voevodin
    if (dc->op2 & 4) {
1841 7b5eff4d Evgeny Voevodin
        t_gen_swapw(t0, t0);
1842 7b5eff4d Evgeny Voevodin
    }
1843 7b5eff4d Evgeny Voevodin
    if (dc->op2 & 2) {
1844 7b5eff4d Evgeny Voevodin
        t_gen_swapb(t0, t0);
1845 7b5eff4d Evgeny Voevodin
    }
1846 7b5eff4d Evgeny Voevodin
    if (dc->op2 & 1) {
1847 7b5eff4d Evgeny Voevodin
        t_gen_swapr(t0, t0);
1848 7b5eff4d Evgeny Voevodin
    }
1849 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op1], cpu_R[dc->op1], t0, 4);
1850 7b5eff4d Evgeny Voevodin
    tcg_temp_free(t0);
1851 7b5eff4d Evgeny Voevodin
    return 2;
1852 8170028d ths
}
1853 8170028d ths
1854 cf7e0c80 Aurelien Jarno
static int dec_or_r(CPUCRISState *env, DisasContext *dc)
1855 8170028d ths
{
1856 7b5eff4d Evgeny Voevodin
    TCGv t[2];
1857 7b5eff4d Evgeny Voevodin
    int size = memsize_zz(dc);
1858 7b5eff4d Evgeny Voevodin
    LOG_DIS("or.%c $r%u, $r%u\n",
1859 7b5eff4d Evgeny Voevodin
            memsize_char(size), dc->op1, dc->op2);
1860 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1861 7b5eff4d Evgeny Voevodin
    cris_alu_alloc_temps(dc, size, t);
1862 7b5eff4d Evgeny Voevodin
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1863 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
1864 7b5eff4d Evgeny Voevodin
    cris_alu_free_temps(dc, size, t);
1865 7b5eff4d Evgeny Voevodin
    return 2;
1866 8170028d ths
}
1867 8170028d ths
1868 cf7e0c80 Aurelien Jarno
static int dec_addi_r(CPUCRISState *env, DisasContext *dc)
1869 8170028d ths
{
1870 7b5eff4d Evgeny Voevodin
    TCGv t0;
1871 7b5eff4d Evgeny Voevodin
    LOG_DIS("addi.%c $r%u, $r%u\n",
1872 7b5eff4d Evgeny Voevodin
            memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1873 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
1874 7b5eff4d Evgeny Voevodin
    t0 = tcg_temp_new();
1875 7b5eff4d Evgeny Voevodin
    tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1876 7b5eff4d Evgeny Voevodin
    tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0);
1877 7b5eff4d Evgeny Voevodin
    tcg_temp_free(t0);
1878 7b5eff4d Evgeny Voevodin
    return 2;
1879 8170028d ths
}
1880 8170028d ths
1881 cf7e0c80 Aurelien Jarno
static int dec_addi_acr(CPUCRISState *env, DisasContext *dc)
1882 8170028d ths
{
1883 7b5eff4d Evgeny Voevodin
    TCGv t0;
1884 7b5eff4d Evgeny Voevodin
    LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
1885 7b5eff4d Evgeny Voevodin
          memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1886 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
1887 7b5eff4d Evgeny Voevodin
    t0 = tcg_temp_new();
1888 7b5eff4d Evgeny Voevodin
    tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1889 7b5eff4d Evgeny Voevodin
    tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
1890 7b5eff4d Evgeny Voevodin
    tcg_temp_free(t0);
1891 7b5eff4d Evgeny Voevodin
    return 2;
1892 8170028d ths
}
1893 8170028d ths
1894 cf7e0c80 Aurelien Jarno
static int dec_neg_r(CPUCRISState *env, DisasContext *dc)
1895 8170028d ths
{
1896 7b5eff4d Evgeny Voevodin
    TCGv t[2];
1897 7b5eff4d Evgeny Voevodin
    int size = memsize_zz(dc);
1898 7b5eff4d Evgeny Voevodin
    LOG_DIS("neg.%c $r%u, $r%u\n",
1899 7b5eff4d Evgeny Voevodin
            memsize_char(size), dc->op1, dc->op2);
1900 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
1901 7b5eff4d Evgeny Voevodin
    cris_alu_alloc_temps(dc, size, t);
1902 7b5eff4d Evgeny Voevodin
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1903 30abcfc7 edgar_igl
1904 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
1905 7b5eff4d Evgeny Voevodin
    cris_alu_free_temps(dc, size, t);
1906 7b5eff4d Evgeny Voevodin
    return 2;
1907 8170028d ths
}
1908 8170028d ths
1909 cf7e0c80 Aurelien Jarno
static int dec_btst_r(CPUCRISState *env, DisasContext *dc)
1910 8170028d ths
{
1911 7b5eff4d Evgeny Voevodin
    LOG_DIS("btst $r%u, $r%u\n",
1912 7b5eff4d Evgeny Voevodin
            dc->op1, dc->op2);
1913 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1914 7b5eff4d Evgeny Voevodin
    cris_evaluate_flags(dc);
1915 febc9920 Aurelien Jarno
        gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
1916 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op1], cpu_PR[PR_CCS]);
1917 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
1918 7b5eff4d Evgeny Voevodin
         cpu_R[dc->op2], cpu_R[dc->op2], 4);
1919 7b5eff4d Evgeny Voevodin
    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1920 7b5eff4d Evgeny Voevodin
    dc->flags_uptodate = 1;
1921 7b5eff4d Evgeny Voevodin
    return 2;
1922 8170028d ths
}
1923 8170028d ths
1924 cf7e0c80 Aurelien Jarno
static int dec_sub_r(CPUCRISState *env, DisasContext *dc)
1925 8170028d ths
{
1926 7b5eff4d Evgeny Voevodin
    TCGv t[2];
1927 7b5eff4d Evgeny Voevodin
    int size = memsize_zz(dc);
1928 7b5eff4d Evgeny Voevodin
    LOG_DIS("sub.%c $r%u, $r%u\n",
1929 7b5eff4d Evgeny Voevodin
            memsize_char(size), dc->op1, dc->op2);
1930 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
1931 7b5eff4d Evgeny Voevodin
    cris_alu_alloc_temps(dc, size, t);
1932 7b5eff4d Evgeny Voevodin
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1933 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
1934 7b5eff4d Evgeny Voevodin
    cris_alu_free_temps(dc, size, t);
1935 7b5eff4d Evgeny Voevodin
    return 2;
1936 8170028d ths
}
1937 8170028d ths
1938 8170028d ths
/* Zero extension. From size to dword.  */
1939 cf7e0c80 Aurelien Jarno
static int dec_movu_r(CPUCRISState *env, DisasContext *dc)
1940 8170028d ths
{
1941 7b5eff4d Evgeny Voevodin
    TCGv t0;
1942 7b5eff4d Evgeny Voevodin
    int size = memsize_z(dc);
1943 7b5eff4d Evgeny Voevodin
    LOG_DIS("movu.%c $r%u, $r%u\n",
1944 7b5eff4d Evgeny Voevodin
            memsize_char(size),
1945 7b5eff4d Evgeny Voevodin
            dc->op1, dc->op2);
1946 8170028d ths
1947 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1948 7b5eff4d Evgeny Voevodin
    t0 = tcg_temp_new();
1949 7b5eff4d Evgeny Voevodin
    dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1950 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1951 7b5eff4d Evgeny Voevodin
    tcg_temp_free(t0);
1952 7b5eff4d Evgeny Voevodin
    return 2;
1953 8170028d ths
}
1954 8170028d ths
1955 8170028d ths
/* Sign extension. From size to dword.  */
1956 cf7e0c80 Aurelien Jarno
static int dec_movs_r(CPUCRISState *env, DisasContext *dc)
1957 8170028d ths
{
1958 7b5eff4d Evgeny Voevodin
    TCGv t0;
1959 7b5eff4d Evgeny Voevodin
    int size = memsize_z(dc);
1960 7b5eff4d Evgeny Voevodin
    LOG_DIS("movs.%c $r%u, $r%u\n",
1961 7b5eff4d Evgeny Voevodin
            memsize_char(size),
1962 7b5eff4d Evgeny Voevodin
            dc->op1, dc->op2);
1963 8170028d ths
1964 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
1965 7b5eff4d Evgeny Voevodin
    t0 = tcg_temp_new();
1966 7b5eff4d Evgeny Voevodin
    /* Size can only be qi or hi.  */
1967 7b5eff4d Evgeny Voevodin
    t_gen_sext(t0, cpu_R[dc->op1], size);
1968 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_MOVE,
1969 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op1], t0, 4);
1970 7b5eff4d Evgeny Voevodin
    tcg_temp_free(t0);
1971 7b5eff4d Evgeny Voevodin
    return 2;
1972 8170028d ths
}
1973 8170028d ths
1974 8170028d ths
/* zero extension. From size to dword.  */
1975 cf7e0c80 Aurelien Jarno
static int dec_addu_r(CPUCRISState *env, DisasContext *dc)
1976 8170028d ths
{
1977 7b5eff4d Evgeny Voevodin
    TCGv t0;
1978 7b5eff4d Evgeny Voevodin
    int size = memsize_z(dc);
1979 7b5eff4d Evgeny Voevodin
    LOG_DIS("addu.%c $r%u, $r%u\n",
1980 7b5eff4d Evgeny Voevodin
            memsize_char(size),
1981 7b5eff4d Evgeny Voevodin
            dc->op1, dc->op2);
1982 8170028d ths
1983 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
1984 7b5eff4d Evgeny Voevodin
    t0 = tcg_temp_new();
1985 7b5eff4d Evgeny Voevodin
    /* Size can only be qi or hi.  */
1986 7b5eff4d Evgeny Voevodin
    t_gen_zext(t0, cpu_R[dc->op1], size);
1987 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1988 7b5eff4d Evgeny Voevodin
    tcg_temp_free(t0);
1989 7b5eff4d Evgeny Voevodin
    return 2;
1990 8170028d ths
}
1991 05ba7d5f edgar_igl
1992 8170028d ths
/* Sign extension. From size to dword.  */
1993 cf7e0c80 Aurelien Jarno
static int dec_adds_r(CPUCRISState *env, DisasContext *dc)
1994 8170028d ths
{
1995 7b5eff4d Evgeny Voevodin
    TCGv t0;
1996 7b5eff4d Evgeny Voevodin
    int size = memsize_z(dc);
1997 7b5eff4d Evgeny Voevodin
    LOG_DIS("adds.%c $r%u, $r%u\n",
1998 7b5eff4d Evgeny Voevodin
            memsize_char(size),
1999 7b5eff4d Evgeny Voevodin
            dc->op1, dc->op2);
2000 8170028d ths
2001 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
2002 7b5eff4d Evgeny Voevodin
    t0 = tcg_temp_new();
2003 7b5eff4d Evgeny Voevodin
    /* Size can only be qi or hi.  */
2004 7b5eff4d Evgeny Voevodin
    t_gen_sext(t0, cpu_R[dc->op1], size);
2005 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_ADD,
2006 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2007 7b5eff4d Evgeny Voevodin
    tcg_temp_free(t0);
2008 7b5eff4d Evgeny Voevodin
    return 2;
2009 8170028d ths
}
2010 8170028d ths
2011 8170028d ths
/* Zero extension. From size to dword.  */
2012 cf7e0c80 Aurelien Jarno
static int dec_subu_r(CPUCRISState *env, DisasContext *dc)
2013 8170028d ths
{
2014 7b5eff4d Evgeny Voevodin
    TCGv t0;
2015 7b5eff4d Evgeny Voevodin
    int size = memsize_z(dc);
2016 7b5eff4d Evgeny Voevodin
    LOG_DIS("subu.%c $r%u, $r%u\n",
2017 7b5eff4d Evgeny Voevodin
            memsize_char(size),
2018 7b5eff4d Evgeny Voevodin
            dc->op1, dc->op2);
2019 8170028d ths
2020 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
2021 7b5eff4d Evgeny Voevodin
    t0 = tcg_temp_new();
2022 7b5eff4d Evgeny Voevodin
    /* Size can only be qi or hi.  */
2023 7b5eff4d Evgeny Voevodin
    t_gen_zext(t0, cpu_R[dc->op1], size);
2024 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_SUB,
2025 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2026 7b5eff4d Evgeny Voevodin
    tcg_temp_free(t0);
2027 7b5eff4d Evgeny Voevodin
    return 2;
2028 8170028d ths
}
2029 8170028d ths
2030 8170028d ths
/* Sign extension. From size to dword.  */
2031 cf7e0c80 Aurelien Jarno
static int dec_subs_r(CPUCRISState *env, DisasContext *dc)
2032 8170028d ths
{
2033 7b5eff4d Evgeny Voevodin
    TCGv t0;
2034 7b5eff4d Evgeny Voevodin
    int size = memsize_z(dc);
2035 7b5eff4d Evgeny Voevodin
    LOG_DIS("subs.%c $r%u, $r%u\n",
2036 7b5eff4d Evgeny Voevodin
            memsize_char(size),
2037 7b5eff4d Evgeny Voevodin
            dc->op1, dc->op2);
2038 8170028d ths
2039 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
2040 7b5eff4d Evgeny Voevodin
    t0 = tcg_temp_new();
2041 7b5eff4d Evgeny Voevodin
    /* Size can only be qi or hi.  */
2042 7b5eff4d Evgeny Voevodin
    t_gen_sext(t0, cpu_R[dc->op1], size);
2043 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_SUB,
2044 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2045 7b5eff4d Evgeny Voevodin
    tcg_temp_free(t0);
2046 7b5eff4d Evgeny Voevodin
    return 2;
2047 8170028d ths
}
2048 8170028d ths
2049 cf7e0c80 Aurelien Jarno
static int dec_setclrf(CPUCRISState *env, DisasContext *dc)
2050 8170028d ths
{
2051 7b5eff4d Evgeny Voevodin
    uint32_t flags;
2052 7b5eff4d Evgeny Voevodin
    int set = (~dc->opcode >> 2) & 1;
2053 7b5eff4d Evgeny Voevodin
2054 7b5eff4d Evgeny Voevodin
2055 7b5eff4d Evgeny Voevodin
    flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
2056 7b5eff4d Evgeny Voevodin
        | EXTRACT_FIELD(dc->ir, 0, 3);
2057 7b5eff4d Evgeny Voevodin
    if (set && flags == 0) {
2058 7b5eff4d Evgeny Voevodin
        LOG_DIS("nop\n");
2059 7b5eff4d Evgeny Voevodin
        return 2;
2060 7b5eff4d Evgeny Voevodin
    } else if (!set && (flags & 0x20)) {
2061 7b5eff4d Evgeny Voevodin
        LOG_DIS("di\n");
2062 7b5eff4d Evgeny Voevodin
    } else {
2063 7b5eff4d Evgeny Voevodin
        LOG_DIS("%sf %x\n", set ? "set" : "clr", flags);
2064 7b5eff4d Evgeny Voevodin
    }
2065 7b5eff4d Evgeny Voevodin
2066 7b5eff4d Evgeny Voevodin
    /* User space is not allowed to touch these. Silently ignore.  */
2067 7b5eff4d Evgeny Voevodin
    if (dc->tb_flags & U_FLAG) {
2068 7b5eff4d Evgeny Voevodin
        flags &= ~(S_FLAG | I_FLAG | U_FLAG);
2069 7b5eff4d Evgeny Voevodin
    }
2070 7b5eff4d Evgeny Voevodin
2071 7b5eff4d Evgeny Voevodin
    if (flags & X_FLAG) {
2072 7b5eff4d Evgeny Voevodin
        dc->flagx_known = 1;
2073 7b5eff4d Evgeny Voevodin
        if (set) {
2074 7b5eff4d Evgeny Voevodin
            dc->flags_x = X_FLAG;
2075 7b5eff4d Evgeny Voevodin
        } else {
2076 7b5eff4d Evgeny Voevodin
            dc->flags_x = 0;
2077 7b5eff4d Evgeny Voevodin
        }
2078 7b5eff4d Evgeny Voevodin
    }
2079 7b5eff4d Evgeny Voevodin
2080 7b5eff4d Evgeny Voevodin
    /* Break the TB if any of the SPI flag changes.  */
2081 7b5eff4d Evgeny Voevodin
    if (flags & (P_FLAG | S_FLAG)) {
2082 7b5eff4d Evgeny Voevodin
        tcg_gen_movi_tl(env_pc, dc->pc + 2);
2083 7b5eff4d Evgeny Voevodin
        dc->is_jmp = DISAS_UPDATE;
2084 7b5eff4d Evgeny Voevodin
        dc->cpustate_changed = 1;
2085 7b5eff4d Evgeny Voevodin
    }
2086 7b5eff4d Evgeny Voevodin
2087 7b5eff4d Evgeny Voevodin
    /* For the I flag, only act on posedge.  */
2088 7b5eff4d Evgeny Voevodin
    if ((flags & I_FLAG)) {
2089 7b5eff4d Evgeny Voevodin
        tcg_gen_movi_tl(env_pc, dc->pc + 2);
2090 7b5eff4d Evgeny Voevodin
        dc->is_jmp = DISAS_UPDATE;
2091 7b5eff4d Evgeny Voevodin
        dc->cpustate_changed = 1;
2092 7b5eff4d Evgeny Voevodin
    }
2093 7b5eff4d Evgeny Voevodin
2094 7b5eff4d Evgeny Voevodin
2095 7b5eff4d Evgeny Voevodin
    /* Simply decode the flags.  */
2096 7b5eff4d Evgeny Voevodin
    cris_evaluate_flags(dc);
2097 7b5eff4d Evgeny Voevodin
    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2098 7b5eff4d Evgeny Voevodin
    cris_update_cc_x(dc);
2099 7b5eff4d Evgeny Voevodin
    tcg_gen_movi_tl(cc_op, dc->cc_op);
2100 7b5eff4d Evgeny Voevodin
2101 7b5eff4d Evgeny Voevodin
    if (set) {
2102 7b5eff4d Evgeny Voevodin
        if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) {
2103 7b5eff4d Evgeny Voevodin
            /* Enter user mode.  */
2104 7b5eff4d Evgeny Voevodin
            t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
2105 7b5eff4d Evgeny Voevodin
            tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
2106 7b5eff4d Evgeny Voevodin
            dc->cpustate_changed = 1;
2107 7b5eff4d Evgeny Voevodin
        }
2108 7b5eff4d Evgeny Voevodin
        tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
2109 7b5eff4d Evgeny Voevodin
    } else {
2110 7b5eff4d Evgeny Voevodin
        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
2111 7b5eff4d Evgeny Voevodin
    }
2112 7b5eff4d Evgeny Voevodin
2113 7b5eff4d Evgeny Voevodin
    dc->flags_uptodate = 1;
2114 7b5eff4d Evgeny Voevodin
    dc->clear_x = 0;
2115 7b5eff4d Evgeny Voevodin
    return 2;
2116 8170028d ths
}
2117 8170028d ths
2118 cf7e0c80 Aurelien Jarno
static int dec_move_rs(CPUCRISState *env, DisasContext *dc)
2119 8170028d ths
{
2120 7b5eff4d Evgeny Voevodin
    LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
2121 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2122 febc9920 Aurelien Jarno
        gen_helper_movl_sreg_reg(cpu_env, tcg_const_tl(dc->op2),
2123 febc9920 Aurelien Jarno
                                 tcg_const_tl(dc->op1));
2124 7b5eff4d Evgeny Voevodin
    return 2;
2125 8170028d ths
}
2126 cf7e0c80 Aurelien Jarno
static int dec_move_sr(CPUCRISState *env, DisasContext *dc)
2127 8170028d ths
{
2128 7b5eff4d Evgeny Voevodin
    LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
2129 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2130 febc9920 Aurelien Jarno
        gen_helper_movl_reg_sreg(cpu_env, tcg_const_tl(dc->op1),
2131 febc9920 Aurelien Jarno
                                 tcg_const_tl(dc->op2));
2132 7b5eff4d Evgeny Voevodin
    return 2;
2133 8170028d ths
}
2134 dceaf394 edgar_igl
2135 cf7e0c80 Aurelien Jarno
static int dec_move_rp(CPUCRISState *env, DisasContext *dc)
2136 8170028d ths
{
2137 7b5eff4d Evgeny Voevodin
    TCGv t[2];
2138 7b5eff4d Evgeny Voevodin
    LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
2139 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2140 7b5eff4d Evgeny Voevodin
2141 7b5eff4d Evgeny Voevodin
    t[0] = tcg_temp_new();
2142 7b5eff4d Evgeny Voevodin
    if (dc->op2 == PR_CCS) {
2143 7b5eff4d Evgeny Voevodin
        cris_evaluate_flags(dc);
2144 7b5eff4d Evgeny Voevodin
        t_gen_mov_TN_reg(t[0], dc->op1);
2145 7b5eff4d Evgeny Voevodin
        if (dc->tb_flags & U_FLAG) {
2146 7b5eff4d Evgeny Voevodin
            t[1] = tcg_temp_new();
2147 7b5eff4d Evgeny Voevodin
            /* User space is not allowed to touch all flags.  */
2148 7b5eff4d Evgeny Voevodin
            tcg_gen_andi_tl(t[0], t[0], 0x39f);
2149 7b5eff4d Evgeny Voevodin
            tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
2150 7b5eff4d Evgeny Voevodin
            tcg_gen_or_tl(t[0], t[1], t[0]);
2151 7b5eff4d Evgeny Voevodin
            tcg_temp_free(t[1]);
2152 7b5eff4d Evgeny Voevodin
        }
2153 7b5eff4d Evgeny Voevodin
    } else {
2154 7b5eff4d Evgeny Voevodin
        t_gen_mov_TN_reg(t[0], dc->op1);
2155 7b5eff4d Evgeny Voevodin
    }
2156 7b5eff4d Evgeny Voevodin
2157 7b5eff4d Evgeny Voevodin
    t_gen_mov_preg_TN(dc, dc->op2, t[0]);
2158 7b5eff4d Evgeny Voevodin
    if (dc->op2 == PR_CCS) {
2159 7b5eff4d Evgeny Voevodin
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2160 7b5eff4d Evgeny Voevodin
        dc->flags_uptodate = 1;
2161 7b5eff4d Evgeny Voevodin
    }
2162 7b5eff4d Evgeny Voevodin
    tcg_temp_free(t[0]);
2163 7b5eff4d Evgeny Voevodin
    return 2;
2164 8170028d ths
}
2165 cf7e0c80 Aurelien Jarno
static int dec_move_pr(CPUCRISState *env, DisasContext *dc)
2166 8170028d ths
{
2167 7b5eff4d Evgeny Voevodin
    TCGv t0;
2168 7b5eff4d Evgeny Voevodin
    LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
2169 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2170 2a44f7f1 edgar_igl
2171 7b5eff4d Evgeny Voevodin
    if (dc->op2 == PR_CCS) {
2172 7b5eff4d Evgeny Voevodin
        cris_evaluate_flags(dc);
2173 7b5eff4d Evgeny Voevodin
    }
2174 2a44f7f1 edgar_igl
2175 7b5eff4d Evgeny Voevodin
    if (dc->op2 == PR_DZ) {
2176 7b5eff4d Evgeny Voevodin
        tcg_gen_movi_tl(cpu_R[dc->op1], 0);
2177 7b5eff4d Evgeny Voevodin
    } else {
2178 7b5eff4d Evgeny Voevodin
        t0 = tcg_temp_new();
2179 7b5eff4d Evgeny Voevodin
        t_gen_mov_TN_preg(t0, dc->op2);
2180 7b5eff4d Evgeny Voevodin
        cris_alu(dc, CC_OP_MOVE,
2181 7b5eff4d Evgeny Voevodin
                cpu_R[dc->op1], cpu_R[dc->op1], t0,
2182 7b5eff4d Evgeny Voevodin
                preg_sizes[dc->op2]);
2183 7b5eff4d Evgeny Voevodin
        tcg_temp_free(t0);
2184 7b5eff4d Evgeny Voevodin
    }
2185 7b5eff4d Evgeny Voevodin
    return 2;
2186 8170028d ths
}
2187 8170028d ths
2188 cf7e0c80 Aurelien Jarno
static int dec_move_mr(CPUCRISState *env, DisasContext *dc)
2189 8170028d ths
{
2190 7b5eff4d Evgeny Voevodin
    int memsize = memsize_zz(dc);
2191 7b5eff4d Evgeny Voevodin
    int insn_len;
2192 7b5eff4d Evgeny Voevodin
    LOG_DIS("move.%c [$r%u%s, $r%u\n",
2193 7b5eff4d Evgeny Voevodin
            memsize_char(memsize),
2194 7b5eff4d Evgeny Voevodin
            dc->op1, dc->postinc ? "+]" : "]",
2195 7b5eff4d Evgeny Voevodin
                    dc->op2);
2196 7b5eff4d Evgeny Voevodin
2197 7b5eff4d Evgeny Voevodin
    if (memsize == 4) {
2198 7b5eff4d Evgeny Voevodin
        insn_len = dec_prep_move_m(env, dc, 0, 4, cpu_R[dc->op2]);
2199 7b5eff4d Evgeny Voevodin
        cris_cc_mask(dc, CC_MASK_NZ);
2200 7b5eff4d Evgeny Voevodin
        cris_update_cc_op(dc, CC_OP_MOVE, 4);
2201 7b5eff4d Evgeny Voevodin
        cris_update_cc_x(dc);
2202 7b5eff4d Evgeny Voevodin
        cris_update_result(dc, cpu_R[dc->op2]);
2203 7b5eff4d Evgeny Voevodin
    } else {
2204 7b5eff4d Evgeny Voevodin
        TCGv t0;
2205 7b5eff4d Evgeny Voevodin
2206 7b5eff4d Evgeny Voevodin
        t0 = tcg_temp_new();
2207 7b5eff4d Evgeny Voevodin
        insn_len = dec_prep_move_m(env, dc, 0, memsize, t0);
2208 7b5eff4d Evgeny Voevodin
        cris_cc_mask(dc, CC_MASK_NZ);
2209 7b5eff4d Evgeny Voevodin
        cris_alu(dc, CC_OP_MOVE,
2210 7b5eff4d Evgeny Voevodin
                cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
2211 7b5eff4d Evgeny Voevodin
        tcg_temp_free(t0);
2212 7b5eff4d Evgeny Voevodin
    }
2213 7b5eff4d Evgeny Voevodin
    do_postinc(dc, memsize);
2214 7b5eff4d Evgeny Voevodin
    return insn_len;
2215 8170028d ths
}
2216 8170028d ths
2217 31c18d87 edgar_igl
static inline void cris_alu_m_alloc_temps(TCGv *t)
2218 31c18d87 edgar_igl
{
2219 7b5eff4d Evgeny Voevodin
    t[0] = tcg_temp_new();
2220 7b5eff4d Evgeny Voevodin
    t[1] = tcg_temp_new();
2221 31c18d87 edgar_igl
}
2222 31c18d87 edgar_igl
2223 31c18d87 edgar_igl
static inline void cris_alu_m_free_temps(TCGv *t)
2224 31c18d87 edgar_igl
{
2225 7b5eff4d Evgeny Voevodin
    tcg_temp_free(t[0]);
2226 7b5eff4d Evgeny Voevodin
    tcg_temp_free(t[1]);
2227 31c18d87 edgar_igl
}
2228 31c18d87 edgar_igl
2229 cf7e0c80 Aurelien Jarno
static int dec_movs_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("movs.%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, 1, memsize, t[0], t[1]);
2242 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
2243 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_MOVE,
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_addu_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("addu.%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, 0, 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,
2265 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2266 7b5eff4d Evgeny Voevodin
    do_postinc(dc, memsize);
2267 7b5eff4d Evgeny Voevodin
    cris_alu_m_free_temps(t);
2268 7b5eff4d Evgeny Voevodin
    return insn_len;
2269 8170028d ths
}
2270 8170028d ths
2271 cf7e0c80 Aurelien Jarno
static int dec_adds_m(CPUCRISState *env, DisasContext *dc)
2272 8170028d ths
{
2273 7b5eff4d Evgeny Voevodin
    TCGv t[2];
2274 7b5eff4d Evgeny Voevodin
    int memsize = memsize_z(dc);
2275 7b5eff4d Evgeny Voevodin
    int insn_len;
2276 7b5eff4d Evgeny Voevodin
    LOG_DIS("adds.%c [$r%u%s, $r%u\n",
2277 7b5eff4d Evgeny Voevodin
            memsize_char(memsize),
2278 7b5eff4d Evgeny Voevodin
            dc->op1, dc->postinc ? "+]" : "]",
2279 7b5eff4d Evgeny Voevodin
            dc->op2);
2280 8170028d ths
2281 7b5eff4d Evgeny Voevodin
    cris_alu_m_alloc_temps(t);
2282 7b5eff4d Evgeny Voevodin
    /* sign extend.  */
2283 cf7e0c80 Aurelien Jarno
        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2284 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
2285 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2286 7b5eff4d Evgeny Voevodin
    do_postinc(dc, memsize);
2287 7b5eff4d Evgeny Voevodin
    cris_alu_m_free_temps(t);
2288 7b5eff4d Evgeny Voevodin
    return insn_len;
2289 8170028d ths
}
2290 8170028d ths
2291 cf7e0c80 Aurelien Jarno
static int dec_subu_m(CPUCRISState *env, DisasContext *dc)
2292 8170028d ths
{
2293 7b5eff4d Evgeny Voevodin
    TCGv t[2];
2294 7b5eff4d Evgeny Voevodin
    int memsize = memsize_z(dc);
2295 7b5eff4d Evgeny Voevodin
    int insn_len;
2296 7b5eff4d Evgeny Voevodin
    LOG_DIS("subu.%c [$r%u%s, $r%u\n",
2297 7b5eff4d Evgeny Voevodin
            memsize_char(memsize),
2298 7b5eff4d Evgeny Voevodin
            dc->op1, dc->postinc ? "+]" : "]",
2299 7b5eff4d Evgeny Voevodin
            dc->op2);
2300 8170028d ths
2301 7b5eff4d Evgeny Voevodin
    cris_alu_m_alloc_temps(t);
2302 7b5eff4d Evgeny Voevodin
    /* sign extend.  */
2303 cf7e0c80 Aurelien Jarno
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2304 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
2305 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2306 7b5eff4d Evgeny Voevodin
    do_postinc(dc, memsize);
2307 7b5eff4d Evgeny Voevodin
    cris_alu_m_free_temps(t);
2308 7b5eff4d Evgeny Voevodin
    return insn_len;
2309 8170028d ths
}
2310 8170028d ths
2311 cf7e0c80 Aurelien Jarno
static int dec_subs_m(CPUCRISState *env, DisasContext *dc)
2312 8170028d ths
{
2313 7b5eff4d Evgeny Voevodin
    TCGv t[2];
2314 7b5eff4d Evgeny Voevodin
    int memsize = memsize_z(dc);
2315 7b5eff4d Evgeny Voevodin
    int insn_len;
2316 7b5eff4d Evgeny Voevodin
    LOG_DIS("subs.%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 7b5eff4d Evgeny Voevodin
    /* sign extend.  */
2323 cf7e0c80 Aurelien Jarno
        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2324 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
2325 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2326 7b5eff4d Evgeny Voevodin
    do_postinc(dc, memsize);
2327 7b5eff4d Evgeny Voevodin
    cris_alu_m_free_temps(t);
2328 7b5eff4d Evgeny Voevodin
    return insn_len;
2329 8170028d ths
}
2330 8170028d ths
2331 cf7e0c80 Aurelien Jarno
static int dec_movu_m(CPUCRISState *env, DisasContext *dc)
2332 8170028d ths
{
2333 7b5eff4d Evgeny Voevodin
    TCGv t[2];
2334 7b5eff4d Evgeny Voevodin
    int memsize = memsize_z(dc);
2335 7b5eff4d Evgeny Voevodin
    int insn_len;
2336 8170028d ths
2337 7b5eff4d Evgeny Voevodin
    LOG_DIS("movu.%c [$r%u%s, $r%u\n",
2338 7b5eff4d Evgeny Voevodin
            memsize_char(memsize),
2339 7b5eff4d Evgeny Voevodin
            dc->op1, dc->postinc ? "+]" : "]",
2340 7b5eff4d Evgeny Voevodin
            dc->op2);
2341 8170028d ths
2342 7b5eff4d Evgeny Voevodin
    cris_alu_m_alloc_temps(t);
2343 cf7e0c80 Aurelien Jarno
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2344 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
2345 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2346 7b5eff4d Evgeny Voevodin
    do_postinc(dc, memsize);
2347 7b5eff4d Evgeny Voevodin
    cris_alu_m_free_temps(t);
2348 7b5eff4d Evgeny Voevodin
    return insn_len;
2349 8170028d ths
}
2350 8170028d ths
2351 cf7e0c80 Aurelien Jarno
static int dec_cmpu_m(CPUCRISState *env, DisasContext *dc)
2352 8170028d ths
{
2353 7b5eff4d Evgeny Voevodin
    TCGv t[2];
2354 7b5eff4d Evgeny Voevodin
    int memsize = memsize_z(dc);
2355 7b5eff4d Evgeny Voevodin
    int insn_len;
2356 7b5eff4d Evgeny Voevodin
    LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
2357 7b5eff4d Evgeny Voevodin
            memsize_char(memsize),
2358 7b5eff4d Evgeny Voevodin
            dc->op1, dc->postinc ? "+]" : "]",
2359 7b5eff4d Evgeny Voevodin
            dc->op2);
2360 8170028d ths
2361 7b5eff4d Evgeny Voevodin
    cris_alu_m_alloc_temps(t);
2362 cf7e0c80 Aurelien Jarno
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2363 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
2364 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
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_cmps_m(CPUCRISState *env, DisasContext *dc)
2371 8170028d ths
{
2372 7b5eff4d Evgeny Voevodin
    TCGv t[2];
2373 7b5eff4d Evgeny Voevodin
    int memsize = memsize_z(dc);
2374 7b5eff4d Evgeny Voevodin
    int insn_len;
2375 7b5eff4d Evgeny Voevodin
    LOG_DIS("cmps.%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, 1, 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_cmp_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("cmp.%c [$r%u%s, $r%u\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_alu_m_alloc_temps(t);
2402 cf7e0c80 Aurelien Jarno
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2403 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
2404 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_CMP,
2405 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2406 7b5eff4d Evgeny Voevodin
            memsize_zz(dc));
2407 7b5eff4d Evgeny Voevodin
    do_postinc(dc, memsize);
2408 7b5eff4d Evgeny Voevodin
    cris_alu_m_free_temps(t);
2409 7b5eff4d Evgeny Voevodin
    return insn_len;
2410 8170028d ths
}
2411 8170028d ths
2412 cf7e0c80 Aurelien Jarno
static int dec_test_m(CPUCRISState *env, DisasContext *dc)
2413 8170028d ths
{
2414 7b5eff4d Evgeny Voevodin
    TCGv t[2];
2415 7b5eff4d Evgeny Voevodin
    int memsize = memsize_zz(dc);
2416 7b5eff4d Evgeny Voevodin
    int insn_len;
2417 7b5eff4d Evgeny Voevodin
    LOG_DIS("test.%c [$r%u%s] op2=%x\n",
2418 7b5eff4d Evgeny Voevodin
            memsize_char(memsize),
2419 7b5eff4d Evgeny Voevodin
            dc->op1, dc->postinc ? "+]" : "]",
2420 7b5eff4d Evgeny Voevodin
            dc->op2);
2421 8170028d ths
2422 7b5eff4d Evgeny Voevodin
    cris_evaluate_flags(dc);
2423 dceaf394 edgar_igl
2424 7b5eff4d Evgeny Voevodin
    cris_alu_m_alloc_temps(t);
2425 cf7e0c80 Aurelien Jarno
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2426 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
2427 7b5eff4d Evgeny Voevodin
    tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
2428 b41f7df0 edgar_igl
2429 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_CMP,
2430 7b5eff4d Evgeny Voevodin
         cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc));
2431 7b5eff4d Evgeny Voevodin
    do_postinc(dc, memsize);
2432 7b5eff4d Evgeny Voevodin
    cris_alu_m_free_temps(t);
2433 7b5eff4d Evgeny Voevodin
    return insn_len;
2434 8170028d ths
}
2435 8170028d ths
2436 cf7e0c80 Aurelien Jarno
static int dec_and_m(CPUCRISState *env, DisasContext *dc)
2437 8170028d ths
{
2438 7b5eff4d Evgeny Voevodin
    TCGv t[2];
2439 7b5eff4d Evgeny Voevodin
    int memsize = memsize_zz(dc);
2440 7b5eff4d Evgeny Voevodin
    int insn_len;
2441 7b5eff4d Evgeny Voevodin
    LOG_DIS("and.%c [$r%u%s, $r%u\n",
2442 7b5eff4d Evgeny Voevodin
            memsize_char(memsize),
2443 7b5eff4d Evgeny Voevodin
            dc->op1, dc->postinc ? "+]" : "]",
2444 7b5eff4d Evgeny Voevodin
            dc->op2);
2445 8170028d ths
2446 7b5eff4d Evgeny Voevodin
    cris_alu_m_alloc_temps(t);
2447 cf7e0c80 Aurelien Jarno
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2448 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
2449 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2450 7b5eff4d Evgeny Voevodin
    do_postinc(dc, memsize);
2451 7b5eff4d Evgeny Voevodin
    cris_alu_m_free_temps(t);
2452 7b5eff4d Evgeny Voevodin
    return insn_len;
2453 8170028d ths
}
2454 8170028d ths
2455 cf7e0c80 Aurelien Jarno
static int dec_add_m(CPUCRISState *env, DisasContext *dc)
2456 8170028d ths
{
2457 7b5eff4d Evgeny Voevodin
    TCGv t[2];
2458 7b5eff4d Evgeny Voevodin
    int memsize = memsize_zz(dc);
2459 7b5eff4d Evgeny Voevodin
    int insn_len;
2460 7b5eff4d Evgeny Voevodin
    LOG_DIS("add.%c [$r%u%s, $r%u\n",
2461 7b5eff4d Evgeny Voevodin
            memsize_char(memsize),
2462 7b5eff4d Evgeny Voevodin
            dc->op1, dc->postinc ? "+]" : "]",
2463 7b5eff4d Evgeny Voevodin
            dc->op2);
2464 8170028d ths
2465 7b5eff4d Evgeny Voevodin
    cris_alu_m_alloc_temps(t);
2466 cf7e0c80 Aurelien Jarno
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2467 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
2468 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_ADD,
2469 7b5eff4d Evgeny Voevodin
         cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2470 7b5eff4d Evgeny Voevodin
    do_postinc(dc, memsize);
2471 7b5eff4d Evgeny Voevodin
    cris_alu_m_free_temps(t);
2472 7b5eff4d Evgeny Voevodin
    return insn_len;
2473 8170028d ths
}
2474 8170028d ths
2475 cf7e0c80 Aurelien Jarno
static int dec_addo_m(CPUCRISState *env, DisasContext *dc)
2476 8170028d ths
{
2477 7b5eff4d Evgeny Voevodin
    TCGv t[2];
2478 7b5eff4d Evgeny Voevodin
    int memsize = memsize_zz(dc);
2479 7b5eff4d Evgeny Voevodin
    int insn_len;
2480 7b5eff4d Evgeny Voevodin
    LOG_DIS("add.%c [$r%u%s, $r%u\n",
2481 7b5eff4d Evgeny Voevodin
            memsize_char(memsize),
2482 7b5eff4d Evgeny Voevodin
            dc->op1, dc->postinc ? "+]" : "]",
2483 7b5eff4d Evgeny Voevodin
            dc->op2);
2484 8170028d ths
2485 7b5eff4d Evgeny Voevodin
    cris_alu_m_alloc_temps(t);
2486 cf7e0c80 Aurelien Jarno
        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2487 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2488 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
2489 7b5eff4d Evgeny Voevodin
    do_postinc(dc, memsize);
2490 7b5eff4d Evgeny Voevodin
    cris_alu_m_free_temps(t);
2491 7b5eff4d Evgeny Voevodin
    return insn_len;
2492 8170028d ths
}
2493 8170028d ths
2494 cf7e0c80 Aurelien Jarno
static int dec_bound_m(CPUCRISState *env, DisasContext *dc)
2495 8170028d ths
{
2496 7b5eff4d Evgeny Voevodin
    TCGv l[2];
2497 7b5eff4d Evgeny Voevodin
    int memsize = memsize_zz(dc);
2498 7b5eff4d Evgeny Voevodin
    int insn_len;
2499 7b5eff4d Evgeny Voevodin
    LOG_DIS("bound.%c [$r%u%s, $r%u\n",
2500 7b5eff4d Evgeny Voevodin
            memsize_char(memsize),
2501 7b5eff4d Evgeny Voevodin
            dc->op1, dc->postinc ? "+]" : "]",
2502 7b5eff4d Evgeny Voevodin
            dc->op2);
2503 8170028d ths
2504 7b5eff4d Evgeny Voevodin
    l[0] = tcg_temp_local_new();
2505 7b5eff4d Evgeny Voevodin
    l[1] = tcg_temp_local_new();
2506 cf7e0c80 Aurelien Jarno
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, l[0], l[1]);
2507 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
2508 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
2509 7b5eff4d Evgeny Voevodin
    do_postinc(dc, memsize);
2510 7b5eff4d Evgeny Voevodin
    tcg_temp_free(l[0]);
2511 7b5eff4d Evgeny Voevodin
    tcg_temp_free(l[1]);
2512 7b5eff4d Evgeny Voevodin
    return insn_len;
2513 8170028d ths
}
2514 8170028d ths
2515 cf7e0c80 Aurelien Jarno
static int dec_addc_mr(CPUCRISState *env, DisasContext *dc)
2516 8170028d ths
{
2517 7b5eff4d Evgeny Voevodin
    TCGv t[2];
2518 7b5eff4d Evgeny Voevodin
    int insn_len = 2;
2519 7b5eff4d Evgeny Voevodin
    LOG_DIS("addc [$r%u%s, $r%u\n",
2520 7b5eff4d Evgeny Voevodin
            dc->op1, dc->postinc ? "+]" : "]",
2521 7b5eff4d Evgeny Voevodin
            dc->op2);
2522 8170028d ths
2523 7b5eff4d Evgeny Voevodin
    cris_evaluate_flags(dc);
2524 a8cf66bb edgar_igl
2525 7b5eff4d Evgeny Voevodin
    /* Set for this insn.  */
2526 7b5eff4d Evgeny Voevodin
    dc->flagx_known = 1;
2527 7b5eff4d Evgeny Voevodin
    dc->flags_x = X_FLAG;
2528 a8cf66bb edgar_igl
2529 7b5eff4d Evgeny Voevodin
    cris_alu_m_alloc_temps(t);
2530 cf7e0c80 Aurelien Jarno
        insn_len = dec_prep_alu_m(env, dc, 0, 4, t[0], t[1]);
2531 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
2532 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
2533 7b5eff4d Evgeny Voevodin
    do_postinc(dc, 4);
2534 7b5eff4d Evgeny Voevodin
    cris_alu_m_free_temps(t);
2535 7b5eff4d Evgeny Voevodin
    return insn_len;
2536 8170028d ths
}
2537 8170028d ths
2538 cf7e0c80 Aurelien Jarno
static int dec_sub_m(CPUCRISState *env, DisasContext *dc)
2539 8170028d ths
{
2540 7b5eff4d Evgeny Voevodin
    TCGv t[2];
2541 7b5eff4d Evgeny Voevodin
    int memsize = memsize_zz(dc);
2542 7b5eff4d Evgeny Voevodin
    int insn_len;
2543 7b5eff4d Evgeny Voevodin
    LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2544 7b5eff4d Evgeny Voevodin
            memsize_char(memsize),
2545 7b5eff4d Evgeny Voevodin
            dc->op1, dc->postinc ? "+]" : "]",
2546 7b5eff4d Evgeny Voevodin
            dc->op2, dc->ir, dc->zzsize);
2547 8170028d ths
2548 7b5eff4d Evgeny Voevodin
    cris_alu_m_alloc_temps(t);
2549 cf7e0c80 Aurelien Jarno
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2550 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZVC);
2551 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
2552 7b5eff4d Evgeny Voevodin
    do_postinc(dc, memsize);
2553 7b5eff4d Evgeny Voevodin
    cris_alu_m_free_temps(t);
2554 7b5eff4d Evgeny Voevodin
    return insn_len;
2555 8170028d ths
}
2556 8170028d ths
2557 cf7e0c80 Aurelien Jarno
static int dec_or_m(CPUCRISState *env, DisasContext *dc)
2558 8170028d ths
{
2559 7b5eff4d Evgeny Voevodin
    TCGv t[2];
2560 7b5eff4d Evgeny Voevodin
    int memsize = memsize_zz(dc);
2561 7b5eff4d Evgeny Voevodin
    int insn_len;
2562 7b5eff4d Evgeny Voevodin
    LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
2563 7b5eff4d Evgeny Voevodin
            memsize_char(memsize),
2564 7b5eff4d Evgeny Voevodin
            dc->op1, dc->postinc ? "+]" : "]",
2565 7b5eff4d Evgeny Voevodin
            dc->op2, dc->pc);
2566 8170028d ths
2567 7b5eff4d Evgeny Voevodin
    cris_alu_m_alloc_temps(t);
2568 cf7e0c80 Aurelien Jarno
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2569 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, CC_MASK_NZ);
2570 7b5eff4d Evgeny Voevodin
    cris_alu(dc, CC_OP_OR,
2571 7b5eff4d Evgeny Voevodin
            cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2572 7b5eff4d Evgeny Voevodin
    do_postinc(dc, memsize);
2573 7b5eff4d Evgeny Voevodin
    cris_alu_m_free_temps(t);
2574 7b5eff4d Evgeny Voevodin
    return insn_len;
2575 8170028d ths
}
2576 8170028d ths
2577 cf7e0c80 Aurelien Jarno
static int dec_move_mp(CPUCRISState *env, DisasContext *dc)
2578 8170028d ths
{
2579 7b5eff4d Evgeny Voevodin
    TCGv t[2];
2580 7b5eff4d Evgeny Voevodin
    int memsize = memsize_zz(dc);
2581 7b5eff4d Evgeny Voevodin
    int insn_len = 2;
2582 8170028d ths
2583 7b5eff4d Evgeny Voevodin
    LOG_DIS("move.%c [$r%u%s, $p%u\n",
2584 7b5eff4d Evgeny Voevodin
            memsize_char(memsize),
2585 7b5eff4d Evgeny Voevodin
            dc->op1,
2586 7b5eff4d Evgeny Voevodin
            dc->postinc ? "+]" : "]",
2587 7b5eff4d Evgeny Voevodin
            dc->op2);
2588 8170028d ths
2589 7b5eff4d Evgeny Voevodin
    cris_alu_m_alloc_temps(t);
2590 cf7e0c80 Aurelien Jarno
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2591 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2592 7b5eff4d Evgeny Voevodin
    if (dc->op2 == PR_CCS) {
2593 7b5eff4d Evgeny Voevodin
        cris_evaluate_flags(dc);
2594 7b5eff4d Evgeny Voevodin
        if (dc->tb_flags & U_FLAG) {
2595 7b5eff4d Evgeny Voevodin
            /* User space is not allowed to touch all flags.  */
2596 7b5eff4d Evgeny Voevodin
            tcg_gen_andi_tl(t[1], t[1], 0x39f);
2597 7b5eff4d Evgeny Voevodin
            tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
2598 7b5eff4d Evgeny Voevodin
            tcg_gen_or_tl(t[1], t[0], t[1]);
2599 7b5eff4d Evgeny Voevodin
        }
2600 7b5eff4d Evgeny Voevodin
    }
2601 b41f7df0 edgar_igl
2602 7b5eff4d Evgeny Voevodin
    t_gen_mov_preg_TN(dc, dc->op2, t[1]);
2603 8170028d ths
2604 7b5eff4d Evgeny Voevodin
    do_postinc(dc, memsize);
2605 7b5eff4d Evgeny Voevodin
    cris_alu_m_free_temps(t);
2606 7b5eff4d Evgeny Voevodin
    return insn_len;
2607 8170028d ths
}
2608 8170028d ths
2609 cf7e0c80 Aurelien Jarno
static int dec_move_pm(CPUCRISState *env, DisasContext *dc)
2610 8170028d ths
{
2611 7b5eff4d Evgeny Voevodin
    TCGv t0;
2612 7b5eff4d Evgeny Voevodin
    int memsize;
2613 8170028d ths
2614 7b5eff4d Evgeny Voevodin
    memsize = preg_sizes[dc->op2];
2615 8170028d ths
2616 7b5eff4d Evgeny Voevodin
    LOG_DIS("move.%c $p%u, [$r%u%s\n",
2617 7b5eff4d Evgeny Voevodin
            memsize_char(memsize),
2618 7b5eff4d Evgeny Voevodin
            dc->op2, dc->op1, dc->postinc ? "+]" : "]");
2619 8170028d ths
2620 7b5eff4d Evgeny Voevodin
    /* prepare store. Address in T0, value in T1.  */
2621 7b5eff4d Evgeny Voevodin
    if (dc->op2 == PR_CCS) {
2622 7b5eff4d Evgeny Voevodin
        cris_evaluate_flags(dc);
2623 7b5eff4d Evgeny Voevodin
    }
2624 7b5eff4d Evgeny Voevodin
    t0 = tcg_temp_new();
2625 7b5eff4d Evgeny Voevodin
    t_gen_mov_TN_preg(t0, dc->op2);
2626 7b5eff4d Evgeny Voevodin
    cris_flush_cc_state(dc);
2627 7b5eff4d Evgeny Voevodin
    gen_store(dc, cpu_R[dc->op1], t0, memsize);
2628 7b5eff4d Evgeny Voevodin
    tcg_temp_free(t0);
2629 7b5eff4d Evgeny Voevodin
2630 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2631 7b5eff4d Evgeny Voevodin
    if (dc->postinc) {
2632 7b5eff4d Evgeny Voevodin
        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2633 7b5eff4d Evgeny Voevodin
    }
2634 7b5eff4d Evgeny Voevodin
    return 2;
2635 8170028d ths
}
2636 8170028d ths
2637 cf7e0c80 Aurelien Jarno
static int dec_movem_mr(CPUCRISState *env, DisasContext *dc)
2638 8170028d ths
{
2639 7b5eff4d Evgeny Voevodin
    TCGv_i64 tmp[16];
2640 7b5eff4d Evgeny Voevodin
    TCGv tmp32;
2641 7b5eff4d Evgeny Voevodin
    TCGv addr;
2642 7b5eff4d Evgeny Voevodin
    int i;
2643 7b5eff4d Evgeny Voevodin
    int nr = dc->op2 + 1;
2644 7b5eff4d Evgeny Voevodin
2645 7b5eff4d Evgeny Voevodin
    LOG_DIS("movem [$r%u%s, $r%u\n", dc->op1,
2646 7b5eff4d Evgeny Voevodin
            dc->postinc ? "+]" : "]", dc->op2);
2647 7b5eff4d Evgeny Voevodin
2648 7b5eff4d Evgeny Voevodin
    addr = tcg_temp_new();
2649 7b5eff4d Evgeny Voevodin
    /* There are probably better ways of doing this.  */
2650 7b5eff4d Evgeny Voevodin
    cris_flush_cc_state(dc);
2651 7b5eff4d Evgeny Voevodin
    for (i = 0; i < (nr >> 1); i++) {
2652 7b5eff4d Evgeny Voevodin
        tmp[i] = tcg_temp_new_i64();
2653 7b5eff4d Evgeny Voevodin
        tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2654 7b5eff4d Evgeny Voevodin
        gen_load64(dc, tmp[i], addr);
2655 7b5eff4d Evgeny Voevodin
    }
2656 7b5eff4d Evgeny Voevodin
    if (nr & 1) {
2657 7b5eff4d Evgeny Voevodin
        tmp32 = tcg_temp_new_i32();
2658 7b5eff4d Evgeny Voevodin
        tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2659 7b5eff4d Evgeny Voevodin
        gen_load(dc, tmp32, addr, 4, 0);
2660 7b5eff4d Evgeny Voevodin
    } else {
2661 7b5eff4d Evgeny Voevodin
        TCGV_UNUSED(tmp32);
2662 7b5eff4d Evgeny Voevodin
    }
2663 7b5eff4d Evgeny Voevodin
    tcg_temp_free(addr);
2664 7b5eff4d Evgeny Voevodin
2665 7b5eff4d Evgeny Voevodin
    for (i = 0; i < (nr >> 1); i++) {
2666 7b5eff4d Evgeny Voevodin
        tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]);
2667 7b5eff4d Evgeny Voevodin
        tcg_gen_shri_i64(tmp[i], tmp[i], 32);
2668 7b5eff4d Evgeny Voevodin
        tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
2669 7b5eff4d Evgeny Voevodin
        tcg_temp_free_i64(tmp[i]);
2670 7b5eff4d Evgeny Voevodin
    }
2671 7b5eff4d Evgeny Voevodin
    if (nr & 1) {
2672 7b5eff4d Evgeny Voevodin
        tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
2673 7b5eff4d Evgeny Voevodin
        tcg_temp_free(tmp32);
2674 7b5eff4d Evgeny Voevodin
    }
2675 7b5eff4d Evgeny Voevodin
2676 7b5eff4d Evgeny Voevodin
    /* writeback the updated pointer value.  */
2677 7b5eff4d Evgeny Voevodin
    if (dc->postinc) {
2678 7b5eff4d Evgeny Voevodin
        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);
2679 7b5eff4d Evgeny Voevodin
    }
2680 7b5eff4d Evgeny Voevodin
2681 7b5eff4d Evgeny Voevodin
    /* gen_load might want to evaluate the previous insns flags.  */
2682 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2683 7b5eff4d Evgeny Voevodin
    return 2;
2684 8170028d ths
}
2685 8170028d ths
2686 cf7e0c80 Aurelien Jarno
static int dec_movem_rm(CPUCRISState *env, DisasContext *dc)
2687 8170028d ths
{
2688 7b5eff4d Evgeny Voevodin
    TCGv tmp;
2689 7b5eff4d Evgeny Voevodin
    TCGv addr;
2690 7b5eff4d Evgeny Voevodin
    int i;
2691 7b5eff4d Evgeny Voevodin
2692 7b5eff4d Evgeny Voevodin
    LOG_DIS("movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
2693 7b5eff4d Evgeny Voevodin
            dc->postinc ? "+]" : "]");
2694 7b5eff4d Evgeny Voevodin
2695 7b5eff4d Evgeny Voevodin
    cris_flush_cc_state(dc);
2696 7b5eff4d Evgeny Voevodin
2697 7b5eff4d Evgeny Voevodin
    tmp = tcg_temp_new();
2698 7b5eff4d Evgeny Voevodin
    addr = tcg_temp_new();
2699 7b5eff4d Evgeny Voevodin
    tcg_gen_movi_tl(tmp, 4);
2700 7b5eff4d Evgeny Voevodin
    tcg_gen_mov_tl(addr, cpu_R[dc->op1]);
2701 7b5eff4d Evgeny Voevodin
    for (i = 0; i <= dc->op2; i++) {
2702 7b5eff4d Evgeny Voevodin
        /* Displace addr.  */
2703 7b5eff4d Evgeny Voevodin
        /* Perform the store.  */
2704 7b5eff4d Evgeny Voevodin
        gen_store(dc, addr, cpu_R[i], 4);
2705 7b5eff4d Evgeny Voevodin
        tcg_gen_add_tl(addr, addr, tmp);
2706 7b5eff4d Evgeny Voevodin
    }
2707 7b5eff4d Evgeny Voevodin
    if (dc->postinc) {
2708 7b5eff4d Evgeny Voevodin
        tcg_gen_mov_tl(cpu_R[dc->op1], addr);
2709 7b5eff4d Evgeny Voevodin
    }
2710 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2711 7b5eff4d Evgeny Voevodin
    tcg_temp_free(tmp);
2712 7b5eff4d Evgeny Voevodin
    tcg_temp_free(addr);
2713 7b5eff4d Evgeny Voevodin
    return 2;
2714 8170028d ths
}
2715 8170028d ths
2716 cf7e0c80 Aurelien Jarno
static int dec_move_rm(CPUCRISState *env, DisasContext *dc)
2717 8170028d ths
{
2718 7b5eff4d Evgeny Voevodin
    int memsize;
2719 8170028d ths
2720 7b5eff4d Evgeny Voevodin
    memsize = memsize_zz(dc);
2721 8170028d ths
2722 7b5eff4d Evgeny Voevodin
    LOG_DIS("move.%c $r%u, [$r%u]\n",
2723 7b5eff4d Evgeny Voevodin
            memsize_char(memsize), dc->op2, dc->op1);
2724 8170028d ths
2725 7b5eff4d Evgeny Voevodin
    /* prepare store.  */
2726 7b5eff4d Evgeny Voevodin
    cris_flush_cc_state(dc);
2727 7b5eff4d Evgeny Voevodin
    gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
2728 17ac9754 edgar_igl
2729 7b5eff4d Evgeny Voevodin
    if (dc->postinc) {
2730 7b5eff4d Evgeny Voevodin
        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2731 7b5eff4d Evgeny Voevodin
    }
2732 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2733 7b5eff4d Evgeny Voevodin
    return 2;
2734 8170028d ths
}
2735 8170028d ths
2736 cf7e0c80 Aurelien Jarno
static int dec_lapcq(CPUCRISState *env, DisasContext *dc)
2737 8170028d ths
{
2738 7b5eff4d Evgeny Voevodin
    LOG_DIS("lapcq %x, $r%u\n",
2739 7b5eff4d Evgeny Voevodin
            dc->pc + dc->op1*2, dc->op2);
2740 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2741 7b5eff4d Evgeny Voevodin
    tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2);
2742 7b5eff4d Evgeny Voevodin
    return 2;
2743 8170028d ths
}
2744 8170028d ths
2745 cf7e0c80 Aurelien Jarno
static int dec_lapc_im(CPUCRISState *env, DisasContext *dc)
2746 8170028d ths
{
2747 7b5eff4d Evgeny Voevodin
    unsigned int rd;
2748 7b5eff4d Evgeny Voevodin
    int32_t imm;
2749 7b5eff4d Evgeny Voevodin
    int32_t pc;
2750 8170028d ths
2751 7b5eff4d Evgeny Voevodin
    rd = dc->op2;
2752 8170028d ths
2753 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2754 7b5eff4d Evgeny Voevodin
    imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2755 7b5eff4d Evgeny Voevodin
    LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
2756 b41f7df0 edgar_igl
2757 7b5eff4d Evgeny Voevodin
    pc = dc->pc;
2758 7b5eff4d Evgeny Voevodin
    pc += imm;
2759 7b5eff4d Evgeny Voevodin
    tcg_gen_movi_tl(cpu_R[rd], pc);
2760 7b5eff4d Evgeny Voevodin
    return 6;
2761 8170028d ths
}
2762 8170028d ths
2763 8170028d ths
/* Jump to special reg.  */
2764 cf7e0c80 Aurelien Jarno
static int dec_jump_p(CPUCRISState *env, DisasContext *dc)
2765 8170028d ths
{
2766 7b5eff4d Evgeny Voevodin
    LOG_DIS("jump $p%u\n", dc->op2);
2767 b41f7df0 edgar_igl
2768 7b5eff4d Evgeny Voevodin
    if (dc->op2 == PR_CCS) {
2769 7b5eff4d Evgeny Voevodin
        cris_evaluate_flags(dc);
2770 7b5eff4d Evgeny Voevodin
    }
2771 7b5eff4d Evgeny Voevodin
    t_gen_mov_TN_preg(env_btarget, dc->op2);
2772 7b5eff4d Evgeny Voevodin
    /* rete will often have low bit set to indicate delayslot.  */
2773 7b5eff4d Evgeny Voevodin
    tcg_gen_andi_tl(env_btarget, env_btarget, ~1);
2774 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2775 7b5eff4d Evgeny Voevodin
    cris_prepare_jmp(dc, JMP_INDIRECT);
2776 7b5eff4d Evgeny Voevodin
    return 2;
2777 8170028d ths
}
2778 8170028d ths
2779 8170028d ths
/* Jump and save.  */
2780 cf7e0c80 Aurelien Jarno
static int dec_jas_r(CPUCRISState *env, DisasContext *dc)
2781 8170028d ths
{
2782 7b5eff4d Evgeny Voevodin
    LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2);
2783 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2784 7b5eff4d Evgeny Voevodin
    /* Store the return address in Pd.  */
2785 7b5eff4d Evgeny Voevodin
    tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2786 7b5eff4d Evgeny Voevodin
    if (dc->op2 > 15) {
2787 7b5eff4d Evgeny Voevodin
        abort();
2788 7b5eff4d Evgeny Voevodin
    }
2789 7b5eff4d Evgeny Voevodin
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4));
2790 b41f7df0 edgar_igl
2791 7b5eff4d Evgeny Voevodin
    cris_prepare_jmp(dc, JMP_INDIRECT);
2792 7b5eff4d Evgeny Voevodin
    return 2;
2793 8170028d ths
}
2794 8170028d ths
2795 cf7e0c80 Aurelien Jarno
static int dec_jas_im(CPUCRISState *env, DisasContext *dc)
2796 8170028d ths
{
2797 7b5eff4d Evgeny Voevodin
    uint32_t imm;
2798 8170028d ths
2799 7b5eff4d Evgeny Voevodin
    imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2800 8170028d ths
2801 7b5eff4d Evgeny Voevodin
    LOG_DIS("jas 0x%x\n", imm);
2802 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2803 7b5eff4d Evgeny Voevodin
    /* Store the return address in Pd.  */
2804 7b5eff4d Evgeny Voevodin
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2805 2a44f7f1 edgar_igl
2806 7b5eff4d Evgeny Voevodin
    dc->jmp_pc = imm;
2807 7b5eff4d Evgeny Voevodin
    cris_prepare_jmp(dc, JMP_DIRECT);
2808 7b5eff4d Evgeny Voevodin
    return 6;
2809 8170028d ths
}
2810 8170028d ths
2811 cf7e0c80 Aurelien Jarno
static int dec_jasc_im(CPUCRISState *env, DisasContext *dc)
2812 8170028d ths
{
2813 7b5eff4d Evgeny Voevodin
    uint32_t imm;
2814 8170028d ths
2815 7b5eff4d Evgeny Voevodin
    imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2816 8170028d ths
2817 7b5eff4d Evgeny Voevodin
    LOG_DIS("jasc 0x%x\n", imm);
2818 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2819 7b5eff4d Evgeny Voevodin
    /* Store the return address in Pd.  */
2820 7b5eff4d Evgeny Voevodin
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8 + 4));
2821 2a44f7f1 edgar_igl
2822 7b5eff4d Evgeny Voevodin
    dc->jmp_pc = imm;
2823 7b5eff4d Evgeny Voevodin
    cris_prepare_jmp(dc, JMP_DIRECT);
2824 7b5eff4d Evgeny Voevodin
    return 6;
2825 8170028d ths
}
2826 8170028d ths
2827 cf7e0c80 Aurelien Jarno
static int dec_jasc_r(CPUCRISState *env, DisasContext *dc)
2828 8170028d ths
{
2829 7b5eff4d Evgeny Voevodin
    LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2);
2830 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2831 7b5eff4d Evgeny Voevodin
    /* Store the return address in Pd.  */
2832 7b5eff4d Evgeny Voevodin
    tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2833 7b5eff4d Evgeny Voevodin
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4 + 4));
2834 7b5eff4d Evgeny Voevodin
    cris_prepare_jmp(dc, JMP_INDIRECT);
2835 7b5eff4d Evgeny Voevodin
    return 2;
2836 8170028d ths
}
2837 8170028d ths
2838 cf7e0c80 Aurelien Jarno
static int dec_bcc_im(CPUCRISState *env, DisasContext *dc)
2839 8170028d ths
{
2840 7b5eff4d Evgeny Voevodin
    int32_t offset;
2841 7b5eff4d Evgeny Voevodin
    uint32_t cond = dc->op2;
2842 8170028d ths
2843 7b5eff4d Evgeny Voevodin
    offset = cris_fetch(env, dc, dc->pc + 2, 2, 1);
2844 8170028d ths
2845 7b5eff4d Evgeny Voevodin
    LOG_DIS("b%s %d pc=%x dst=%x\n",
2846 7b5eff4d Evgeny Voevodin
            cc_name(cond), offset,
2847 7b5eff4d Evgeny Voevodin
            dc->pc, dc->pc + offset);
2848 8170028d ths
2849 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2850 7b5eff4d Evgeny Voevodin
    /* op2 holds the condition-code.  */
2851 7b5eff4d Evgeny Voevodin
    cris_prepare_cc_branch(dc, offset, cond);
2852 7b5eff4d Evgeny Voevodin
    return 4;
2853 8170028d ths
}
2854 8170028d ths
2855 cf7e0c80 Aurelien Jarno
static int dec_bas_im(CPUCRISState *env, DisasContext *dc)
2856 8170028d ths
{
2857 7b5eff4d Evgeny Voevodin
    int32_t simm;
2858 8170028d ths
2859 7b5eff4d Evgeny Voevodin
    simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2860 8170028d ths
2861 7b5eff4d Evgeny Voevodin
    LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2862 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2863 7b5eff4d Evgeny Voevodin
    /* Store the return address in Pd.  */
2864 7b5eff4d Evgeny Voevodin
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2865 8170028d ths
2866 7b5eff4d Evgeny Voevodin
    dc->jmp_pc = dc->pc + simm;
2867 7b5eff4d Evgeny Voevodin
    cris_prepare_jmp(dc, JMP_DIRECT);
2868 7b5eff4d Evgeny Voevodin
    return 6;
2869 8170028d ths
}
2870 8170028d ths
2871 cf7e0c80 Aurelien Jarno
static int dec_basc_im(CPUCRISState *env, DisasContext *dc)
2872 8170028d ths
{
2873 7b5eff4d Evgeny Voevodin
    int32_t simm;
2874 7b5eff4d Evgeny Voevodin
    simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2875 8170028d ths
2876 7b5eff4d Evgeny Voevodin
    LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2877 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2878 7b5eff4d Evgeny Voevodin
    /* Store the return address in Pd.  */
2879 7b5eff4d Evgeny Voevodin
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 12));
2880 2a44f7f1 edgar_igl
2881 7b5eff4d Evgeny Voevodin
    dc->jmp_pc = dc->pc + simm;
2882 7b5eff4d Evgeny Voevodin
    cris_prepare_jmp(dc, JMP_DIRECT);
2883 7b5eff4d Evgeny Voevodin
    return 6;
2884 8170028d ths
}
2885 8170028d ths
2886 cf7e0c80 Aurelien Jarno
static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
2887 8170028d ths
{
2888 7b5eff4d Evgeny Voevodin
    cris_cc_mask(dc, 0);
2889 7b5eff4d Evgeny Voevodin
2890 7b5eff4d Evgeny Voevodin
    if (dc->op2 == 15) {
2891 259186a7 Andreas Färber
        tcg_gen_st_i32(tcg_const_i32(1), cpu_env,
2892 259186a7 Andreas Färber
                       -offsetof(CRISCPU, env) + offsetof(CPUState, halted));
2893 7b5eff4d Evgeny Voevodin
        tcg_gen_movi_tl(env_pc, dc->pc + 2);
2894 7b5eff4d Evgeny Voevodin
        t_gen_raise_exception(EXCP_HLT);
2895 7b5eff4d Evgeny Voevodin
        return 2;
2896 7b5eff4d Evgeny Voevodin
    }
2897 7b5eff4d Evgeny Voevodin
2898 7b5eff4d Evgeny Voevodin
    switch (dc->op2 & 7) {
2899 7b5eff4d Evgeny Voevodin
    case 2:
2900 7b5eff4d Evgeny Voevodin
        /* rfe.  */
2901 7b5eff4d Evgeny Voevodin
        LOG_DIS("rfe\n");
2902 7b5eff4d Evgeny Voevodin
        cris_evaluate_flags(dc);
2903 7b5eff4d Evgeny Voevodin
        gen_helper_rfe(cpu_env);
2904 7b5eff4d Evgeny Voevodin
        dc->is_jmp = DISAS_UPDATE;
2905 7b5eff4d Evgeny Voevodin
        break;
2906 7b5eff4d Evgeny Voevodin
    case 5:
2907 7b5eff4d Evgeny Voevodin
        /* rfn.  */
2908 7b5eff4d Evgeny Voevodin
        LOG_DIS("rfn\n");
2909 7b5eff4d Evgeny Voevodin
        cris_evaluate_flags(dc);
2910 7b5eff4d Evgeny Voevodin
        gen_helper_rfn(cpu_env);
2911 7b5eff4d Evgeny Voevodin
        dc->is_jmp = DISAS_UPDATE;
2912 7b5eff4d Evgeny Voevodin
        break;
2913 7b5eff4d Evgeny Voevodin
    case 6:
2914 7b5eff4d Evgeny Voevodin
        LOG_DIS("break %d\n", dc->op1);
2915 7b5eff4d Evgeny Voevodin
        cris_evaluate_flags(dc);
2916 7b5eff4d Evgeny Voevodin
        /* break.  */
2917 7b5eff4d Evgeny Voevodin
        tcg_gen_movi_tl(env_pc, dc->pc + 2);
2918 7b5eff4d Evgeny Voevodin
2919 7b5eff4d Evgeny Voevodin
        /* Breaks start at 16 in the exception vector.  */
2920 7b5eff4d Evgeny Voevodin
        t_gen_mov_env_TN(trap_vector,
2921 7b5eff4d Evgeny Voevodin
                tcg_const_tl(dc->op1 + 16));
2922 7b5eff4d Evgeny Voevodin
        t_gen_raise_exception(EXCP_BREAK);
2923 7b5eff4d Evgeny Voevodin
        dc->is_jmp = DISAS_UPDATE;
2924 7b5eff4d Evgeny Voevodin
        break;
2925 7b5eff4d Evgeny Voevodin
    default:
2926 7b5eff4d Evgeny Voevodin
        printf("op2=%x\n", dc->op2);
2927 7b5eff4d Evgeny Voevodin
        BUG();
2928 7b5eff4d Evgeny Voevodin
        break;
2929 7b5eff4d Evgeny Voevodin
2930 7b5eff4d Evgeny Voevodin
    }
2931 7b5eff4d Evgeny Voevodin
    return 2;
2932 8170028d ths
}
2933 8170028d ths
2934 cf7e0c80 Aurelien Jarno
static int dec_ftag_fidx_d_m(CPUCRISState *env, DisasContext *dc)
2935 5d4a534d edgar_igl
{
2936 7b5eff4d Evgeny Voevodin
    return 2;
2937 5d4a534d edgar_igl
}
2938 5d4a534d edgar_igl
2939 cf7e0c80 Aurelien Jarno
static int dec_ftag_fidx_i_m(CPUCRISState *env, DisasContext *dc)
2940 5d4a534d edgar_igl
{
2941 7b5eff4d Evgeny Voevodin
    return 2;
2942 5d4a534d edgar_igl
}
2943 5d4a534d edgar_igl
2944 cf7e0c80 Aurelien Jarno
static int dec_null(CPUCRISState *env, DisasContext *dc)
2945 8170028d ths
{
2946 7b5eff4d Evgeny Voevodin
    printf("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2947 7b5eff4d Evgeny Voevodin
        dc->pc, dc->opcode, dc->op1, dc->op2);
2948 7b5eff4d Evgeny Voevodin
    fflush(NULL);
2949 7b5eff4d Evgeny Voevodin
    BUG();
2950 7b5eff4d Evgeny Voevodin
    return 2;
2951 8170028d ths
}
2952 8170028d ths
2953 9b32fbf8 edgar_igl
static struct decoder_info {
2954 7b5eff4d Evgeny Voevodin
    struct {
2955 7b5eff4d Evgeny Voevodin
        uint32_t bits;
2956 7b5eff4d Evgeny Voevodin
        uint32_t mask;
2957 7b5eff4d Evgeny Voevodin
    };
2958 7b5eff4d Evgeny Voevodin
    int (*dec)(CPUCRISState *env, DisasContext *dc);
2959 8170028d ths
} decinfo[] = {
2960 7b5eff4d Evgeny Voevodin
    /* Order matters here.  */
2961 7b5eff4d Evgeny Voevodin
    {DEC_MOVEQ, dec_moveq},
2962 7b5eff4d Evgeny Voevodin
    {DEC_BTSTQ, dec_btstq},
2963 7b5eff4d Evgeny Voevodin
    {DEC_CMPQ, dec_cmpq},
2964 7b5eff4d Evgeny Voevodin
    {DEC_ADDOQ, dec_addoq},
2965 7b5eff4d Evgeny Voevodin
    {DEC_ADDQ, dec_addq},
2966 7b5eff4d Evgeny Voevodin
    {DEC_SUBQ, dec_subq},
2967 7b5eff4d Evgeny Voevodin
    {DEC_ANDQ, dec_andq},
2968 7b5eff4d Evgeny Voevodin
    {DEC_ORQ, dec_orq},
2969 7b5eff4d Evgeny Voevodin
    {DEC_ASRQ, dec_asrq},
2970 7b5eff4d Evgeny Voevodin
    {DEC_LSLQ, dec_lslq},
2971 7b5eff4d Evgeny Voevodin
    {DEC_LSRQ, dec_lsrq},
2972 7b5eff4d Evgeny Voevodin
    {DEC_BCCQ, dec_bccq},
2973 7b5eff4d Evgeny Voevodin
2974 7b5eff4d Evgeny Voevodin
    {DEC_BCC_IM, dec_bcc_im},
2975 7b5eff4d Evgeny Voevodin
    {DEC_JAS_IM, dec_jas_im},
2976 7b5eff4d Evgeny Voevodin
    {DEC_JAS_R, dec_jas_r},
2977 7b5eff4d Evgeny Voevodin
    {DEC_JASC_IM, dec_jasc_im},
2978 7b5eff4d Evgeny Voevodin
    {DEC_JASC_R, dec_jasc_r},
2979 7b5eff4d Evgeny Voevodin
    {DEC_BAS_IM, dec_bas_im},
2980 7b5eff4d Evgeny Voevodin
    {DEC_BASC_IM, dec_basc_im},
2981 7b5eff4d Evgeny Voevodin
    {DEC_JUMP_P, dec_jump_p},
2982 7b5eff4d Evgeny Voevodin
    {DEC_LAPC_IM, dec_lapc_im},
2983 7b5eff4d Evgeny Voevodin
    {DEC_LAPCQ, dec_lapcq},
2984 7b5eff4d Evgeny Voevodin
2985 7b5eff4d Evgeny Voevodin
    {DEC_RFE_ETC, dec_rfe_etc},
2986 7b5eff4d Evgeny Voevodin
    {DEC_ADDC_MR, dec_addc_mr},
2987 7b5eff4d Evgeny Voevodin
2988 7b5eff4d Evgeny Voevodin
    {DEC_MOVE_MP, dec_move_mp},
2989 7b5eff4d Evgeny Voevodin
    {DEC_MOVE_PM, dec_move_pm},
2990 7b5eff4d Evgeny Voevodin
    {DEC_MOVEM_MR, dec_movem_mr},
2991 7b5eff4d Evgeny Voevodin
    {DEC_MOVEM_RM, dec_movem_rm},
2992 7b5eff4d Evgeny Voevodin
    {DEC_MOVE_PR, dec_move_pr},
2993 7b5eff4d Evgeny Voevodin
    {DEC_SCC_R, dec_scc_r},
2994 7b5eff4d Evgeny Voevodin
    {DEC_SETF, dec_setclrf},
2995 7b5eff4d Evgeny Voevodin
    {DEC_CLEARF, dec_setclrf},
2996 7b5eff4d Evgeny Voevodin
2997 7b5eff4d Evgeny Voevodin
    {DEC_MOVE_SR, dec_move_sr},
2998 7b5eff4d Evgeny Voevodin
    {DEC_MOVE_RP, dec_move_rp},
2999 7b5eff4d Evgeny Voevodin
    {DEC_SWAP_R, dec_swap_r},
3000 7b5eff4d Evgeny Voevodin
    {DEC_ABS_R, dec_abs_r},
3001 7b5eff4d Evgeny Voevodin
    {DEC_LZ_R, dec_lz_r},
3002 7b5eff4d Evgeny Voevodin
    {DEC_MOVE_RS, dec_move_rs},
3003 7b5eff4d Evgeny Voevodin
    {DEC_BTST_R, dec_btst_r},
3004 7b5eff4d Evgeny Voevodin
    {DEC_ADDC_R, dec_addc_r},
3005 7b5eff4d Evgeny Voevodin
3006 7b5eff4d Evgeny Voevodin
    {DEC_DSTEP_R, dec_dstep_r},
3007 7b5eff4d Evgeny Voevodin
    {DEC_XOR_R, dec_xor_r},
3008 7b5eff4d Evgeny Voevodin
    {DEC_MCP_R, dec_mcp_r},
3009 7b5eff4d Evgeny Voevodin
    {DEC_CMP_R, dec_cmp_r},
3010 7b5eff4d Evgeny Voevodin
3011 7b5eff4d Evgeny Voevodin
    {DEC_ADDI_R, dec_addi_r},
3012 7b5eff4d Evgeny Voevodin
    {DEC_ADDI_ACR, dec_addi_acr},
3013 7b5eff4d Evgeny Voevodin
3014 7b5eff4d Evgeny Voevodin
    {DEC_ADD_R, dec_add_r},
3015 7b5eff4d Evgeny Voevodin
    {DEC_SUB_R, dec_sub_r},
3016 7b5eff4d Evgeny Voevodin
3017 7b5eff4d Evgeny Voevodin
    {DEC_ADDU_R, dec_addu_r},
3018 7b5eff4d Evgeny Voevodin
    {DEC_ADDS_R, dec_adds_r},
3019 7b5eff4d Evgeny Voevodin
    {DEC_SUBU_R, dec_subu_r},
3020 7b5eff4d Evgeny Voevodin
    {DEC_SUBS_R, dec_subs_r},
3021 7b5eff4d Evgeny Voevodin
    {DEC_LSL_R, dec_lsl_r},
3022 7b5eff4d Evgeny Voevodin
3023 7b5eff4d Evgeny Voevodin
    {DEC_AND_R, dec_and_r},
3024 7b5eff4d Evgeny Voevodin
    {DEC_OR_R, dec_or_r},
3025 7b5eff4d Evgeny Voevodin
    {DEC_BOUND_R, dec_bound_r},
3026 7b5eff4d Evgeny Voevodin
    {DEC_ASR_R, dec_asr_r},
3027 7b5eff4d Evgeny Voevodin
    {DEC_LSR_R, dec_lsr_r},
3028 7b5eff4d Evgeny Voevodin
3029 7b5eff4d Evgeny Voevodin
    {DEC_MOVU_R, dec_movu_r},
3030 7b5eff4d Evgeny Voevodin
    {DEC_MOVS_R, dec_movs_r},
3031 7b5eff4d Evgeny Voevodin
    {DEC_NEG_R, dec_neg_r},
3032 7b5eff4d Evgeny Voevodin
    {DEC_MOVE_R, dec_move_r},
3033 7b5eff4d Evgeny Voevodin
3034 7b5eff4d Evgeny Voevodin
    {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
3035 7b5eff4d Evgeny Voevodin
    {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
3036 7b5eff4d Evgeny Voevodin
3037 7b5eff4d Evgeny Voevodin
    {DEC_MULS_R, dec_muls_r},
3038 7b5eff4d Evgeny Voevodin
    {DEC_MULU_R, dec_mulu_r},
3039 7b5eff4d Evgeny Voevodin
3040 7b5eff4d Evgeny Voevodin
    {DEC_ADDU_M, dec_addu_m},
3041 7b5eff4d Evgeny Voevodin
    {DEC_ADDS_M, dec_adds_m},
3042 7b5eff4d Evgeny Voevodin
    {DEC_SUBU_M, dec_subu_m},
3043 7b5eff4d Evgeny Voevodin
    {DEC_SUBS_M, dec_subs_m},
3044 7b5eff4d Evgeny Voevodin
3045 7b5eff4d Evgeny Voevodin
    {DEC_CMPU_M, dec_cmpu_m},
3046 7b5eff4d Evgeny Voevodin
    {DEC_CMPS_M, dec_cmps_m},
3047 7b5eff4d Evgeny Voevodin
    {DEC_MOVU_M, dec_movu_m},
3048 7b5eff4d Evgeny Voevodin
    {DEC_MOVS_M, dec_movs_m},
3049 7b5eff4d Evgeny Voevodin
3050 7b5eff4d Evgeny Voevodin
    {DEC_CMP_M, dec_cmp_m},
3051 7b5eff4d Evgeny Voevodin
    {DEC_ADDO_M, dec_addo_m},
3052 7b5eff4d Evgeny Voevodin
    {DEC_BOUND_M, dec_bound_m},
3053 7b5eff4d Evgeny Voevodin
    {DEC_ADD_M, dec_add_m},
3054 7b5eff4d Evgeny Voevodin
    {DEC_SUB_M, dec_sub_m},
3055 7b5eff4d Evgeny Voevodin
    {DEC_AND_M, dec_and_m},
3056 7b5eff4d Evgeny Voevodin
    {DEC_OR_M, dec_or_m},
3057 7b5eff4d Evgeny Voevodin
    {DEC_MOVE_RM, dec_move_rm},
3058 7b5eff4d Evgeny Voevodin
    {DEC_TEST_M, dec_test_m},
3059 7b5eff4d Evgeny Voevodin
    {DEC_MOVE_MR, dec_move_mr},
3060 7b5eff4d Evgeny Voevodin
3061 7b5eff4d Evgeny Voevodin
    {{0, 0}, dec_null}
3062 8170028d ths
};
3063 8170028d ths
3064 cf7e0c80 Aurelien Jarno
static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
3065 8170028d ths
{
3066 7b5eff4d Evgeny Voevodin
    int insn_len = 2;
3067 7b5eff4d Evgeny Voevodin
    int i;
3068 8170028d ths
3069 7b5eff4d Evgeny Voevodin
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3070 7b5eff4d Evgeny Voevodin
        tcg_gen_debug_insn_start(dc->pc);
3071 fdefe51c Richard Henderson
        }
3072 28de16da edgar_igl
3073 7b5eff4d Evgeny Voevodin
    /* Load a halfword onto the instruction register.  */
3074 cf7e0c80 Aurelien Jarno
        dc->ir = cris_fetch(env, dc, dc->pc, 2, 0);
3075 8170028d ths
3076 7b5eff4d Evgeny Voevodin
    /* Now decode it.  */
3077 7b5eff4d Evgeny Voevodin
    dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
3078 7b5eff4d Evgeny Voevodin
    dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
3079 7b5eff4d Evgeny Voevodin
    dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
3080 7b5eff4d Evgeny Voevodin
    dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
3081 7b5eff4d Evgeny Voevodin
    dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
3082 7b5eff4d Evgeny Voevodin
    dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
3083 7b5eff4d Evgeny Voevodin
3084 7b5eff4d Evgeny Voevodin
    /* Large switch for all insns.  */
3085 7b5eff4d Evgeny Voevodin
    for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
3086 7b5eff4d Evgeny Voevodin
        if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
3087 7b5eff4d Evgeny Voevodin
            insn_len = decinfo[i].dec(env, dc);
3088 7b5eff4d Evgeny Voevodin
            break;
3089 7b5eff4d Evgeny Voevodin
        }
3090 7b5eff4d Evgeny Voevodin
    }
3091 8170028d ths
3092 dd20fcd0 edgar_igl
#if !defined(CONFIG_USER_ONLY)
3093 7b5eff4d Evgeny Voevodin
    /* Single-stepping ?  */
3094 7b5eff4d Evgeny Voevodin
    if (dc->tb_flags & S_FLAG) {
3095 7b5eff4d Evgeny Voevodin
        int l1;
3096 7b5eff4d Evgeny Voevodin
3097 7b5eff4d Evgeny Voevodin
        l1 = gen_new_label();
3098 7b5eff4d Evgeny Voevodin
        tcg_gen_brcondi_tl(TCG_COND_NE, cpu_PR[PR_SPC], dc->pc, l1);
3099 7b5eff4d Evgeny Voevodin
        /* We treat SPC as a break with an odd trap vector.  */
3100 7b5eff4d Evgeny Voevodin
        cris_evaluate_flags(dc);
3101 7b5eff4d Evgeny Voevodin
        t_gen_mov_env_TN(trap_vector, tcg_const_tl(3));
3102 7b5eff4d Evgeny Voevodin
        tcg_gen_movi_tl(env_pc, dc->pc + insn_len);
3103 7b5eff4d Evgeny Voevodin
        tcg_gen_movi_tl(cpu_PR[PR_SPC], dc->pc + insn_len);
3104 7b5eff4d Evgeny Voevodin
        t_gen_raise_exception(EXCP_BREAK);
3105 7b5eff4d Evgeny Voevodin
        gen_set_label(l1);
3106 7b5eff4d Evgeny Voevodin
    }
3107 a1aebcb8 edgar_igl
#endif
3108 7b5eff4d Evgeny Voevodin
    return insn_len;
3109 8170028d ths
}
3110 8170028d ths
3111 a1170bfd Andreas Färber
static void check_breakpoint(CPUCRISState *env, DisasContext *dc)
3112 8170028d ths
{
3113 7b5eff4d Evgeny Voevodin
    CPUBreakpoint *bp;
3114 a1d1bb31 aliguori
3115 7b5eff4d Evgeny Voevodin
    if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
3116 7b5eff4d Evgeny Voevodin
        QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
3117 7b5eff4d Evgeny Voevodin
            if (bp->pc == dc->pc) {
3118 7b5eff4d Evgeny Voevodin
                cris_evaluate_flags(dc);
3119 7b5eff4d Evgeny Voevodin
                tcg_gen_movi_tl(env_pc, dc->pc);
3120 7b5eff4d Evgeny Voevodin
                t_gen_raise_exception(EXCP_DEBUG);
3121 7b5eff4d Evgeny Voevodin
                dc->is_jmp = DISAS_UPDATE;
3122 7b5eff4d Evgeny Voevodin
            }
3123 7b5eff4d Evgeny Voevodin
        }
3124 7b5eff4d Evgeny Voevodin
    }
3125 8170028d ths
}
3126 8170028d ths
3127 40e9eddd Edgar E. Iglesias
#include "translate_v10.c"
3128 cf1d97f0 edgar_igl
3129 cf1d97f0 edgar_igl
/*
3130 cf1d97f0 edgar_igl
 * Delay slots on QEMU/CRIS.
3131 cf1d97f0 edgar_igl
 *
3132 cf1d97f0 edgar_igl
 * If an exception hits on a delayslot, the core will let ERP (the Exception
3133 cf1d97f0 edgar_igl
 * Return Pointer) point to the branch (the previous) insn and set the lsb to
3134 cf1d97f0 edgar_igl
 * to give SW a hint that the exception actually hit on the dslot.
3135 cf1d97f0 edgar_igl
 *
3136 cf1d97f0 edgar_igl
 * CRIS expects all PC addresses to be 16-bit aligned. The lsb is ignored by
3137 cf1d97f0 edgar_igl
 * the core and any jmp to an odd addresses will mask off that lsb. It is 
3138 cf1d97f0 edgar_igl
 * simply there to let sw know there was an exception on a dslot.
3139 cf1d97f0 edgar_igl
 *
3140 cf1d97f0 edgar_igl
 * When the software returns from an exception, the branch will re-execute.
3141 cf1d97f0 edgar_igl
 * On QEMU care needs to be taken when a branch+delayslot sequence is broken
3142 cf1d97f0 edgar_igl
 * and the branch and delayslot dont share pages.
3143 cf1d97f0 edgar_igl
 *
3144 cf1d97f0 edgar_igl
 * The TB contaning the branch insn will set up env->btarget and evaluate 
3145 cf1d97f0 edgar_igl
 * env->btaken. When the translation loop exits we will note that the branch 
3146 cf1d97f0 edgar_igl
 * sequence is broken and let env->dslot be the size of the branch insn (those
3147 cf1d97f0 edgar_igl
 * vary in length).
3148 cf1d97f0 edgar_igl
 *
3149 cf1d97f0 edgar_igl
 * The TB contaning the delayslot will have the PC of its real insn (i.e no lsb
3150 cf1d97f0 edgar_igl
 * set). It will also expect to have env->dslot setup with the size of the 
3151 cf1d97f0 edgar_igl
 * delay slot so that env->pc - env->dslot point to the branch insn. This TB 
3152 cf1d97f0 edgar_igl
 * will execute the dslot and take the branch, either to btarget or just one 
3153 cf1d97f0 edgar_igl
 * insn ahead.
3154 cf1d97f0 edgar_igl
 *
3155 cf1d97f0 edgar_igl
 * When exceptions occur, we check for env->dslot in do_interrupt to detect 
3156 cf1d97f0 edgar_igl
 * broken branch sequences and setup $erp accordingly (i.e let it point to the
3157 cf1d97f0 edgar_igl
 * branch and set lsb). Then env->dslot gets cleared so that the exception 
3158 cf1d97f0 edgar_igl
 * handler can enter. When returning from exceptions (jump $erp) the lsb gets
3159 cf1d97f0 edgar_igl
 * masked off and we will reexecute the branch insn.
3160 cf1d97f0 edgar_igl
 *
3161 cf1d97f0 edgar_igl
 */
3162 cf1d97f0 edgar_igl
3163 8170028d ths
/* generate intermediate code for basic block 'tb'.  */
3164 6f47ec50 Andreas Färber
static inline void
3165 7fd2592d Andreas Färber
gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
3166 7fd2592d Andreas Färber
                               bool search_pc)
3167 8170028d ths
{
3168 7fd2592d Andreas Färber
    CPUCRISState *env = &cpu->env;
3169 7b5eff4d Evgeny Voevodin
    uint16_t *gen_opc_end;
3170 7b5eff4d Evgeny Voevodin
    uint32_t pc_start;
3171 7b5eff4d Evgeny Voevodin
    unsigned int insn_len;
3172 7b5eff4d Evgeny Voevodin
    int j, lj;
3173 7b5eff4d Evgeny Voevodin
    struct DisasContext ctx;
3174 7b5eff4d Evgeny Voevodin
    struct DisasContext *dc = &ctx;
3175 7b5eff4d Evgeny Voevodin
    uint32_t next_page_start;
3176 7b5eff4d Evgeny Voevodin
    target_ulong npc;
3177 7b5eff4d Evgeny Voevodin
    int num_insns;
3178 7b5eff4d Evgeny Voevodin
    int max_insns;
3179 7b5eff4d Evgeny Voevodin
3180 7b5eff4d Evgeny Voevodin
    if (env->pregs[PR_VR] == 32) {
3181 7b5eff4d Evgeny Voevodin
        dc->decoder = crisv32_decoder;
3182 7b5eff4d Evgeny Voevodin
        dc->clear_locked_irq = 0;
3183 7b5eff4d Evgeny Voevodin
    } else {
3184 7b5eff4d Evgeny Voevodin
        dc->decoder = crisv10_decoder;
3185 7b5eff4d Evgeny Voevodin
        dc->clear_locked_irq = 1;
3186 7b5eff4d Evgeny Voevodin
    }
3187 7b5eff4d Evgeny Voevodin
3188 7b5eff4d Evgeny Voevodin
    /* Odd PC indicates that branch is rexecuting due to exception in the
3189 7b5eff4d Evgeny Voevodin
     * delayslot, like in real hw.
3190 7b5eff4d Evgeny Voevodin
     */
3191 7b5eff4d Evgeny Voevodin
    pc_start = tb->pc & ~1;
3192 7b5eff4d Evgeny Voevodin
    dc->env = env;
3193 7b5eff4d Evgeny Voevodin
    dc->tb = tb;
3194 7b5eff4d Evgeny Voevodin
3195 92414b31 Evgeny Voevodin
    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
3196 7b5eff4d Evgeny Voevodin
3197 7b5eff4d Evgeny Voevodin
    dc->is_jmp = DISAS_NEXT;
3198 7b5eff4d Evgeny Voevodin
    dc->ppc = pc_start;
3199 7b5eff4d Evgeny Voevodin
    dc->pc = pc_start;
3200 7b5eff4d Evgeny Voevodin
    dc->singlestep_enabled = env->singlestep_enabled;
3201 7b5eff4d Evgeny Voevodin
    dc->flags_uptodate = 1;
3202 7b5eff4d Evgeny Voevodin
    dc->flagx_known = 1;
3203 7b5eff4d Evgeny Voevodin
    dc->flags_x = tb->flags & X_FLAG;
3204 7b5eff4d Evgeny Voevodin
    dc->cc_x_uptodate = 0;
3205 7b5eff4d Evgeny Voevodin
    dc->cc_mask = 0;
3206 7b5eff4d Evgeny Voevodin
    dc->update_cc = 0;
3207 7b5eff4d Evgeny Voevodin
    dc->clear_prefix = 0;
3208 7b5eff4d Evgeny Voevodin
3209 7b5eff4d Evgeny Voevodin
    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
3210 7b5eff4d Evgeny Voevodin
    dc->cc_size_uptodate = -1;
3211 7b5eff4d Evgeny Voevodin
3212 7b5eff4d Evgeny Voevodin
    /* Decode TB flags.  */
3213 7b5eff4d Evgeny Voevodin
    dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
3214 7b5eff4d Evgeny Voevodin
            | X_FLAG | PFIX_FLAG);
3215 7b5eff4d Evgeny Voevodin
    dc->delayed_branch = !!(tb->flags & 7);
3216 7b5eff4d Evgeny Voevodin
    if (dc->delayed_branch) {
3217 7b5eff4d Evgeny Voevodin
        dc->jmp = JMP_INDIRECT;
3218 7b5eff4d Evgeny Voevodin
    } else {
3219 7b5eff4d Evgeny Voevodin
        dc->jmp = JMP_NOJMP;
3220 7b5eff4d Evgeny Voevodin
    }
3221 7b5eff4d Evgeny Voevodin
3222 7b5eff4d Evgeny Voevodin
    dc->cpustate_changed = 0;
3223 7b5eff4d Evgeny Voevodin
3224 7b5eff4d Evgeny Voevodin
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3225 7b5eff4d Evgeny Voevodin
        qemu_log(
3226 7b5eff4d Evgeny Voevodin
                "srch=%d pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n"
3227 7b5eff4d Evgeny Voevodin
                "pid=%x usp=%x\n"
3228 7b5eff4d Evgeny Voevodin
                "%x.%x.%x.%x\n"
3229 7b5eff4d Evgeny Voevodin
                "%x.%x.%x.%x\n"
3230 7b5eff4d Evgeny Voevodin
                "%x.%x.%x.%x\n"
3231 7b5eff4d Evgeny Voevodin
                "%x.%x.%x.%x\n",
3232 7b5eff4d Evgeny Voevodin
                search_pc, dc->pc, dc->ppc,
3233 7b5eff4d Evgeny Voevodin
                (uint64_t)tb->flags,
3234 7b5eff4d Evgeny Voevodin
                env->btarget, (unsigned)tb->flags & 7,
3235 7b5eff4d Evgeny Voevodin
                env->pregs[PR_CCS],
3236 7b5eff4d Evgeny Voevodin
                env->pregs[PR_PID], env->pregs[PR_USP],
3237 7b5eff4d Evgeny Voevodin
                env->regs[0], env->regs[1], env->regs[2], env->regs[3],
3238 7b5eff4d Evgeny Voevodin
                env->regs[4], env->regs[5], env->regs[6], env->regs[7],
3239 7b5eff4d Evgeny Voevodin
                env->regs[8], env->regs[9],
3240 7b5eff4d Evgeny Voevodin
                env->regs[10], env->regs[11],
3241 7b5eff4d Evgeny Voevodin
                env->regs[12], env->regs[13],
3242 7b5eff4d Evgeny Voevodin
                env->regs[14], env->regs[15]);
3243 7b5eff4d Evgeny Voevodin
        qemu_log("--------------\n");
3244 7b5eff4d Evgeny Voevodin
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
3245 7b5eff4d Evgeny Voevodin
    }
3246 7b5eff4d Evgeny Voevodin
3247 7b5eff4d Evgeny Voevodin
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
3248 7b5eff4d Evgeny Voevodin
    lj = -1;
3249 7b5eff4d Evgeny Voevodin
    num_insns = 0;
3250 7b5eff4d Evgeny Voevodin
    max_insns = tb->cflags & CF_COUNT_MASK;
3251 7b5eff4d Evgeny Voevodin
    if (max_insns == 0) {
3252 7b5eff4d Evgeny Voevodin
        max_insns = CF_COUNT_MASK;
3253 7b5eff4d Evgeny Voevodin
    }
3254 7b5eff4d Evgeny Voevodin
3255 806f352d Peter Maydell
    gen_tb_start();
3256 7b5eff4d Evgeny Voevodin
    do {
3257 7b5eff4d Evgeny Voevodin
        check_breakpoint(env, dc);
3258 7b5eff4d Evgeny Voevodin
3259 7b5eff4d Evgeny Voevodin
        if (search_pc) {
3260 92414b31 Evgeny Voevodin
            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3261 7b5eff4d Evgeny Voevodin
            if (lj < j) {
3262 7b5eff4d Evgeny Voevodin
                lj++;
3263 7b5eff4d Evgeny Voevodin
                while (lj < j) {
3264 ab1103de Evgeny Voevodin
                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
3265 7b5eff4d Evgeny Voevodin
                }
3266 7b5eff4d Evgeny Voevodin
            }
3267 7b5eff4d Evgeny Voevodin
            if (dc->delayed_branch == 1) {
3268 25983cad Evgeny Voevodin
                tcg_ctx.gen_opc_pc[lj] = dc->ppc | 1;
3269 7b5eff4d Evgeny Voevodin
            } else {
3270 25983cad Evgeny Voevodin
                tcg_ctx.gen_opc_pc[lj] = dc->pc;
3271 7b5eff4d Evgeny Voevodin
            }
3272 ab1103de Evgeny Voevodin
            tcg_ctx.gen_opc_instr_start[lj] = 1;
3273 c9c99c22 Evgeny Voevodin
            tcg_ctx.gen_opc_icount[lj] = num_insns;
3274 7b5eff4d Evgeny Voevodin
        }
3275 7b5eff4d Evgeny Voevodin
3276 7b5eff4d Evgeny Voevodin
        /* Pretty disas.  */
3277 7b5eff4d Evgeny Voevodin
        LOG_DIS("%8.8x:\t", dc->pc);
3278 7b5eff4d Evgeny Voevodin
3279 7b5eff4d Evgeny Voevodin
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
3280 7b5eff4d Evgeny Voevodin
            gen_io_start();
3281 7b5eff4d Evgeny Voevodin
        }
3282 7b5eff4d Evgeny Voevodin
        dc->clear_x = 1;
3283 7b5eff4d Evgeny Voevodin
3284 7b5eff4d Evgeny Voevodin
        insn_len = dc->decoder(env, dc);
3285 7b5eff4d Evgeny Voevodin
        dc->ppc = dc->pc;
3286 7b5eff4d Evgeny Voevodin
        dc->pc += insn_len;
3287 7b5eff4d Evgeny Voevodin
        if (dc->clear_x) {
3288 7b5eff4d Evgeny Voevodin
            cris_clear_x_flag(dc);
3289 7b5eff4d Evgeny Voevodin
        }
3290 7b5eff4d Evgeny Voevodin
3291 7b5eff4d Evgeny Voevodin
        num_insns++;
3292 7b5eff4d Evgeny Voevodin
        /* Check for delayed branches here. If we do it before
3293 7b5eff4d Evgeny Voevodin
           actually generating any host code, the simulator will just
3294 7b5eff4d Evgeny Voevodin
           loop doing nothing for on this program location.  */
3295 7b5eff4d Evgeny Voevodin
        if (dc->delayed_branch) {
3296 7b5eff4d Evgeny Voevodin
            dc->delayed_branch--;
3297 7b5eff4d Evgeny Voevodin
            if (dc->delayed_branch == 0) {
3298 7b5eff4d Evgeny Voevodin
                if (tb->flags & 7) {
3299 7b5eff4d Evgeny Voevodin
                    t_gen_mov_env_TN(dslot, tcg_const_tl(0));
3300 7b5eff4d Evgeny Voevodin
                }
3301 7b5eff4d Evgeny Voevodin
                if (dc->cpustate_changed || !dc->flagx_known
3302 7b5eff4d Evgeny Voevodin
                    || (dc->flags_x != (tb->flags & X_FLAG))) {
3303 7b5eff4d Evgeny Voevodin
                    cris_store_direct_jmp(dc);
3304 7b5eff4d Evgeny Voevodin
                }
3305 7b5eff4d Evgeny Voevodin
3306 7b5eff4d Evgeny Voevodin
                if (dc->clear_locked_irq) {
3307 7b5eff4d Evgeny Voevodin
                    dc->clear_locked_irq = 0;
3308 7b5eff4d Evgeny Voevodin
                    t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
3309 7b5eff4d Evgeny Voevodin
                }
3310 7b5eff4d Evgeny Voevodin
3311 7b5eff4d Evgeny Voevodin
                if (dc->jmp == JMP_DIRECT_CC) {
3312 7b5eff4d Evgeny Voevodin
                    int l1;
3313 7b5eff4d Evgeny Voevodin
3314 7b5eff4d Evgeny Voevodin
                    l1 = gen_new_label();
3315 7b5eff4d Evgeny Voevodin
                    cris_evaluate_flags(dc);
3316 7b5eff4d Evgeny Voevodin
3317 7b5eff4d Evgeny Voevodin
                    /* Conditional jmp.  */
3318 7b5eff4d Evgeny Voevodin
                    tcg_gen_brcondi_tl(TCG_COND_EQ,
3319 7b5eff4d Evgeny Voevodin
                               env_btaken, 0, l1);
3320 7b5eff4d Evgeny Voevodin
                    gen_goto_tb(dc, 1, dc->jmp_pc);
3321 7b5eff4d Evgeny Voevodin
                    gen_set_label(l1);
3322 7b5eff4d Evgeny Voevodin
                    gen_goto_tb(dc, 0, dc->pc);
3323 7b5eff4d Evgeny Voevodin
                    dc->is_jmp = DISAS_TB_JUMP;
3324 7b5eff4d Evgeny Voevodin
                    dc->jmp = JMP_NOJMP;
3325 7b5eff4d Evgeny Voevodin
                } else if (dc->jmp == JMP_DIRECT) {
3326 7b5eff4d Evgeny Voevodin
                    cris_evaluate_flags(dc);
3327 7b5eff4d Evgeny Voevodin
                    gen_goto_tb(dc, 0, dc->jmp_pc);
3328 7b5eff4d Evgeny Voevodin
                    dc->is_jmp = DISAS_TB_JUMP;
3329 7b5eff4d Evgeny Voevodin
                    dc->jmp = JMP_NOJMP;
3330 7b5eff4d Evgeny Voevodin
                } else {
3331 7b5eff4d Evgeny Voevodin
                    t_gen_cc_jmp(env_btarget, tcg_const_tl(dc->pc));
3332 7b5eff4d Evgeny Voevodin
                    dc->is_jmp = DISAS_JUMP;
3333 7b5eff4d Evgeny Voevodin
                }
3334 7b5eff4d Evgeny Voevodin
                break;
3335 7b5eff4d Evgeny Voevodin
            }
3336 7b5eff4d Evgeny Voevodin
        }
3337 7b5eff4d Evgeny Voevodin
3338 7b5eff4d Evgeny Voevodin
        /* If we are rexecuting a branch due to exceptions on
3339 7b5eff4d Evgeny Voevodin
           delay slots dont break.  */
3340 7b5eff4d Evgeny Voevodin
        if (!(tb->pc & 1) && env->singlestep_enabled) {
3341 7b5eff4d Evgeny Voevodin
            break;
3342 7b5eff4d Evgeny Voevodin
        }
3343 7b5eff4d Evgeny Voevodin
    } while (!dc->is_jmp && !dc->cpustate_changed
3344 efd7f486 Evgeny Voevodin
            && tcg_ctx.gen_opc_ptr < gen_opc_end
3345 7b5eff4d Evgeny Voevodin
            && !singlestep
3346 7b5eff4d Evgeny Voevodin
            && (dc->pc < next_page_start)
3347 7b5eff4d Evgeny Voevodin
            && num_insns < max_insns);
3348 7b5eff4d Evgeny Voevodin
3349 7b5eff4d Evgeny Voevodin
    if (dc->clear_locked_irq) {
3350 7b5eff4d Evgeny Voevodin
        t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
3351 7b5eff4d Evgeny Voevodin
    }
3352 7b5eff4d Evgeny Voevodin
3353 7b5eff4d Evgeny Voevodin
    npc = dc->pc;
3354 2a44f7f1 edgar_igl
3355 2e70f6ef pbrook
        if (tb->cflags & CF_LAST_IO)
3356 2e70f6ef pbrook
            gen_io_end();
3357 7b5eff4d Evgeny Voevodin
    /* Force an update if the per-tb cpu state has changed.  */
3358 7b5eff4d Evgeny Voevodin
    if (dc->is_jmp == DISAS_NEXT
3359 7b5eff4d Evgeny Voevodin
        && (dc->cpustate_changed || !dc->flagx_known
3360 7b5eff4d Evgeny Voevodin
        || (dc->flags_x != (tb->flags & X_FLAG)))) {
3361 7b5eff4d Evgeny Voevodin
        dc->is_jmp = DISAS_UPDATE;
3362 7b5eff4d Evgeny Voevodin
        tcg_gen_movi_tl(env_pc, npc);
3363 7b5eff4d Evgeny Voevodin
    }
3364 7b5eff4d Evgeny Voevodin
    /* Broken branch+delayslot sequence.  */
3365 7b5eff4d Evgeny Voevodin
    if (dc->delayed_branch == 1) {
3366 7b5eff4d Evgeny Voevodin
        /* Set env->dslot to the size of the branch insn.  */
3367 7b5eff4d Evgeny Voevodin
        t_gen_mov_env_TN(dslot, tcg_const_tl(dc->pc - dc->ppc));
3368 7b5eff4d Evgeny Voevodin
        cris_store_direct_jmp(dc);
3369 7b5eff4d Evgeny Voevodin
    }
3370 7b5eff4d Evgeny Voevodin
3371 7b5eff4d Evgeny Voevodin
    cris_evaluate_flags(dc);
3372 7b5eff4d Evgeny Voevodin
3373 7b5eff4d Evgeny Voevodin
    if (unlikely(env->singlestep_enabled)) {
3374 7b5eff4d Evgeny Voevodin
        if (dc->is_jmp == DISAS_NEXT) {
3375 7b5eff4d Evgeny Voevodin
            tcg_gen_movi_tl(env_pc, npc);
3376 7b5eff4d Evgeny Voevodin
        }
3377 7b5eff4d Evgeny Voevodin
        t_gen_raise_exception(EXCP_DEBUG);
3378 7b5eff4d Evgeny Voevodin
    } else {
3379 7b5eff4d Evgeny Voevodin
        switch (dc->is_jmp) {
3380 7b5eff4d Evgeny Voevodin
        case DISAS_NEXT:
3381 7b5eff4d Evgeny Voevodin
            gen_goto_tb(dc, 1, npc);
3382 7b5eff4d Evgeny Voevodin
            break;
3383 7b5eff4d Evgeny Voevodin
        default:
3384 7b5eff4d Evgeny Voevodin
        case DISAS_JUMP:
3385 7b5eff4d Evgeny Voevodin
        case DISAS_UPDATE:
3386 7b5eff4d Evgeny Voevodin
            /* indicate that the hash table must be used
3387 7b5eff4d Evgeny Voevodin
                   to find the next TB */
3388 7b5eff4d Evgeny Voevodin
            tcg_gen_exit_tb(0);
3389 7b5eff4d Evgeny Voevodin
            break;
3390 7b5eff4d Evgeny Voevodin
        case DISAS_SWI:
3391 7b5eff4d Evgeny Voevodin
        case DISAS_TB_JUMP:
3392 7b5eff4d Evgeny Voevodin
            /* nothing more to generate */
3393 7b5eff4d Evgeny Voevodin
            break;
3394 7b5eff4d Evgeny Voevodin
        }
3395 7b5eff4d Evgeny Voevodin
    }
3396 806f352d Peter Maydell
    gen_tb_end(tb, num_insns);
3397 efd7f486 Evgeny Voevodin
    *tcg_ctx.gen_opc_ptr = INDEX_op_end;
3398 7b5eff4d Evgeny Voevodin
    if (search_pc) {
3399 92414b31 Evgeny Voevodin
        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3400 7b5eff4d Evgeny Voevodin
        lj++;
3401 7b5eff4d Evgeny Voevodin
        while (lj <= j) {
3402 ab1103de Evgeny Voevodin
            tcg_ctx.gen_opc_instr_start[lj++] = 0;
3403 7b5eff4d Evgeny Voevodin
        }
3404 7b5eff4d Evgeny Voevodin
    } else {
3405 7b5eff4d Evgeny Voevodin
        tb->size = dc->pc - pc_start;
3406 7b5eff4d Evgeny Voevodin
        tb->icount = num_insns;
3407 7b5eff4d Evgeny Voevodin
    }
3408 8170028d ths
3409 8170028d ths
#ifdef DEBUG_DISAS
3410 a1aebcb8 edgar_igl
#if !DISAS_CRIS
3411 7b5eff4d Evgeny Voevodin
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3412 7b5eff4d Evgeny Voevodin
        log_target_disas(env, pc_start, dc->pc - pc_start,
3413 40e9eddd Edgar E. Iglesias
                                 dc->env->pregs[PR_VR]);
3414 7b5eff4d Evgeny Voevodin
        qemu_log("\nisize=%d osize=%td\n",
3415 92414b31 Evgeny Voevodin
            dc->pc - pc_start, tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf);
3416 7b5eff4d Evgeny Voevodin
    }
3417 8170028d ths
#endif
3418 a1aebcb8 edgar_igl
#endif
3419 8170028d ths
}
3420 8170028d ths
3421 a1170bfd Andreas Färber
void gen_intermediate_code (CPUCRISState *env, struct TranslationBlock *tb)
3422 8170028d ths
{
3423 7fd2592d Andreas Färber
    gen_intermediate_code_internal(cris_env_get_cpu(env), tb, false);
3424 8170028d ths
}
3425 8170028d ths
3426 a1170bfd Andreas Färber
void gen_intermediate_code_pc (CPUCRISState *env, struct TranslationBlock *tb)
3427 8170028d ths
{
3428 7fd2592d Andreas Färber
    gen_intermediate_code_internal(cris_env_get_cpu(env), tb, true);
3429 8170028d ths
}
3430 8170028d ths
3431 878096ee Andreas Färber
void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
3432 878096ee Andreas Färber
                         int flags)
3433 8170028d ths
{
3434 878096ee Andreas Färber
    CRISCPU *cpu = CRIS_CPU(cs);
3435 878096ee Andreas Färber
    CPUCRISState *env = &cpu->env;
3436 7b5eff4d Evgeny Voevodin
    int i;
3437 7b5eff4d Evgeny Voevodin
    uint32_t srs;
3438 7b5eff4d Evgeny Voevodin
3439 7b5eff4d Evgeny Voevodin
    if (!env || !f) {
3440 7b5eff4d Evgeny Voevodin
        return;
3441 7b5eff4d Evgeny Voevodin
    }
3442 7b5eff4d Evgeny Voevodin
3443 7b5eff4d Evgeny Voevodin
    cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
3444 7b5eff4d Evgeny Voevodin
            "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
3445 7b5eff4d Evgeny Voevodin
            env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
3446 7b5eff4d Evgeny Voevodin
            env->cc_op,
3447 7b5eff4d Evgeny Voevodin
            env->cc_src, env->cc_dest, env->cc_result, env->cc_mask);
3448 7b5eff4d Evgeny Voevodin
3449 7b5eff4d Evgeny Voevodin
3450 7b5eff4d Evgeny Voevodin
    for (i = 0; i < 16; i++) {
3451 7b5eff4d Evgeny Voevodin
        cpu_fprintf(f, "%s=%8.8x ", regnames[i], env->regs[i]);
3452 7b5eff4d Evgeny Voevodin
        if ((i + 1) % 4 == 0) {
3453 7b5eff4d Evgeny Voevodin
            cpu_fprintf(f, "\n");
3454 7b5eff4d Evgeny Voevodin
        }
3455 7b5eff4d Evgeny Voevodin
    }
3456 7b5eff4d Evgeny Voevodin
    cpu_fprintf(f, "\nspecial regs:\n");
3457 7b5eff4d Evgeny Voevodin
    for (i = 0; i < 16; i++) {
3458 7b5eff4d Evgeny Voevodin
        cpu_fprintf(f, "%s=%8.8x ", pregnames[i], env->pregs[i]);
3459 7b5eff4d Evgeny Voevodin
        if ((i + 1) % 4 == 0) {
3460 7b5eff4d Evgeny Voevodin
            cpu_fprintf(f, "\n");
3461 7b5eff4d Evgeny Voevodin
        }
3462 7b5eff4d Evgeny Voevodin
    }
3463 7b5eff4d Evgeny Voevodin
    srs = env->pregs[PR_SRS];
3464 7b5eff4d Evgeny Voevodin
    cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
3465 7b5eff4d Evgeny Voevodin
    if (srs < ARRAY_SIZE(env->sregs)) {
3466 7b5eff4d Evgeny Voevodin
        for (i = 0; i < 16; i++) {
3467 7b5eff4d Evgeny Voevodin
            cpu_fprintf(f, "s%2.2d=%8.8x ",
3468 7b5eff4d Evgeny Voevodin
                    i, env->sregs[srs][i]);
3469 7b5eff4d Evgeny Voevodin
            if ((i + 1) % 4 == 0) {
3470 7b5eff4d Evgeny Voevodin
                cpu_fprintf(f, "\n");
3471 7b5eff4d Evgeny Voevodin
            }
3472 7b5eff4d Evgeny Voevodin
        }
3473 7b5eff4d Evgeny Voevodin
    }
3474 7b5eff4d Evgeny Voevodin
    cpu_fprintf(f, "\n\n");
3475 8170028d ths
3476 8170028d ths
}
3477 8170028d ths
3478 d1a94fec Andreas Färber
void cris_initialize_tcg(void)
3479 d1a94fec Andreas Färber
{
3480 d1a94fec Andreas Färber
    int i;
3481 05ba7d5f edgar_igl
3482 40e9eddd Edgar E. Iglesias
#define GEN_HELPER 2
3483 40e9eddd Edgar E. Iglesias
#include "helper.h"
3484 40e9eddd Edgar E. Iglesias
3485 dd10ce6d Andreas Färber
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
3486 dd10ce6d Andreas Färber
    cc_x = tcg_global_mem_new(TCG_AREG0,
3487 dd10ce6d Andreas Färber
                              offsetof(CPUCRISState, cc_x), "cc_x");
3488 dd10ce6d Andreas Färber
    cc_src = tcg_global_mem_new(TCG_AREG0,
3489 dd10ce6d Andreas Färber
                                offsetof(CPUCRISState, cc_src), "cc_src");
3490 dd10ce6d Andreas Färber
    cc_dest = tcg_global_mem_new(TCG_AREG0,
3491 dd10ce6d Andreas Färber
                                 offsetof(CPUCRISState, cc_dest),
3492 dd10ce6d Andreas Färber
                                 "cc_dest");
3493 dd10ce6d Andreas Färber
    cc_result = tcg_global_mem_new(TCG_AREG0,
3494 dd10ce6d Andreas Färber
                                   offsetof(CPUCRISState, cc_result),
3495 dd10ce6d Andreas Färber
                                   "cc_result");
3496 dd10ce6d Andreas Färber
    cc_op = tcg_global_mem_new(TCG_AREG0,
3497 dd10ce6d Andreas Färber
                               offsetof(CPUCRISState, cc_op), "cc_op");
3498 dd10ce6d Andreas Färber
    cc_size = tcg_global_mem_new(TCG_AREG0,
3499 dd10ce6d Andreas Färber
                                 offsetof(CPUCRISState, cc_size),
3500 dd10ce6d Andreas Färber
                                 "cc_size");
3501 dd10ce6d Andreas Färber
    cc_mask = tcg_global_mem_new(TCG_AREG0,
3502 dd10ce6d Andreas Färber
                                 offsetof(CPUCRISState, cc_mask),
3503 dd10ce6d Andreas Färber
                                 "cc_mask");
3504 dd10ce6d Andreas Färber
3505 dd10ce6d Andreas Färber
    env_pc = tcg_global_mem_new(TCG_AREG0,
3506 dd10ce6d Andreas Färber
                                offsetof(CPUCRISState, pc),
3507 dd10ce6d Andreas Färber
                                "pc");
3508 dd10ce6d Andreas Färber
    env_btarget = tcg_global_mem_new(TCG_AREG0,
3509 dd10ce6d Andreas Färber
                                     offsetof(CPUCRISState, btarget),
3510 dd10ce6d Andreas Färber
                                     "btarget");
3511 dd10ce6d Andreas Färber
    env_btaken = tcg_global_mem_new(TCG_AREG0,
3512 dd10ce6d Andreas Färber
                                    offsetof(CPUCRISState, btaken),
3513 dd10ce6d Andreas Färber
                                    "btaken");
3514 dd10ce6d Andreas Färber
    for (i = 0; i < 16; i++) {
3515 dd10ce6d Andreas Färber
        cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
3516 dd10ce6d Andreas Färber
                                      offsetof(CPUCRISState, regs[i]),
3517 dd10ce6d Andreas Färber
                                      regnames[i]);
3518 dd10ce6d Andreas Färber
    }
3519 dd10ce6d Andreas Färber
    for (i = 0; i < 16; i++) {
3520 dd10ce6d Andreas Färber
        cpu_PR[i] = tcg_global_mem_new(TCG_AREG0,
3521 dd10ce6d Andreas Färber
                                       offsetof(CPUCRISState, pregs[i]),
3522 dd10ce6d Andreas Färber
                                       pregnames[i]);
3523 dd10ce6d Andreas Färber
    }
3524 8170028d ths
}
3525 8170028d ths
3526 a1170bfd Andreas Färber
void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb, int pc_pos)
3527 d2856f1a aurel32
{
3528 25983cad Evgeny Voevodin
    env->pc = tcg_ctx.gen_opc_pc[pc_pos];
3529 d2856f1a aurel32
}