mirror of https://github.com/inolen/redream.git
don't persist fastmem state for blocks that weren't invalidated by a fastmem exception
This commit is contained in:
parent
578e032c7e
commit
559137d4a0
|
@ -179,51 +179,51 @@ static void sh4_frontend_analyze_code(struct jit_frontend *base,
|
|||
if (def->flags & SH4_FLAG_SET_PC) {
|
||||
if (def->op == SH4_OP_BF) {
|
||||
uint32_t dest_addr = ((int8_t)instr.disp_8.disp * 2) + addr + 4;
|
||||
block->branch_type = BRANCH_STATIC_FALSE;
|
||||
block->branch_type = JIT_BRANCH_STATIC_FALSE;
|
||||
block->branch_addr = dest_addr;
|
||||
block->next_addr = addr + 4;
|
||||
} else if (def->op == SH4_OP_BFS) {
|
||||
uint32_t dest_addr = ((int8_t)instr.disp_8.disp * 2) + addr + 4;
|
||||
block->branch_type = BRANCH_STATIC_FALSE;
|
||||
block->branch_type = JIT_BRANCH_STATIC_FALSE;
|
||||
block->branch_addr = dest_addr;
|
||||
block->next_addr = addr + 4;
|
||||
} else if (def->op == SH4_OP_BT) {
|
||||
uint32_t dest_addr = ((int8_t)instr.disp_8.disp * 2) + addr + 4;
|
||||
block->branch_type = BRANCH_STATIC_TRUE;
|
||||
block->branch_type = JIT_BRANCH_STATIC_TRUE;
|
||||
block->branch_addr = dest_addr;
|
||||
block->next_addr = addr + 4;
|
||||
} else if (def->op == SH4_OP_BTS) {
|
||||
uint32_t dest_addr = ((int8_t)instr.disp_8.disp * 2) + addr + 4;
|
||||
block->branch_type = BRANCH_STATIC_TRUE;
|
||||
block->branch_type = JIT_BRANCH_STATIC_TRUE;
|
||||
block->branch_addr = dest_addr;
|
||||
block->next_addr = addr + 4;
|
||||
} else if (def->op == SH4_OP_BRA) {
|
||||
/* 12-bit displacement must be sign extended */
|
||||
int32_t disp = ((instr.disp_12.disp & 0xfff) << 20) >> 20;
|
||||
uint32_t dest_addr = (disp * 2) + addr + 4;
|
||||
block->branch_type = BRANCH_STATIC;
|
||||
block->branch_type = JIT_BRANCH_STATIC;
|
||||
block->branch_addr = dest_addr;
|
||||
} else if (def->op == SH4_OP_BRAF) {
|
||||
block->branch_type = BRANCH_DYNAMIC;
|
||||
block->branch_type = JIT_BRANCH_DYNAMIC;
|
||||
} else if (def->op == SH4_OP_BSR) {
|
||||
/* 12-bit displacement must be sign extended */
|
||||
int32_t disp = ((instr.disp_12.disp & 0xfff) << 20) >> 20;
|
||||
uint32_t ret_addr = addr + 4;
|
||||
uint32_t dest_addr = ret_addr + disp * 2;
|
||||
block->branch_type = BRANCH_STATIC;
|
||||
block->branch_type = JIT_BRANCH_STATIC;
|
||||
block->branch_addr = dest_addr;
|
||||
} else if (def->op == SH4_OP_BSRF) {
|
||||
block->branch_type = BRANCH_DYNAMIC;
|
||||
block->branch_type = JIT_BRANCH_DYNAMIC;
|
||||
} else if (def->op == SH4_OP_JMP) {
|
||||
block->branch_type = BRANCH_DYNAMIC;
|
||||
block->branch_type = JIT_BRANCH_DYNAMIC;
|
||||
} else if (def->op == SH4_OP_JSR) {
|
||||
block->branch_type = BRANCH_DYNAMIC;
|
||||
block->branch_type = JIT_BRANCH_DYNAMIC;
|
||||
} else if (def->op == SH4_OP_RTS) {
|
||||
block->branch_type = BRANCH_DYNAMIC;
|
||||
block->branch_type = JIT_BRANCH_DYNAMIC;
|
||||
} else if (def->op == SH4_OP_RTE) {
|
||||
block->branch_type = BRANCH_DYNAMIC;
|
||||
block->branch_type = JIT_BRANCH_DYNAMIC;
|
||||
} else if (def->op == SH4_OP_TRAPA) {
|
||||
block->branch_type = BRANCH_DYNAMIC;
|
||||
block->branch_type = JIT_BRANCH_DYNAMIC;
|
||||
} else {
|
||||
LOG_FATAL("unexpected branch op");
|
||||
}
|
||||
|
|
|
@ -139,7 +139,9 @@ static void jit_restore_edges(struct jit *jit, struct jit_block *block) {
|
|||
PROF_LEAVE();
|
||||
}
|
||||
|
||||
static void jit_invalidate_block(struct jit *jit, struct jit_block *block) {
|
||||
static void jit_invalidate_block(struct jit *jit, struct jit_block *block, int reason) {
|
||||
block->invalidate_reason = reason;
|
||||
|
||||
jit->backend->invalidate_code(jit->backend, block->guest_addr);
|
||||
|
||||
jit_restore_edges(jit, block);
|
||||
|
@ -165,7 +167,7 @@ static void jit_cache_block(struct jit *jit, struct jit_block *block) {
|
|||
}
|
||||
|
||||
static void jit_free_block(struct jit *jit, struct jit_block *block) {
|
||||
jit_invalidate_block(jit, block);
|
||||
jit_invalidate_block(jit, block, JIT_REASON_UNKNOWN);
|
||||
|
||||
rb_unlink(&jit->blocks, &block->it, &block_map_cb);
|
||||
rb_unlink(&jit->reverse_blocks, &block->rit, &reverse_block_map_cb);
|
||||
|
@ -224,7 +226,7 @@ void jit_invalidate_blocks(struct jit *jit) {
|
|||
struct rb_node *next = rb_next(it);
|
||||
|
||||
struct jit_block *block = container_of(it, struct jit_block, it);
|
||||
jit_invalidate_block(jit, block);
|
||||
jit_invalidate_block(jit, block, JIT_REASON_UNKNOWN);
|
||||
|
||||
it = next;
|
||||
}
|
||||
|
@ -289,11 +291,15 @@ void jit_compile_block(struct jit *jit, uint32_t guest_addr) {
|
|||
fastmem = 0;
|
||||
#endif
|
||||
|
||||
/* if the block being compiled had previously been invalidated by a fastmem
|
||||
exception, finish removing it at this time and disable fastmem opts */
|
||||
/* if the block had previously been invalidated, finish removing it now */
|
||||
struct jit_block *existing = jit_get_block(jit, guest_addr);
|
||||
if (existing) {
|
||||
fastmem = existing->fastmem;
|
||||
/* if the block was invalidated due to a fastmem exception, persist its
|
||||
fastmem state */
|
||||
if (existing->invalidate_reason == JIT_REASON_FASTMEM) {
|
||||
fastmem = existing->fastmem;
|
||||
}
|
||||
|
||||
jit_free_block(jit, existing);
|
||||
}
|
||||
|
||||
|
@ -360,12 +366,11 @@ static int jit_handle_exception(void *data, struct exception_state *ex) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* invalidate the block so it's recompiled without fastmem optimizations
|
||||
on the next access. note, the block can't be removed from the lookup
|
||||
maps at this point because it's still executing and may raise more
|
||||
exceptions */
|
||||
/* disable fastmem optimizations for this block on future compiles */
|
||||
block->fastmem = 0;
|
||||
jit_invalidate_block(jit, block);
|
||||
|
||||
/* invalidate the block so it's recompiled on the next access */
|
||||
jit_invalidate_block(jit, block, JIT_REASON_FASTMEM);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -18,12 +18,17 @@ typedef uint32_t (*mem_read_cb)(void *, uint32_t, uint32_t);
|
|||
typedef void (*mem_write_cb)(void *, uint32_t, uint32_t, uint32_t);
|
||||
|
||||
enum {
|
||||
BRANCH_STATIC,
|
||||
BRANCH_STATIC_TRUE,
|
||||
BRANCH_STATIC_FALSE,
|
||||
BRANCH_DYNAMIC,
|
||||
BRANCH_DYNAMIC_TRUE,
|
||||
BRANCH_DYNAMIC_FALSE,
|
||||
JIT_BRANCH_STATIC,
|
||||
JIT_BRANCH_STATIC_TRUE,
|
||||
JIT_BRANCH_STATIC_FALSE,
|
||||
JIT_BRANCH_DYNAMIC,
|
||||
JIT_BRANCH_DYNAMIC_TRUE,
|
||||
JIT_BRANCH_DYNAMIC_FALSE,
|
||||
};
|
||||
|
||||
enum {
|
||||
JIT_REASON_UNKNOWN,
|
||||
JIT_REASON_FASTMEM,
|
||||
};
|
||||
|
||||
struct jit_block {
|
||||
|
@ -31,13 +36,6 @@ struct jit_block {
|
|||
uint32_t guest_addr;
|
||||
int guest_size;
|
||||
|
||||
/* address of compiled block in host memory */
|
||||
void *host_addr;
|
||||
int host_size;
|
||||
|
||||
/* compile with fastmem support */
|
||||
int fastmem;
|
||||
|
||||
/* destination address of terminating branch */
|
||||
int branch_type;
|
||||
uint32_t branch_addr;
|
||||
|
@ -54,6 +52,16 @@ struct jit_block {
|
|||
/* estimated number of guest cycles to execute block */
|
||||
int num_cycles;
|
||||
|
||||
/* compile with fastmem support */
|
||||
int fastmem;
|
||||
|
||||
/* address of compiled block in host memory */
|
||||
void *host_addr;
|
||||
int host_size;
|
||||
|
||||
/* reason the block was invalidated */
|
||||
int invalidate_reason;
|
||||
|
||||
/* edges to other blocks */
|
||||
struct list in_edges;
|
||||
struct list out_edges;
|
||||
|
|
Loading…
Reference in New Issue