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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [cpu/] [or32/] [op.c] - Diff between revs 1684 and 1687

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

Rev 1684 Rev 1687
Line 43... Line 43...
 
 
#include "i386_regs.h"
#include "i386_regs.h"
 
 
#include "dyn_rec.h"
#include "dyn_rec.h"
 
 
/* This must be here since the function in op_i386.h use this variable */
 
register struct cpu_state *env asm(CPU_STATE_REG);
register struct cpu_state *env asm(CPU_STATE_REG);
 
 
#include "op_i386.h"
#include "op_i386.h"
 
 
/*
/*
Line 108... Line 107...
    env->reg[(reg >> 10) & 0x1f] = t2;
    env->reg[(reg >> 10) & 0x1f] = t2;
}
}
 
 
void do_sched_wrap(void)
void do_sched_wrap(void)
{
{
  upd_sim_cycles();
  env->pc += 4;
 
  //runtime.cpu.instructions++;
 
  runtime.sim.cycles -= env->cycles_dec;
 
  scheduler.job_queue->time += env->cycles_dec;
 
  if(scheduler.job_queue->time <= 0) {
  save_t_bound(env->pc - 4);
  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)
{
{
  upd_sim_cycles();
  /* FIXME: Can't this be eliminated? */
 
  env->pc += 4;
 
  //runtime.cpu.instructions++;
 
  runtime.sim.cycles -= env->cycles_dec;
 
  scheduler.job_queue->time += env->cycles_dec;
 
  if(scheduler.job_queue->time <= 0)
  do_scheduler();
  do_scheduler();
}
}
 
 
void enter_dyn_code(oraddr_t addr, struct dyn_page *dp)
void enter_dyn_code(oraddr_t addr, struct dyn_page *dp)
{
{
Line 145... Line 154...
}
}
 
 
 
 
__or_dynop void op_set_pc_pc_delay(void)
__or_dynop void op_set_pc_pc_delay(void)
{
{
  env->sprs[SPR_PPC] = get_pc();
  env->sprs[SPR_PPC] = env->pc;
  /* pc_delay is pulled back 4 since imediatly after this is run, the scheduler
  /* pc_delay is pulled back 4 since imediatly after this is run, the scheduler
   * runs which also increments it by 4 */
   * runs which also increments it by 4 */
  set_pc(env->pc_delay - 4);
  env->pc = env->pc_delay - 4;
}
}
 
 
__or_dynop void op_set_pc_delay_imm(void)
__or_dynop void op_set_pc_delay_imm(void)
{
{
  env->pc_delay = get_pc() + (orreg_t)OP_PARAM1;
  env->pc_delay = env->pc + (orreg_t)OP_PARAM1;
  env->delay_insn = 1;
  env->delay_insn = 1;
}
}
 
 
__or_dynop void op_set_pc_delay_pc(void)
__or_dynop void op_set_pc_delay_pc(void)
{
{
  env->pc_delay = get_pc();
  env->pc_delay = env->pc;
  env->delay_insn = 1;
  env->delay_insn = 1;
}
}
 
 
__or_dynop void op_clear_pc_delay(void)
__or_dynop void op_clear_pc_delay(void)
{
{
Line 171... Line 180...
  env->delay_insn = 1;
  env->delay_insn = 1;
}
}
 
 
__or_dynop void op_do_jump(void)
__or_dynop void op_do_jump(void)
{
{
  do_jump(get_pc());
  do_jump(env->pc);
}
}
 
 
__or_dynop void op_do_jump_delay(void)
__or_dynop void op_do_jump_delay(void)
{
{
  do_jump(env->pc_delay);
  do_jump(env->pc_delay);
Line 215... Line 224...
/* Used for the l.bf instruction.  Therefore if the flag is not set, jump over
/* Used for the l.bf instruction.  Therefore if the flag is not set, jump over
 * all the jumping stuff */
 * all the jumping stuff */
__or_dynop void op_check_flag(void)
__or_dynop void op_check_flag(void)
{
{
  if(!(env->sprs[SPR_SR] & SPR_SR_F)) {
  if(!(env->sprs[SPR_SR] & SPR_SR_F)) {
    HANDLE_SCHED(do_sched_wrap, "no_sched_chk_flg");
    SPEEDY_CALL(do_sched_wrap);
    OP_JUMP(OP_PARAM1);
    OP_JUMP(OP_PARAM1);
  }
  }
}
}
 
 
/* Used for l.bf if the delay slot instruction is on another page */
/* Used for l.bf if the delay slot instruction is on another page */
__or_dynop void op_check_flag_delay(void)
__or_dynop void op_check_flag_delay(void)
{
{
  if(env->sprs[SPR_SR] & SPR_SR_F) {
  if(env->sprs[SPR_SR] & SPR_SR_F) {
    env->delay_insn = 1;
    env->delay_insn = 1;
    env->pc_delay = get_pc() + (orreg_t)OP_PARAM1;
    env->pc_delay = env->pc + (orreg_t)OP_PARAM1;
  }
  }
}
}
 
 
/* Used for the l.bnf instruction.  Therefore if the flag is set, jump over all
/* Used for the l.bnf instruction.  Therefore if the flag is set, jump over all
 * the jumping stuff */
 * the jumping stuff */
__or_dynop void op_check_not_flag(void)
__or_dynop void op_check_not_flag(void)
{
{
  if(env->sprs[SPR_SR] & SPR_SR_F) {
  if(env->sprs[SPR_SR] & SPR_SR_F) {
    HANDLE_SCHED(do_sched_wrap, "no_sched_chk_not_flg");
    SPEEDY_CALL(do_sched_wrap);
    OP_JUMP(OP_PARAM1);
    OP_JUMP(OP_PARAM1);
  }
  }
}
}
 
 
/* Used for l.bnf if the delay slot instruction is on another page */
/* Used for l.bnf if the delay slot instruction is on another page */
__or_dynop void op_check_not_flag_delay(void)
__or_dynop void op_check_not_flag_delay(void)
{
{
  if(!(env->sprs[SPR_SR] & SPR_SR_F)) {
  if(!(env->sprs[SPR_SR] & SPR_SR_F)) {
    env->delay_insn = 1;
    env->delay_insn = 1;
    env->pc_delay = get_pc() + (orreg_t)OP_PARAM1;
    env->pc_delay = env->pc + (orreg_t)OP_PARAM1;
  }
  }
}
}
 
 
__or_dynop void op_add_pc(void)
__or_dynop void op_add_pc(void)
{
{
  /* FIXME: Optimise */
  env->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();
 
  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)
{
{
  upd_sim_cycles();
 
  op_support_nop_reset();
  op_support_nop_reset();
  do_jump(EXCEPT_RESET);
  do_jump(EXCEPT_RESET);
}
}
 
 
__or_dynop void op_nop_printf(void)
__or_dynop void op_nop_printf(void)
{
{
  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)
{
{
  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)
{
{
  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)
{
{
Line 859... Line 862...
#undef S_FUNC
#undef S_FUNC
#undef S_OP_NAME
#undef S_OP_NAME
 
 
__or_dynop void op_join_mem_cycles(void)
__or_dynop void op_join_mem_cycles(void)
{
{
  join_mem_cycles();
  runtime.sim.cycles += runtime.sim.mem_cycles;
 
  scheduler.job_queue->time -= runtime.sim.mem_cycles;
 
  runtime.sim.mem_cycles = 0;
}
}
 
 
__or_dynop void op_store_link_addr_gpr(void)
__or_dynop void op_store_link_addr_gpr(void)
{
{
  env->reg[LINK_REGNO] = get_pc() + 8;
  env->reg[LINK_REGNO] = env->pc + 8;
}
}
 
 
__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] = env->pc;
  set_pc(env->sprs[SPR_EPCR_BASE] - 4);
  env->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)
{
{
  env->sprs[SPR_EPCR_BASE] = epcr_base;
  env->sprs[SPR_EPCR_BASE] = epcr_base;
Line 892... Line 897...
  env->sprs[SPR_SR] &= ~(SPR_SR_IEE | SPR_SR_TEE);    /* Disable interrupts. */
  env->sprs[SPR_SR] &= ~(SPR_SR_IEE | SPR_SR_TEE);    /* Disable interrupts. */
}
}
 
 
__or_dynop void op_set_except_pc(void)
__or_dynop void op_set_except_pc(void)
{
{
  set_pc(OP_PARAM1);
  env->pc = OP_PARAM1;
}
}
 
 
/* Before the code in op_{sys,trap}{,_delay} gets run, the scheduler runs.
/* Before the code in op_{sys,trap}{,_delay} gets run, the scheduler runs.
 * 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;
  prep_except(get_pc() - 4);
  prep_except(env->pc - 4);
  set_pc(EXCEPT_SYSCALL - 4);
  env->pc = EXCEPT_SYSCALL - 4;
}
}
 
 
__or_dynop void op_prep_sys(void)
__or_dynop void op_prep_sys(void)
{
{
  prep_except(get_pc() + 4);
  prep_except(env->pc + 4);
  set_pc(EXCEPT_SYSCALL - 4);
  env->pc = EXCEPT_SYSCALL - 4;
}
}
 
 
__or_dynop void op_prep_trap_delay(void)
__or_dynop void op_prep_trap_delay(void)
{
{
  env->delay_insn = 0;
  env->delay_insn = 0;
  prep_except(get_pc() - 4);
  prep_except(env->pc - 4);
  set_pc(EXCEPT_TRAP - 4);
  env->pc = EXCEPT_TRAP - 4;
}
}
 
 
__or_dynop void op_prep_trap(void)
__or_dynop void op_prep_trap(void)
{
{
  prep_except(get_pc());
  prep_except(env->pc);
  set_pc(EXCEPT_TRAP - 4);
  env->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->sprs[SPR_EEAR_BASE] = get_pc() - 4;
  env->sprs[SPR_EEAR_BASE] = env->pc - 4;
  do_jump(EXCEPT_ILLEGAL - 4);
  do_jump(EXCEPT_ILLEGAL - 4);
}
}
 
 
__or_dynop void op_illegal(void)
__or_dynop void op_illegal(void)
{
{
  env->sprs[SPR_EEAR_BASE] = get_pc();
  env->sprs[SPR_EEAR_BASE] = env->pc;
  do_jump(EXCEPT_ILLEGAL);
  do_jump(EXCEPT_ILLEGAL);
}
}
 
 
__or_dynop void op_do_sched(void)
__or_dynop void op_do_sched(void)
{
{
  HANDLE_SCHED(do_sched_wrap, "no_sched");
  SPEEDY_CALL(do_sched_wrap);
}
}
 
 
__or_dynop void op_do_sched_delay(void)
__or_dynop void op_do_sched_delay(void)
{
{
  HANDLE_SCHED(do_sched_wrap_delay, "no_sched_delay");
  SPEEDY_CALL(do_sched_wrap_delay);
}
}
 
 
__or_dynop void op_macc(void)
__or_dynop void op_macc(void)
{
{
  env->sprs[SPR_MACLO] = 0;
  env->sprs[SPR_MACLO] = 0;

powered by: WebSVN 2.1.0

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