- tcg_temp_free(t[0]);
- tcg_temp_free(t[1]);
-}
-
-static int dec_movs_m(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
- LOG_DIS("movs.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- cris_alu_m_alloc_temps(t);
- /* sign extend. */
- insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu(dc, CC_OP_MOVE,
- cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_addu_m(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
- LOG_DIS("addu.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- cris_alu_m_alloc_temps(t);
- /* sign extend. */
- insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_ADD,
- cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_adds_m(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
- LOG_DIS("adds.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- cris_alu_m_alloc_temps(t);
- /* sign extend. */
- insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_subu_m(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
- LOG_DIS("subu.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- cris_alu_m_alloc_temps(t);
- /* sign extend. */
- insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_subs_m(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
- LOG_DIS("subs.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- cris_alu_m_alloc_temps(t);
- /* sign extend. */
- insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_movu_m(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
-
- LOG_DIS("movu.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- cris_alu_m_alloc_temps(t);
- insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_cmpu_m(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
- LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- cris_alu_m_alloc_temps(t);
- insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_cmps_m(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
- LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- cris_alu_m_alloc_temps(t);
- insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_CMP,
- cpu_R[dc->op2], cpu_R[dc->op2], t[1],
- memsize_zz(dc));
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_cmp_m(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- cris_alu_m_alloc_temps(t);
- insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_CMP,
- cpu_R[dc->op2], cpu_R[dc->op2], t[1],
- memsize_zz(dc));
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_test_m(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("test.%c [$r%u%s] op2=%x\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- cris_evaluate_flags(dc);
-
- cris_alu_m_alloc_temps(t);
- insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZ);
- tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
-
- cris_alu(dc, CC_OP_CMP,
- cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc));
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_and_m(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("and.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- cris_alu_m_alloc_temps(t);
- insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_add_m(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("add.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- cris_alu_m_alloc_temps(t);
- insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_ADD,
- cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_addo_m(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("add.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- cris_alu_m_alloc_temps(t);
- insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
- cris_cc_mask(dc, 0);
- cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_bound_m(DisasContext *dc)
-{
- TCGv l[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("bound.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- l[0] = tcg_temp_local_new();
- l[1] = tcg_temp_local_new();
- insn_len = dec_prep_alu_m(dc, 0, memsize, l[0], l[1]);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
- do_postinc(dc, memsize);
- tcg_temp_free(l[0]);
- tcg_temp_free(l[1]);
- return insn_len;
-}
-
-static int dec_addc_mr(DisasContext *dc)
-{
- TCGv t[2];
- int insn_len = 2;
- LOG_DIS("addc [$r%u%s, $r%u\n",
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- cris_evaluate_flags(dc);
-
- /* Set for this insn. */
- dc->flagx_known = 1;
- dc->flags_x = X_FLAG;
-
- cris_alu_m_alloc_temps(t);
- insn_len = dec_prep_alu_m(dc, 0, 4, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
- do_postinc(dc, 4);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_sub_m(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2, dc->ir, dc->zzsize);
-
- cris_alu_m_alloc_temps(t);
- insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_or_m(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2, dc->pc);
-
- cris_alu_m_alloc_temps(t);
- insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu(dc, CC_OP_OR,
- cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_move_mp(DisasContext *dc)
-{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len = 2;
-
- LOG_DIS("move.%c [$r%u%s, $p%u\n",
- memsize_char(memsize),
- dc->op1,
- dc->postinc ? "+]" : "]",
- dc->op2);
-
- cris_alu_m_alloc_temps(t);
- insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, 0);
- if (dc->op2 == PR_CCS) {
- cris_evaluate_flags(dc);
- if (dc->tb_flags & U_FLAG) {
- /* User space is not allowed to touch all flags. */
- tcg_gen_andi_tl(t[1], t[1], 0x39f);
- tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
- tcg_gen_or_tl(t[1], t[0], t[1]);
- }
- }
-
- t_gen_mov_preg_TN(dc, dc->op2, t[1]);
-
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
-}
-
-static int dec_move_pm(DisasContext *dc)
-{
- TCGv t0;
- int memsize;
-
- memsize = preg_sizes[dc->op2];
-
- LOG_DIS("move.%c $p%u, [$r%u%s\n",
- memsize_char(memsize),
- dc->op2, dc->op1, dc->postinc ? "+]" : "]");
-
- /* prepare store. Address in T0, value in T1. */
- if (dc->op2 == PR_CCS)
- cris_evaluate_flags(dc);
- t0 = tcg_temp_new();
- t_gen_mov_TN_preg(t0, dc->op2);
- cris_flush_cc_state(dc);
- gen_store(dc, cpu_R[dc->op1], t0, memsize);
- tcg_temp_free(t0);
-
- cris_cc_mask(dc, 0);
- if (dc->postinc)
- tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
- return 2;
-}
-
-static int dec_movem_mr(DisasContext *dc)
-{
- TCGv_i64 tmp[16];
- TCGv tmp32;
- TCGv addr;
- int i;
- int nr = dc->op2 + 1;
-
- LOG_DIS("movem [$r%u%s, $r%u\n", dc->op1,
- dc->postinc ? "+]" : "]", dc->op2);
-
- addr = tcg_temp_new();
- /* There are probably better ways of doing this. */
- cris_flush_cc_state(dc);
- for (i = 0; i < (nr >> 1); i++) {
- tmp[i] = tcg_temp_new_i64();
- tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
- gen_load64(dc, tmp[i], addr);
- }
- if (nr & 1) {
- tmp32 = tcg_temp_new_i32();
- tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
- gen_load(dc, tmp32, addr, 4, 0);
- } else
- TCGV_UNUSED(tmp32);
- tcg_temp_free(addr);
-
- for (i = 0; i < (nr >> 1); i++) {
- tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]);
- tcg_gen_shri_i64(tmp[i], tmp[i], 32);
- tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
- tcg_temp_free_i64(tmp[i]);
- }
- if (nr & 1) {
- tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
- tcg_temp_free(tmp32);
- }
+ tcg_temp_free(t[0]);
+ tcg_temp_free(t[1]);
+}
+
+static int dec_movs_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
+ LOG_DIS("movs.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ cris_alu_m_alloc_temps(t);
+ /* sign extend. */
+ insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu(dc, CC_OP_MOVE,
+ cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_addu_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
+ LOG_DIS("addu.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ cris_alu_m_alloc_temps(t);
+ /* sign extend. */
+ insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_ADD,
+ cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_adds_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
+ LOG_DIS("adds.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ cris_alu_m_alloc_temps(t);
+ /* sign extend. */
+ insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_subu_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
+ LOG_DIS("subu.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ cris_alu_m_alloc_temps(t);
+ /* sign extend. */
+ insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_subs_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
+ LOG_DIS("subs.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ cris_alu_m_alloc_temps(t);
+ /* sign extend. */
+ insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_movu_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
+
+ LOG_DIS("movu.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ cris_alu_m_alloc_temps(t);
+ insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_cmpu_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
+ LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ cris_alu_m_alloc_temps(t);
+ insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_cmps_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
+ LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ cris_alu_m_alloc_temps(t);
+ insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_CMP,
+ cpu_R[dc->op2], cpu_R[dc->op2], t[1],
+ memsize_zz(dc));
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_cmp_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ cris_alu_m_alloc_temps(t);
+ insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_CMP,
+ cpu_R[dc->op2], cpu_R[dc->op2], t[1],
+ memsize_zz(dc));
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_test_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("test.%c [$r%u%s] op2=%x\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ cris_evaluate_flags(dc);
+
+ cris_alu_m_alloc_temps(t);
+ insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
+
+ cris_alu(dc, CC_OP_CMP,
+ cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc));
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_and_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("and.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ cris_alu_m_alloc_temps(t);
+ insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_add_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("add.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ cris_alu_m_alloc_temps(t);
+ insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_ADD,
+ cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_addo_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("add.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ cris_alu_m_alloc_temps(t);
+ insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
+ cris_cc_mask(dc, 0);
+ cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_bound_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv l[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("bound.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ l[0] = tcg_temp_local_new();
+ l[1] = tcg_temp_local_new();
+ insn_len = dec_prep_alu_m(env, dc, 0, memsize, l[0], l[1]);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
+ do_postinc(dc, memsize);
+ tcg_temp_free(l[0]);
+ tcg_temp_free(l[1]);
+ return insn_len;
+}
+
+static int dec_addc_mr(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int insn_len = 2;
+ LOG_DIS("addc [$r%u%s, $r%u\n",
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ cris_evaluate_flags(dc);
+
+ /* Set for this insn. */
+ dc->flagx_known = 1;
+ dc->flags_x = X_FLAG;
+
+ cris_alu_m_alloc_temps(t);
+ insn_len = dec_prep_alu_m(env, dc, 0, 4, t[0], t[1]);
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
+ do_postinc(dc, 4);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_sub_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2, dc->ir, dc->zzsize);
+
+ cris_alu_m_alloc_temps(t);
+ insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_or_m(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2, dc->pc);
+
+ cris_alu_m_alloc_temps(t);
+ insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu(dc, CC_OP_OR,
+ cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_move_mp(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len = 2;
+
+ LOG_DIS("move.%c [$r%u%s, $p%u\n",
+ memsize_char(memsize),
+ dc->op1,
+ dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ cris_alu_m_alloc_temps(t);
+ insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ cris_cc_mask(dc, 0);
+ if (dc->op2 == PR_CCS) {
+ cris_evaluate_flags(dc);
+ if (dc->tb_flags & U_FLAG) {
+ /* User space is not allowed to touch all flags. */
+ tcg_gen_andi_tl(t[1], t[1], 0x39f);
+ tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
+ tcg_gen_or_tl(t[1], t[0], t[1]);
+ }
+ }
+
+ t_gen_mov_preg_TN(dc, dc->op2, t[1]);
+
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
+}
+
+static int dec_move_pm(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv t0;
+ int memsize;
+
+ memsize = preg_sizes[dc->op2];
+
+ LOG_DIS("move.%c $p%u, [$r%u%s\n",
+ memsize_char(memsize),
+ dc->op2, dc->op1, dc->postinc ? "+]" : "]");
+
+ /* prepare store. Address in T0, value in T1. */
+ if (dc->op2 == PR_CCS) {
+ cris_evaluate_flags(dc);
+ }
+ t0 = tcg_temp_new();
+ t_gen_mov_TN_preg(t0, dc->op2);
+ cris_flush_cc_state(dc);
+ gen_store(dc, cpu_R[dc->op1], t0, memsize);
+ tcg_temp_free(t0);
+
+ cris_cc_mask(dc, 0);
+ if (dc->postinc) {
+ tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
+ }
+ return 2;
+}
+
+static int dec_movem_mr(CPUCRISState *env, DisasContext *dc)
+{
+ TCGv_i64 tmp[16];
+ TCGv tmp32;
+ TCGv addr;
+ int i;
+ int nr = dc->op2 + 1;
+
+ LOG_DIS("movem [$r%u%s, $r%u\n", dc->op1,
+ dc->postinc ? "+]" : "]", dc->op2);
+
+ addr = tcg_temp_new();
+ /* There are probably better ways of doing this. */
+ cris_flush_cc_state(dc);
+ for (i = 0; i < (nr >> 1); i++) {
+ tmp[i] = tcg_temp_new_i64();
+ tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
+ gen_load64(dc, tmp[i], addr);
+ }
+ if (nr & 1) {
+ tmp32 = tcg_temp_new_i32();
+ tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
+ gen_load(dc, tmp32, addr, 4, 0);
+ } else {
+ TCGV_UNUSED(tmp32);
+ }
+ tcg_temp_free(addr);
+
+ for (i = 0; i < (nr >> 1); i++) {
+ tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]);
+ tcg_gen_shri_i64(tmp[i], tmp[i], 32);
+ tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
+ tcg_temp_free_i64(tmp[i]);
+ }
+ if (nr & 1) {
+ tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
+ tcg_temp_free(tmp32);
+ }