diff --git a/src/decode.h b/src/decode.h index 159e36e2..2d552730 100644 --- a/src/decode.h +++ b/src/decode.h @@ -254,9 +254,10 @@ typedef struct { #define HISTORY_SIZE 16 typedef struct { - uint32_t PC; - struct rv_insn *branch_target; -} branch_history_entry_t; + uint8_t idx; + uint32_t PC[HISTORY_SIZE]; + struct rv_insn *target[HISTORY_SIZE]; +} branch_history_table_t; typedef struct rv_insn { union { @@ -300,8 +301,7 @@ typedef struct rv_insn { * specific IR array without the need for additional copying. */ struct rv_insn *branch_taken, *branch_untaken; - uint8_t branch_table_count; - branch_history_entry_t *branch_table; + branch_history_table_t *branch_table; } rv_insn_t; /* decode the RISC-V instruction */ diff --git a/src/emulate.c b/src/emulate.c index 197b88c3..c8d790c5 100644 --- a/src/emulate.c +++ b/src/emulate.c @@ -639,8 +639,7 @@ static void block_translate(riscv_t *rv, block_t *block) || ir->opcode == rv_insn_cjalr || ir->opcode == rv_insn_cjr #endif ) - ir->branch_table = - calloc(1, HISTORY_SIZE * sizeof(branch_history_entry_t)); + ir->branch_table = calloc(1, sizeof(branch_history_table_t)); break; } diff --git a/src/rv32_template.c b/src/rv32_template.c index 8d08f044..4c5c5472 100644 --- a/src/rv32_template.c +++ b/src/rv32_template.c @@ -49,19 +49,18 @@ RVOP(jal, { */ #define LOOKUP_OR_UPDATE_BRANCH_HISTORY_TABLE() \ /* lookup branch history table */ \ - for (int i = 0; i < ir->branch_table_count; i++) { \ - if (ir->branch_table[i].PC == PC) { \ - MUST_TAIL return ir->branch_table[i].branch_target->impl( \ - rv, ir->branch_table[i].branch_target, cycle, PC); \ + for (int i = 0; i < HISTORY_SIZE; i++) { \ + if (ir->branch_table->PC[i] == PC) { \ + MUST_TAIL return ir->branch_table->target[i]->impl( \ + rv, ir->branch_table->target[i], cycle, PC); \ } \ } \ block_t *block = block_find(&rv->block_map, PC); \ if (block) { \ /* update branch history table */ \ - ir->branch_table_count = (ir->branch_table_count + 1) % HISTORY_SIZE; \ - ir->branch_table[ir->branch_table_count].PC = PC; \ - ir->branch_table[ir->branch_table_count].branch_target = \ - block->ir_head; \ + ir->branch_table->PC[ir->branch_table->idx] = PC; \ + ir->branch_table->target[ir->branch_table->idx] = block->ir_head; \ + ir->branch_table->idx = (ir->branch_table->idx + 1) % HISTORY_SIZE; \ MUST_TAIL return block->ir_head->impl(rv, block->ir_head, cycle, PC); \ }