]> git.proxmox.com Git - qemu.git/blame - target-cris/translate_v10.c
cris: Add support for CRISv10 translation.
[qemu.git] / target-cris / translate_v10.c
CommitLineData
40e9eddd
EI
1/*
2 * CRISv10 emulation for qemu: main translation routines.
3 *
4 * Copyright (c) 2010 AXIS Communications AB
5 * Written by Edgar E. Iglesias.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
20 */
21
22#include "crisv10-decode.h"
23
24static const char *regnames_v10[] =
25{
26 "$r0", "$r1", "$r2", "$r3",
27 "$r4", "$r5", "$r6", "$r7",
28 "$r8", "$r9", "$r10", "$r11",
29 "$r12", "$r13", "$sp", "$pc",
30};
31
32static const char *pregnames_v10[] =
33{
34 "$bz", "$vr", "$p2", "$p3",
35 "$wz", "$ccr", "$p6-prefix", "$mof",
36 "$dz", "$ibr", "$irp", "$srp",
37 "$bar", "$dccr", "$brp", "$usp",
38};
39
40/* We need this table to handle preg-moves with implicit width. */
41static int preg_sizes_v10[] = {
42 1, /* bz. */
43 1, /* vr. */
44 1, /* pid. */
45 1, /* srs. */
46 2, /* wz. */
47 2, 2, 4,
48 4, 4, 4, 4,
49 4, 4, 4, 4,
50};
51
52static inline int dec10_size(unsigned int size)
53{
54 size++;
55 if (size == 3)
56 size++;
57 return size;
58}
59
60static inline void cris_illegal_insn(DisasContext *dc)
61{
62 qemu_log("illegal insn at pc=%x\n", dc->pc);
63 t_gen_raise_exception(EXCP_BREAK);
64}
65
66/* Prefix flag and register are used to handle the more complex
67 addressing modes. */
68static void cris_set_prefix(DisasContext *dc)
69{
70 dc->clear_prefix = 0;
71 dc->tb_flags |= PFIX_FLAG;
72 tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], PFIX_FLAG);
73
74 /* prefix insns dont clear the x flag. */
75 dc->clear_x = 0;
76 cris_lock_irq(dc);
77}
78
79static void crisv10_prepare_memaddr(DisasContext *dc,
80 TCGv addr, unsigned int size)
81{
82 if (dc->tb_flags & PFIX_FLAG) {
83 tcg_gen_mov_tl(addr, cpu_PR[PR_PREFIX]);
84 } else {
85 tcg_gen_mov_tl(addr, cpu_R[dc->src]);
86 }
87}
88
89static unsigned int crisv10_post_memaddr(DisasContext *dc, unsigned int size)
90{
91 unsigned int insn_len = 0;
92
93 if (dc->tb_flags & PFIX_FLAG) {
94 if (dc->mode == CRISV10_MODE_AUTOINC) {
95 tcg_gen_mov_tl(cpu_R[dc->src], cpu_PR[PR_PREFIX]);
96 }
97 } else {
98 if (dc->mode == CRISV10_MODE_AUTOINC) {
99 if (dc->src == 15) {
100 insn_len += size & ~1;
101 } else {
102 tcg_gen_addi_tl(cpu_R[dc->src], cpu_R[dc->src], size);
103 }
104 }
105 }
106 return insn_len;
107}
108
109static int dec10_prep_move_m(DisasContext *dc, int s_ext, int memsize,
110 TCGv dst)
111{
112 unsigned int rs, rd;
113 uint32_t imm;
114 int is_imm;
115 int insn_len = 0;
116
117 rs = dc->src;
118 rd = dc->dst;
119 is_imm = rs == 15 && !(dc->tb_flags & PFIX_FLAG);
120 LOG_DIS("rs=%d rd=%d is_imm=%d mode=%d pfix=%d\n",
121 rs, rd, is_imm, dc->mode, dc->tb_flags & PFIX_FLAG);
122
123 /* Load [$rs] onto T1. */
124 if (is_imm) {
125 if (memsize != 4) {
126 if (s_ext) {
127 if (memsize == 1)
128 imm = ldsb_code(dc->pc + 2);
129 else
130 imm = ldsw_code(dc->pc + 2);
131 } else {
132 if (memsize == 1)
133 imm = ldub_code(dc->pc + 2);
134 else
135 imm = lduw_code(dc->pc + 2);
136 }
137 } else
138 imm = ldl_code(dc->pc + 2);
139
140 tcg_gen_movi_tl(dst, imm);
141
142 if (dc->mode == CRISV10_MODE_AUTOINC) {
143 insn_len += memsize;
144 if (memsize == 1)
145 insn_len++;
146 tcg_gen_addi_tl(cpu_R[15], cpu_R[15], insn_len);
147 }
148 } else {
149 TCGv addr;
150
151 addr = tcg_temp_new();
152 cris_flush_cc_state(dc);
153 crisv10_prepare_memaddr(dc, addr, memsize);
154 gen_load(dc, dst, addr, memsize, 0);
155 if (s_ext)
156 t_gen_sext(dst, dst, memsize);
157 else
158 t_gen_zext(dst, dst, memsize);
159 insn_len += crisv10_post_memaddr(dc, memsize);
160 tcg_temp_free(addr);
161 }
162
163 if (dc->mode == CRISV10_MODE_INDIRECT && (dc->tb_flags & PFIX_FLAG)) {
164 dc->dst = dc->src;
165 }
166 return insn_len;
167}
168
169static unsigned int dec10_quick_imm(DisasContext *dc)
170{
171 int32_t imm, simm;
172 int op;
173
174 /* sign extend. */
175 imm = dc->ir & ((1 << 6) - 1);
176 simm = (int8_t) (imm << 2);
177 simm >>= 2;
178 switch (dc->opcode) {
179 case CRISV10_QIMM_BDAP_R0:
180 case CRISV10_QIMM_BDAP_R1:
181 case CRISV10_QIMM_BDAP_R2:
182 case CRISV10_QIMM_BDAP_R3:
183 simm = (int8_t)dc->ir;
184 LOG_DIS("bdap %d $r%d\n", simm, dc->dst);
185 LOG_DIS("pc=%x mode=%x quickimm %d r%d r%d\n",
186 dc->pc, dc->mode, dc->opcode, dc->src, dc->dst);
187 cris_set_prefix(dc);
188 if (dc->dst == 15) {
189 tcg_gen_movi_tl(cpu_PR[PR_PREFIX], dc->pc + 2 + simm);
190 } else {
191 tcg_gen_addi_tl(cpu_PR[PR_PREFIX], cpu_R[dc->dst], simm);
192 }
193 break;
194
195 case CRISV10_QIMM_MOVEQ:
196 LOG_DIS("moveq %d, $r%d\n", simm, dc->dst);
197
198 cris_cc_mask(dc, CC_MASK_NZVC);
199 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst],
200 cpu_R[dc->dst], tcg_const_tl(simm), 4);
201 break;
202 case CRISV10_QIMM_CMPQ:
203 LOG_DIS("cmpq %d, $r%d\n", simm, dc->dst);
204
205 cris_cc_mask(dc, CC_MASK_NZVC);
206 cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst],
207 cpu_R[dc->dst], tcg_const_tl(simm), 4);
208 break;
209 case CRISV10_QIMM_ADDQ:
210 LOG_DIS("addq %d, $r%d\n", imm, dc->dst);
211
212 cris_cc_mask(dc, CC_MASK_NZVC);
213 cris_alu(dc, CC_OP_ADD, cpu_R[dc->dst],
214 cpu_R[dc->dst], tcg_const_tl(imm), 4);
215 break;
216 case CRISV10_QIMM_ANDQ:
217 LOG_DIS("andq %d, $r%d\n", simm, dc->dst);
218
219 cris_cc_mask(dc, CC_MASK_NZVC);
220 cris_alu(dc, CC_OP_AND, cpu_R[dc->dst],
221 cpu_R[dc->dst], tcg_const_tl(simm), 4);
222 break;
223 case CRISV10_QIMM_ASHQ:
224 LOG_DIS("ashq %d, $r%d\n", simm, dc->dst);
225
226 cris_cc_mask(dc, CC_MASK_NZVC);
227 op = imm & (1 << 5);
228 imm &= 0x1f;
229 if (op) {
230 cris_alu(dc, CC_OP_ASR, cpu_R[dc->dst],
231 cpu_R[dc->dst], tcg_const_tl(imm), 4);
232 } else {
233 /* BTST */
234 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
235 gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->dst],
236 tcg_const_tl(imm), cpu_PR[PR_CCS]);
237 }
238 break;
239 case CRISV10_QIMM_LSHQ:
240 LOG_DIS("lshq %d, $r%d\n", simm, dc->dst);
241
242 op = CC_OP_LSL;
243 if (imm & (1 << 5)) {
244 op = CC_OP_LSR;
245 }
246 imm &= 0x1f;
247 cris_cc_mask(dc, CC_MASK_NZVC);
248 cris_alu(dc, op, cpu_R[dc->dst],
249 cpu_R[dc->dst], tcg_const_tl(imm), 4);
250 break;
251 case CRISV10_QIMM_SUBQ:
252 LOG_DIS("subq %d, $r%d\n", imm, dc->dst);
253
254 cris_cc_mask(dc, CC_MASK_NZVC);
255 cris_alu(dc, CC_OP_SUB, cpu_R[dc->dst],
256 cpu_R[dc->dst], tcg_const_tl(imm), 4);
257 break;
258 case CRISV10_QIMM_ORQ:
259 LOG_DIS("andq %d, $r%d\n", simm, dc->dst);
260
261 cris_cc_mask(dc, CC_MASK_NZVC);
262 cris_alu(dc, CC_OP_OR, cpu_R[dc->dst],
263 cpu_R[dc->dst], tcg_const_tl(simm), 4);
264 break;
265
266 case CRISV10_QIMM_BCC_R0:
267 if (!dc->ir) {
268 cpu_abort(dc->env, "opcode zero\n");
269 }
270 case CRISV10_QIMM_BCC_R1:
271 case CRISV10_QIMM_BCC_R2:
272 case CRISV10_QIMM_BCC_R3:
273 imm = dc->ir & 0xff;
274 /* bit 0 is a sign bit. */
275 if (imm & 1) {
276 imm |= 0xffffff00; /* sign extend. */
277 imm &= ~1; /* get rid of the sign bit. */
278 }
279 imm += 2;
280 LOG_DIS("b%s %d\n", cc_name(dc->cond), imm);
281
282 cris_cc_mask(dc, 0);
283 cris_prepare_cc_branch(dc, imm, dc->cond);
284 break;
285
286 default:
287 LOG_DIS("pc=%x mode=%x quickimm %d r%d r%d\n",
288 dc->pc, dc->mode, dc->opcode, dc->src, dc->dst);
289 assert(0);
290 break;
291 }
292 return 2;
293}
294
295static unsigned int dec10_setclrf(DisasContext *dc)
296{
297 uint32_t flags;
298 unsigned int set = ~dc->opcode & 1;
299
300 flags = EXTRACT_FIELD(dc->ir, 0, 3)
301 | (EXTRACT_FIELD(dc->ir, 12, 15) << 4);
302 LOG_DIS("%s set=%d flags=%x\n", __func__, set, flags);
303
304
305 if (flags & X_FLAG) {
306 dc->flagx_known = 1;
307 if (set)
308 dc->flags_x = X_FLAG;
309 else
310 dc->flags_x = 0;
311 }
312
313 cris_evaluate_flags (dc);
314 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
315 cris_update_cc_x(dc);
316 tcg_gen_movi_tl(cc_op, dc->cc_op);
317
318 if (set) {
319 tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
320 } else {
321 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
322 }
323
324 dc->flags_uptodate = 1;
325 dc->clear_x = 0;
326 cris_lock_irq(dc);
327 return 2;
328}
329
330static inline void dec10_reg_prep_sext(DisasContext *dc, int size, int sext,
331 TCGv dd, TCGv ds, TCGv sd, TCGv ss)
332{
333 if (sext) {
334 t_gen_sext(dd, sd, size);
335 t_gen_sext(ds, ss, size);
336 } else {
337 t_gen_zext(dd, sd, size);
338 t_gen_zext(ds, ss, size);
339 }
340}
341
342static void dec10_reg_alu(DisasContext *dc, int op, int size, int sext)
343{
344 TCGv t[2];
345
346 t[0] = tcg_temp_new();
347 t[1] = tcg_temp_new();
348 dec10_reg_prep_sext(dc, size, sext,
349 t[0], t[1], cpu_R[dc->dst], cpu_R[dc->src]);
350
351 if (op == CC_OP_LSL || op == CC_OP_LSR || op == CC_OP_ASR) {
352 tcg_gen_andi_tl(t[1], t[1], 63);
353 }
354
355 assert(dc->dst != 15);
356 cris_alu(dc, op, cpu_R[dc->dst], t[0], t[1], size);
357 tcg_temp_free(t[0]);
358 tcg_temp_free(t[1]);
359}
360
361static void dec10_reg_bound(DisasContext *dc, int size)
362{
363 TCGv t;
364
365 t = tcg_temp_local_new();
366 t_gen_zext(t, cpu_R[dc->src], size);
367 cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
368 tcg_temp_free(t);
369}
370
371static void dec10_reg_mul(DisasContext *dc, int size, int sext)
372{
373 int op = sext ? CC_OP_MULS : CC_OP_MULU;
374 TCGv t[2];
375
376 t[0] = tcg_temp_new();
377 t[1] = tcg_temp_new();
378 dec10_reg_prep_sext(dc, size, sext,
379 t[0], t[1], cpu_R[dc->dst], cpu_R[dc->src]);
380
381 cris_alu(dc, op, cpu_R[dc->dst], t[0], t[1], 4);
382
383 tcg_temp_free(t[0]);
384 tcg_temp_free(t[1]);
385}
386
387
388static void dec10_reg_movs(DisasContext *dc)
389{
390 int size = (dc->size & 1) + 1;
391 TCGv t;
392
393 LOG_DIS("movx.%d $r%d, $r%d\n", size, dc->src, dc->dst);
394 cris_cc_mask(dc, CC_MASK_NZVC);
395
396 t = tcg_temp_new();
397 if (dc->ir & 32)
398 t_gen_sext(t, cpu_R[dc->src], size);
399 else
400 t_gen_zext(t, cpu_R[dc->src], size);
401
402 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
403 tcg_temp_free(t);
404}
405
406static void dec10_reg_alux(DisasContext *dc, int op)
407{
408 int size = (dc->size & 1) + 1;
409 TCGv t;
410
411 LOG_DIS("movx.%d $r%d, $r%d\n", size, dc->src, dc->dst);
412 cris_cc_mask(dc, CC_MASK_NZVC);
413
414 t = tcg_temp_new();
415 if (dc->ir & 32)
416 t_gen_sext(t, cpu_R[dc->src], size);
417 else
418 t_gen_zext(t, cpu_R[dc->src], size);
419
420 cris_alu(dc, op, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
421 tcg_temp_free(t);
422}
423
424static void dec10_reg_mov_pr(DisasContext *dc)
425{
426 LOG_DIS("move p%d r%d sz=%d\n", dc->dst, dc->src, preg_sizes_v10[dc->dst]);
427 cris_lock_irq(dc);
428 if (dc->src == 15) {
429 tcg_gen_mov_tl(env_btarget, cpu_PR[dc->dst]);
430 cris_prepare_jmp(dc, JMP_INDIRECT);
431 return;
432 }
433 if (dc->dst == PR_CCS) {
434 cris_evaluate_flags(dc);
435 }
436 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->src],
437 cpu_R[dc->src], cpu_PR[dc->dst], preg_sizes_v10[dc->dst]);
438}
439
440static void dec10_reg_abs(DisasContext *dc)
441{
442 TCGv t0;
443
444 LOG_DIS("abs $r%u, $r%u\n",
445 dc->src, dc->dst);
446
447 assert(dc->dst != 15);
448 t0 = tcg_temp_new();
449 tcg_gen_sari_tl(t0, cpu_R[dc->src], 31);
450 tcg_gen_xor_tl(cpu_R[dc->dst], cpu_R[dc->src], t0);
451 tcg_gen_sub_tl(t0, cpu_R[dc->dst], t0);
452
453 cris_alu(dc, CC_OP_MOVE,
454 cpu_R[dc->dst], cpu_R[dc->dst], t0, 4);
455 tcg_temp_free(t0);
456}
457
458static void dec10_reg_swap(DisasContext *dc)
459{
460 TCGv t0;
461
462 LOG_DIS("not $r%d, $r%d\n", dc->src, dc->dst);
463
464 cris_cc_mask(dc, CC_MASK_NZVC);
465 t0 = tcg_temp_new();
466 t_gen_mov_TN_reg(t0, dc->src);
467 if (dc->dst & 8)
468 tcg_gen_not_tl(t0, t0);
469 if (dc->dst & 4)
470 t_gen_swapw(t0, t0);
471 if (dc->dst & 2)
472 t_gen_swapb(t0, t0);
473 if (dc->dst & 1)
474 t_gen_swapr(t0, t0);
475 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->src], cpu_R[dc->src], t0, 4);
476 tcg_temp_free(t0);
477}
478
479static void dec10_reg_scc(DisasContext *dc)
480{
481 int cond = dc->dst;
482
483 LOG_DIS("s%s $r%u\n",
484 cc_name(cond), dc->src);
485
486 if (cond != CC_A)
487 {
488 int l1;
489
490 gen_tst_cc (dc, cpu_R[dc->src], cond);
491 l1 = gen_new_label();
492 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->src], 0, l1);
493 tcg_gen_movi_tl(cpu_R[dc->src], 1);
494 gen_set_label(l1);
495 }
496 else
497 tcg_gen_movi_tl(cpu_R[dc->src], 1);
498
499 cris_cc_mask(dc, 0);
500}
501
502static unsigned int dec10_reg(DisasContext *dc)
503{
504 TCGv t;
505 unsigned int insn_len = 2;
506 unsigned int size = dec10_size(dc->size);
507 unsigned int tmp;
508
509 if (dc->size != 3) {
510 switch (dc->opcode) {
511 case CRISV10_REG_MOVE_R:
512 LOG_DIS("move.%d $r%d, $r%d\n", dc->size, dc->src, dc->dst);
513 cris_cc_mask(dc, CC_MASK_NZVC);
514 dec10_reg_alu(dc, CC_OP_MOVE, size, 0);
515 if (dc->dst == 15) {
516 tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
517 cris_prepare_jmp(dc, JMP_INDIRECT);
518 dc->delayed_branch = 1;
519 }
520 break;
521 case CRISV10_REG_MOVX:
522 cris_cc_mask(dc, CC_MASK_NZVC);
523 dec10_reg_movs(dc);
524 break;
525 case CRISV10_REG_ADDX:
526 cris_cc_mask(dc, CC_MASK_NZVC);
527 dec10_reg_alux(dc, CC_OP_ADD);
528 break;
529 case CRISV10_REG_SUBX:
530 cris_cc_mask(dc, CC_MASK_NZVC);
531 dec10_reg_alux(dc, CC_OP_SUB);
532 break;
533 case CRISV10_REG_ADD:
534 LOG_DIS("add $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
535 cris_cc_mask(dc, CC_MASK_NZVC);
536 dec10_reg_alu(dc, CC_OP_ADD, size, 0);
537 break;
538 case CRISV10_REG_SUB:
539 LOG_DIS("sub $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
540 cris_cc_mask(dc, CC_MASK_NZVC);
541 dec10_reg_alu(dc, CC_OP_SUB, size, 0);
542 break;
543 case CRISV10_REG_CMP:
544 LOG_DIS("cmp $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
545 cris_cc_mask(dc, CC_MASK_NZVC);
546 dec10_reg_alu(dc, CC_OP_CMP, size, 0);
547 break;
548 case CRISV10_REG_BOUND:
549 LOG_DIS("bound $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
550 cris_cc_mask(dc, CC_MASK_NZVC);
551 dec10_reg_bound(dc, size);
552 break;
553 case CRISV10_REG_AND:
554 LOG_DIS("and $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
555 cris_cc_mask(dc, CC_MASK_NZVC);
556 dec10_reg_alu(dc, CC_OP_AND, size, 0);
557 break;
558 case CRISV10_REG_ADDI:
559 if (dc->src == 15) {
560 /* nop. */
561 return 2;
562 }
563 t = tcg_temp_new();
564 LOG_DIS("addi r%d r%d size=%d\n", dc->src, dc->dst, dc->size);
565 tcg_gen_shli_tl(t, cpu_R[dc->dst], dc->size & 3);
566 tcg_gen_add_tl(cpu_R[dc->src], cpu_R[dc->src], t);
567 tcg_temp_free(t);
568 break;
569 case CRISV10_REG_LSL:
570 LOG_DIS("lsl $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
571 cris_cc_mask(dc, CC_MASK_NZVC);
572 dec10_reg_alu(dc, CC_OP_LSL, size, 0);
573 break;
574 case CRISV10_REG_LSR:
575 LOG_DIS("lsr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
576 cris_cc_mask(dc, CC_MASK_NZVC);
577 dec10_reg_alu(dc, CC_OP_LSR, size, 0);
578 break;
579 case CRISV10_REG_ASR:
580 LOG_DIS("asr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
581 cris_cc_mask(dc, CC_MASK_NZVC);
582 dec10_reg_alu(dc, CC_OP_ASR, size, 1);
583 break;
584 case CRISV10_REG_OR:
585 LOG_DIS("or $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
586 cris_cc_mask(dc, CC_MASK_NZVC);
587 dec10_reg_alu(dc, CC_OP_OR, size, 0);
588 break;
589 case CRISV10_REG_NEG:
590 LOG_DIS("neg $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
591 cris_cc_mask(dc, CC_MASK_NZVC);
592 dec10_reg_alu(dc, CC_OP_NEG, size, 0);
593 break;
594 case CRISV10_REG_BIAP:
595 LOG_DIS("BIAP pc=%x reg %d r%d r%d size=%d\n", dc->pc,
596 dc->opcode, dc->src, dc->dst, size);
597 switch (size) {
598 case 4: tmp = 2; break;
599 case 2: tmp = 1; break;
600 case 1: tmp = 0; break;
601 default: assert(0); break;
602 }
603
604 t = tcg_temp_new();
605 tcg_gen_shli_tl(t, cpu_R[dc->dst], tmp);
606 if (dc->src == 15) {
607 tcg_gen_addi_tl(cpu_PR[PR_PREFIX], t, ((dc->pc +2)| 1) + 1);
608 } else {
609 tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_R[dc->src], t);
610 }
611 tcg_temp_free(t);
612 cris_set_prefix(dc);
613 break;
614
615 default:
616 LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc,
617 dc->opcode, dc->src, dc->dst);
618 assert(0);
619 break;
620 }
621 } else {
622 switch (dc->opcode) {
623 case CRISV10_REG_MOVX:
624 cris_cc_mask(dc, CC_MASK_NZVC);
625 dec10_reg_movs(dc);
626 break;
627 case CRISV10_REG_ADDX:
628 cris_cc_mask(dc, CC_MASK_NZVC);
629 dec10_reg_alux(dc, CC_OP_ADD);
630 break;
631 case CRISV10_REG_SUBX:
632 cris_cc_mask(dc, CC_MASK_NZVC);
633 dec10_reg_alux(dc, CC_OP_SUB);
634 break;
635 case CRISV10_REG_MOVE_SPR_R:
636 cris_evaluate_flags(dc);
637 cris_cc_mask(dc, 0);
638 dec10_reg_mov_pr(dc);
639 break;
640 case CRISV10_REG_MOVE_R_SPR:
641 LOG_DIS("move r%d p%d\n", dc->src, dc->dst);
642 cris_evaluate_flags(dc);
643 if (dc->src != 11) /* fast for srp. */
644 dc->cpustate_changed = 1;
645 t_gen_mov_preg_TN(dc, dc->dst, cpu_R[dc->src]);
646 break;
647 case CRISV10_REG_SETF:
648 case CRISV10_REG_CLEARF:
649 dec10_setclrf(dc);
650 break;
651 case CRISV10_REG_SWAP:
652 dec10_reg_swap(dc);
653 break;
654 case CRISV10_REG_ABS:
655 cris_cc_mask(dc, CC_MASK_NZVC);
656 dec10_reg_abs(dc);
657 break;
658 case CRISV10_REG_LZ:
659 LOG_DIS("lz $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
660 cris_cc_mask(dc, CC_MASK_NZVC);
661 dec10_reg_alu(dc, CC_OP_LZ, 4, 0);
662 break;
663 case CRISV10_REG_XOR:
664 LOG_DIS("xor $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
665 cris_cc_mask(dc, CC_MASK_NZVC);
666 dec10_reg_alu(dc, CC_OP_XOR, 4, 0);
667 break;
668 case CRISV10_REG_BTST:
669 LOG_DIS("btst $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
670 cris_cc_mask(dc, CC_MASK_NZVC);
671 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
672 gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->dst],
673 cpu_R[dc->src], cpu_PR[PR_CCS]);
674 break;
675 case CRISV10_REG_DSTEP:
676 LOG_DIS("dstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
677 cris_cc_mask(dc, CC_MASK_NZVC);
678 cris_alu(dc, CC_OP_DSTEP, cpu_R[dc->dst],
679 cpu_R[dc->dst], cpu_R[dc->src], 4);
680 break;
681 case CRISV10_REG_MSTEP:
682 LOG_DIS("mstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
683 cris_evaluate_flags(dc);
684 cris_cc_mask(dc, CC_MASK_NZVC);
685 cris_alu(dc, CC_OP_MSTEP, cpu_R[dc->dst],
686 cpu_R[dc->dst], cpu_R[dc->src], 4);
687 break;
688 case CRISV10_REG_SCC:
689 dec10_reg_scc(dc);
690 break;
691 default:
692 LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc,
693 dc->opcode, dc->src, dc->dst);
694 assert(0);
695 break;
696 }
697 }
698 return insn_len;
699}
700
701static unsigned int dec10_ind_move_m_r(DisasContext *dc, unsigned int size)
702{
703 unsigned int insn_len = 2;
704 TCGv t;
705
706 LOG_DIS("%s: move.%d [$r%d], $r%d\n", __func__,
707 size, dc->src, dc->dst);
708
709 cris_cc_mask(dc, CC_MASK_NZVC);
710 t = tcg_temp_new();
711 insn_len += dec10_prep_move_m(dc, 0, size, t);
712 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t, size);
713 if (dc->dst == 15) {
714 tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
715 cris_prepare_jmp(dc, JMP_INDIRECT);
716 dc->delayed_branch = 1;
717 return insn_len;
718 }
719
720 tcg_temp_free(t);
721 return insn_len;
722}
723
724static unsigned int dec10_ind_move_r_m(DisasContext *dc, unsigned int size)
725{
726 unsigned int insn_len = 2;
727 TCGv addr;
728
729 LOG_DIS("move.%d $r%d, [$r%d]\n", dc->size, dc->src, dc->dst);
730 addr = tcg_temp_new();
731 crisv10_prepare_memaddr(dc, addr, size);
732 gen_store(dc, addr, cpu_R[dc->dst], size);
733 insn_len += crisv10_post_memaddr(dc, size);
734
735 return insn_len;
736}
737
738static unsigned int dec10_ind_move_m_pr(DisasContext *dc)
739{
740 unsigned int insn_len = 2, rd = dc->dst;
741 TCGv t, addr;
742
743 LOG_DIS("move.%d $p%d, [$r%d]\n", dc->size, dc->dst, dc->src);
744 cris_lock_irq(dc);
745
746 addr = tcg_temp_new();
747 t = tcg_temp_new();
748 insn_len += dec10_prep_move_m(dc, 0, 4, t);
749 if (rd == 15) {
750 tcg_gen_mov_tl(env_btarget, t);
751 cris_prepare_jmp(dc, JMP_INDIRECT);
752 dc->delayed_branch = 1;
753 return insn_len;
754 }
755
756 tcg_gen_mov_tl(cpu_PR[rd], t);
757 dc->cpustate_changed = 1;
758 tcg_temp_free(addr);
759 tcg_temp_free(t);
760 return insn_len;
761}
762
763static unsigned int dec10_ind_move_pr_m(DisasContext *dc)
764{
765 unsigned int insn_len = 2, size = preg_sizes_v10[dc->dst];
766 TCGv addr, t0;
767
768 LOG_DIS("move.%d $p%d, [$r%d]\n", dc->size, dc->dst, dc->src);
769
770 addr = tcg_temp_new();
771 crisv10_prepare_memaddr(dc, addr, size);
772 if (dc->dst == PR_CCS) {
773 t0 = tcg_temp_new();
774 cris_evaluate_flags(dc);
775 tcg_gen_andi_tl(t0, cpu_PR[PR_CCS], ~PFIX_FLAG);
776 gen_store(dc, addr, t0, size);
777 tcg_temp_free(t0);
778 } else {
779 gen_store(dc, addr, cpu_PR[dc->dst], size);
780 }
781 t0 = tcg_temp_new();
782 insn_len += crisv10_post_memaddr(dc, size);
783 cris_lock_irq(dc);
784
785 return insn_len;
786}
787
788static void dec10_movem_r_m(DisasContext *dc)
789{
790 int i, pfix = dc->tb_flags & PFIX_FLAG;
791 TCGv addr, t0;
792
793 LOG_DIS("%s r%d, [r%d] pi=%d ir=%x\n", __func__,
794 dc->dst, dc->src, dc->postinc, dc->ir);
795
796 addr = tcg_temp_new();
797 t0 = tcg_temp_new();
798 crisv10_prepare_memaddr(dc, addr, 4);
799 tcg_gen_mov_tl(t0, addr);
800 for (i = dc->dst; i >= 0; i--) {
801 if ((pfix && dc->mode == CRISV10_MODE_AUTOINC) && dc->src == i) {
802 gen_store(dc, addr, t0, 4);
803 } else {
804 gen_store(dc, addr, cpu_R[i], 4);
805 }
806 tcg_gen_addi_tl(addr, addr, 4);
807 }
808
809 if (pfix && dc->mode == CRISV10_MODE_AUTOINC) {
810 tcg_gen_mov_tl(cpu_R[dc->src], t0);
811 }
812
813 if (!pfix && dc->mode == CRISV10_MODE_AUTOINC) {
814 tcg_gen_mov_tl(cpu_R[dc->src], addr);
815 }
816 tcg_temp_free(addr);
817 tcg_temp_free(t0);
818}
819
820static void dec10_movem_m_r(DisasContext *dc)
821{
822 int i, pfix = dc->tb_flags & PFIX_FLAG;
823 TCGv addr, t0;
824
825 LOG_DIS("%s [r%d], r%d pi=%d ir=%x\n", __func__,
826 dc->src, dc->dst, dc->postinc, dc->ir);
827
828 addr = tcg_temp_new();
829 t0 = tcg_temp_new();
830 crisv10_prepare_memaddr(dc, addr, 4);
831 tcg_gen_mov_tl(t0, addr);
832 for (i = dc->dst; i >= 0; i--) {
833 gen_load(dc, cpu_R[i], addr, 4, 0);
834 tcg_gen_addi_tl(addr, addr, 4);
835 }
836
837 if (pfix && dc->mode == CRISV10_MODE_AUTOINC) {
838 tcg_gen_mov_tl(cpu_R[dc->src], t0);
839 }
840
841
842 if (!pfix && dc->mode == CRISV10_MODE_AUTOINC) {
843 tcg_gen_mov_tl(cpu_R[dc->src], addr);
844 }
845 tcg_temp_free(addr);
846 tcg_temp_free(t0);
847}
848
849static int dec10_ind_alu(DisasContext *dc, int op, unsigned int size)
850{
851 int insn_len = 0;
852 int rd = dc->dst;
853 TCGv t[2];
854
855 cris_alu_m_alloc_temps(t);
856 insn_len += dec10_prep_move_m(dc, 0, size, t[0]);
857 cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t[0], size);
858 if (dc->dst == 15) {
859 tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
860 cris_prepare_jmp(dc, JMP_INDIRECT);
861 dc->delayed_branch = 1;
862 return insn_len;
863 }
864
865 cris_alu_m_free_temps(t);
866
867 return insn_len;
868}
869
870static int dec10_ind_bound(DisasContext *dc, unsigned int size)
871{
872 int insn_len = 0;
873 int rd = dc->dst;
874 TCGv t;
875
876 t = tcg_temp_local_new();
877 insn_len += dec10_prep_move_m(dc, 0, size, t);
878 cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[rd], t, 4);
879 if (dc->dst == 15) {
880 tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
881 cris_prepare_jmp(dc, JMP_INDIRECT);
882 dc->delayed_branch = 1;
883 return insn_len;
884 }
885
886 tcg_temp_free(t);
887 return insn_len;
888}
889
890static int dec10_alux_m(DisasContext *dc, int op)
891{
892 unsigned int size = (dc->size & 1) ? 2 : 1;
893 unsigned int sx = !!(dc->size & 2);
894 int insn_len = 2;
895 int rd = dc->dst;
896 TCGv t;
897
898 LOG_DIS("addx size=%d sx=%d op=%d %d\n", size, sx, dc->src, dc->dst);
899
900 t = tcg_temp_new();
901
902 cris_cc_mask(dc, CC_MASK_NZVC);
903 insn_len += dec10_prep_move_m(dc, sx, size, t);
904 cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t, 4);
905 if (dc->dst == 15) {
906 tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
907 cris_prepare_jmp(dc, JMP_INDIRECT);
908 dc->delayed_branch = 1;
909 return insn_len;
910 }
911
912 tcg_temp_free(t);
913 return insn_len;
914}
915
916static int dec10_dip(DisasContext *dc)
917{
918 int insn_len = 2;
919 uint32_t imm;
920
921 LOG_DIS("dip pc=%x opcode=%d r%d r%d\n",
922 dc->pc, dc->opcode, dc->src, dc->dst);
923 if (dc->src == 15) {
924 imm = ldl_code(dc->pc + 2);
925 tcg_gen_movi_tl(cpu_PR[PR_PREFIX], imm);
926 if (dc->postinc)
927 insn_len += 4;
928 tcg_gen_addi_tl(cpu_R[15], cpu_R[15], insn_len - 2);
929 } else {
930 gen_load(dc, cpu_PR[PR_PREFIX], cpu_R[dc->src], 4, 0);
931 if (dc->postinc)
932 tcg_gen_addi_tl(cpu_R[dc->src], cpu_R[dc->src], 4);
933 }
934
935 cris_set_prefix(dc);
936 return insn_len;
937}
938
939static int dec10_bdap_m(DisasContext *dc, int size)
940{
941 int insn_len = 2;
942 int rd = dc->dst;
943
944 LOG_DIS("bdap_m pc=%x opcode=%d r%d r%d sz=%d\n",
945 dc->pc, dc->opcode, dc->src, dc->dst, size);
946
947 assert(dc->dst != 15);
948#if 0
949 /* 8bit embedded offset? */
950 if (!dc->postinc && (dc->ir & (1 << 11))) {
951 int simm = dc->ir & 0xff;
952
953 // assert(0);
954 /* sign extended. */
955 simm = (int8_t)simm;
956
957 tcg_gen_addi_tl(cpu_PR[PR_PREFIX], cpu_R[dc->dst], simm);
958
959 cris_set_prefix(dc);
960 return insn_len;
961 }
962#endif
963 /* Now the rest of the modes are truely indirect. */
964 insn_len += dec10_prep_move_m(dc, 1, size, cpu_PR[PR_PREFIX]);
965 tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_PR[PR_PREFIX], cpu_R[rd]);
966 cris_set_prefix(dc);
967 return insn_len;
968}
969
970static unsigned int dec10_ind(DisasContext *dc)
971{
972 unsigned int insn_len = 2;
973 unsigned int size = dec10_size(dc->size);
974 uint32_t imm;
975 int32_t simm;
976 TCGv t[2];
977
978 if (dc->size != 3) {
979 switch (dc->opcode) {
980 case CRISV10_IND_MOVE_M_R:
981 return dec10_ind_move_m_r(dc, size);
982 break;
983 case CRISV10_IND_MOVE_R_M:
984 return dec10_ind_move_r_m(dc, size);
985 break;
986 case CRISV10_IND_CMP:
987 LOG_DIS("cmp size=%d op=%d %d\n", size, dc->src, dc->dst);
988 cris_cc_mask(dc, CC_MASK_NZVC);
989 insn_len += dec10_ind_alu(dc, CC_OP_CMP, size);
990 break;
991 case CRISV10_IND_TEST:
992 LOG_DIS("test size=%d op=%d %d\n", size, dc->src, dc->dst);
993
994 cris_evaluate_flags(dc);
995 cris_cc_mask(dc, CC_MASK_NZVC);
996 cris_alu_m_alloc_temps(t);
997 insn_len += dec10_prep_move_m(dc, 0, size, t[0]);
998 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
999 cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst],
1000 t[0], tcg_const_tl(0), size);
1001 cris_alu_m_free_temps(t);
1002 break;
1003 case CRISV10_IND_ADD:
1004 LOG_DIS("add size=%d op=%d %d\n", size, dc->src, dc->dst);
1005 cris_cc_mask(dc, CC_MASK_NZVC);
1006 insn_len += dec10_ind_alu(dc, CC_OP_ADD, size);
1007 break;
1008 case CRISV10_IND_SUB:
1009 LOG_DIS("sub size=%d op=%d %d\n", size, dc->src, dc->dst);
1010 cris_cc_mask(dc, CC_MASK_NZVC);
1011 insn_len += dec10_ind_alu(dc, CC_OP_SUB, size);
1012 break;
1013 case CRISV10_IND_BOUND:
1014 LOG_DIS("bound size=%d op=%d %d\n", size, dc->src, dc->dst);
1015 cris_cc_mask(dc, CC_MASK_NZVC);
1016 insn_len += dec10_ind_bound(dc, size);
1017 break;
1018 case CRISV10_IND_AND:
1019 LOG_DIS("and size=%d op=%d %d\n", size, dc->src, dc->dst);
1020 cris_cc_mask(dc, CC_MASK_NZVC);
1021 insn_len += dec10_ind_alu(dc, CC_OP_AND, size);
1022 break;
1023 case CRISV10_IND_OR:
1024 LOG_DIS("or size=%d op=%d %d\n", size, dc->src, dc->dst);
1025 cris_cc_mask(dc, CC_MASK_NZVC);
1026 insn_len += dec10_ind_alu(dc, CC_OP_OR, size);
1027 break;
1028 case CRISV10_IND_MOVX:
1029 insn_len = dec10_alux_m(dc, CC_OP_MOVE);
1030 break;
1031 case CRISV10_IND_ADDX:
1032 insn_len = dec10_alux_m(dc, CC_OP_ADD);
1033 break;
1034 case CRISV10_IND_SUBX:
1035 insn_len = dec10_alux_m(dc, CC_OP_SUB);
1036 break;
1037 case CRISV10_IND_CMPX:
1038 insn_len = dec10_alux_m(dc, CC_OP_CMP);
1039 break;
1040 case CRISV10_IND_MUL:
1041 /* This is a reg insn coded in the mem indir space. */
1042 LOG_DIS("mul pc=%x opcode=%d\n", dc->pc, dc->opcode);
1043 cris_cc_mask(dc, CC_MASK_NZVC);
1044 dec10_reg_mul(dc, size, dc->ir & (1 << 10));
1045 break;
1046 case CRISV10_IND_BDAP_M:
1047 insn_len = dec10_bdap_m(dc, size);
1048 break;
1049 default:
1050 LOG_DIS("pc=%x var-ind.%d %d r%d r%d\n",
1051 dc->pc, size, dc->opcode, dc->src, dc->dst);
1052 assert(0);
1053 break;
1054 }
1055 return insn_len;
1056 }
1057
1058 switch (dc->opcode) {
1059 case CRISV10_IND_MOVE_M_SPR:
1060 insn_len = dec10_ind_move_m_pr(dc);
1061 break;
1062 case CRISV10_IND_MOVE_SPR_M:
1063 insn_len = dec10_ind_move_pr_m(dc);
1064 break;
1065 case CRISV10_IND_JUMP_M:
1066 if (dc->src == 15) {
1067 LOG_DIS("jump.%d %d r%d r%d\n", size,
1068 dc->opcode, dc->src, dc->dst);
1069 imm = ldl_code(dc->pc + 2);
1070 if (dc->mode == CRISV10_MODE_AUTOINC)
1071 insn_len += size;
1072
1073 t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len));
1074 tcg_gen_movi_tl(env_btarget, imm);
1075 cris_prepare_jmp(dc, JMP_INDIRECT);
1076 dc->delayed_branch--; /* v10 has no dslot here. */
1077 } else {
1078 if (dc->dst == 14) {
1079 LOG_DIS("break %d\n", dc->src);
1080 cris_evaluate_flags(dc);
1081 tcg_gen_movi_tl(env_pc, dc->pc + 2);
1082 t_gen_raise_exception(EXCP_BREAK);
1083 dc->is_jmp = DISAS_UPDATE;
1084 return insn_len;
1085 }
1086 LOG_DIS("%d: jump.%d %d r%d r%d\n", __LINE__, size,
1087 dc->opcode, dc->src, dc->dst);
1088 t[0] = tcg_temp_new();
1089 t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len));
1090 crisv10_prepare_memaddr(dc, t[0], size);
1091 gen_load(dc, env_btarget, t[0], 4, 0);
1092 insn_len += crisv10_post_memaddr(dc, size);
1093 cris_prepare_jmp(dc, JMP_INDIRECT);
1094 dc->delayed_branch--; /* v10 has no dslot here. */
1095 tcg_temp_free(t[0]);
1096 }
1097 break;
1098
1099 case CRISV10_IND_MOVEM_R_M:
1100 LOG_DIS("movem_r_m pc=%x opcode=%d r%d r%d\n",
1101 dc->pc, dc->opcode, dc->dst, dc->src);
1102 dec10_movem_r_m(dc);
1103 break;
1104 case CRISV10_IND_MOVEM_M_R:
1105 LOG_DIS("movem_m_r pc=%x opcode=%d\n", dc->pc, dc->opcode);
1106 dec10_movem_m_r(dc);
1107 break;
1108 case CRISV10_IND_JUMP_R:
1109 LOG_DIS("jmp pc=%x opcode=%d r%d r%d\n",
1110 dc->pc, dc->opcode, dc->dst, dc->src);
1111 tcg_gen_mov_tl(env_btarget, cpu_R[dc->src]);
1112 t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len));
1113 cris_prepare_jmp(dc, JMP_INDIRECT);
1114 dc->delayed_branch--; /* v10 has no dslot here. */
1115 break;
1116 case CRISV10_IND_MOVX:
1117 insn_len = dec10_alux_m(dc, CC_OP_MOVE);
1118 break;
1119 case CRISV10_IND_ADDX:
1120 insn_len = dec10_alux_m(dc, CC_OP_ADD);
1121 break;
1122 case CRISV10_IND_SUBX:
1123 insn_len = dec10_alux_m(dc, CC_OP_SUB);
1124 break;
1125 case CRISV10_IND_CMPX:
1126 insn_len = dec10_alux_m(dc, CC_OP_CMP);
1127 break;
1128 case CRISV10_IND_DIP:
1129 insn_len = dec10_dip(dc);
1130 break;
1131 case CRISV10_IND_BCC_M:
1132
1133 cris_cc_mask(dc, 0);
1134 imm = ldsw_code(dc->pc + 2);
1135 simm = (int16_t)imm;
1136 simm += 4;
1137
1138 LOG_DIS("bcc_m: b%s %x\n", cc_name(dc->cond), dc->pc + simm);
1139 cris_prepare_cc_branch(dc, simm, dc->cond);
1140 insn_len = 4;
1141 break;
1142 default:
1143 LOG_DIS("ERROR pc=%x opcode=%d\n", dc->pc, dc->opcode);
1144 assert(0);
1145 break;
1146 }
1147
1148 return insn_len;
1149}
1150
1151static unsigned int crisv10_decoder(DisasContext *dc)
1152{
1153 unsigned int insn_len = 2;
1154
1155 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
1156 tcg_gen_debug_insn_start(dc->pc);
1157
1158 /* Load a halfword onto the instruction register. */
1159 dc->ir = lduw_code(dc->pc);
1160
1161 /* Now decode it. */
1162 dc->opcode = EXTRACT_FIELD(dc->ir, 6, 9);
1163 dc->mode = EXTRACT_FIELD(dc->ir, 10, 11);
1164 dc->src = EXTRACT_FIELD(dc->ir, 0, 3);
1165 dc->size = EXTRACT_FIELD(dc->ir, 4, 5);
1166 dc->cond = dc->dst = EXTRACT_FIELD(dc->ir, 12, 15);
1167 dc->postinc = EXTRACT_FIELD(dc->ir, 10, 10);
1168
1169 dc->clear_prefix = 1;
1170
1171 /* FIXME: What if this insn insn't 2 in length?? */
1172 if (dc->src == 15 || dc->dst == 15)
1173 tcg_gen_movi_tl(cpu_R[15], dc->pc + 2);
1174
1175 switch (dc->mode) {
1176 case CRISV10_MODE_QIMMEDIATE:
1177 insn_len = dec10_quick_imm(dc);
1178 break;
1179 case CRISV10_MODE_REG:
1180 insn_len = dec10_reg(dc);
1181 break;
1182 case CRISV10_MODE_AUTOINC:
1183 case CRISV10_MODE_INDIRECT:
1184 insn_len = dec10_ind(dc);
1185 break;
1186 }
1187
1188 if (dc->clear_prefix && dc->tb_flags & PFIX_FLAG) {
1189 dc->tb_flags &= ~PFIX_FLAG;
1190 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~PFIX_FLAG);
1191 dc->cpustate_changed = 1;
1192 }
1193
1194 return insn_len;
1195}
1196
1197static CPUCRISState *cpu_crisv10_init (CPUState *env)
1198{
1199 int i;
1200
1201 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
1202 cc_x = tcg_global_mem_new(TCG_AREG0,
1203 offsetof(CPUState, cc_x), "cc_x");
1204 cc_src = tcg_global_mem_new(TCG_AREG0,
1205 offsetof(CPUState, cc_src), "cc_src");
1206 cc_dest = tcg_global_mem_new(TCG_AREG0,
1207 offsetof(CPUState, cc_dest),
1208 "cc_dest");
1209 cc_result = tcg_global_mem_new(TCG_AREG0,
1210 offsetof(CPUState, cc_result),
1211 "cc_result");
1212 cc_op = tcg_global_mem_new(TCG_AREG0,
1213 offsetof(CPUState, cc_op), "cc_op");
1214 cc_size = tcg_global_mem_new(TCG_AREG0,
1215 offsetof(CPUState, cc_size),
1216 "cc_size");
1217 cc_mask = tcg_global_mem_new(TCG_AREG0,
1218 offsetof(CPUState, cc_mask),
1219 "cc_mask");
1220
1221 env_pc = tcg_global_mem_new(TCG_AREG0,
1222 offsetof(CPUState, pc),
1223 "pc");
1224 env_btarget = tcg_global_mem_new(TCG_AREG0,
1225 offsetof(CPUState, btarget),
1226 "btarget");
1227 env_btaken = tcg_global_mem_new(TCG_AREG0,
1228 offsetof(CPUState, btaken),
1229 "btaken");
1230 for (i = 0; i < 16; i++) {
1231 cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
1232 offsetof(CPUState, regs[i]),
1233 regnames_v10[i]);
1234 }
1235 for (i = 0; i < 16; i++) {
1236 cpu_PR[i] = tcg_global_mem_new(TCG_AREG0,
1237 offsetof(CPUState, pregs[i]),
1238 pregnames_v10[i]);
1239 }
1240
1241 return env;
1242}
1243