static int dec10_bdap_m(DisasContext *dc, int size) { int insn_len = 2; int rd = dc->dst; LOG_DIS("bdap_m pc=%x opcode=%d r%d r%d sz=%d\n", dc->pc, dc->opcode, dc->src, dc->dst, size); assert(dc->dst != 15); #if 0 /* 8bit embedded offset? */ if (!dc->postinc && (dc->ir & (1 << 11))) { int simm = dc->ir & 0xff; /* cpu_abort(dc->env, "Unhandled opcode"); */ /* sign extended. */ simm = (int8_t)simm; tcg_gen_addi_tl(cpu_PR[PR_PREFIX], cpu_R[dc->dst], simm); cris_set_prefix(dc); return insn_len; } #endif /* Now the rest of the modes are truly indirect. */ insn_len += dec10_prep_move_m(dc, 1, size, cpu_PR[PR_PREFIX]); tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_PR[PR_PREFIX], cpu_R[rd]); cris_set_prefix(dc); return insn_len; }
static void dec_add(DisasContext *dc) { if (dc->format == OP_FMT_RI) { if (dc->r0 == R_R0) { if (dc->r1 == R_R0 && dc->imm16 == 0) { LOG_DIS("nop\n"); } else { LOG_DIS("mvi r%d, %d\n", dc->r1, sign_extend(dc->imm16, 16)); } } else { LOG_DIS("addi r%d, r%d, %d\n", dc->r1, dc->r0, sign_extend(dc->imm16, 16)); } } else { LOG_DIS("add r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1); } if (dc->format == OP_FMT_RI) { tcg_gen_addi_tl(cpu_R[dc->r1], cpu_R[dc->r0], sign_extend(dc->imm16, 16)); } else { tcg_gen_add_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]); } }
static unsigned int dec10_reg(DisasContext *dc) { TCGv t; unsigned int insn_len = 2; unsigned int size = dec10_size(dc->size); unsigned int tmp; if (dc->size != 3) { switch (dc->opcode) { case CRISV10_REG_MOVE_R: LOG_DIS("move.%d $r%d, $r%d\n", dc->size, dc->src, dc->dst); cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alu(dc, CC_OP_MOVE, size, 0); if (dc->dst == 15) { tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]); cris_prepare_jmp(dc, JMP_INDIRECT); dc->delayed_branch = 1; } break; case CRISV10_REG_MOVX: cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_movs(dc); break; case CRISV10_REG_ADDX: cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alux(dc, CC_OP_ADD); break; case CRISV10_REG_SUBX: cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alux(dc, CC_OP_SUB); break; case CRISV10_REG_ADD: LOG_DIS("add $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alu(dc, CC_OP_ADD, size, 0); break; case CRISV10_REG_SUB: LOG_DIS("sub $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alu(dc, CC_OP_SUB, size, 0); break; case CRISV10_REG_CMP: LOG_DIS("cmp $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alu(dc, CC_OP_CMP, size, 0); break; case CRISV10_REG_BOUND: LOG_DIS("bound $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_bound(dc, size); break; case CRISV10_REG_AND: LOG_DIS("and $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alu(dc, CC_OP_AND, size, 0); break; case CRISV10_REG_ADDI: if (dc->src == 15) { /* nop. */ return 2; } t = tcg_temp_new(); LOG_DIS("addi r%d r%d size=%d\n", dc->src, dc->dst, dc->size); tcg_gen_shli_tl(t, cpu_R[dc->dst], dc->size & 3); tcg_gen_add_tl(cpu_R[dc->src], cpu_R[dc->src], t); tcg_temp_free(t); break; case CRISV10_REG_LSL: LOG_DIS("lsl $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alu(dc, CC_OP_LSL, size, 0); break; case CRISV10_REG_LSR: LOG_DIS("lsr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alu(dc, CC_OP_LSR, size, 0); break; case CRISV10_REG_ASR: LOG_DIS("asr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alu(dc, CC_OP_ASR, size, 1); break; case CRISV10_REG_OR: LOG_DIS("or $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alu(dc, CC_OP_OR, size, 0); break; case CRISV10_REG_NEG: LOG_DIS("neg $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alu(dc, CC_OP_NEG, size, 0); break; case CRISV10_REG_BIAP: LOG_DIS("BIAP pc=%x reg %d r%d r%d size=%d\n", dc->pc, dc->opcode, dc->src, dc->dst, size); switch (size) { case 4: tmp = 2; break; case 2: tmp = 1; break; case 1: tmp = 0; break; default: cpu_abort(dc->env, "Unhandled BIAP"); break; } t = tcg_temp_new(); tcg_gen_shli_tl(t, cpu_R[dc->dst], tmp); if (dc->src == 15) { tcg_gen_addi_tl(cpu_PR[PR_PREFIX], t, ((dc->pc +2)| 1) + 1); } else { tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_R[dc->src], t); } tcg_temp_free(t); cris_set_prefix(dc); break; default: LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc, dc->opcode, dc->src, dc->dst); cpu_abort(dc->env, "Unhandled opcode"); break; } } else { switch (dc->opcode) { case CRISV10_REG_MOVX: cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_movs(dc); break; case CRISV10_REG_ADDX: cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alux(dc, CC_OP_ADD); break; case CRISV10_REG_SUBX: cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alux(dc, CC_OP_SUB); break; case CRISV10_REG_MOVE_SPR_R: cris_evaluate_flags(dc); cris_cc_mask(dc, 0); dec10_reg_mov_pr(dc); break; case CRISV10_REG_MOVE_R_SPR: LOG_DIS("move r%d p%d\n", dc->src, dc->dst); cris_evaluate_flags(dc); if (dc->src != 11) /* fast for srp. */ dc->cpustate_changed = 1; t_gen_mov_preg_TN(dc, dc->dst, cpu_R[dc->src]); break; case CRISV10_REG_SETF: case CRISV10_REG_CLEARF: dec10_setclrf(dc); break; case CRISV10_REG_SWAP: dec10_reg_swap(dc); break; case CRISV10_REG_ABS: cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_abs(dc); break; case CRISV10_REG_LZ: LOG_DIS("lz $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alu(dc, CC_OP_LZ, 4, 0); break; case CRISV10_REG_XOR: LOG_DIS("xor $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); cris_cc_mask(dc, CC_MASK_NZVC); dec10_reg_alu(dc, CC_OP_XOR, 4, 0); break; case CRISV10_REG_BTST: LOG_DIS("btst $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); cris_cc_mask(dc, CC_MASK_NZVC); cris_update_cc_op(dc, CC_OP_FLAGS, 4); gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->dst], cpu_R[dc->src], cpu_PR[PR_CCS]); break; case CRISV10_REG_DSTEP: LOG_DIS("dstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); cris_cc_mask(dc, CC_MASK_NZVC); cris_alu(dc, CC_OP_DSTEP, cpu_R[dc->dst], cpu_R[dc->dst], cpu_R[dc->src], 4); break; case CRISV10_REG_MSTEP: LOG_DIS("mstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); cris_evaluate_flags(dc); cris_cc_mask(dc, CC_MASK_NZVC); cris_alu(dc, CC_OP_MSTEP, cpu_R[dc->dst], cpu_R[dc->dst], cpu_R[dc->src], 4); break; case CRISV10_REG_SCC: dec10_reg_scc(dc); break; default: LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc, dc->opcode, dc->src, dc->dst); cpu_abort(dc->env, "Unhandled opcode"); break; } } return insn_len; }