OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [rel-0-3-0-rc1/] [or1ksim/] [cpu/] [or32/] [op.c] - Diff between revs 1667 and 1678

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 1667 Rev 1678
Line 89... Line 89...
extern uorreg_t __op_param1;
extern uorreg_t __op_param1;
extern uorreg_t __op_param2;
extern uorreg_t __op_param2;
extern uorreg_t __op_param3;
extern uorreg_t __op_param3;
 
 
 
 
/* Helper function.  Whenever we escape the recompiled code and there is a
static inline void save_t_bound(oraddr_t pc)
 * potential that an exception may happen this function must be called */
 
static inline void save_t_temporary(void)
 
{
{
  env->t0 = t0;
  int reg;
  env->t1 = t1;
 
  env->t2 = t2;
  pc = (pc & config.immu.page_offset_mask) / 4;
 
  reg = env->curr_page->ts_bound[pc];
 
 
 
  if(reg & 0x1f)
 
    env->reg[reg & 0x1f] = t0;
 
 
 
  if((reg >> 5) & 0x1f)
 
    env->reg[(reg >> 5) & 0x1f] = t1;
 
 
 
  if((reg >> 10) & 0x1f)
 
    env->reg[(reg >> 10) & 0x1f] = t2;
}
}
 
 
/* Wrapper around do_scheduler.  This is needed because op_do_sched must be as
 
 * small as possible. */
 
void do_sched_wrap(void)
void do_sched_wrap(void)
{
{
  save_t_temporary();
 
  upd_sim_cycles();
  upd_sim_cycles();
 
  save_t_bound(env->pc - 4);
  do_scheduler();
  do_scheduler();
}
}
 
 
/* do_scheduler wrapper for instructions that are in the delay slot */
/* do_scheduler wrapper for instructions that are in the delay slot */
void do_sched_wrap_delay(void)
void do_sched_wrap_delay(void)
{
{
  save_t_temporary();
 
  upd_sim_cycles();
  upd_sim_cycles();
  env->ts_current = 1;
 
  /* The PC gets set to the location of the jump, but do_sched increments that
 
   * so pull it back here to point to the right location again.  This could be
 
   * done in op_add_pc/op_set_pc_pc_delay but that would enlarge the recompiled
 
   * code. */
 
  //env->pc -= 4;
 
  do_scheduler();
  do_scheduler();
  env->ts_current = 0;
 
}
}
 
 
void enter_dyn_code(oraddr_t addr, struct dyn_page *dp)
void enter_dyn_code(oraddr_t addr, struct dyn_page *dp)
{
{
  uint16_t reg;
  uint16_t reg = 0;
 
 
  addr &= config.immu.pagesize - 1;
  addr &= config.immu.pagesize - 1;
  addr >>= 2;
  addr >>= 2;
 
 
  reg = dp->ts_bound[addr];
  if(addr)
 
    reg = dp->ts_bound[addr - 1];
 
 
  if(reg & 0x1f)
  if(reg & 0x1f)
    t0 = cpu_state.reg[reg & 0x1f];
    t0 = cpu_state.reg[reg & 0x1f];
 
 
  if((reg >> 5) & 0x1f)
  if((reg >> 5) & 0x1f)
Line 249... Line 248...
    env->delay_insn = 1;
    env->delay_insn = 1;
    env->pc_delay = get_pc() + (orreg_t)OP_PARAM1;
    env->pc_delay = get_pc() + (orreg_t)OP_PARAM1;
  }
  }
}
}
 
 
__or_dynop void op_set_ts_current(void)
 
{
 
  env->ts_current = 1;
 
}
 
 
 
