Line 53... |
Line 53... |
|
|
/* NOTE: All openrisc (or) addresses in this file are *PHYSICAL* addresses */
|
/* NOTE: All openrisc (or) addresses in this file are *PHYSICAL* addresses */
|
|
|
/* FIXME: Optimise sorted list adding */
|
/* FIXME: Optimise sorted list adding */
|
|
|
/* FIXME: remove this and use config.immu.pagesize */
|
|
#define PAGE_LEN 8192
|
|
|
|
typedef void (*generic_gen_op)(struct op_queue *opq, int end);
|
typedef void (*generic_gen_op)(struct op_queue *opq, int end);
|
typedef void (*imm_gen_op)(struct op_queue *opq, int end, uorreg_t imm);
|
typedef void (*imm_gen_op)(struct op_queue *opq, int end, uorreg_t imm);
|
|
|
void gen_l_invalid(struct op_queue *opq, int param_t[3], orreg_t param[3],
|
void gen_l_invalid(struct op_queue *opq, int param_t[3], orreg_t param[3],
|
int delay_slot);
|
int delay_slot);
|
Line 384... |
Line 381... |
struct dyn_page *new_dp(oraddr_t page)
|
struct dyn_page *new_dp(oraddr_t page)
|
{
|
{
|
struct dyn_page *dp = malloc(sizeof(struct dyn_page));
|
struct dyn_page *dp = malloc(sizeof(struct dyn_page));
|
dp->or_page = ADDR_PAGE(page);
|
dp->or_page = ADDR_PAGE(page);
|
|
|
dp->locs = malloc(sizeof(void *) * (PAGE_LEN / 4));
|
dp->locs = malloc(sizeof(void *) * (config.immu.pagesize / 4));
|
|
|
dp->host_len = 0;
|
dp->host_len = 0;
|
dp->host_page = NULL;
|
dp->host_page = NULL;
|
dp->dirty = 1;
|
dp->dirty = 1;
|
|
|
Line 398... |
Line 395... |
|
|
struct dyn_page *find_dynd_page(oraddr_t addr)
|
struct dyn_page *find_dynd_page(oraddr_t addr)
|
{
|
{
|
struct dyn_page *cur = cpu_state.dyn_pages;
|
struct dyn_page *cur = cpu_state.dyn_pages;
|
|
|
addr &= ~(ADDR_C(PAGE_LEN) - 1);
|
addr &= ~(config.immu.pagesize - 1);
|
while(cur) {
|
while(cur) {
|
if(cur->or_page == addr)
|
if(cur->or_page == addr)
|
return cur;
|
return cur;
|
if(cur->or_page > addr)
|
if(cur->or_page > addr)
|
return NULL; /* The dyn_page linked list is ordered */
|
return NULL; /* The dyn_page linked list is ordered */
|
Line 641... |
Line 638... |
unsigned int i;
|
unsigned int i;
|
|
|
cpu_state.opqs = NULL;
|
cpu_state.opqs = NULL;
|
|
|
/* Allocate the operation queue list (+1 for the page chaining) */
|
/* Allocate the operation queue list (+1 for the page chaining) */
|
for(i = 0; i < (PAGE_LEN / 4) + 1; i++) {
|
for(i = 0; i < (config.immu.pagesize / 4) + 1; i++) {
|
if(!(opq = malloc(sizeof(struct op_queue)))) {
|
if(!(opq = malloc(sizeof(struct op_queue)))) {
|
fprintf(stderr, "OOM\n");
|
fprintf(stderr, "OOM\n");
|
exit(1);
|
exit(1);
|
}
|
}
|
|
|
Line 907... |
Line 904... |
oraddr_t rec_addr = dyn->or_page;
|
oraddr_t rec_addr = dyn->or_page;
|
oraddr_t rec_page = dyn->or_page;
|
oraddr_t rec_page = dyn->or_page;
|
void **loc;
|
void **loc;
|
|
|
/* The start of the next page */
|
/* The start of the next page */
|
rec_page += PAGE_LEN;
|
rec_page += config.immu.pagesize;
|
|
|
printf("Recompileing page %"PRIxADDR"\n", rec_addr);
|
printf("Recompileing page %"PRIxADDR"\n", rec_addr);
|
fflush(stdout);
|
fflush(stdout);
|
|
|
/* Mark all temporaries as not containing a register */
|
/* Mark all temporaries as not containing a register */
|
Line 965... |
Line 962... |
}
|
}
|
|
|
dyn->dirty = 0;
|
dyn->dirty = 0;
|
|
|
/* Store the state of the temporaries */
|
/* Store the state of the temporaries */
|
dyn->ts_bound[PAGE_LEN >> 2] = dyn->ts_during[j];
|
dyn->ts_bound[config.immu.pagesize >> 2] = dyn->ts_during[j];
|
|
|
/* Ship temporaries out to the corrisponding registers */
|
/* Ship temporaries out to the corrisponding registers */
|
ship_gprs_out_t(opq->prev, 1, opq->reg_t);
|
ship_gprs_out_t(opq->prev, 1, opq->reg_t);
|
|
|
opq->num_ops = 0;
|
opq->num_ops = 0;
|
Line 983... |
Line 980... |
|
|
/* Generate the code */
|
/* Generate the code */
|
gen_code(cpu_state.opqs, dyn);
|
gen_code(cpu_state.opqs, dyn);
|
|
|
/* Fix up the locations */
|
/* Fix up the locations */
|
for(loc = dyn->locs; loc < &dyn->locs[PAGE_LEN / 4]; loc++)
|
for(loc = dyn->locs; loc < &dyn->locs[config.immu.pagesize / 4]; loc++)
|
*loc += (unsigned int)dyn->host_page;
|
*loc += (unsigned int)dyn->host_page;
|
|
|
cpu_state.opqs->ops_param[0] += (unsigned int)dyn->host_page;
|
cpu_state.opqs->ops_param[0] += (unsigned int)dyn->host_page;
|
|
|
/* Search for page-local jumps */
|
/* Search for page-local jumps */
|
for(opq = cpu_state.opqs, j = 0; j < (PAGE_LEN / 4); opq = opq->next, j++) {
|
opq = cpu_state.opqs;
|
|
for(j = 0; j < (config.immu.pagesize / 4); opq = opq->next, j++) {
|
if(opq->jump_local != -1)
|
if(opq->jump_local != -1)
|
opq->ops_param[opq->jump_local] =
|
opq->ops_param[opq->jump_local] =
|
(unsigned int)dyn->locs[opq->jump_local_loc >> 2];
|
(unsigned int)dyn->locs[opq->jump_local_loc >> 2];
|
|
|
if(opq->not_jump_loc != -1)
|
if(opq->not_jump_loc != -1)
|
Line 1112... |
Line 1110... |
gen_op_do_sched_delay(opq, 1);
|
gen_op_do_sched_delay(opq, 1);
|
|
|
if(jump_local) {
|
if(jump_local) {
|
gen_op_jmp_imm(opq, 1, 0);
|
gen_op_jmp_imm(opq, 1, 0);
|
opq->jump_local = opq->num_ops_param - 1;
|
opq->jump_local = opq->num_ops_param - 1;
|
opq->jump_local_loc = (opq->insn_addr + (orreg_t)off) & (PAGE_LEN - 1);
|
opq->jump_local_loc = (opq->insn_addr + (orreg_t)off) & (config.immu.pagesize - 1);
|
} else
|
} else
|
gen_op_do_jump(opq, 1);
|
gen_op_do_jump(opq, 1);
|
}
|
}
|
|
|
static const generic_gen_op set_pc_delay_gpr[32] = {
|
static const generic_gen_op set_pc_delay_gpr[32] = {
|