Revision 2e70f6ef target-arm/translate.c
b/target-arm/translate.c | ||
---|---|---|
84 | 84 |
static TCGv cpu_T[2]; |
85 | 85 |
static TCGv cpu_F0s, cpu_F1s, cpu_F0d, cpu_F1d; |
86 | 86 |
|
87 |
#define ICOUNT_TEMP cpu_T[0] |
|
88 |
#include "gen-icount.h" |
|
89 |
|
|
87 | 90 |
/* initialize TCG globals. */ |
88 | 91 |
void arm_translate_init(void) |
89 | 92 |
{ |
... | ... | |
8539 | 8542 |
int j, lj; |
8540 | 8543 |
target_ulong pc_start; |
8541 | 8544 |
uint32_t next_page_start; |
8545 |
int num_insns; |
|
8546 |
int max_insns; |
|
8542 | 8547 |
|
8543 | 8548 |
/* generate intermediate code */ |
8544 | 8549 |
num_temps = 0; |
... | ... | |
8575 | 8580 |
cpu_M0 = tcg_temp_new(TCG_TYPE_I64); |
8576 | 8581 |
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; |
8577 | 8582 |
lj = -1; |
8583 |
num_insns = 0; |
|
8584 |
max_insns = tb->cflags & CF_COUNT_MASK; |
|
8585 |
if (max_insns == 0) |
|
8586 |
max_insns = CF_COUNT_MASK; |
|
8587 |
|
|
8588 |
gen_icount_start(); |
|
8578 | 8589 |
/* Reset the conditional execution bits immediately. This avoids |
8579 | 8590 |
complications trying to do it at the end of the block. */ |
8580 | 8591 |
if (env->condexec_bits) |
... | ... | |
8625 | 8636 |
} |
8626 | 8637 |
gen_opc_pc[lj] = dc->pc; |
8627 | 8638 |
gen_opc_instr_start[lj] = 1; |
8639 |
gen_opc_icount[lj] = num_insns; |
|
8628 | 8640 |
} |
8629 | 8641 |
|
8642 |
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) |
|
8643 |
gen_io_start(); |
|
8644 |
|
|
8630 | 8645 |
if (env->thumb) { |
8631 | 8646 |
disas_thumb_insn(env, dc); |
8632 | 8647 |
if (dc->condexec_mask) { |
... | ... | |
8659 | 8674 |
* Otherwise the subsequent code could get translated several times. |
8660 | 8675 |
* Also stop translation when a page boundary is reached. This |
8661 | 8676 |
* ensures prefech aborts occur at the right place. */ |
8677 |
num_insns ++; |
|
8662 | 8678 |
} while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && |
8663 | 8679 |
!env->singlestep_enabled && |
8664 |
dc->pc < next_page_start); |
|
8680 |
dc->pc < next_page_start && |
|
8681 |
num_insns < max_insns); |
|
8682 |
|
|
8683 |
if (tb->cflags & CF_LAST_IO) { |
|
8684 |
if (dc->condjmp) { |
|
8685 |
/* FIXME: This can theoretically happen with self-modifying |
|
8686 |
code. */ |
|
8687 |
cpu_abort(env, "IO on conditional branch instruction"); |
|
8688 |
} |
|
8689 |
gen_io_end(); |
|
8690 |
} |
|
8665 | 8691 |
|
8666 | 8692 |
/* At this stage dc->condjmp will only be set when the skipped |
8667 | 8693 |
instruction was a conditional branch or trap, and the PC has |
... | ... | |
8726 | 8752 |
dc->condjmp = 0; |
8727 | 8753 |
} |
8728 | 8754 |
} |
8755 |
|
|
8729 | 8756 |
done_generating: |
8757 |
gen_icount_end(tb, num_insns); |
|
8730 | 8758 |
*gen_opc_ptr = INDEX_op_end; |
8731 | 8759 |
|
8732 | 8760 |
#ifdef DEBUG_DISAS |
... | ... | |
8744 | 8772 |
gen_opc_instr_start[lj++] = 0; |
8745 | 8773 |
} else { |
8746 | 8774 |
tb->size = dc->pc - pc_start; |
8775 |
tb->icount = num_insns; |
|
8747 | 8776 |
} |
8748 | 8777 |
return 0; |
8749 | 8778 |
} |
Also available in: Unified diff