Commit 8170028d75297abac0124a2520380ec988ea1d19

Authored by ths
1 parent a25fd137

CRIS instruction translation, by Edgar E. Iglesias.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3358 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 2507 additions and 0 deletions
target-cris/translate.c 0 → 100644
  1 +/*
  2 + * CRIS emulation for qemu: main translation routines.
  3 + *
  4 + * Copyright (c) 2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20 + */
  21 +
  22 +/*
  23 + * This file implements a CRIS decoder-stage in SW. The decoder translates the
  24 + * guest (CRIS) machine-code into host machine code via dyngen using the
  25 + * micro-operations described in op.c
  26 + *
  27 + * The micro-operations for CRIS translation implement a RISC style ISA.
  28 + * Note that the micro-operations typically order their operands
  29 + * starting with the dst. CRIS asm, does the opposite.
  30 + *
  31 + * For example the following CRIS code:
  32 + * add.d [$r0], $r1
  33 + *
  34 + * translates into:
  35 + *
  36 + * gen_movl_T0_reg(0); // Fetch $r0 into T0
  37 + * gen_load_T0_T0(); // Load T0, @T0
  38 + * gen_movl_reg_T0(1); // Writeback T0 into $r1
  39 + *
  40 + * The actual names for the micro-code generators vary but the example
  41 + * illustrates the point.
  42 + */
  43 +
  44 +#include <stdarg.h>
  45 +#include <stdlib.h>
  46 +#include <stdio.h>
  47 +#include <string.h>
  48 +#include <inttypes.h>
  49 +#include <assert.h>
  50 +
  51 +#include "cpu.h"
  52 +#include "exec-all.h"
  53 +#include "disas.h"
  54 +#include "crisv32-decode.h"
  55 +
  56 +#define CRIS_STATS 0
  57 +#if CRIS_STATS
  58 +#define STATS(x) x
  59 +#else
  60 +#define STATS(x)
  61 +#endif
  62 +
  63 +#define DISAS_CRIS 0
  64 +#if DISAS_CRIS
  65 +#define DIS(x) x
  66 +#else
  67 +#define DIS(x)
  68 +#endif
  69 +
  70 +#ifdef USE_DIRECT_JUMP
  71 +#define TBPARAM(x)
  72 +#else
  73 +#define TBPARAM(x) (long)(x)
  74 +#endif
  75 +
  76 +#define BUG() (gen_BUG(dc, __FILE__, __LINE__))
  77 +#define BUG_ON(x) ({if (x) BUG();})
  78 +
  79 +/* Used by the decoder. */
  80 +#define EXTRACT_FIELD(src, start, end) \
  81 + (((src) >> start) & ((1 << (end - start + 1)) - 1))
  82 +
  83 +#define CC_MASK_NZ 0xc
  84 +#define CC_MASK_NZV 0xe
  85 +#define CC_MASK_NZVC 0xf
  86 +#define CC_MASK_RNZV 0x10e
  87 +
  88 +static uint16_t *gen_opc_ptr;
  89 +static uint32_t *gen_opparam_ptr;
  90 +
  91 +enum {
  92 +#define DEF(s, n, copy_size) INDEX_op_ ## s,
  93 +#include "opc.h"
  94 +#undef DEF
  95 + NB_OPS,
  96 +};
  97 +#include "gen-op.h"
  98 +
  99 +/* This is the state at translation time. */
  100 +typedef struct DisasContext {
  101 + CPUState *env;
  102 + target_ulong pc, insn_pc;
  103 +
  104 + /* Decoder. */
  105 + uint32_t ir;
  106 + uint32_t opcode;
  107 + unsigned int op1;
  108 + unsigned int op2;
  109 + unsigned int zsize, zzsize;
  110 + unsigned int mode;
  111 + unsigned int postinc;
  112 +
  113 +
  114 + struct
  115 + {
  116 + int op;
  117 + int size;
  118 + unsigned int mask;
  119 + } cc_state[3];
  120 + int cc_i;
  121 +
  122 + int update_cc;
  123 + int cc_op;
  124 + int cc_size;
  125 + uint32_t cc_mask;
  126 + int flags_live;
  127 + int flagx_live;
  128 + int flags_x;
  129 + uint32_t tb_entry_flags;
  130 +
  131 + int memidx; /* user or kernel mode. */
  132 + int is_jmp;
  133 + int dyn_jmp;
  134 +
  135 + uint32_t delayed_pc;
  136 + int delayed_branch;
  137 + int bcc;
  138 + uint32_t condlabel;
  139 +
  140 + struct TranslationBlock *tb;
  141 + int singlestep_enabled;
  142 +} DisasContext;
  143 +
  144 +void cris_prepare_jmp (DisasContext *dc, uint32_t dst);
  145 +static void gen_BUG(DisasContext *dc, char *file, int line)
  146 +{
  147 + printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
  148 + fprintf (logfile, "BUG: pc=%x %s %d\n", dc->pc, file, line);
  149 + cpu_dump_state (dc->env, stdout, fprintf, 0);
  150 + fflush(NULL);
  151 + cris_prepare_jmp (dc, 0x70000000 + line);
  152 +}
  153 +
  154 +/* Table to generate quick moves from T0 onto any register. */
  155 +static GenOpFunc *gen_movl_reg_T0[16] =
  156 +{
  157 + gen_op_movl_r0_T0, gen_op_movl_r1_T0,
  158 + gen_op_movl_r2_T0, gen_op_movl_r3_T0,
  159 + gen_op_movl_r4_T0, gen_op_movl_r5_T0,
  160 + gen_op_movl_r6_T0, gen_op_movl_r7_T0,
  161 + gen_op_movl_r8_T0, gen_op_movl_r9_T0,
  162 + gen_op_movl_r10_T0, gen_op_movl_r11_T0,
  163 + gen_op_movl_r12_T0, gen_op_movl_r13_T0,
  164 + gen_op_movl_r14_T0, gen_op_movl_r15_T0,
  165 +};
  166 +static GenOpFunc *gen_movl_T0_reg[16] =
  167 +{
  168 + gen_op_movl_T0_r0, gen_op_movl_T0_r1,
  169 + gen_op_movl_T0_r2, gen_op_movl_T0_r3,
  170 + gen_op_movl_T0_r4, gen_op_movl_T0_r5,
  171 + gen_op_movl_T0_r6, gen_op_movl_T0_r7,
  172 + gen_op_movl_T0_r8, gen_op_movl_T0_r9,
  173 + gen_op_movl_T0_r10, gen_op_movl_T0_r11,
  174 + gen_op_movl_T0_r12, gen_op_movl_T0_r13,
  175 + gen_op_movl_T0_r14, gen_op_movl_T0_r15,
  176 +};
  177 +
  178 +static void noop_write(void) {
  179 + /* nop. */
  180 +}
  181 +
  182 +static void gen_vr_read(void) {
  183 + gen_op_movl_T0_im(32);
  184 +}
  185 +
  186 +static void gen_ccs_read(void) {
  187 + gen_op_movl_T0_p13();
  188 +}
  189 +
  190 +static void gen_ccs_write(void) {
  191 + gen_op_movl_p13_T0();
  192 +}
  193 +
  194 +/* Table to generate quick moves from T0 onto any register. */
  195 +static GenOpFunc *gen_movl_preg_T0[16] =
  196 +{
  197 + noop_write, /* bz, not writeable. */
  198 + noop_write, /* vr, not writeable. */
  199 + gen_op_movl_p2_T0, gen_op_movl_p3_T0,
  200 + noop_write, /* wz, not writeable. */
  201 + gen_op_movl_p5_T0,
  202 + gen_op_movl_p6_T0, gen_op_movl_p7_T0,
  203 + noop_write, /* dz, not writeable. */
  204 + gen_op_movl_p9_T0,
  205 + gen_op_movl_p10_T0, gen_op_movl_p11_T0,
  206 + gen_op_movl_p12_T0,
  207 + gen_ccs_write, /* ccs needs special treatment. */
  208 + gen_op_movl_p14_T0, gen_op_movl_p15_T0,
  209 +};
  210 +static GenOpFunc *gen_movl_T0_preg[16] =
  211 +{
  212 + gen_op_movl_T0_p0,
  213 + gen_vr_read,
  214 + gen_op_movl_T0_p2, gen_op_movl_T0_p3,
  215 + gen_op_movl_T0_p4, gen_op_movl_T0_p5,
  216 + gen_op_movl_T0_p6, gen_op_movl_T0_p7,
  217 + gen_op_movl_T0_p8, gen_op_movl_T0_p9,
  218 + gen_op_movl_T0_p10, gen_op_movl_T0_p11,
  219 + gen_op_movl_T0_p12,
  220 + gen_ccs_read, /* ccs needs special treatment. */
  221 + gen_op_movl_T0_p14, gen_op_movl_T0_p15,
  222 +};
  223 +
  224 +/* We need this table to handle moves with implicit width. */
  225 +int preg_sizes[] = {
  226 + 1, /* bz. */
  227 + 1, /* vr. */
  228 + 4, /* pid. */
  229 + 1, /* srs. */
  230 + 2, /* wz. */
  231 + 4, 4, 4,
  232 + 4, 4, 4, 4,
  233 + 4, 4, 4, 4,
  234 +};
  235 +
  236 +#ifdef CONFIG_USER_ONLY
  237 +#define GEN_OP_LD(width, reg) \
  238 + void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
  239 + gen_op_ld##width##_T0_##reg##_raw(); \
  240 + }
  241 +#define GEN_OP_ST(width, reg) \
  242 + void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
  243 + gen_op_st##width##_##reg##_T1_raw(); \
  244 + }
  245 +#else
  246 +#define GEN_OP_LD(width, reg) \
  247 + void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
  248 + if (dc->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
  249 + else gen_op_ld##width##_T0_##reg##_user();\
  250 + }
  251 +#define GEN_OP_ST(width, reg) \
  252 + void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
  253 + if (dc->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
  254 + else gen_op_st##width##_##reg##_T1_user();\
  255 + }
  256 +#endif
  257 +
  258 +GEN_OP_LD(ub, T0)
  259 +GEN_OP_LD(b, T0)
  260 +GEN_OP_ST(b, T0)
  261 +GEN_OP_LD(uw, T0)
  262 +GEN_OP_LD(w, T0)
  263 +GEN_OP_ST(w, T0)
  264 +GEN_OP_LD(l, T0)
  265 +GEN_OP_ST(l, T0)
  266 +
  267 +static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
  268 +{
  269 + TranslationBlock *tb;
  270 + tb = dc->tb;
  271 + if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
  272 + if (n == 0)
  273 + gen_op_goto_tb0(TBPARAM(tb));
  274 + else
  275 + gen_op_goto_tb1(TBPARAM(tb));
  276 + gen_op_movl_T0_0();
  277 + } else {
  278 + gen_op_movl_T0_0();
  279 + }
  280 + gen_op_exit_tb();
  281 +}
  282 +
  283 +/* Sign extend at translation time. */
  284 +static int sign_extend(unsigned int val, unsigned int width)
  285 +{
  286 + int sval;
  287 +
  288 + /* LSL. */
  289 + val <<= 31 - width;
  290 + sval = val;
  291 + /* ASR. */
  292 + sval >>= 31 - width;
  293 + return sval;
  294 +}
  295 +
  296 +static void cris_evaluate_flags(DisasContext *dc)
  297 +{
  298 + if (!dc->flags_live) {
  299 +
  300 + switch (dc->cc_op)
  301 + {
  302 + case CC_OP_MCP:
  303 + gen_op_evaluate_flags_mcp ();
  304 + break;
  305 + case CC_OP_MULS:
  306 + gen_op_evaluate_flags_muls ();
  307 + break;
  308 + case CC_OP_MULU:
  309 + gen_op_evaluate_flags_mulu ();
  310 + break;
  311 + case CC_OP_MOVE:
  312 + switch (dc->cc_size)
  313 + {
  314 + case 4:
  315 + gen_op_evaluate_flags_move_4();
  316 + break;
  317 + case 2:
  318 + gen_op_evaluate_flags_move_2();
  319 + break;
  320 + default:
  321 + gen_op_evaluate_flags ();
  322 + break;
  323 + }
  324 + break;
  325 +
  326 + default:
  327 + {
  328 + switch (dc->cc_size)
  329 + {
  330 + case 4:
  331 + gen_op_evaluate_flags_alu_4 ();
  332 + break;
  333 + default:
  334 + gen_op_evaluate_flags ();
  335 + break;
  336 + }
  337 + }
  338 + break;
  339 + }
  340 + dc->flags_live = 1;
  341 + }
  342 +}
  343 +
  344 +static void cris_cc_mask(DisasContext *dc, unsigned int mask)
  345 +{
  346 + uint32_t ovl;
  347 +
  348 + ovl = (dc->cc_mask ^ mask) & ~mask;
  349 + if (ovl) {
  350 + /* TODO: optimize this case. It trigs all the time. */
  351 + cris_evaluate_flags (dc);
  352 + }
  353 + dc->cc_mask = mask;
  354 +
  355 + dc->update_cc = 1;
  356 + if (mask == 0)
  357 + dc->update_cc = 0;
  358 + else {
  359 + gen_op_update_cc_mask(mask);
  360 + dc->flags_live = 0;
  361 + }
  362 +}
  363 +
  364 +static void cris_update_cc_op(DisasContext *dc, int op)
  365 +{
  366 + dc->cc_op = op;
  367 + gen_op_update_cc_op(op);
  368 + dc->flags_live = 0;
  369 +}
  370 +static void cris_update_cc_size(DisasContext *dc, int size)
  371 +{
  372 + dc->cc_size = size;
  373 + gen_op_update_cc_size_im(size);
  374 +}
  375 +
  376 +/* op is the operation.
  377 + T0, T1 are the operands.
  378 + dst is the destination reg.
  379 +*/
  380 +static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
  381 +{
  382 + int writeback = 1;
  383 + if (dc->update_cc) {
  384 + cris_update_cc_op(dc, op);
  385 + cris_update_cc_size(dc, size);
  386 + gen_op_update_cc_x(dc->flagx_live, dc->flags_x);
  387 + gen_op_update_cc_dest_T0();
  388 + }
  389 +
  390 + /* Emit the ALU insns. */
  391 + switch (op)
  392 + {
  393 + case CC_OP_ADD:
  394 + gen_op_addl_T0_T1();
  395 + /* Extended arithmetics. */
  396 + if (!dc->flagx_live)
  397 + gen_op_addxl_T0_C();
  398 + else if (dc->flags_x)
  399 + gen_op_addxl_T0_C();
  400 + break;
  401 + case CC_OP_ADDC:
  402 + gen_op_addl_T0_T1();
  403 + gen_op_addl_T0_C();
  404 + break;
  405 + case CC_OP_MCP:
  406 + gen_op_addl_T0_T1();
  407 + gen_op_addl_T0_R();
  408 + break;
  409 + case CC_OP_SUB:
  410 + gen_op_negl_T1_T1();
  411 + gen_op_addl_T0_T1();
  412 + /* CRIS flag evaluation needs ~src. */
  413 + gen_op_negl_T1_T1();
  414 + gen_op_not_T1_T1();
  415 +
  416 + /* Extended arithmetics. */
  417 + if (!dc->flagx_live)
  418 + gen_op_subxl_T0_C();
  419 + else if (dc->flags_x)
  420 + gen_op_subxl_T0_C();
  421 + break;
  422 + case CC_OP_MOVE:
  423 + gen_op_movl_T0_T1();
  424 + break;
  425 + case CC_OP_OR:
  426 + gen_op_orl_T0_T1();
  427 + break;
  428 + case CC_OP_AND:
  429 + gen_op_andl_T0_T1();
  430 + break;
  431 + case CC_OP_XOR:
  432 + gen_op_xorl_T0_T1();
  433 + break;
  434 + case CC_OP_LSL:
  435 + gen_op_lsll_T0_T1();
  436 + break;
  437 + case CC_OP_LSR:
  438 + gen_op_lsrl_T0_T1();
  439 + break;
  440 + case CC_OP_ASR:
  441 + gen_op_asrl_T0_T1();
  442 + break;
  443 + case CC_OP_NEG:
  444 + gen_op_negl_T0_T1();
  445 + /* Extended arithmetics. */
  446 + gen_op_subxl_T0_C();
  447 + break;
  448 + case CC_OP_LZ:
  449 + gen_op_lz_T0_T1();
  450 + break;
  451 + case CC_OP_BTST:
  452 + gen_op_btst_T0_T1();
  453 + writeback = 0;
  454 + break;
  455 + case CC_OP_MULS:
  456 + gen_op_muls_T0_T1();
  457 + break;
  458 + case CC_OP_MULU:
  459 + gen_op_mulu_T0_T1();
  460 + break;
  461 + case CC_OP_DSTEP:
  462 + gen_op_dstep_T0_T1();
  463 + break;
  464 + case CC_OP_BOUND:
  465 + gen_op_bound_T0_T1();
  466 + break;
  467 + case CC_OP_CMP:
  468 + gen_op_negl_T1_T1();
  469 + gen_op_addl_T0_T1();
  470 + /* CRIS flag evaluation needs ~src. */
  471 + gen_op_negl_T1_T1();
  472 + gen_op_not_T1_T1();
  473 +
  474 + /* Extended arithmetics. */
  475 + gen_op_subxl_T0_C();
  476 + writeback = 0;
  477 + break;
  478 + default:
  479 + fprintf (logfile, "illegal ALU op.\n");
  480 + BUG();
  481 + break;
  482 + }
  483 +
  484 + if (dc->update_cc)
  485 + gen_op_update_cc_src_T1();
  486 +
  487 + if (size == 1)
  488 + gen_op_andl_T0_im(0xff);
  489 + else if (size == 2)
  490 + gen_op_andl_T0_im(0xffff);
  491 + /* Writeback. */
  492 + if (writeback) {
  493 + if (size == 4)
  494 + gen_movl_reg_T0[rd]();
  495 + else {
  496 + gen_op_movl_T1_T0();
  497 + gen_movl_T0_reg[rd]();
  498 + if (size == 1)
  499 + gen_op_andl_T0_im(~0xff);
  500 + else
  501 + gen_op_andl_T0_im(~0xffff);
  502 + gen_op_orl_T0_T1();
  503 + gen_movl_reg_T0[rd]();
  504 + gen_op_movl_T0_T1();
  505 + }
  506 + }
  507 + if (dc->update_cc)
  508 + gen_op_update_cc_result_T0();
  509 +
  510 + {
  511 + /* TODO: Optimize this. */
  512 + if (!dc->flagx_live)
  513 + cris_evaluate_flags(dc);
  514 + }
  515 +}
  516 +
  517 +static int arith_cc(DisasContext *dc)
  518 +{
  519 + if (dc->update_cc) {
  520 + switch (dc->cc_op) {
  521 + case CC_OP_ADD: return 1;
  522 + case CC_OP_SUB: return 1;
  523 + case CC_OP_LSL: return 1;
  524 + case CC_OP_LSR: return 1;
  525 + case CC_OP_ASR: return 1;
  526 + case CC_OP_CMP: return 1;
  527 + default:
  528 + return 0;
  529 + }
  530 + }
  531 + return 0;
  532 +}
  533 +
  534 +static void gen_tst_cc (DisasContext *dc, int cond)
  535 +{
  536 + int arith_opt;
  537 +
  538 + /* TODO: optimize more condition codes. */
  539 + arith_opt = arith_cc(dc) && !dc->flags_live;
  540 + switch (cond) {
  541 + case CC_EQ:
  542 + if (arith_opt)
  543 + gen_op_tst_cc_eq_fast ();
  544 + else {
  545 + cris_evaluate_flags(dc);
  546 + gen_op_tst_cc_eq ();
  547 + }
  548 + break;
  549 + case CC_NE:
  550 + if (arith_opt)
  551 + gen_op_tst_cc_ne_fast ();
  552 + else {
  553 + cris_evaluate_flags(dc);
  554 + gen_op_tst_cc_ne ();
  555 + }
  556 + break;
  557 + case CC_CS:
  558 + cris_evaluate_flags(dc);
  559 + gen_op_tst_cc_cs ();
  560 + break;
  561 + case CC_CC:
  562 + cris_evaluate_flags(dc);
  563 + gen_op_tst_cc_cc ();
  564 + break;
  565 + case CC_VS:
  566 + cris_evaluate_flags(dc);
  567 + gen_op_tst_cc_vs ();
  568 + break;
  569 + case CC_VC:
  570 + cris_evaluate_flags(dc);
  571 + gen_op_tst_cc_vc ();
  572 + break;
  573 + case CC_PL:
  574 + if (arith_opt)
  575 + gen_op_tst_cc_pl_fast ();
  576 + else {
  577 + cris_evaluate_flags(dc);
  578 + gen_op_tst_cc_pl ();
  579 + }
  580 + break;
  581 + case CC_MI:
  582 + if (arith_opt)
  583 + gen_op_tst_cc_mi_fast ();
  584 + else {
  585 + cris_evaluate_flags(dc);
  586 + gen_op_tst_cc_mi ();
  587 + }
  588 + break;
  589 + case CC_LS:
  590 + cris_evaluate_flags(dc);
  591 + gen_op_tst_cc_ls ();
  592 + break;
  593 + case CC_HI:
  594 + cris_evaluate_flags(dc);
  595 + gen_op_tst_cc_hi ();
  596 + break;
  597 + case CC_GE:
  598 + cris_evaluate_flags(dc);
  599 + gen_op_tst_cc_ge ();
  600 + break;
  601 + case CC_LT:
  602 + cris_evaluate_flags(dc);
  603 + gen_op_tst_cc_lt ();
  604 + break;
  605 + case CC_GT:
  606 + cris_evaluate_flags(dc);
  607 + gen_op_tst_cc_gt ();
  608 + break;
  609 + case CC_LE:
  610 + cris_evaluate_flags(dc);
  611 + gen_op_tst_cc_le ();
  612 + break;
  613 + case CC_P:
  614 + cris_evaluate_flags(dc);
  615 + gen_op_tst_cc_p ();
  616 + break;
  617 + case CC_A:
  618 + cris_evaluate_flags(dc);
  619 + gen_op_movl_T0_im (1);
  620 + break;
  621 + default:
  622 + BUG();
  623 + break;
  624 + };
  625 +}
  626 +
  627 +static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond)
  628 +{
  629 + /* This helps us re-schedule the micro-code to insns in delay-slots
  630 + before the actual jump. */
  631 + dc->delayed_branch = 2;
  632 + dc->delayed_pc = dc->pc + offset;
  633 + dc->bcc = cond;
  634 + if (cond != CC_A)
  635 + {
  636 + gen_tst_cc (dc, cond);
  637 + gen_op_evaluate_bcc ();
  638 + }
  639 + gen_op_movl_T0_im (dc->delayed_pc);
  640 + gen_op_movl_btarget_T0 ();
  641 +}
  642 +
  643 +/* Dynamic jumps, when the dest is in a live reg for example. */
  644 +void cris_prepare_dyn_jmp (DisasContext *dc)
  645 +{
  646 + /* This helps us re-schedule the micro-code to insns in delay-slots
  647 + before the actual jump. */
  648 + dc->delayed_branch = 2;
  649 + dc->dyn_jmp = 1;
  650 + dc->bcc = CC_A;
  651 +}
  652 +
  653 +void cris_prepare_jmp (DisasContext *dc, uint32_t dst)
  654 +{
  655 + /* This helps us re-schedule the micro-code to insns in delay-slots
  656 + before the actual jump. */
  657 + dc->delayed_branch = 2;
  658 + dc->delayed_pc = dst;
  659 + dc->dyn_jmp = 0;
  660 + dc->bcc = CC_A;
  661 +}
  662 +
  663 +void gen_load_T0_T0 (DisasContext *dc, unsigned int size, int sign)
  664 +{
  665 + if (size == 1) {
  666 + if (sign)
  667 + gen_op_ldb_T0_T0(dc);
  668 + else
  669 + gen_op_ldub_T0_T0(dc);
  670 + }
  671 + else if (size == 2) {
  672 + if (sign)
  673 + gen_op_ldw_T0_T0(dc);
  674 + else
  675 + gen_op_lduw_T0_T0(dc);
  676 + }
  677 + else {
  678 + gen_op_ldl_T0_T0(dc);
  679 + }
  680 +}
  681 +
  682 +void gen_store_T0_T1 (DisasContext *dc, unsigned int size)
  683 +{
  684 + /* Remember, operands are flipped. CRIS has reversed order. */
  685 + if (size == 1) {
  686 + gen_op_stb_T0_T1(dc);
  687 + }
  688 + else if (size == 2) {
  689 + gen_op_stw_T0_T1(dc);
  690 + }
  691 + else
  692 + gen_op_stl_T0_T1(dc);
  693 +}
  694 +
  695 +/* sign extend T1 according to size. */
  696 +static void gen_sext_T1_T0(int size)
  697 +{
  698 + if (size == 1)
  699 + gen_op_extb_T1_T0();
  700 + else if (size == 2)
  701 + gen_op_extw_T1_T0();
  702 +}
  703 +
  704 +static void gen_sext_T1_T1(int size)
  705 +{
  706 + if (size == 1)
  707 + gen_op_extb_T1_T1();
  708 + else if (size == 2)
  709 + gen_op_extw_T1_T1();
  710 +}
  711 +
  712 +static void gen_sext_T0_T0(int size)
  713 +{
  714 + if (size == 1)
  715 + gen_op_extb_T0_T0();
  716 + else if (size == 2)
  717 + gen_op_extw_T0_T0();
  718 +}
  719 +
  720 +static void gen_zext_T0_T0(int size)
  721 +{
  722 + if (size == 1)
  723 + gen_op_zextb_T0_T0();
  724 + else if (size == 2)
  725 + gen_op_zextw_T0_T0();
  726 +}
  727 +
  728 +static void gen_zext_T1_T0(int size)
  729 +{
  730 + if (size == 1)
  731 + gen_op_zextb_T1_T0();
  732 + else if (size == 2)
  733 + gen_op_zextw_T1_T0();
  734 +}
  735 +
  736 +static void gen_zext_T1_T1(int size)
  737 +{
  738 + if (size == 1)
  739 + gen_op_zextb_T1_T1();
  740 + else if (size == 2)
  741 + gen_op_zextw_T1_T1();
  742 +}
  743 +
  744 +#if DISAS_CRIS
  745 +static char memsize_char(int size)
  746 +{
  747 + switch (size)
  748 + {
  749 + case 1: return 'b'; break;
  750 + case 2: return 'w'; break;
  751 + case 4: return 'd'; break;
  752 + default:
  753 + return 'x';
  754 + break;
  755 + }
  756 +}
  757 +#endif
  758 +
  759 +static unsigned int memsize_z(DisasContext *dc)
  760 +{
  761 + return dc->zsize + 1;
  762 +}
  763 +
  764 +static unsigned int memsize_zz(DisasContext *dc)
  765 +{
  766 + switch (dc->zzsize)
  767 + {
  768 + case 0: return 1;
  769 + case 1: return 2;
  770 + default:
  771 + return 4;
  772 + }
  773 +}
  774 +
  775 +static void do_postinc (DisasContext *dc, int size)
  776 +{
  777 + if (!dc->postinc)
  778 + return;
  779 + gen_movl_T0_reg[dc->op1]();
  780 + gen_op_addl_T0_im(size);
  781 + gen_movl_reg_T0[dc->op1]();
  782 +}
  783 +
  784 +
  785 +static void dec_prep_move_r(DisasContext *dc, int rs, int rd,
  786 + int size, int s_ext)
  787 +{
  788 + gen_movl_T0_reg[rs]();
  789 + gen_op_movl_T1_T0();
  790 + if (s_ext)
  791 + gen_sext_T1_T1(size);
  792 + else
  793 + gen_zext_T1_T1(size);
  794 +}
  795 +
  796 +/* Prepare T0 and T1 for a register alu operation.
  797 + s_ext decides if the operand1 should be sign-extended or zero-extended when
  798 + needed. */
  799 +static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
  800 + int size, int s_ext)
  801 +{
  802 + dec_prep_move_r(dc, rs, rd, size, s_ext);
  803 +
  804 + gen_movl_T0_reg[rd]();
  805 + if (s_ext)
  806 + gen_sext_T0_T0(size);
  807 + else
  808 + gen_zext_T0_T0(size);
  809 +}
  810 +
  811 +/* Prepare T0 and T1 for a memory + alu operation.
  812 + s_ext decides if the operand1 should be sign-extended or zero-extended when
  813 + needed. */
  814 +static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
  815 +{
  816 + unsigned int rs, rd;
  817 + uint32_t imm;
  818 + int is_imm;
  819 + int insn_len = 2;
  820 +
  821 + rs = dc->op1;
  822 + rd = dc->op2;
  823 + is_imm = rs == 15 && dc->postinc;
  824 +
  825 + /* Load [$rs] onto T1. */
  826 + if (is_imm) {
  827 + insn_len = 2 + memsize;
  828 + if (memsize == 1)
  829 + insn_len++;
  830 +
  831 + imm = ldl_code(dc->pc + 2);
  832 + if (memsize != 4) {
  833 + if (s_ext) {
  834 + imm = sign_extend(imm, (memsize * 8) - 1);
  835 + } else {
  836 + if (memsize == 1)
  837 + imm &= 0xff;
  838 + else
  839 + imm &= 0xffff;
  840 + }
  841 + }
  842 + DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n",
  843 + imm, rd, s_ext, memsize));
  844 + gen_op_movl_T1_im (imm);
  845 + dc->postinc = 0;
  846 + } else {
  847 + gen_movl_T0_reg[rs]();
  848 + gen_load_T0_T0(dc, memsize, 0);
  849 + gen_op_movl_T1_T0();
  850 + if (s_ext)
  851 + gen_sext_T1_T1(memsize);
  852 + else
  853 + gen_zext_T1_T1(memsize);
  854 + }
  855 +
  856 + /* put dest in T0. */
  857 + gen_movl_T0_reg[rd]();
  858 + return insn_len;
  859 +}
  860 +
  861 +#if DISAS_CRIS
  862 +static const char *cc_name(int cc)
  863 +{
  864 + static char *cc_names[16] = {
  865 + "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
  866 + "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
  867 + };
  868 + assert(cc < 16);
  869 + return cc_names[cc];
  870 +}
  871 +#endif
  872 +
  873 +static unsigned int dec_bccq(DisasContext *dc)
  874 +{
  875 + int32_t offset;
  876 + int sign;
  877 + uint32_t cond = dc->op2;
  878 + int tmp;
  879 +
  880 + offset = EXTRACT_FIELD (dc->ir, 1, 7);
  881 + sign = EXTRACT_FIELD(dc->ir, 0, 0);
  882 +
  883 + offset *= 2;
  884 + offset |= sign << 8;
  885 + tmp = offset;
  886 + offset = sign_extend(offset, 8);
  887 +
  888 + /* op2 holds the condition-code. */
  889 + cris_cc_mask(dc, 0);
  890 + cris_prepare_cc_branch (dc, offset, cond);
  891 + return 2;
  892 +}
  893 +static unsigned int dec_addoq(DisasContext *dc)
  894 +{
  895 + uint32_t imm;
  896 +
  897 + dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
  898 + imm = sign_extend(dc->op1, 7);
  899 +
  900 + DIS(fprintf (logfile, "addoq %d, $r%u\n", imm, dc->op2));
  901 + cris_cc_mask(dc, 0);
  902 + /* Fetch register operand, */
  903 + gen_movl_T0_reg[dc->op2]();
  904 + gen_op_movl_T1_im(imm);
  905 + crisv32_alu_op(dc, CC_OP_ADD, REG_ACR, 4);
  906 + return 2;
  907 +}
  908 +static unsigned int dec_addq(DisasContext *dc)
  909 +{
  910 + DIS(fprintf (logfile, "addq %u, $r%u\n", dc->op1, dc->op2));
  911 +
  912 + dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
  913 +
  914 + cris_cc_mask(dc, CC_MASK_NZVC);
  915 + /* Fetch register operand, */
  916 + gen_movl_T0_reg[dc->op2]();
  917 + gen_op_movl_T1_im(dc->op1);
  918 + crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
  919 + return 2;
  920 +}
  921 +static unsigned int dec_moveq(DisasContext *dc)
  922 +{
  923 + uint32_t imm;
  924 +
  925 + dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
  926 + imm = sign_extend(dc->op1, 5);
  927 + DIS(fprintf (logfile, "moveq %d, $r%u\n", imm, dc->op2));
  928 +
  929 + cris_cc_mask(dc, 0);
  930 + gen_op_movl_T1_im(imm);
  931 + crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
  932 +
  933 + return 2;
  934 +}
  935 +static unsigned int dec_subq(DisasContext *dc)
  936 +{
  937 + dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
  938 +
  939 + DIS(fprintf (logfile, "subq %u, $r%u\n", dc->op1, dc->op2));
  940 +
  941 + cris_cc_mask(dc, CC_MASK_NZVC);
  942 + /* Fetch register operand, */
  943 + gen_movl_T0_reg[dc->op2]();
  944 + gen_op_movl_T1_im(dc->op1);
  945 + crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
  946 + return 2;
  947 +}
  948 +static unsigned int dec_cmpq(DisasContext *dc)
  949 +{
  950 + uint32_t imm;
  951 + dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
  952 + imm = sign_extend(dc->op1, 5);
  953 +
  954 + DIS(fprintf (logfile, "cmpq %d, $r%d\n", imm, dc->op2));
  955 + cris_cc_mask(dc, CC_MASK_NZVC);
  956 + gen_movl_T0_reg[dc->op2]();
  957 + gen_op_movl_T1_im(imm);
  958 + crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
  959 + return 2;
  960 +}
  961 +static unsigned int dec_andq(DisasContext *dc)
  962 +{
  963 + uint32_t imm;
  964 + dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
  965 + imm = sign_extend(dc->op1, 5);
  966 +
  967 + DIS(fprintf (logfile, "andq %d, $r%d\n", imm, dc->op2));
  968 + cris_cc_mask(dc, CC_MASK_NZ);
  969 + gen_movl_T0_reg[dc->op2]();
  970 + gen_op_movl_T1_im(imm);
  971 + crisv32_alu_op(dc, CC_OP_AND, dc->op2, 4);
  972 + return 2;
  973 +}
  974 +static unsigned int dec_orq(DisasContext *dc)
  975 +{
  976 + uint32_t imm;
  977 + dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
  978 + imm = sign_extend(dc->op1, 5);
  979 + DIS(fprintf (logfile, "orq %d, $r%d\n", imm, dc->op2));
  980 + cris_cc_mask(dc, CC_MASK_NZ);
  981 + gen_movl_T0_reg[dc->op2]();
  982 + gen_op_movl_T1_im(imm);
  983 + crisv32_alu_op(dc, CC_OP_OR, dc->op2, 4);
  984 + return 2;
  985 +}
  986 +static unsigned int dec_btstq(DisasContext *dc)
  987 +{
  988 + dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
  989 + DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2));
  990 + cris_evaluate_flags(dc);
  991 + cris_cc_mask(dc, CC_MASK_NZ);
  992 + gen_movl_T0_reg[dc->op2]();
  993 + gen_op_movl_T1_im(dc->op1);
  994 + crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
  995 +
  996 + cris_update_cc_op(dc, CC_OP_FLAGS);
  997 + gen_op_movl_flags_T0();
  998 + dc->flags_live = 1;
  999 + return 2;
  1000 +}
  1001 +static unsigned int dec_asrq(DisasContext *dc)
  1002 +{
  1003 + dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
  1004 + DIS(fprintf (logfile, "asrq %u, $r%d\n", dc->op1, dc->op2));
  1005 + cris_cc_mask(dc, CC_MASK_NZ);
  1006 + gen_movl_T0_reg[dc->op2]();
  1007 + gen_op_movl_T1_im(dc->op1);
  1008 + crisv32_alu_op(dc, CC_OP_ASR, dc->op2, 4);
  1009 + return 2;
  1010 +}
  1011 +static unsigned int dec_lslq(DisasContext *dc)
  1012 +{
  1013 + dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
  1014 + DIS(fprintf (logfile, "lslq %u, $r%d\n", dc->op1, dc->op2));
  1015 +
  1016 + cris_cc_mask(dc, CC_MASK_NZ);
  1017 + gen_movl_T0_reg[dc->op2]();
  1018 + gen_op_movl_T1_im(dc->op1);
  1019 + crisv32_alu_op(dc, CC_OP_LSL, dc->op2, 4);
  1020 + return 2;
  1021 +}
  1022 +static unsigned int dec_lsrq(DisasContext *dc)
  1023 +{
  1024 + dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
  1025 + DIS(fprintf (logfile, "lsrq %u, $r%d\n", dc->op1, dc->op2));
  1026 +
  1027 + cris_cc_mask(dc, CC_MASK_NZ);
  1028 + gen_movl_T0_reg[dc->op2]();
  1029 + gen_op_movl_T1_im(dc->op1);
  1030 + crisv32_alu_op(dc, CC_OP_LSR, dc->op2, 4);
  1031 + return 2;
  1032 +}
  1033 +
  1034 +static unsigned int dec_move_r(DisasContext *dc)
  1035 +{
  1036 + int size = memsize_zz(dc);
  1037 +
  1038 + DIS(fprintf (logfile, "move.%c $r%u, $r%u\n",
  1039 + memsize_char(size), dc->op1, dc->op2));
  1040 +
  1041 + cris_cc_mask(dc, CC_MASK_NZ);
  1042 + dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
  1043 + crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, size);
  1044 + return 2;
  1045 +}
  1046 +
  1047 +static unsigned int dec_scc_r(DisasContext *dc)
  1048 +{
  1049 + int cond = dc->op2;
  1050 +
  1051 + DIS(fprintf (logfile, "s%s $r%u\n",
  1052 + cc_name(cond), dc->op1));
  1053 +
  1054 + if (cond != CC_A)
  1055 + {
  1056 + gen_tst_cc (dc, cond);
  1057 + gen_op_movl_T1_T0();
  1058 + }
  1059 + else
  1060 + gen_op_movl_T1_im(1);
  1061 +
  1062 + cris_cc_mask(dc, 0);
  1063 + crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
  1064 + return 2;
  1065 +}
  1066 +
  1067 +static unsigned int dec_and_r(DisasContext *dc)
  1068 +{
  1069 + int size = memsize_zz(dc);
  1070 +
  1071 + DIS(fprintf (logfile, "and.%c $r%u, $r%u\n",
  1072 + memsize_char(size), dc->op1, dc->op2));
  1073 + cris_cc_mask(dc, CC_MASK_NZ);
  1074 + dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
  1075 + crisv32_alu_op(dc, CC_OP_AND, dc->op2, size);
  1076 + return 2;
  1077 +}
  1078 +
  1079 +static unsigned int dec_lz_r(DisasContext *dc)
  1080 +{
  1081 + DIS(fprintf (logfile, "lz $r%u, $r%u\n",
  1082 + dc->op1, dc->op2));
  1083 + cris_cc_mask(dc, CC_MASK_NZ);
  1084 + dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
  1085 + crisv32_alu_op(dc, CC_OP_LZ, dc->op2, 4);
  1086 + return 2;
  1087 +}
  1088 +
  1089 +static unsigned int dec_lsl_r(DisasContext *dc)
  1090 +{
  1091 + int size = memsize_zz(dc);
  1092 +
  1093 + DIS(fprintf (logfile, "lsl.%c $r%u, $r%u\n",
  1094 + memsize_char(size), dc->op1, dc->op2));
  1095 + cris_cc_mask(dc, CC_MASK_NZ);
  1096 + dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
  1097 + gen_op_andl_T1_im(63);
  1098 + crisv32_alu_op(dc, CC_OP_LSL, dc->op2, size);
  1099 + return 2;
  1100 +}
  1101 +
  1102 +static unsigned int dec_lsr_r(DisasContext *dc)
  1103 +{
  1104 + int size = memsize_zz(dc);
  1105 +
  1106 + DIS(fprintf (logfile, "lsr.%c $r%u, $r%u\n",
  1107 + memsize_char(size), dc->op1, dc->op2));
  1108 + cris_cc_mask(dc, CC_MASK_NZ);
  1109 + dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
  1110 + gen_op_andl_T1_im(63);
  1111 + crisv32_alu_op(dc, CC_OP_LSR, dc->op2, size);
  1112 + return 2;
  1113 +}
  1114 +
  1115 +static unsigned int dec_asr_r(DisasContext *dc)
  1116 +{
  1117 + int size = memsize_zz(dc);
  1118 +
  1119 + DIS(fprintf (logfile, "asr.%c $r%u, $r%u\n",
  1120 + memsize_char(size), dc->op1, dc->op2));
  1121 + cris_cc_mask(dc, CC_MASK_NZ);
  1122 + dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
  1123 + gen_op_andl_T1_im(63);
  1124 + crisv32_alu_op(dc, CC_OP_ASR, dc->op2, size);
  1125 + return 2;
  1126 +}
  1127 +
  1128 +static unsigned int dec_muls_r(DisasContext *dc)
  1129 +{
  1130 + int size = memsize_zz(dc);
  1131 +
  1132 + DIS(fprintf (logfile, "muls.%c $r%u, $r%u\n",
  1133 + memsize_char(size), dc->op1, dc->op2));
  1134 + cris_cc_mask(dc, CC_MASK_NZV);
  1135 + dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
  1136 + gen_sext_T0_T0(size);
  1137 + crisv32_alu_op(dc, CC_OP_MULS, dc->op2, 4);
  1138 + return 2;
  1139 +}
  1140 +
  1141 +static unsigned int dec_mulu_r(DisasContext *dc)
  1142 +{
  1143 + int size = memsize_zz(dc);
  1144 +
  1145 + DIS(fprintf (logfile, "mulu.%c $r%u, $r%u\n",
  1146 + memsize_char(size), dc->op1, dc->op2));
  1147 + cris_cc_mask(dc, CC_MASK_NZV);
  1148 + dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
  1149 + gen_zext_T0_T0(size);
  1150 + crisv32_alu_op(dc, CC_OP_MULU, dc->op2, 4);
  1151 + return 2;
  1152 +}
  1153 +
  1154 +
  1155 +static unsigned int dec_dstep_r(DisasContext *dc)
  1156 +{
  1157 + DIS(fprintf (logfile, "dstep $r%u, $r%u\n", dc->op1, dc->op2));
  1158 + cris_cc_mask(dc, CC_MASK_NZ);
  1159 + gen_movl_T0_reg[dc->op1]();
  1160 + gen_op_movl_T1_T0();
  1161 + gen_movl_T0_reg[dc->op2]();
  1162 + crisv32_alu_op(dc, CC_OP_DSTEP, dc->op2, 4);
  1163 + return 2;
  1164 +}
  1165 +
  1166 +static unsigned int dec_xor_r(DisasContext *dc)
  1167 +{
  1168 + int size = memsize_zz(dc);
  1169 + DIS(fprintf (logfile, "xor.%c $r%u, $r%u\n",
  1170 + memsize_char(size), dc->op1, dc->op2));
  1171 + BUG_ON(size != 4); /* xor is dword. */
  1172 + cris_cc_mask(dc, CC_MASK_NZ);
  1173 + dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
  1174 + crisv32_alu_op(dc, CC_OP_XOR, dc->op2, 4);
  1175 + return 2;
  1176 +}
  1177 +
  1178 +static unsigned int dec_bound_r(DisasContext *dc)
  1179 +{
  1180 + int size = memsize_zz(dc);
  1181 + DIS(fprintf (logfile, "bound.%c $r%u, $r%u\n",
  1182 + memsize_char(size), dc->op1, dc->op2));
  1183 + cris_cc_mask(dc, CC_MASK_NZ);
  1184 + /* TODO: needs optmimization. */
  1185 + dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
  1186 + /* rd should be 4. */
  1187 + gen_movl_T0_reg[dc->op2]();
  1188 + crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
  1189 + return 2;
  1190 +}
  1191 +
  1192 +static unsigned int dec_cmp_r(DisasContext *dc)
  1193 +{
  1194 + int size = memsize_zz(dc);
  1195 + DIS(fprintf (logfile, "cmp.%c $r%u, $r%u\n",
  1196 + memsize_char(size), dc->op1, dc->op2));
  1197 + cris_cc_mask(dc, CC_MASK_NZVC);
  1198 + dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
  1199 + crisv32_alu_op(dc, CC_OP_CMP, dc->op2, size);
  1200 + return 2;
  1201 +}
  1202 +
  1203 +static unsigned int dec_abs_r(DisasContext *dc)
  1204 +{
  1205 + DIS(fprintf (logfile, "abs $r%u, $r%u\n",
  1206 + dc->op1, dc->op2));
  1207 + cris_cc_mask(dc, CC_MASK_NZ);
  1208 + dec_prep_move_r(dc, dc->op1, dc->op2, 4, 0);
  1209 + gen_op_absl_T1_T1();
  1210 + crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
  1211 + return 2;
  1212 +}
  1213 +
  1214 +static unsigned int dec_add_r(DisasContext *dc)
  1215 +{
  1216 + int size = memsize_zz(dc);
  1217 + DIS(fprintf (logfile, "add.%c $r%u, $r%u\n",
  1218 + memsize_char(size), dc->op1, dc->op2));
  1219 + cris_cc_mask(dc, CC_MASK_NZVC);
  1220 + dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
  1221 + crisv32_alu_op(dc, CC_OP_ADD, dc->op2, size);
  1222 + return 2;
  1223 +}
  1224 +
  1225 +static unsigned int dec_addc_r(DisasContext *dc)
  1226 +{
  1227 + DIS(fprintf (logfile, "addc $r%u, $r%u\n",
  1228 + dc->op1, dc->op2));
  1229 + cris_evaluate_flags(dc);
  1230 + cris_cc_mask(dc, CC_MASK_NZVC);
  1231 + dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
  1232 + crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
  1233 + return 2;
  1234 +}
  1235 +
  1236 +static unsigned int dec_mcp_r(DisasContext *dc)
  1237 +{
  1238 + DIS(fprintf (logfile, "mcp $p%u, $r%u\n",
  1239 + dc->op2, dc->op1));
  1240 + cris_evaluate_flags(dc);
  1241 + cris_cc_mask(dc, CC_MASK_RNZV);
  1242 + gen_movl_T0_preg[dc->op2]();
  1243 + gen_op_movl_T1_T0();
  1244 + gen_movl_T0_reg[dc->op1]();
  1245 + crisv32_alu_op(dc, CC_OP_MCP, dc->op1, 4);
  1246 + return 2;
  1247 +}
  1248 +
  1249 +#if DISAS_CRIS
  1250 +static char * swapmode_name(int mode, char *modename) {
  1251 + int i = 0;
  1252 + if (mode & 8)
  1253 + modename[i++] = 'n';
  1254 + if (mode & 4)
  1255 + modename[i++] = 'w';
  1256 + if (mode & 2)
  1257 + modename[i++] = 'b';
  1258 + if (mode & 1)
  1259 + modename[i++] = 'r';
  1260 + modename[i++] = 0;
  1261 + return modename;
  1262 +}
  1263 +#endif
  1264 +
  1265 +static unsigned int dec_swap_r(DisasContext *dc)
  1266 +{
  1267 + DIS(char modename[4]);
  1268 + DIS(fprintf (logfile, "swap%s $r%u\n",
  1269 + swapmode_name(dc->op2, modename), dc->op1));
  1270 +
  1271 + cris_cc_mask(dc, CC_MASK_NZ);
  1272 + gen_movl_T0_reg[dc->op1]();
  1273 + if (dc->op2 & 8)
  1274 + gen_op_not_T0_T0();
  1275 + if (dc->op2 & 4)
  1276 + gen_op_swapw_T0_T0();
  1277 + if (dc->op2 & 2)
  1278 + gen_op_swapb_T0_T0();
  1279 + if (dc->op2 & 1)
  1280 + gen_op_swapr_T0_T0();
  1281 + gen_op_movl_T1_T0();
  1282 + crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
  1283 + return 2;
  1284 +}
  1285 +
  1286 +static unsigned int dec_or_r(DisasContext *dc)
  1287 +{
  1288 + int size = memsize_zz(dc);
  1289 + DIS(fprintf (logfile, "or.%c $r%u, $r%u\n",
  1290 + memsize_char(size), dc->op1, dc->op2));
  1291 + cris_cc_mask(dc, CC_MASK_NZ);
  1292 + dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
  1293 + crisv32_alu_op(dc, CC_OP_OR, dc->op2, size);
  1294 + return 2;
  1295 +}
  1296 +
  1297 +static unsigned int dec_addi_r(DisasContext *dc)
  1298 +{
  1299 + DIS(fprintf (logfile, "addi.%c $r%u, $r%u\n",
  1300 + memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
  1301 + cris_cc_mask(dc, 0);
  1302 + dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
  1303 + gen_op_lsll_T0_im(dc->zzsize);
  1304 + gen_op_addl_T0_T1();
  1305 + gen_movl_reg_T0[dc->op1]();
  1306 + return 2;
  1307 +}
  1308 +
  1309 +static unsigned int dec_addi_acr(DisasContext *dc)
  1310 +{
  1311 + DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n",
  1312 + memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
  1313 + cris_cc_mask(dc, 0);
  1314 + dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
  1315 + gen_op_lsll_T0_im(dc->zzsize);
  1316 + gen_op_addl_T0_T1();
  1317 + gen_movl_reg_T0[REG_ACR]();
  1318 + return 2;
  1319 +}
  1320 +
  1321 +static unsigned int dec_neg_r(DisasContext *dc)
  1322 +{
  1323 + int size = memsize_zz(dc);
  1324 + DIS(fprintf (logfile, "neg.%c $r%u, $r%u\n",
  1325 + memsize_char(size), dc->op1, dc->op2));
  1326 + cris_cc_mask(dc, CC_MASK_NZVC);
  1327 + dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
  1328 + crisv32_alu_op(dc, CC_OP_NEG, dc->op2, size);
  1329 + return 2;
  1330 +}
  1331 +
  1332 +static unsigned int dec_btst_r(DisasContext *dc)
  1333 +{
  1334 + DIS(fprintf (logfile, "btst $r%u, $r%u\n",
  1335 + dc->op1, dc->op2));
  1336 + cris_evaluate_flags(dc);
  1337 + cris_cc_mask(dc, CC_MASK_NZ);
  1338 + dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
  1339 + crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
  1340 +
  1341 + cris_update_cc_op(dc, CC_OP_FLAGS);
  1342 + gen_op_movl_flags_T0();
  1343 + dc->flags_live = 1;
  1344 + return 2;
  1345 +}
  1346 +
  1347 +static unsigned int dec_sub_r(DisasContext *dc)
  1348 +{
  1349 + int size = memsize_zz(dc);
  1350 + DIS(fprintf (logfile, "sub.%c $r%u, $r%u\n",
  1351 + memsize_char(size), dc->op1, dc->op2));
  1352 + cris_cc_mask(dc, CC_MASK_NZVC);
  1353 + dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
  1354 + crisv32_alu_op(dc, CC_OP_SUB, dc->op2, size);
  1355 + return 2;
  1356 +}
  1357 +
  1358 +/* Zero extension. From size to dword. */
  1359 +static unsigned int dec_movu_r(DisasContext *dc)
  1360 +{
  1361 + int size = memsize_z(dc);
  1362 + DIS(fprintf (logfile, "movu.%c $r%u, $r%u\n",
  1363 + memsize_char(size),
  1364 + dc->op1, dc->op2));
  1365 +
  1366 + cris_cc_mask(dc, CC_MASK_NZ);
  1367 + dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
  1368 + crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
  1369 + return 2;
  1370 +}
  1371 +
  1372 +/* Sign extension. From size to dword. */
  1373 +static unsigned int dec_movs_r(DisasContext *dc)
  1374 +{
  1375 + int size = memsize_z(dc);
  1376 + DIS(fprintf (logfile, "movs.%c $r%u, $r%u\n",
  1377 + memsize_char(size),
  1378 + dc->op1, dc->op2));
  1379 +
  1380 + cris_cc_mask(dc, CC_MASK_NZ);
  1381 + gen_movl_T0_reg[dc->op1]();
  1382 + /* Size can only be qi or hi. */
  1383 + gen_sext_T1_T0(size);
  1384 + crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
  1385 + return 2;
  1386 +}
  1387 +
  1388 +/* zero extension. From size to dword. */
  1389 +static unsigned int dec_addu_r(DisasContext *dc)
  1390 +{
  1391 + int size = memsize_z(dc);
  1392 + DIS(fprintf (logfile, "addu.%c $r%u, $r%u\n",
  1393 + memsize_char(size),
  1394 + dc->op1, dc->op2));
  1395 +
  1396 + cris_cc_mask(dc, CC_MASK_NZVC);
  1397 + gen_movl_T0_reg[dc->op1]();
  1398 + /* Size can only be qi or hi. */
  1399 + gen_zext_T1_T0(size);
  1400 + gen_movl_T0_reg[dc->op2]();
  1401 + crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
  1402 + return 2;
  1403 +}
  1404 +/* Sign extension. From size to dword. */
  1405 +static unsigned int dec_adds_r(DisasContext *dc)
  1406 +{
  1407 + int size = memsize_z(dc);
  1408 + DIS(fprintf (logfile, "adds.%c $r%u, $r%u\n",
  1409 + memsize_char(size),
  1410 + dc->op1, dc->op2));
  1411 +
  1412 + cris_cc_mask(dc, CC_MASK_NZVC);
  1413 + gen_movl_T0_reg[dc->op1]();
  1414 + /* Size can only be qi or hi. */
  1415 + gen_sext_T1_T0(size);
  1416 + gen_movl_T0_reg[dc->op2]();
  1417 + crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
  1418 + return 2;
  1419 +}
  1420 +
  1421 +/* Zero extension. From size to dword. */
  1422 +static unsigned int dec_subu_r(DisasContext *dc)
  1423 +{
  1424 + int size = memsize_z(dc);
  1425 + DIS(fprintf (logfile, "subu.%c $r%u, $r%u\n",
  1426 + memsize_char(size),
  1427 + dc->op1, dc->op2));
  1428 +
  1429 + cris_cc_mask(dc, CC_MASK_NZVC);
  1430 + gen_movl_T0_reg[dc->op1]();
  1431 + /* Size can only be qi or hi. */
  1432 + gen_zext_T1_T0(size);
  1433 + gen_movl_T0_reg[dc->op2]();
  1434 + crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
  1435 + return 2;
  1436 +}
  1437 +
  1438 +/* Sign extension. From size to dword. */
  1439 +static unsigned int dec_subs_r(DisasContext *dc)
  1440 +{
  1441 + int size = memsize_z(dc);
  1442 + DIS(fprintf (logfile, "subs.%c $r%u, $r%u\n",
  1443 + memsize_char(size),
  1444 + dc->op1, dc->op2));
  1445 +
  1446 + cris_cc_mask(dc, CC_MASK_NZVC);
  1447 + gen_movl_T0_reg[dc->op1]();
  1448 + /* Size can only be qi or hi. */
  1449 + gen_sext_T1_T0(size);
  1450 + gen_movl_T0_reg[dc->op2]();
  1451 + crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
  1452 + return 2;
  1453 +}
  1454 +
  1455 +static unsigned int dec_setclrf(DisasContext *dc)
  1456 +{
  1457 + uint32_t flags;
  1458 + int set = (~dc->opcode >> 2) & 1;
  1459 +
  1460 + flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
  1461 + | EXTRACT_FIELD(dc->ir, 0, 3);
  1462 + DIS(fprintf (logfile, "set=%d flags=%x\n", set, flags));
  1463 + if (set && flags == 0)
  1464 + DIS(fprintf (logfile, "nop\n"));
  1465 + else if (!set && (flags & 0x20))
  1466 + DIS(fprintf (logfile, "di\n"));
  1467 + else
  1468 + DIS(fprintf (logfile, "%sf %x\n",
  1469 + set ? "set" : "clr",
  1470 + flags));
  1471 +
  1472 + if (set && (flags & X_FLAG)) {
  1473 + dc->flagx_live = 1;
  1474 + dc->flags_x = 1;
  1475 + }
  1476 +
  1477 + /* Simply decode the flags. */
  1478 + cris_evaluate_flags (dc);
  1479 + cris_update_cc_op(dc, CC_OP_FLAGS);
  1480 + if (set)
  1481 + gen_op_setf (flags);
  1482 + else
  1483 + gen_op_clrf (flags);
  1484 + dc->flags_live = 1;
  1485 + return 2;
  1486 +}
  1487 +
  1488 +static unsigned int dec_move_rs(DisasContext *dc)
  1489 +{
  1490 + DIS(fprintf (logfile, "move $r%u, $s%u\n", dc->op1, dc->op2));
  1491 + cris_cc_mask(dc, 0);
  1492 + gen_movl_T0_reg[dc->op1]();
  1493 + gen_op_movl_sreg_T0(dc->op2);
  1494 +
  1495 + if (dc->op2 == 5) /* srs is checked at runtime. */
  1496 + gen_op_movl_tlb_lo_T0();
  1497 + return 2;
  1498 +}
  1499 +static unsigned int dec_move_sr(DisasContext *dc)
  1500 +{
  1501 + DIS(fprintf (logfile, "move $s%u, $r%u\n", dc->op1, dc->op2));
  1502 + cris_cc_mask(dc, 0);
  1503 + gen_op_movl_T0_sreg(dc->op1);
  1504 + gen_op_movl_T1_T0();
  1505 + crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
  1506 + return 2;
  1507 +}
  1508 +static unsigned int dec_move_rp(DisasContext *dc)
  1509 +{
  1510 + DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2));
  1511 + cris_cc_mask(dc, 0);
  1512 + gen_movl_T0_reg[dc->op1]();
  1513 + gen_op_movl_T1_T0();
  1514 + gen_movl_preg_T0[dc->op2]();
  1515 + return 2;
  1516 +}
  1517 +static unsigned int dec_move_pr(DisasContext *dc)
  1518 +{
  1519 + DIS(fprintf (logfile, "move $p%u, $r%u\n", dc->op1, dc->op2));
  1520 + cris_cc_mask(dc, 0);
  1521 + gen_movl_T0_preg[dc->op2]();
  1522 + gen_op_movl_T1_T0();
  1523 + crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, preg_sizes[dc->op2]);
  1524 + return 2;
  1525 +}
  1526 +
  1527 +static unsigned int dec_move_mr(DisasContext *dc)
  1528 +{
  1529 + int memsize = memsize_zz(dc);
  1530 + int insn_len;
  1531 + DIS(fprintf (logfile, "move.%c [$r%u%s, $r%u\n",
  1532 + memsize_char(memsize),
  1533 + dc->op1, dc->postinc ? "+]" : "]",
  1534 + dc->op2));
  1535 +
  1536 + cris_cc_mask(dc, CC_MASK_NZ);
  1537 + insn_len = dec_prep_alu_m(dc, 0, memsize);
  1538 + crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, memsize);
  1539 + do_postinc(dc, memsize);
  1540 + return insn_len;
  1541 +}
  1542 +
  1543 +static unsigned int dec_movs_m(DisasContext *dc)
  1544 +{
  1545 + int memsize = memsize_z(dc);
  1546 + int insn_len;
  1547 + DIS(fprintf (logfile, "movs.%c [$r%u%s, $r%u\n",
  1548 + memsize_char(memsize),
  1549 + dc->op1, dc->postinc ? "+]" : "]",
  1550 + dc->op2));
  1551 +
  1552 + /* sign extend. */
  1553 + cris_cc_mask(dc, CC_MASK_NZ);
  1554 + insn_len = dec_prep_alu_m(dc, 1, memsize);
  1555 + crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
  1556 + do_postinc(dc, memsize);
  1557 + return insn_len;
  1558 +}
  1559 +
  1560 +static unsigned int dec_addu_m(DisasContext *dc)
  1561 +{
  1562 + int memsize = memsize_z(dc);
  1563 + int insn_len;
  1564 + DIS(fprintf (logfile, "addu.%c [$r%u%s, $r%u\n",
  1565 + memsize_char(memsize),
  1566 + dc->op1, dc->postinc ? "+]" : "]",
  1567 + dc->op2));
  1568 +
  1569 + /* sign extend. */
  1570 + cris_cc_mask(dc, CC_MASK_NZVC);
  1571 + insn_len = dec_prep_alu_m(dc, 0, memsize);
  1572 + crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
  1573 + do_postinc(dc, memsize);
  1574 + return insn_len;
  1575 +}
  1576 +
  1577 +static unsigned int dec_adds_m(DisasContext *dc)
  1578 +{
  1579 + int memsize = memsize_z(dc);
  1580 + int insn_len;
  1581 + DIS(fprintf (logfile, "adds.%c [$r%u%s, $r%u\n",
  1582 + memsize_char(memsize),
  1583 + dc->op1, dc->postinc ? "+]" : "]",
  1584 + dc->op2));
  1585 +
  1586 + /* sign extend. */
  1587 + cris_cc_mask(dc, CC_MASK_NZVC);
  1588 + insn_len = dec_prep_alu_m(dc, 1, memsize);
  1589 + crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
  1590 + do_postinc(dc, memsize);
  1591 + return insn_len;
  1592 +}
  1593 +
  1594 +static unsigned int dec_subu_m(DisasContext *dc)
  1595 +{
  1596 + int memsize = memsize_z(dc);
  1597 + int insn_len;
  1598 + DIS(fprintf (logfile, "subu.%c [$r%u%s, $r%u\n",
  1599 + memsize_char(memsize),
  1600 + dc->op1, dc->postinc ? "+]" : "]",
  1601 + dc->op2));
  1602 +
  1603 + /* sign extend. */
  1604 + cris_cc_mask(dc, CC_MASK_NZVC);
  1605 + insn_len = dec_prep_alu_m(dc, 0, memsize);
  1606 + crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
  1607 + do_postinc(dc, memsize);
  1608 + return insn_len;
  1609 +}
  1610 +
  1611 +static unsigned int dec_subs_m(DisasContext *dc)
  1612 +{
  1613 + int memsize = memsize_z(dc);
  1614 + int insn_len;
  1615 + DIS(fprintf (logfile, "subs.%c [$r%u%s, $r%u\n",
  1616 + memsize_char(memsize),
  1617 + dc->op1, dc->postinc ? "+]" : "]",
  1618 + dc->op2));
  1619 +
  1620 + /* sign extend. */
  1621 + cris_cc_mask(dc, CC_MASK_NZVC);
  1622 + insn_len = dec_prep_alu_m(dc, 1, memsize);
  1623 + crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
  1624 + do_postinc(dc, memsize);
  1625 + return insn_len;
  1626 +}
  1627 +
  1628 +static unsigned int dec_movu_m(DisasContext *dc)
  1629 +{
  1630 + int memsize = memsize_z(dc);
  1631 + int insn_len;
  1632 +
  1633 + DIS(fprintf (logfile, "movu.%c [$r%u%s, $r%u\n",
  1634 + memsize_char(memsize),
  1635 + dc->op1, dc->postinc ? "+]" : "]",
  1636 + dc->op2));
  1637 +
  1638 + cris_cc_mask(dc, CC_MASK_NZ);
  1639 + insn_len = dec_prep_alu_m(dc, 0, memsize);
  1640 + crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
  1641 + do_postinc(dc, memsize);
  1642 + return insn_len;
  1643 +}
  1644 +
  1645 +static unsigned int dec_cmpu_m(DisasContext *dc)
  1646 +{
  1647 + int memsize = memsize_z(dc);
  1648 + int insn_len;
  1649 + DIS(fprintf (logfile, "cmpu.%c [$r%u%s, $r%u\n",
  1650 + memsize_char(memsize),
  1651 + dc->op1, dc->postinc ? "+]" : "]",
  1652 + dc->op2));
  1653 +
  1654 + cris_cc_mask(dc, CC_MASK_NZVC);
  1655 + insn_len = dec_prep_alu_m(dc, 0, memsize);
  1656 + crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
  1657 + do_postinc(dc, memsize);
  1658 + return insn_len;
  1659 +}
  1660 +
  1661 +static unsigned int dec_cmps_m(DisasContext *dc)
  1662 +{
  1663 + int memsize = memsize_z(dc);
  1664 + int insn_len;
  1665 + DIS(fprintf (logfile, "cmps.%c [$r%u%s, $r%u\n",
  1666 + memsize_char(memsize),
  1667 + dc->op1, dc->postinc ? "+]" : "]",
  1668 + dc->op2));
  1669 +
  1670 + cris_cc_mask(dc, CC_MASK_NZVC);
  1671 + insn_len = dec_prep_alu_m(dc, 1, memsize);
  1672 + crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
  1673 + do_postinc(dc, memsize);
  1674 + return insn_len;
  1675 +}
  1676 +
  1677 +static unsigned int dec_cmp_m(DisasContext *dc)
  1678 +{
  1679 + int memsize = memsize_zz(dc);
  1680 + int insn_len;
  1681 + DIS(fprintf (logfile, "cmp.%c [$r%u%s, $r%u\n",
  1682 + memsize_char(memsize),
  1683 + dc->op1, dc->postinc ? "+]" : "]",
  1684 + dc->op2));
  1685 +
  1686 + cris_cc_mask(dc, CC_MASK_NZVC);
  1687 + insn_len = dec_prep_alu_m(dc, 0, memsize);
  1688 + crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
  1689 + do_postinc(dc, memsize);
  1690 + return insn_len;
  1691 +}
  1692 +
  1693 +static unsigned int dec_test_m(DisasContext *dc)
  1694 +{
  1695 + int memsize = memsize_zz(dc);
  1696 + int insn_len;
  1697 + DIS(fprintf (logfile, "test.%d [$r%u%s] op2=%x\n",
  1698 + memsize_char(memsize),
  1699 + dc->op1, dc->postinc ? "+]" : "]",
  1700 + dc->op2));
  1701 +
  1702 + cris_cc_mask(dc, CC_MASK_NZ);
  1703 + gen_op_clrf(3);
  1704 + insn_len = dec_prep_alu_m(dc, 0, memsize);
  1705 + gen_op_swp_T0_T1();
  1706 + gen_op_movl_T1_im(0);
  1707 + crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
  1708 + do_postinc(dc, memsize);
  1709 + return insn_len;
  1710 +}
  1711 +
  1712 +static unsigned int dec_and_m(DisasContext *dc)
  1713 +{
  1714 + int memsize = memsize_zz(dc);
  1715 + int insn_len;
  1716 + DIS(fprintf (logfile, "and.%d [$r%u%s, $r%u\n",
  1717 + memsize_char(memsize),
  1718 + dc->op1, dc->postinc ? "+]" : "]",
  1719 + dc->op2));
  1720 +
  1721 + cris_cc_mask(dc, CC_MASK_NZ);
  1722 + insn_len = dec_prep_alu_m(dc, 0, memsize);
  1723 + crisv32_alu_op(dc, CC_OP_AND, dc->op2, memsize_zz(dc));
  1724 + do_postinc(dc, memsize);
  1725 + return insn_len;
  1726 +}
  1727 +
  1728 +static unsigned int dec_add_m(DisasContext *dc)
  1729 +{
  1730 + int memsize = memsize_zz(dc);
  1731 + int insn_len;
  1732 + DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
  1733 + memsize_char(memsize),
  1734 + dc->op1, dc->postinc ? "+]" : "]",
  1735 + dc->op2));
  1736 +
  1737 + cris_cc_mask(dc, CC_MASK_NZVC);
  1738 + insn_len = dec_prep_alu_m(dc, 0, memsize);
  1739 + crisv32_alu_op(dc, CC_OP_ADD, dc->op2, memsize_zz(dc));
  1740 + do_postinc(dc, memsize);
  1741 + return insn_len;
  1742 +}
  1743 +
  1744 +static unsigned int dec_addo_m(DisasContext *dc)
  1745 +{
  1746 + int memsize = memsize_zz(dc);
  1747 + int insn_len;
  1748 + DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
  1749 + memsize_char(memsize),
  1750 + dc->op1, dc->postinc ? "+]" : "]",
  1751 + dc->op2));
  1752 +
  1753 + cris_cc_mask(dc, 0);
  1754 + insn_len = dec_prep_alu_m(dc, 1, memsize);
  1755 + crisv32_alu_op(dc, CC_OP_ADD, REG_ACR, 4);
  1756 + do_postinc(dc, memsize);
  1757 + return insn_len;
  1758 +}
  1759 +
  1760 +static unsigned int dec_bound_m(DisasContext *dc)
  1761 +{
  1762 + int memsize = memsize_zz(dc);
  1763 + int insn_len;
  1764 + DIS(fprintf (logfile, "bound.%d [$r%u%s, $r%u\n",
  1765 + memsize_char(memsize),
  1766 + dc->op1, dc->postinc ? "+]" : "]",
  1767 + dc->op2));
  1768 +
  1769 + cris_cc_mask(dc, CC_MASK_NZ);
  1770 + insn_len = dec_prep_alu_m(dc, 0, memsize);
  1771 + crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
  1772 + do_postinc(dc, memsize);
  1773 + return insn_len;
  1774 +}
  1775 +
  1776 +static unsigned int dec_addc_mr(DisasContext *dc)
  1777 +{
  1778 + int insn_len = 2;
  1779 + DIS(fprintf (logfile, "addc [$r%u%s, $r%u\n",
  1780 + dc->op1, dc->postinc ? "+]" : "]",
  1781 + dc->op2));
  1782 +
  1783 + cris_evaluate_flags(dc);
  1784 + cris_cc_mask(dc, CC_MASK_NZVC);
  1785 + insn_len = dec_prep_alu_m(dc, 0, 4);
  1786 + crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
  1787 + do_postinc(dc, 4);
  1788 + return insn_len;
  1789 +}
  1790 +
  1791 +static unsigned int dec_sub_m(DisasContext *dc)
  1792 +{
  1793 + int memsize = memsize_zz(dc);
  1794 + int insn_len;
  1795 + DIS(fprintf (logfile, "sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
  1796 + memsize_char(memsize),
  1797 + dc->op1, dc->postinc ? "+]" : "]",
  1798 + dc->op2, dc->ir, dc->zzsize));
  1799 +
  1800 + cris_cc_mask(dc, CC_MASK_NZVC);
  1801 + insn_len = dec_prep_alu_m(dc, 0, memsize);
  1802 + crisv32_alu_op(dc, CC_OP_SUB, dc->op2, memsize);
  1803 + do_postinc(dc, memsize);
  1804 + return insn_len;
  1805 +}
  1806 +
  1807 +static unsigned int dec_or_m(DisasContext *dc)
  1808 +{
  1809 + int memsize = memsize_zz(dc);
  1810 + int insn_len;
  1811 + DIS(fprintf (logfile, "or.%d [$r%u%s, $r%u pc=%x\n",
  1812 + memsize_char(memsize),
  1813 + dc->op1, dc->postinc ? "+]" : "]",
  1814 + dc->op2, dc->pc));
  1815 +
  1816 + cris_cc_mask(dc, CC_MASK_NZ);
  1817 + insn_len = dec_prep_alu_m(dc, 0, memsize);
  1818 + crisv32_alu_op(dc, CC_OP_OR, dc->op2, memsize_zz(dc));
  1819 + do_postinc(dc, memsize);
  1820 + return insn_len;
  1821 +}
  1822 +
  1823 +static unsigned int dec_move_mp(DisasContext *dc)
  1824 +{
  1825 + int memsize = memsize_zz(dc);
  1826 + int insn_len = 2;
  1827 +
  1828 + DIS(fprintf (logfile, "move.%c [$r%u%s, $p%u\n",
  1829 + memsize_char(memsize),
  1830 + dc->op1,
  1831 + dc->postinc ? "+]" : "]",
  1832 + dc->op2));
  1833 +
  1834 + cris_cc_mask(dc, 0);
  1835 + insn_len = dec_prep_alu_m(dc, 0, memsize);
  1836 + gen_op_movl_T0_T1();
  1837 + gen_movl_preg_T0[dc->op2]();
  1838 +
  1839 + do_postinc(dc, memsize);
  1840 + return insn_len;
  1841 +}
  1842 +
  1843 +static unsigned int dec_move_pm(DisasContext *dc)
  1844 +{
  1845 + int memsize;
  1846 +
  1847 + memsize = preg_sizes[dc->op2];
  1848 +
  1849 + DIS(fprintf (logfile, "move.%d $p%u, [$r%u%s\n",
  1850 + memsize, dc->op2, dc->op1, dc->postinc ? "+]" : "]"));
  1851 +
  1852 + cris_cc_mask(dc, 0);
  1853 + /* prepare store. */
  1854 + gen_movl_T0_preg[dc->op2]();
  1855 + gen_op_movl_T1_T0();
  1856 + gen_movl_T0_reg[dc->op1]();
  1857 + gen_store_T0_T1(dc, memsize);
  1858 + if (dc->postinc)
  1859 + {
  1860 + gen_op_addl_T0_im(memsize);
  1861 + gen_movl_reg_T0[dc->op1]();
  1862 + }
  1863 + return 2;
  1864 +}
  1865 +
  1866 +static unsigned int dec_movem_mr(DisasContext *dc)
  1867 +{
  1868 + int i;
  1869 +
  1870 + DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1,
  1871 + dc->postinc ? "+]" : "]", dc->op2));
  1872 +
  1873 + cris_cc_mask(dc, 0);
  1874 + /* fetch the address into T1. */
  1875 + gen_movl_T0_reg[dc->op1]();
  1876 + gen_op_movl_T1_T0();
  1877 + for (i = 0; i <= dc->op2; i++) {
  1878 + /* Perform the load onto regnum i. Always dword wide. */
  1879 + gen_load_T0_T0(dc, 4, 0);
  1880 + gen_movl_reg_T0[i]();
  1881 + /* Update the address. */
  1882 + gen_op_addl_T1_im(4);
  1883 + gen_op_movl_T0_T1();
  1884 + }
  1885 + if (dc->postinc) {
  1886 + /* writeback the updated pointer value. */
  1887 + gen_movl_reg_T0[dc->op1]();
  1888 + }
  1889 + return 2;
  1890 +}
  1891 +
  1892 +static unsigned int dec_movem_rm(DisasContext *dc)
  1893 +{
  1894 + int i;
  1895 +
  1896 + DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
  1897 + dc->postinc ? "+]" : "]"));
  1898 +
  1899 + cris_cc_mask(dc, 0);
  1900 + for (i = 0; i <= dc->op2; i++) {
  1901 + /* Fetch register i into T1. */
  1902 + gen_movl_T0_reg[i]();
  1903 + gen_op_movl_T1_T0();
  1904 +
  1905 + /* Fetch the address into T0. */
  1906 + gen_movl_T0_reg[dc->op1]();
  1907 + /* Displace it. */
  1908 + gen_op_addl_T0_im(i * 4);
  1909 +
  1910 + /* Perform the store. */
  1911 + gen_store_T0_T1(dc, 4);
  1912 + }
  1913 + if (dc->postinc) {
  1914 + /* Update the address. */
  1915 + gen_op_addl_T0_im(4);
  1916 + /* writeback the updated pointer value. */
  1917 + gen_movl_reg_T0[dc->op1]();
  1918 + }
  1919 + return 2;
  1920 +}
  1921 +
  1922 +static unsigned int dec_move_rm(DisasContext *dc)
  1923 +{
  1924 + int memsize;
  1925 +
  1926 + memsize = memsize_zz(dc);
  1927 +
  1928 + DIS(fprintf (logfile, "move.%d $r%u, [$r%u]\n",
  1929 + memsize, dc->op2, dc->op1));
  1930 +
  1931 + cris_cc_mask(dc, 0);
  1932 + /* prepare store. */
  1933 + gen_movl_T0_reg[dc->op2]();
  1934 + gen_op_movl_T1_T0();
  1935 + gen_movl_T0_reg[dc->op1]();
  1936 + gen_store_T0_T1(dc, memsize);
  1937 + if (dc->postinc)
  1938 + {
  1939 + gen_op_addl_T0_im(memsize);
  1940 + gen_movl_reg_T0[dc->op1]();
  1941 + }
  1942 + return 2;
  1943 +}
  1944 +
  1945 +
  1946 +static unsigned int dec_lapcq(DisasContext *dc)
  1947 +{
  1948 + DIS(fprintf (logfile, "lapcq %x, $r%u\n",
  1949 + dc->pc + dc->op1*2, dc->op2));
  1950 + cris_cc_mask(dc, 0);
  1951 + gen_op_movl_T1_im(dc->pc + dc->op1*2);
  1952 + crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
  1953 + return 2;
  1954 +}
  1955 +
  1956 +static unsigned int dec_lapc_im(DisasContext *dc)
  1957 +{
  1958 + unsigned int rd;
  1959 + int32_t imm;
  1960 + int insn_len = 6;
  1961 +
  1962 + rd = dc->op2;
  1963 +
  1964 + cris_cc_mask(dc, 0);
  1965 + imm = ldl_code(dc->pc + 2);
  1966 + DIS(fprintf (logfile, "lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2));
  1967 + gen_op_movl_T0_im (dc->pc + imm);
  1968 + gen_movl_reg_T0[rd] ();
  1969 + return insn_len;
  1970 +}
  1971 +
  1972 +/* Jump to special reg. */
  1973 +static unsigned int dec_jump_p(DisasContext *dc)
  1974 +{
  1975 + DIS(fprintf (logfile, "jump $p%u\n", dc->op2));
  1976 + cris_cc_mask(dc, 0);
  1977 + /* Store the return address in Pd. */
  1978 + gen_movl_T0_preg[dc->op2]();
  1979 + gen_op_movl_btarget_T0();
  1980 + cris_prepare_dyn_jmp(dc);
  1981 + return 2;
  1982 +}
  1983 +
  1984 +/* Jump and save. */
  1985 +static unsigned int dec_jas_r(DisasContext *dc)
  1986 +{
  1987 + DIS(fprintf (logfile, "jas $r%u, $p%u\n", dc->op1, dc->op2));
  1988 + cris_cc_mask(dc, 0);
  1989 + /* Stor the return address in Pd. */
  1990 + gen_movl_T0_reg[dc->op1]();
  1991 + gen_op_movl_btarget_T0();
  1992 + gen_op_movl_T0_im(dc->pc + 4);
  1993 + gen_movl_preg_T0[dc->op2]();
  1994 + cris_prepare_dyn_jmp(dc);
  1995 + return 2;
  1996 +}
  1997 +
  1998 +static unsigned int dec_jas_im(DisasContext *dc)
  1999 +{
  2000 + uint32_t imm;
  2001 +
  2002 + imm = ldl_code(dc->pc + 2);
  2003 +
  2004 + DIS(fprintf (logfile, "jas 0x%x\n", imm));
  2005 + cris_cc_mask(dc, 0);
  2006 + /* Stor the return address in Pd. */
  2007 + gen_op_movl_T0_im(imm);
  2008 + gen_op_movl_btarget_T0();
  2009 + gen_op_movl_T0_im(dc->pc + 8);
  2010 + gen_movl_preg_T0[dc->op2]();
  2011 + cris_prepare_dyn_jmp(dc);
  2012 + return 6;
  2013 +}
  2014 +
  2015 +static unsigned int dec_jasc_im(DisasContext *dc)
  2016 +{
  2017 + uint32_t imm;
  2018 +
  2019 + imm = ldl_code(dc->pc + 2);
  2020 +
  2021 + DIS(fprintf (logfile, "jasc 0x%x\n", imm));
  2022 + cris_cc_mask(dc, 0);
  2023 + /* Stor the return address in Pd. */
  2024 + gen_op_movl_T0_im(imm);
  2025 + gen_op_movl_btarget_T0();
  2026 + gen_op_movl_T0_im(dc->pc + 8 + 4);
  2027 + gen_movl_preg_T0[dc->op2]();
  2028 + cris_prepare_dyn_jmp(dc);
  2029 + return 6;
  2030 +}
  2031 +
  2032 +static unsigned int dec_jasc_r(DisasContext *dc)
  2033 +{
  2034 + DIS(fprintf (logfile, "jasc_r $r%u, $p%u\n", dc->op1, dc->op2));
  2035 + cris_cc_mask(dc, 0);
  2036 + /* Stor the return address in Pd. */
  2037 + gen_movl_T0_reg[dc->op1]();
  2038 + gen_op_movl_btarget_T0();
  2039 + gen_op_movl_T0_im(dc->pc + 4 + 4);
  2040 + gen_movl_preg_T0[dc->op2]();
  2041 + cris_prepare_dyn_jmp(dc);
  2042 + return 2;
  2043 +}
  2044 +
  2045 +static unsigned int dec_bcc_im(DisasContext *dc)
  2046 +{
  2047 + int32_t offset;
  2048 + uint32_t cond = dc->op2;
  2049 +
  2050 + offset = ldl_code(dc->pc + 2);
  2051 + offset = sign_extend(offset, 15);
  2052 +
  2053 + DIS(fprintf (logfile, "b%s %d pc=%x dst=%x\n",
  2054 + cc_name(cond), offset,
  2055 + dc->pc, dc->pc + offset));
  2056 +
  2057 + cris_cc_mask(dc, 0);
  2058 + /* op2 holds the condition-code. */
  2059 + cris_prepare_cc_branch (dc, offset, cond);
  2060 + return 4;
  2061 +}
  2062 +
  2063 +static unsigned int dec_bas_im(DisasContext *dc)
  2064 +{
  2065 + int32_t simm;
  2066 +
  2067 +
  2068 + simm = ldl_code(dc->pc + 2);
  2069 +
  2070 + DIS(fprintf (logfile, "bas 0x%x, $p%u\n", dc->pc + simm, dc->op2));
  2071 + cris_cc_mask(dc, 0);
  2072 + /* Stor the return address in Pd. */
  2073 + gen_op_movl_T0_im(dc->pc + simm);
  2074 + gen_op_movl_btarget_T0();
  2075 + gen_op_movl_T0_im(dc->pc + 8);
  2076 + gen_movl_preg_T0[dc->op2]();
  2077 + cris_prepare_dyn_jmp(dc);
  2078 + return 6;
  2079 +}
  2080 +
  2081 +static unsigned int dec_basc_im(DisasContext *dc)
  2082 +{
  2083 + int32_t simm;
  2084 + simm = ldl_code(dc->pc + 2);
  2085 +
  2086 + DIS(fprintf (logfile, "basc 0x%x, $p%u\n", dc->pc + simm, dc->op2));
  2087 + cris_cc_mask(dc, 0);
  2088 + /* Stor the return address in Pd. */
  2089 + gen_op_movl_T0_im(dc->pc + simm);
  2090 + gen_op_movl_btarget_T0();
  2091 + gen_op_movl_T0_im(dc->pc + 12);
  2092 + gen_movl_preg_T0[dc->op2]();
  2093 + cris_prepare_dyn_jmp(dc);
  2094 + return 6;
  2095 +}
  2096 +
  2097 +static unsigned int dec_rfe_etc(DisasContext *dc)
  2098 +{
  2099 + DIS(fprintf (logfile, "rfe_etc opc=%x pc=0x%x op1=%d op2=%d\n",
  2100 + dc->opcode, dc->pc, dc->op1, dc->op2));
  2101 +
  2102 + cris_cc_mask(dc, 0);
  2103 +
  2104 + if (dc->op2 == 15) /* ignore halt. */
  2105 + goto done;
  2106 +
  2107 + switch (dc->op2 & 7) {
  2108 + case 2:
  2109 + /* rfe. */
  2110 + cris_evaluate_flags(dc);
  2111 + gen_op_ccs_rshift();
  2112 + break;
  2113 + case 5:
  2114 + /* rfn. */
  2115 + BUG();
  2116 + break;
  2117 + case 6:
  2118 + /* break. */
  2119 + gen_op_movl_T0_im(dc->pc);
  2120 + gen_op_movl_pc_T0();
  2121 + /* Breaks start at 16 in the exception vector. */
  2122 + gen_op_break_im(dc->op1 + 16);
  2123 + break;
  2124 + default:
  2125 + printf ("op2=%x\n", dc->op2);
  2126 + BUG();
  2127 + break;
  2128 +
  2129 + }
  2130 + done:
  2131 + return 2;
  2132 +}
  2133 +
  2134 +static unsigned int dec_null(DisasContext *dc)
  2135 +{
  2136 + printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
  2137 + dc->pc, dc->opcode, dc->op1, dc->op2);
  2138 + fflush(NULL);
  2139 + BUG();
  2140 + return 2;
  2141 +}
  2142 +
  2143 +struct decoder_info {
  2144 + struct {
  2145 + uint32_t bits;
  2146 + uint32_t mask;
  2147 + };
  2148 + unsigned int (*dec)(DisasContext *dc);
  2149 +} decinfo[] = {
  2150 + /* Order matters here. */
  2151 + {DEC_MOVEQ, dec_moveq},
  2152 + {DEC_BTSTQ, dec_btstq},
  2153 + {DEC_CMPQ, dec_cmpq},
  2154 + {DEC_ADDOQ, dec_addoq},
  2155 + {DEC_ADDQ, dec_addq},
  2156 + {DEC_SUBQ, dec_subq},
  2157 + {DEC_ANDQ, dec_andq},
  2158 + {DEC_ORQ, dec_orq},
  2159 + {DEC_ASRQ, dec_asrq},
  2160 + {DEC_LSLQ, dec_lslq},
  2161 + {DEC_LSRQ, dec_lsrq},
  2162 + {DEC_BCCQ, dec_bccq},
  2163 +
  2164 + {DEC_BCC_IM, dec_bcc_im},
  2165 + {DEC_JAS_IM, dec_jas_im},
  2166 + {DEC_JAS_R, dec_jas_r},
  2167 + {DEC_JASC_IM, dec_jasc_im},
  2168 + {DEC_JASC_R, dec_jasc_r},
  2169 + {DEC_BAS_IM, dec_bas_im},
  2170 + {DEC_BASC_IM, dec_basc_im},
  2171 + {DEC_JUMP_P, dec_jump_p},
  2172 + {DEC_LAPC_IM, dec_lapc_im},
  2173 + {DEC_LAPCQ, dec_lapcq},
  2174 +
  2175 + {DEC_RFE_ETC, dec_rfe_etc},
  2176 + {DEC_ADDC_MR, dec_addc_mr},
  2177 +
  2178 + {DEC_MOVE_MP, dec_move_mp},
  2179 + {DEC_MOVE_PM, dec_move_pm},
  2180 + {DEC_MOVEM_MR, dec_movem_mr},
  2181 + {DEC_MOVEM_RM, dec_movem_rm},
  2182 + {DEC_MOVE_PR, dec_move_pr},
  2183 + {DEC_SCC_R, dec_scc_r},
  2184 + {DEC_SETF, dec_setclrf},
  2185 + {DEC_CLEARF, dec_setclrf},
  2186 +
  2187 + {DEC_MOVE_SR, dec_move_sr},
  2188 + {DEC_MOVE_RP, dec_move_rp},
  2189 + {DEC_SWAP_R, dec_swap_r},
  2190 + {DEC_ABS_R, dec_abs_r},
  2191 + {DEC_LZ_R, dec_lz_r},
  2192 + {DEC_MOVE_RS, dec_move_rs},
  2193 + {DEC_BTST_R, dec_btst_r},
  2194 + {DEC_ADDC_R, dec_addc_r},
  2195 +
  2196 + {DEC_DSTEP_R, dec_dstep_r},
  2197 + {DEC_XOR_R, dec_xor_r},
  2198 + {DEC_MCP_R, dec_mcp_r},
  2199 + {DEC_CMP_R, dec_cmp_r},
  2200 +
  2201 + {DEC_ADDI_R, dec_addi_r},
  2202 + {DEC_ADDI_ACR, dec_addi_acr},
  2203 +
  2204 + {DEC_ADD_R, dec_add_r},
  2205 + {DEC_SUB_R, dec_sub_r},
  2206 +
  2207 + {DEC_ADDU_R, dec_addu_r},
  2208 + {DEC_ADDS_R, dec_adds_r},
  2209 + {DEC_SUBU_R, dec_subu_r},
  2210 + {DEC_SUBS_R, dec_subs_r},
  2211 + {DEC_LSL_R, dec_lsl_r},
  2212 +
  2213 + {DEC_AND_R, dec_and_r},
  2214 + {DEC_OR_R, dec_or_r},
  2215 + {DEC_BOUND_R, dec_bound_r},
  2216 + {DEC_ASR_R, dec_asr_r},
  2217 + {DEC_LSR_R, dec_lsr_r},
  2218 +
  2219 + {DEC_MOVU_R, dec_movu_r},
  2220 + {DEC_MOVS_R, dec_movs_r},
  2221 + {DEC_NEG_R, dec_neg_r},
  2222 + {DEC_MOVE_R, dec_move_r},
  2223 +
  2224 + /* ftag_fidx_i_m. */
  2225 + /* ftag_fidx_d_m. */
  2226 +
  2227 + {DEC_MULS_R, dec_muls_r},
  2228 + {DEC_MULU_R, dec_mulu_r},
  2229 +
  2230 + {DEC_ADDU_M, dec_addu_m},
  2231 + {DEC_ADDS_M, dec_adds_m},
  2232 + {DEC_SUBU_M, dec_subu_m},
  2233 + {DEC_SUBS_M, dec_subs_m},
  2234 +
  2235 + {DEC_CMPU_M, dec_cmpu_m},
  2236 + {DEC_CMPS_M, dec_cmps_m},
  2237 + {DEC_MOVU_M, dec_movu_m},
  2238 + {DEC_MOVS_M, dec_movs_m},
  2239 +
  2240 + {DEC_CMP_M, dec_cmp_m},
  2241 + {DEC_ADDO_M, dec_addo_m},
  2242 + {DEC_BOUND_M, dec_bound_m},
  2243 + {DEC_ADD_M, dec_add_m},
  2244 + {DEC_SUB_M, dec_sub_m},
  2245 + {DEC_AND_M, dec_and_m},
  2246 + {DEC_OR_M, dec_or_m},
  2247 + {DEC_MOVE_RM, dec_move_rm},
  2248 + {DEC_TEST_M, dec_test_m},
  2249 + {DEC_MOVE_MR, dec_move_mr},
  2250 +
  2251 + {{0, 0}, dec_null}
  2252 +};
  2253 +
  2254 +static inline unsigned int
  2255 +cris_decoder(DisasContext *dc)
  2256 +{
  2257 + unsigned int insn_len = 2;
  2258 + uint32_t tmp;
  2259 + int i;
  2260 +
  2261 + /* Load a halfword onto the instruction register. */
  2262 + tmp = ldl_code(dc->pc);
  2263 + dc->ir = tmp & 0xffff;
  2264 +
  2265 + /* Now decode it. */
  2266 + dc->opcode = EXTRACT_FIELD(dc->ir, 4, 11);
  2267 + dc->op1 = EXTRACT_FIELD(dc->ir, 0, 3);
  2268 + dc->op2 = EXTRACT_FIELD(dc->ir, 12, 15);
  2269 + dc->zsize = EXTRACT_FIELD(dc->ir, 4, 4);
  2270 + dc->zzsize = EXTRACT_FIELD(dc->ir, 4, 5);
  2271 + dc->postinc = EXTRACT_FIELD(dc->ir, 10, 10);
  2272 +
  2273 + /* Large switch for all insns. */
  2274 + for (i = 0; i < sizeof decinfo / sizeof decinfo[0]; i++) {
  2275 + if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
  2276 + {
  2277 + insn_len = decinfo[i].dec(dc);
  2278 + break;
  2279 + }
  2280 + }
  2281 +
  2282 + return insn_len;
  2283 +}
  2284 +
  2285 +static void check_breakpoint(CPUState *env, DisasContext *dc)
  2286 +{
  2287 + int j;
  2288 + if (env->nb_breakpoints > 0) {
  2289 + for(j = 0; j < env->nb_breakpoints; j++) {
  2290 + if (env->breakpoints[j] == dc->pc) {
  2291 + cris_evaluate_flags (dc);
  2292 + gen_op_movl_T0_im((long)dc->pc);
  2293 + gen_op_movl_pc_T0();
  2294 + gen_op_debug();
  2295 + dc->is_jmp = DISAS_UPDATE;
  2296 + }
  2297 + }
  2298 + }
  2299 +}
  2300 +
  2301 +
  2302 +/* generate intermediate code for basic block 'tb'. */
  2303 +struct DisasContext ctx;
  2304 +static int
  2305 +gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
  2306 + int search_pc)
  2307 +{
  2308 + uint16_t *gen_opc_end;
  2309 + uint32_t pc_start;
  2310 + unsigned int insn_len;
  2311 + int j, lj;
  2312 + struct DisasContext *dc = &ctx;
  2313 + uint32_t next_page_start;
  2314 +
  2315 + pc_start = tb->pc;
  2316 + dc->env = env;
  2317 + dc->tb = tb;
  2318 +
  2319 + gen_opc_ptr = gen_opc_buf;
  2320 + gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
  2321 + gen_opparam_ptr = gen_opparam_buf;
  2322 +
  2323 + dc->is_jmp = DISAS_NEXT;
  2324 + dc->pc = pc_start;
  2325 + dc->singlestep_enabled = env->singlestep_enabled;
  2326 + dc->flagx_live = 0;
  2327 + dc->flags_x = 0;
  2328 + next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
  2329 + lj = -1;
  2330 + do
  2331 + {
  2332 + check_breakpoint(env, dc);
  2333 + if (dc->is_jmp == DISAS_JUMP)
  2334 + goto done;
  2335 +
  2336 + if (search_pc) {
  2337 + j = gen_opc_ptr - gen_opc_buf;
  2338 + if (lj < j) {
  2339 + lj++;
  2340 + while (lj < j)
  2341 + gen_opc_instr_start[lj++] = 0;
  2342 + }
  2343 + gen_opc_pc[lj] = dc->pc;
  2344 + gen_opc_instr_start[lj] = 1;
  2345 + }
  2346 +
  2347 + insn_len = cris_decoder(dc);
  2348 + STATS(gen_op_exec_insn());
  2349 + dc->pc += insn_len;
  2350 + if (!dc->flagx_live
  2351 + || (dc->flagx_live &&
  2352 + !(dc->cc_op == CC_OP_FLAGS && dc->flags_x))) {
  2353 + gen_movl_T0_preg[SR_CCS]();
  2354 + gen_op_andl_T0_im(~X_FLAG);
  2355 + gen_movl_preg_T0[SR_CCS]();
  2356 + dc->flagx_live = 1;
  2357 + dc->flags_x = 0;
  2358 + }
  2359 +
  2360 + /* Check for delayed branches here. If we do it before
  2361 + actually genereating any host code, the simulator will just
  2362 + loop doing nothing for on this program location. */
  2363 + if (dc->delayed_branch) {
  2364 + dc->delayed_branch--;
  2365 + if (dc->delayed_branch == 0)
  2366 + {
  2367 + if (dc->bcc == CC_A) {
  2368 + gen_op_jmp ();
  2369 + dc->is_jmp = DISAS_UPDATE;
  2370 + }
  2371 + else {
  2372 + /* Conditional jmp. */
  2373 + gen_op_cc_jmp (dc->delayed_pc, dc->pc);
  2374 + dc->is_jmp = DISAS_UPDATE;
  2375 + }
  2376 + }
  2377 + }
  2378 +
  2379 + if (env->singlestep_enabled)
  2380 + break;
  2381 + } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end
  2382 + && dc->pc < next_page_start);
  2383 +
  2384 + if (!dc->is_jmp) {
  2385 + gen_op_movl_T0_im((long)dc->pc);
  2386 + gen_op_movl_pc_T0();
  2387 + }
  2388 +
  2389 + cris_evaluate_flags (dc);
  2390 + done:
  2391 + if (__builtin_expect(env->singlestep_enabled, 0)) {
  2392 + gen_op_debug();
  2393 + } else {
  2394 + switch(dc->is_jmp) {
  2395 + case DISAS_NEXT:
  2396 + gen_goto_tb(dc, 1, dc->pc);
  2397 + break;
  2398 + default:
  2399 + case DISAS_JUMP:
  2400 + case DISAS_UPDATE:
  2401 + /* indicate that the hash table must be used
  2402 + to find the next TB */
  2403 + /* T0 is used to index the jmp tables. */
  2404 + gen_op_movl_T0_0();
  2405 + gen_op_exit_tb();
  2406 + break;
  2407 + case DISAS_TB_JUMP:
  2408 + /* nothing more to generate */
  2409 + break;
  2410 + }
  2411 + }
  2412 + *gen_opc_ptr = INDEX_op_end;
  2413 + if (search_pc) {
  2414 + j = gen_opc_ptr - gen_opc_buf;
  2415 + lj++;
  2416 + while (lj <= j)
  2417 + gen_opc_instr_start[lj++] = 0;
  2418 + } else {
  2419 + tb->size = dc->pc - pc_start;
  2420 + }
  2421 +
  2422 +#ifdef DEBUG_DISAS
  2423 + if (loglevel & CPU_LOG_TB_IN_ASM) {
  2424 + fprintf(logfile, "--------------\n");
  2425 + fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
  2426 + target_disas(logfile, pc_start, dc->pc + 4 - pc_start, 0);
  2427 + fprintf(logfile, "\n");
  2428 + if (loglevel & CPU_LOG_TB_OP) {
  2429 + fprintf(logfile, "OP:\n");
  2430 + dump_ops(gen_opc_buf, gen_opparam_buf);
  2431 + fprintf(logfile, "\n");
  2432 + }
  2433 + }
  2434 +#endif
  2435 + return 0;
  2436 +}
  2437 +
  2438 +int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
  2439 +{
  2440 + return gen_intermediate_code_internal(env, tb, 0);
  2441 +}
  2442 +
  2443 +int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
  2444 +{
  2445 + return gen_intermediate_code_internal(env, tb, 1);
  2446 +}
  2447 +
  2448 +void cpu_dump_state (CPUState *env, FILE *f,
  2449 + int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
  2450 + int flags)
  2451 +{
  2452 + int i;
  2453 + uint32_t srs;
  2454 +
  2455 + if (!env || !f)
  2456 + return;
  2457 +
  2458 + cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
  2459 + "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n"
  2460 + "debug=%x %x %x\n",
  2461 + env->pc, env->pregs[SR_CCS], env->btaken, env->btarget,
  2462 + env->cc_op,
  2463 + env->cc_src, env->cc_dest, env->cc_result, env->cc_mask,
  2464 + env->debug1, env->debug2, env->debug3);
  2465 +
  2466 + for (i = 0; i < 16; i++) {
  2467 + cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
  2468 + if ((i + 1) % 4 == 0)
  2469 + cpu_fprintf(f, "\n");
  2470 + }
  2471 + cpu_fprintf(f, "\nspecial regs:\n");
  2472 + for (i = 0; i < 16; i++) {
  2473 + cpu_fprintf(f, "p%2.2d=%8.8x ", i, env->pregs[i]);
  2474 + if ((i + 1) % 4 == 0)
  2475 + cpu_fprintf(f, "\n");
  2476 + }
  2477 + srs = env->pregs[SR_SRS];
  2478 + cpu_fprintf(f, "\nsupport function regs bank %d:\n", srs);
  2479 + if (srs < 256) {
  2480 + for (i = 0; i < 16; i++) {
  2481 + cpu_fprintf(f, "s%2.2d=%8.8x ",
  2482 + i, env->sregs[srs][i]);
  2483 + if ((i + 1) % 4 == 0)
  2484 + cpu_fprintf(f, "\n");
  2485 + }
  2486 + }
  2487 + cpu_fprintf(f, "\n\n");
  2488 +
  2489 +}
  2490 +
  2491 +CPUCRISState *cpu_cris_init (void)
  2492 +{
  2493 + CPUCRISState *env;
  2494 +
  2495 + env = qemu_mallocz(sizeof(CPUCRISState));
  2496 + if (!env)
  2497 + return NULL;
  2498 + cpu_exec_init(env);
  2499 + cpu_reset(env);
  2500 + return env;
  2501 +}
  2502 +
  2503 +void cpu_reset (CPUCRISState *env)
  2504 +{
  2505 + memset(env, 0, offsetof(CPUCRISState, breakpoints));
  2506 + tlb_flush(env, 1);
  2507 +}