__or_dynop void op_add_pc(void)
__or_dynop void op_add_pc(void)
{
{
  /* FIXME: Optimise */
  /* FIXME: Optimise */
  set_pc(get_pc() + OP_PARAM1);
  set_pc(get_pc() + OP_PARAM1);
}
}
 
 
__or_dynop void op_nop_exit(void)
__or_dynop void op_nop_exit(void)
{
{
  upd_sim_cycles();
  upd_sim_cycles();
  save_t_temporary();
 
  op_support_nop_exit();
  op_support_nop_exit();
  FORCE_RET;
  FORCE_RET;
}
}
 
 
__or_dynop void op_nop_reset(void)
__or_dynop void op_nop_reset(void)
Line 277... Line 270...
  do_jump(EXCEPT_RESET);
  do_jump(EXCEPT_RESET);
}
}
 
 
__or_dynop void op_nop_printf(void)
__or_dynop void op_nop_printf(void)
{
{
  save_t_temporary();
 
  upd_sim_cycles();
  upd_sim_cycles();
  op_support_nop_printf();
  op_support_nop_printf();
  FORCE_RET;
  FORCE_RET;
}
}
 
 
__or_dynop void op_nop_report(void)
__or_dynop void op_nop_report(void)
{
{
  save_t_temporary();
 
  upd_sim_cycles();
  upd_sim_cycles();
  op_support_nop_report();
  op_support_nop_report();
  FORCE_RET;
  FORCE_RET;
}
}
 
 
__or_dynop void op_nop_report_imm(void)
__or_dynop void op_nop_report_imm(void)
{
{
  save_t_temporary();
 
  upd_sim_cycles();
  upd_sim_cycles();
  op_support_nop_report_imm(OP_PARAM1);
  op_support_nop_report_imm(OP_PARAM1);
}
}
 
 
__or_dynop void op_analysis(void)
__or_dynop void op_analysis(void)
{
{
  env->iqueue.insn_index = OP_PARAM1;
  env->iqueue.insn_index = OP_PARAM1;
  env->iqueue.insn = OP_PARAM2;
  env->iqueue.insn = OP_PARAM2;
  env->iqueue.insn_addr = get_pc();
  env->iqueue.insn_addr = get_pc();
  save_t_temporary();
 
  op_support_analysis();
  op_support_analysis();
  FORCE_RET;
  FORCE_RET;
}
}
 
 
__or_dynop void op_move_gpr1_pc_delay(void)
__or_dynop void op_move_gpr1_pc_delay(void)
Line 885... Line 874...
 
 
__or_dynop void op_prep_rfe(void)
__or_dynop void op_prep_rfe(void)
{
{
  env->sprs[SPR_SR] = env->sprs[SPR_ESR_BASE] | SPR_SR_FO;
  env->sprs[SPR_SR] = env->sprs[SPR_ESR_BASE] | SPR_SR_FO;
  env->sprs[SPR_PPC] = get_pc();
  env->sprs[SPR_PPC] = get_pc();
  env->ts_current = 1;
 
  set_pc(env->sprs[SPR_EPCR_BASE] - 4);
  set_pc(env->sprs[SPR_EPCR_BASE] - 4);
}
}
 
 
static inline void prep_except(oraddr_t epcr_base)
static inline void prep_except(oraddr_t epcr_base)
{
{
Line 916... Line 904...
 * Therefore the pc will point to the instruction after the l.sys or l.trap
 * Therefore the pc will point to the instruction after the l.sys or l.trap
 * instruction */
 * instruction */
__or_dynop void op_prep_sys_delay(void)
__or_dynop void op_prep_sys_delay(void)
{
{
  env->delay_insn = 0;
  env->delay_insn = 0;
  env->ts_current = 1;
 
  prep_except(get_pc() - 4);
  prep_except(get_pc() - 4);
  set_pc(EXCEPT_SYSCALL - 4);
  set_pc(EXCEPT_SYSCALL - 4);
}
}
 
 
__or_dynop void op_prep_sys(void)
__or_dynop void op_prep_sys(void)
{
{
  env->ts_current = 1;
 
  prep_except(get_pc() + 4);
  prep_except(get_pc() + 4);
  set_pc(EXCEPT_SYSCALL - 4);
  set_pc(EXCEPT_SYSCALL - 4);
}
}
 
 
__or_dynop void op_prep_trap_delay(void)
__or_dynop void op_prep_trap_delay(void)
{
{
  env->ts_current = 1;
 
  env->delay_insn = 0;
  env->delay_insn = 0;
  prep_except(get_pc() - 4);
  prep_except(get_pc() - 4);
  set_pc(EXCEPT_TRAP - 4);
  set_pc(EXCEPT_TRAP - 4);
}
}
 
 
__or_dynop void op_prep_trap(void)
__or_dynop void op_prep_trap(void)
{
{
  env->ts_current = 1;
 
  prep_except(get_pc());
  prep_except(get_pc());
  set_pc(EXCEPT_TRAP - 4);
  set_pc(EXCEPT_TRAP - 4);
}
}
 
 
/* FIXME: This `instruction' should be split up like the l.trap and l.sys
/* FIXME: This `instruction' should be split up like the l.trap and l.sys
 * instructions are done */
 * instructions are done */
__or_dynop void op_illegal_delay(void)
__or_dynop void op_illegal_delay(void)
{
{
  env->delay_insn = 0;
  env->delay_insn = 0;
  env->ts_current = 1;
 
  env->sprs[SPR_EEAR_BASE] = get_pc() - 4;
  env->sprs[SPR_EEAR_BASE] = get_pc() - 4;
  do_jump(EXCEPT_ILLEGAL - 4);
  do_jump(EXCEPT_ILLEGAL - 4);
}
}
 
 
__or_dynop void op_illegal(void)
__or_dynop void op_illegal(void)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.