📄 translate.c.svn-base
字号:
gen_op_addl_T1_im(4); gen_op_movl_T0_T1(); } if (dc->postinc) { /* writeback the updated pointer value. */ gen_movl_reg_T0[dc->op1](); } return 2;}static unsigned int dec_movem_rm(DisasContext *dc){ int i; DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1, dc->postinc ? "+]" : "]")); cris_cc_mask(dc, 0); for (i = 0; i <= dc->op2; i++) { /* Fetch register i into T1. */ gen_movl_T0_reg[i](); gen_op_movl_T1_T0(); /* Fetch the address into T0. */ gen_movl_T0_reg[dc->op1](); /* Displace it. */ gen_op_addl_T0_im(i * 4); /* Perform the store. */ gen_store_T0_T1(dc, 4); } if (dc->postinc) { /* Update the address. */ gen_op_addl_T0_im(4); /* writeback the updated pointer value. */ gen_movl_reg_T0[dc->op1](); } return 2;}static unsigned int dec_move_rm(DisasContext *dc){ int memsize; memsize = memsize_zz(dc); DIS(fprintf (logfile, "move.%d $r%u, [$r%u]\n", memsize, dc->op2, dc->op1)); cris_cc_mask(dc, 0); /* prepare store. */ gen_movl_T0_reg[dc->op2](); gen_op_movl_T1_T0(); gen_movl_T0_reg[dc->op1](); gen_store_T0_T1(dc, memsize); if (dc->postinc) { gen_op_addl_T0_im(memsize); gen_movl_reg_T0[dc->op1](); } return 2;}static unsigned int dec_lapcq(DisasContext *dc){ DIS(fprintf (logfile, "lapcq %x, $r%u\n", dc->pc + dc->op1*2, dc->op2)); cris_cc_mask(dc, 0); gen_op_movl_T1_im(dc->pc + dc->op1*2); crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4); return 2;}static unsigned int dec_lapc_im(DisasContext *dc){ unsigned int rd; int32_t imm; int insn_len = 6; rd = dc->op2; cris_cc_mask(dc, 0); imm = ldl_code(dc->pc + 2); DIS(fprintf (logfile, "lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2)); gen_op_movl_T0_im (dc->pc + imm); gen_movl_reg_T0[rd] (); return insn_len;}/* Jump to special reg. */static unsigned int dec_jump_p(DisasContext *dc){ DIS(fprintf (logfile, "jump $p%u\n", dc->op2)); cris_cc_mask(dc, 0); /* Store the return address in Pd. */ gen_movl_T0_preg[dc->op2](); gen_op_movl_btarget_T0(); cris_prepare_dyn_jmp(dc); return 2;}/* Jump and save. */static unsigned int dec_jas_r(DisasContext *dc){ DIS(fprintf (logfile, "jas $r%u, $p%u\n", dc->op1, dc->op2)); cris_cc_mask(dc, 0); /* Stor the return address in Pd. */ gen_movl_T0_reg[dc->op1](); gen_op_movl_btarget_T0(); gen_op_movl_T0_im(dc->pc + 4); gen_movl_preg_T0[dc->op2](); cris_prepare_dyn_jmp(dc); return 2;}static unsigned int dec_jas_im(DisasContext *dc){ uint32_t imm; imm = ldl_code(dc->pc + 2); DIS(fprintf (logfile, "jas 0x%x\n", imm)); cris_cc_mask(dc, 0); /* Stor the return address in Pd. */ gen_op_movl_T0_im(imm); gen_op_movl_btarget_T0(); gen_op_movl_T0_im(dc->pc + 8); gen_movl_preg_T0[dc->op2](); cris_prepare_dyn_jmp(dc); return 6;}static unsigned int dec_jasc_im(DisasContext *dc){ uint32_t imm; imm = ldl_code(dc->pc + 2); DIS(fprintf (logfile, "jasc 0x%x\n", imm)); cris_cc_mask(dc, 0); /* Stor the return address in Pd. */ gen_op_movl_T0_im(imm); gen_op_movl_btarget_T0(); gen_op_movl_T0_im(dc->pc + 8 + 4); gen_movl_preg_T0[dc->op2](); cris_prepare_dyn_jmp(dc); return 6;}static unsigned int dec_jasc_r(DisasContext *dc){ DIS(fprintf (logfile, "jasc_r $r%u, $p%u\n", dc->op1, dc->op2)); cris_cc_mask(dc, 0); /* Stor the return address in Pd. */ gen_movl_T0_reg[dc->op1](); gen_op_movl_btarget_T0(); gen_op_movl_T0_im(dc->pc + 4 + 4); gen_movl_preg_T0[dc->op2](); cris_prepare_dyn_jmp(dc); return 2;}static unsigned int dec_bcc_im(DisasContext *dc){ int32_t offset; uint32_t cond = dc->op2; offset = ldl_code(dc->pc + 2); offset = sign_extend(offset, 15); DIS(fprintf (logfile, "b%s %d pc=%x dst=%x\n", cc_name(cond), offset, dc->pc, dc->pc + offset)); cris_cc_mask(dc, 0); /* op2 holds the condition-code. */ cris_prepare_cc_branch (dc, offset, cond); return 4;}static unsigned int dec_bas_im(DisasContext *dc){ int32_t simm; simm = ldl_code(dc->pc + 2); DIS(fprintf (logfile, "bas 0x%x, $p%u\n", dc->pc + simm, dc->op2)); cris_cc_mask(dc, 0); /* Stor the return address in Pd. */ gen_op_movl_T0_im(dc->pc + simm); gen_op_movl_btarget_T0(); gen_op_movl_T0_im(dc->pc + 8); gen_movl_preg_T0[dc->op2](); cris_prepare_dyn_jmp(dc); return 6;}static unsigned int dec_basc_im(DisasContext *dc){ int32_t simm; simm = ldl_code(dc->pc + 2); DIS(fprintf (logfile, "basc 0x%x, $p%u\n", dc->pc + simm, dc->op2)); cris_cc_mask(dc, 0); /* Stor the return address in Pd. */ gen_op_movl_T0_im(dc->pc + simm); gen_op_movl_btarget_T0(); gen_op_movl_T0_im(dc->pc + 12); gen_movl_preg_T0[dc->op2](); cris_prepare_dyn_jmp(dc); return 6;}static unsigned int dec_rfe_etc(DisasContext *dc){ DIS(fprintf (logfile, "rfe_etc opc=%x pc=0x%x op1=%d op2=%d\n", dc->opcode, dc->pc, dc->op1, dc->op2)); cris_cc_mask(dc, 0); if (dc->op2 == 15) /* ignore halt. */ goto done; switch (dc->op2 & 7) { case 2: /* rfe. */ cris_evaluate_flags(dc); gen_op_ccs_rshift(); break; case 5: /* rfn. */ BUG(); break; case 6: /* break. */ gen_op_movl_T0_im(dc->pc); gen_op_movl_pc_T0(); /* Breaks start at 16 in the exception vector. */ gen_op_break_im(dc->op1 + 16); break; default: printf ("op2=%x\n", dc->op2); BUG(); break; } done: return 2;}static unsigned int dec_null(DisasContext *dc){ printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n", dc->pc, dc->opcode, dc->op1, dc->op2); fflush(NULL); BUG(); return 2;}struct decoder_info { struct { uint32_t bits; uint32_t mask; }; unsigned int (*dec)(DisasContext *dc);} decinfo[] = { /* Order matters here. */ {DEC_MOVEQ, dec_moveq}, {DEC_BTSTQ, dec_btstq}, {DEC_CMPQ, dec_cmpq}, {DEC_ADDOQ, dec_addoq}, {DEC_ADDQ, dec_addq}, {DEC_SUBQ, dec_subq}, {DEC_ANDQ, dec_andq}, {DEC_ORQ, dec_orq}, {DEC_ASRQ, dec_asrq}, {DEC_LSLQ, dec_lslq}, {DEC_LSRQ, dec_lsrq}, {DEC_BCCQ, dec_bccq}, {DEC_BCC_IM, dec_bcc_im}, {DEC_JAS_IM, dec_jas_im}, {DEC_JAS_R, dec_jas_r}, {DEC_JASC_IM, dec_jasc_im}, {DEC_JASC_R, dec_jasc_r}, {DEC_BAS_IM, dec_bas_im}, {DEC_BASC_IM, dec_basc_im}, {DEC_JUMP_P, dec_jump_p}, {DEC_LAPC_IM, dec_lapc_im}, {DEC_LAPCQ, dec_lapcq}, {DEC_RFE_ETC, dec_rfe_etc}, {DEC_ADDC_MR, dec_addc_mr}, {DEC_MOVE_MP, dec_move_mp}, {DEC_MOVE_PM, dec_move_pm}, {DEC_MOVEM_MR, dec_movem_mr}, {DEC_MOVEM_RM, dec_movem_rm}, {DEC_MOVE_PR, dec_move_pr}, {DEC_SCC_R, dec_scc_r}, {DEC_SETF, dec_setclrf}, {DEC_CLEARF, dec_setclrf}, {DEC_MOVE_SR, dec_move_sr}, {DEC_MOVE_RP, dec_move_rp}, {DEC_SWAP_R, dec_swap_r}, {DEC_ABS_R, dec_abs_r}, {DEC_LZ_R, dec_lz_r}, {DEC_MOVE_RS, dec_move_rs}, {DEC_BTST_R, dec_btst_r}, {DEC_ADDC_R, dec_addc_r}, {DEC_DSTEP_R, dec_dstep_r}, {DEC_XOR_R, dec_xor_r}, {DEC_MCP_R, dec_mcp_r}, {DEC_CMP_R, dec_cmp_r}, {DEC_ADDI_R, dec_addi_r}, {DEC_ADDI_ACR, dec_addi_acr}, {DEC_ADD_R, dec_add_r}, {DEC_SUB_R, dec_sub_r}, {DEC_ADDU_R, dec_addu_r}, {DEC_ADDS_R, dec_adds_r}, {DEC_SUBU_R, dec_subu_r}, {DEC_SUBS_R, dec_subs_r}, {DEC_LSL_R, dec_lsl_r}, {DEC_AND_R, dec_and_r}, {DEC_OR_R, dec_or_r}, {DEC_BOUND_R, dec_bound_r}, {DEC_ASR_R, dec_asr_r}, {DEC_LSR_R, dec_lsr_r}, {DEC_MOVU_R, dec_movu_r}, {DEC_MOVS_R, dec_movs_r}, {DEC_NEG_R, dec_neg_r}, {DEC_MOVE_R, dec_move_r}, /* ftag_fidx_i_m. */ /* ftag_fidx_d_m. */ {DEC_MULS_R, dec_muls_r}, {DEC_MULU_R, dec_mulu_r}, {DEC_ADDU_M, dec_addu_m}, {DEC_ADDS_M, dec_adds_m}, {DEC_SUBU_M, dec_subu_m}, {DEC_SUBS_M, dec_subs_m}, {DEC_CMPU_M, dec_cmpu_m}, {DEC_CMPS_M, dec_cmps_m}, {DEC_MOVU_M, dec_movu_m}, {DEC_MOVS_M, dec_movs_m}, {DEC_CMP_M, dec_cmp_m}, {DEC_ADDO_M, dec_addo_m}, {DEC_BOUND_M, dec_bound_m}, {DEC_ADD_M, dec_add_m}, {DEC_SUB_M, dec_sub_m}, {DEC_AND_M, dec_and_m}, {DEC_OR_M, dec_or_m}, {DEC_MOVE_RM, dec_move_rm}, {DEC_TEST_M, dec_test_m}, {DEC_MOVE_MR, dec_move_mr}, {{0, 0}, dec_null}};static inline unsigned intcris_decoder(DisasContext *dc){ unsigned int insn_len = 2; uint32_t tmp; int i; /* Load a halfword onto the instruction register. */ tmp = ldl_code(dc->pc); dc->ir = tmp & 0xffff; /* Now decode it. */ dc->opcode = EXTRACT_FIELD(dc->ir, 4, 11); dc->op1 = EXTRACT_FIELD(dc->ir, 0, 3); dc->op2 = EXTRACT_FIELD(dc->ir, 12, 15); dc->zsize = EXTRACT_FIELD(dc->ir, 4, 4); dc->zzsize = EXTRACT_FIELD(dc->ir, 4, 5); dc->postinc = EXTRACT_FIELD(dc->ir, 10, 10); /* Large switch for all insns. */ for (i = 0; i < sizeof decinfo / sizeof decinfo[0]; i++) { if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) { insn_len = decinfo[i].dec(dc); break; } } return insn_len;}static void check_breakpoint(CPUState *env, DisasContext *dc){ int j; if (env->nb_breakpoints > 0) { for(j = 0; j < env->nb_breakpoints; j++) { if (env->breakpoints[j] == dc->pc) { cris_evaluate_flags (dc); gen_op_movl_T0_im((long)dc->pc); gen_op_movl_pc_T0(); gen_op_debug(); dc->is_jmp = DISAS_UPDATE; } } }}/* generate intermediate code for basic block 'tb'. */struct DisasContext ctx;static intgen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, int search_pc){ uint16_t *gen_opc_end; uint32_t pc_start; unsigned int insn_len; int j, lj; struct DisasContext *dc = &ctx; uint32_t next_page_start; pc_start = tb->pc; dc->env = env; dc->tb = tb; gen_opc_ptr = gen_opc_buf; gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; gen_opparam_ptr = gen_opparam_buf; dc->is_jmp = DISAS_NEXT; dc->pc = pc_start; dc->singlestep_enabled = env->singlestep_enabled; dc->flagx_live = 0; dc->flags_x = 0; next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; lj = -1; do { check_breakpoint(env, dc); if (dc->is_jmp == DISAS_JUMP) goto done; if (search_pc) { j = gen_opc_ptr - gen_opc_buf; if (lj < j) { lj++; while (lj < j) gen_opc_instr_start[lj++] = 0; } gen_opc_pc[lj] = dc->pc; gen_opc_instr_start[lj] = 1; } insn_len = cris_decoder(dc); STATS(gen_op_exec_insn()); dc->pc += insn_len; if (!dc->flagx_live || (dc->flagx_live && !(dc->cc_op == CC_OP_FLAGS && dc->flags_x))) { gen_movl_T0_preg[SR_CCS](); gen_op_andl_T0_im(~X_FLAG); gen_movl_preg_T0[SR_CCS](); dc->flagx_live = 1; dc->flags_x = 0; } /* Check for delayed branches here. If we do it before actually genereating any host code, the simulator will just loop doing nothing for on this program location. */ if (dc->delayed_branch) { dc->delayed_branch--; if (dc->delayed_branch == 0) { if (dc->bcc == CC_A) { gen_op_jmp (); dc->is_jmp = DISAS_UPDATE; } else { /* Conditional jmp. */ gen_op_cc_jmp (dc->delayed_pc, dc->pc); dc->is_jmp = DISAS_UPDATE; } } } if (env->singlestep_enabled) break; } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && dc->pc < next_page_start); if (!dc->is_jmp) { gen_op_movl_T0_im((long)dc->pc); gen_op_movl_pc_T0(); } cris_evaluate_flags (dc); done: if (__builtin_expect(env->singlestep_enabled, 0)) { gen_op_debug(); } else { switch(dc->is_jmp) { case DISAS_NEXT: gen_goto_tb(dc, 1, dc->pc); break; default: case DISAS_JUMP: case DISAS_UPDATE: /* indicate that the hash table must be used to find the next TB */ /* T0 is used to index the jmp tables. */ gen_op_movl_T0_0(); gen_op_exit_tb(); break; case DISAS_TB_JUMP: /* nothing more to generate */ break; } } *gen_opc_ptr = INDEX_op_end; if (search_pc) { j = gen_opc_ptr - gen_opc_buf; lj++; while (lj <= j) gen_opc_instr_start[lj++] = 0; } else { tb->size = dc->pc - pc_start; }#ifdef DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "--------------\n"); fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start)); target_disas(logfile, pc_start, dc->pc + 4 - pc_start, 0); fprintf(logfile, "\n"); if (loglevel & CPU_LOG_TB_OP) { fprintf(logfile, "OP:\n"); dump_ops(gen_opc_buf, gen_opparam_buf); fprintf(logfile, "\n"); } }#endif return 0;}int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb){ return gen_intermediate_code_internal(env, tb, 0);}int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb){ return gen_intermediate_code_internal(env, tb, 1);}void cpu_dump_state (CPUState *env, FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...), int flags){ int i; uint32_t srs; if (!env || !f) return; cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n" "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n" "debug=%x %x %x\n", env->pc, env->pregs[SR_CCS], env->btaken, env->btarget, env->cc_op, env->cc_src, env->cc_dest, env->cc_result, env->cc_mask, env->debug1, env->debug2, env->debug3); for (i = 0; i < 16; i++) { cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]); if ((i + 1) % 4 == 0) cpu_fprintf(f, "\n"); } cpu_fprintf(f, "\nspecial regs:\n"); for (i = 0; i < 16; i++) { cpu_fprintf(f, "p%2.2d=%8.8x ", i, env->pregs[i]); if ((i + 1) % 4 == 0) cpu_fprintf(f, "\n"); } srs = env->pregs[SR_SRS]; cpu_fprintf(f, "\nsupport function regs bank %d:\n", srs); if (srs < 256) { for (i = 0; i < 16; i++) { cpu_fprintf(f, "s%2.2d=%8.8x ", i, env->sregs[srs][i]); if ((i + 1) % 4 == 0) cpu_fprintf(f, "\n"); } } cpu_fprintf(f, "\n\n");}CPUCRISState *cpu_cris_init (const char *cpu_model){ CPUCRISState *env; env = qemu_mallocz(sizeof(CPUCRISState)); if (!env) return NULL; cpu_exec_init(env); cpu_reset(env); return env;}void cpu_reset (CPUCRISState *env){ memset(env, 0, offsetof(CPUCRISState, breakpoints)); tlb_flush(env, 1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -