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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_34/] [or1ksim/] [cpu/] [or32/] [execute.c] - Diff between revs 677 and 678

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 677 Rev 678
/* execute.c -- OR1K architecture dependent simulation
/* execute.c -- OR1K architecture dependent simulation
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
 
 
This file is part of OpenRISC 1000 Architectural Simulator.
This file is part of OpenRISC 1000 Architectural Simulator.
 
 
This program is free software; you can redistribute it and/or modify
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
(at your option) any later version.
 
 
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 
/* Most of the OR1K simulation is done in here. */
/* Most of the OR1K simulation is done in here. */
 
 
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
#include <ctype.h>
#include <ctype.h>
 
 
#include "config.h"
#include "config.h"
#include "arch.h"
#include "arch.h"
#include "opcode/or32.h"
#include "opcode/or32.h"
#include "branch_predict.h"
#include "branch_predict.h"
#include "abstract.h"
#include "abstract.h"
#include "labels.h"
#include "labels.h"
#include "parse.h"
#include "parse.h"
#include "execute.h"
#include "execute.h"
#include "stats.h"
#include "stats.h"
#include "except.h"
#include "except.h"
#include "sprs.h"
#include "sprs.h"
#include "sim-config.h"
#include "sim-config.h"
#include "debug_unit.h"
#include "debug_unit.h"
 
 
/* Whether instructions set overflow flag */
/* Whether instructions set overflow flag */
#define SET_OV_FLAG     1
#define SET_OV_FLAG     1
 
 
/* Whether arithmethic instructions set flag on zero */
/* Whether arithmethic instructions set flag on zero */
#define ARITH_SET_FLAG  1
#define ARITH_SET_FLAG  1
 
 
/* General purpose registers. */
/* General purpose registers. */
machword reg[MAX_GPRS];
machword reg[MAX_GPRS];
 
 
/* Instruction queue */
/* Instruction queue */
struct iqueue_entry iqueue[20];
struct iqueue_entry iqueue[20];
 
 
/* Is current insn in execution a delay insn? */
/* Is current insn in execution a delay insn? */
int delay_insn;
int delay_insn;
 
 
/* Benchmark multi issue execution */
/* Benchmark multi issue execution */
int multissue[20];
int multissue[20];
int supercycles;
int supercycles;
int issued_per_cycle = 4;
int issued_per_cycle = 4;
int hazardwait = 0;
int hazardwait = 0;
 
 
/* Whether break was hit - so we can step over a break */
/* Whether break was hit - so we can step over a break */
static int break_just_hit = 0;
static int break_just_hit = 0;
 
 
/* freemem 'pointer' */
/* freemem 'pointer' */
extern unsigned long freemem;
extern unsigned long freemem;
 
 
/* Completition queue */
/* Completition queue */
struct iqueue_entry icomplet[20];
struct iqueue_entry icomplet[20];
 
 
/* Program counter (and translated PC) */
/* Program counter (and translated PC) */
unsigned long pc;
unsigned long pc;
unsigned long pc_phy;
unsigned long pc_phy;
 
 
/* Previous program counter */
/* Previous program counter */
unsigned long pcprev = 0;
unsigned long pcprev = 0;
 
 
/* Temporary program counter */
/* Temporary program counter */
unsigned long pcnext;
unsigned long pcnext;
 
 
/* Delay instruction effective address register */
/* Delay instruction effective address register */
unsigned long pcdelay;
unsigned long pcdelay;
 
 
/* CCR */
/* CCR */
int flag;
int flag;
 
 
/* CCR (for dependency calculation) */
/* CCR (for dependency calculation) */
char ccr_flag[10] = "flag";
char ccr_flag[10] = "flag";
 
 
/* Cycles counts fetch stages */
/* Cycles counts fetch stages */
int cycles;
int cycles;
 
 
/* Each cycle has counter of mem_cycles; this value is joined with cycles
/* Each cycle has counter of mem_cycles; this value is joined with cycles
   at the end of the cycle; no sim originated memory accesses should be
   at the end of the cycle; no sim originated memory accesses should be
   performed inbetween. */
   performed inbetween. */
int mem_cycles;
int mem_cycles;
 
 
/* Instructions executed */
/* Instructions executed */
int instructions;
int instructions;
 
 
/* Load and store stalls */
/* Load and store stalls */
int loadcycles, storecycles;
int loadcycles, storecycles;
 
 
/* Store buffer analysis - stores are accumulated and commited when IO is idle */
/* Store buffer analysis - stores are accumulated and commited when IO is idle */
static int sbuf_head = 0, sbuf_tail = 0, sbuf_count = 0;
static int sbuf_head = 0, sbuf_tail = 0, sbuf_count = 0;
static int sbuf_buf[MAX_SBUF_LEN] = {0};
static int sbuf_buf[MAX_SBUF_LEN] = {0};
static int sbuf_prev_cycles = 0;
static int sbuf_prev_cycles = 0;
 
 
/* Num cycles waiting for stores to complete */
/* Num cycles waiting for stores to complete */
int sbuf_wait_cyc = 0;
int sbuf_wait_cyc = 0;
 
 
/* Number of total store cycles */
/* Number of total store cycles */
int sbuf_total_cyc = 0;
int sbuf_total_cyc = 0;
 
 
/* Local data needed for execution.  */
/* Local data needed for execution.  */
static struct iqueue_entry *cur;
static struct iqueue_entry *cur;
static int next_delay_insn;
static int next_delay_insn;
static int breakpoint;
static int breakpoint;
static unsigned long *op;
static unsigned long *op;
static int num_op;
static int num_op;
 
 
/* Implementation specific.
/* Implementation specific.
   Get an actual value of a specific register. */
   Get an actual value of a specific register. */
 
 
unsigned long evalsim_reg32(int regno)
unsigned long evalsim_reg32(int regno)
{
{
  if (regno < MAX_GPRS) {
  if (regno < MAX_GPRS) {
    return reg[regno];
    return reg[regno];
  } else {
  } else {
    printf("\nABORT: read out of registers\n");
    printf("\nABORT: read out of registers\n");
    cont_run = 0;
    cont_run = 0;
    return 0;
    return 0;
  }
  }
}
}
 
 
/* Implementation specific.
/* Implementation specific.
   Set a specific register with value. */
   Set a specific register with value. */
 
 
void setsim_reg32(int regno, unsigned long value)
void setsim_reg32(int regno, unsigned long value)
{
{
  if (regno == 0)               /* gpr0 is always zero */
  if (regno == 0)               /* gpr0 is always zero */
    value = 0;
    value = 0;
 
 
  if (regno < MAX_GPRS) {
  if (regno < MAX_GPRS) {
    reg[regno] = value;
    reg[regno] = value;
  } else {
  } else {
    printf("\nABORT: write out of registers\n");
    printf("\nABORT: write out of registers\n");
    cont_run = 0;
    cont_run = 0;
  }
  }
}
}
 
 
/* Implementation specific.
/* Implementation specific.
   Get an actual value of a specific register. */
   Get an actual value of a specific register. */
 
 
inline static unsigned long eval_reg32(int regno)
inline static unsigned long eval_reg32(int regno)
{
{
  if (regno < MAX_GPRS) {
  if (regno < MAX_GPRS) {
    IFF(config.cpu.raw_range) {
    IFF(config.cpu.raw_range) {
      int delta = (cycles - raw_stats.reg[regno]);
      int delta = (cycles - raw_stats.reg[regno]);
      if ((unsigned long)delta < (unsigned long)config.cpu.raw_range)
      if ((unsigned long)delta < (unsigned long)config.cpu.raw_range)
        raw_stats.range[delta]++;
        raw_stats.range[delta]++;
    }
    }
    debug(9, "atoi ret1\n");
    debug(9, "atoi ret1\n");
    return reg[regno];
    return reg[regno];
  } else {
  } else {
    printf("\nABORT: read out of registers\n");
    printf("\nABORT: read out of registers\n");
    cont_run = 0;
    cont_run = 0;
    return 0;
    return 0;
  }
  }
}
}
 
 
/* Implementation specific.
/* Implementation specific.
   Set a specific register with value. */
   Set a specific register with value. */
 
 
inline static void set_reg32(int regno, unsigned long value)
inline static void set_reg32(int regno, unsigned long value)
{
{
#if 0   
#if 0   
  if (strcmp(regstr, FRAME_REG) == 0) {
  if (strcmp(regstr, FRAME_REG) == 0) {
    printf("FP (%s) modified by insn at %x. ", FRAME_REG, pc);
    printf("FP (%s) modified by insn at %x. ", FRAME_REG, pc);
    printf("Old:%.8lx  New:%.8lx\n", eval_reg(regno), value);
    printf("Old:%.8lx  New:%.8lx\n", eval_reg(regno), value);
  }
  }
 
 
  if (strcmp(regstr, STACK_REG) == 0) {
  if (strcmp(regstr, STACK_REG) == 0) {
    printf("SP (%s) modified by insn at %x. ", STACK_REG, pc);
    printf("SP (%s) modified by insn at %x. ", STACK_REG, pc);
    printf("Old:%.8lx  New:%.8lx\n", eval_reg(regmo), value);
    printf("Old:%.8lx  New:%.8lx\n", eval_reg(regmo), value);
  }
  }
#endif
#endif
 
 
  if (regno < MAX_GPRS) {
  if (regno < MAX_GPRS) {
    reg[regno] = value;
    reg[regno] = value;
    IFF(config.cpu.raw_range)
    IFF(config.cpu.raw_range)
      raw_stats.reg[regno] = cycles;
      raw_stats.reg[regno] = cycles;
  } else {
  } else {
    printf("\nABORT: write out of registers\n");
    printf("\nABORT: write out of registers\n");
    cont_run = 0;
    cont_run = 0;
  }
  }
}
}
 
 
/* Does srcoperand depend on computation of dstoperand? Return
/* Does srcoperand depend on computation of dstoperand? Return
   non-zero if yes.
   non-zero if yes.
 
 
 Cycle t                 Cycle t+1
 Cycle t                 Cycle t+1
dst: irrelevant         src: immediate                  always 0
dst: irrelevant         src: immediate                  always 0
dst: reg1 direct        src: reg2 direct                0 if reg1 != reg2
dst: reg1 direct        src: reg2 direct                0 if reg1 != reg2
dst: reg1 disp          src: reg2 direct                always 0
dst: reg1 disp          src: reg2 direct                always 0
dst: reg1 direct        src: reg2 disp                  0 if reg1 != reg2
dst: reg1 direct        src: reg2 disp                  0 if reg1 != reg2
dst: reg1 disp          src: reg2 disp                  always 1 (store must
dst: reg1 disp          src: reg2 disp                  always 1 (store must
                                                        finish before load)
                                                        finish before load)
dst: flag               src: flag                       always 1
dst: flag               src: flag                       always 1
*/
*/
 
 
int depend_operands(prev, next)
int depend_operands(prev, next)
     struct iqueue_entry *prev;
     struct iqueue_entry *prev;
     struct iqueue_entry *next;
     struct iqueue_entry *next;
{
{
  /* Find destination type. */
  /* Find destination type. */
  unsigned long type = 0;
  unsigned long type = 0;
  int i = 0;
  int i = 0;
  if (or32_opcodes[prev->insn_index].flags & OR32_W_FLAG
  if (or32_opcodes[prev->insn_index].flags & OR32_W_FLAG
      && or32_opcodes[next->insn_index].flags & OR32_R_FLAG)
      && or32_opcodes[next->insn_index].flags & OR32_R_FLAG)
    return 1;
    return 1;
 
 
  while (!(prev->op[i + MAX_OPERANDS] & OPTYPE_LAST))
  while (!(prev->op[i + MAX_OPERANDS] & OPTYPE_LAST))
    if (prev->op[i + MAX_OPERANDS] & OPTYPE_DST)
    if (prev->op[i + MAX_OPERANDS] & OPTYPE_DST)
      {
      {
        type = prev->op[i + MAX_OPERANDS];
        type = prev->op[i + MAX_OPERANDS];
        break;
        break;
      }
      }
    else
    else
      i++;
      i++;
 
 
  /* We search all source operands - if we find confict => return 1 */
  /* We search all source operands - if we find confict => return 1 */
  i = 0;
  i = 0;
  while (!(next->op[i + MAX_OPERANDS] & OPTYPE_LAST))
  while (!(next->op[i + MAX_OPERANDS] & OPTYPE_LAST))
    if (!(next->op[i + MAX_OPERANDS] & OPTYPE_DST))
    if (!(next->op[i + MAX_OPERANDS] & OPTYPE_DST))
      {
      {
        if (next->op[i + MAX_OPERANDS] & OPTYPE_DIS)
        if (next->op[i + MAX_OPERANDS] & OPTYPE_DIS)
          if (type & OPTYPE_DIS)
          if (type & OPTYPE_DIS)
            return 1;
            return 1;
          else if (next->op[i] == prev->op[i]
          else if (next->op[i] == prev->op[i]
                   && (next->op[i + MAX_OPERANDS] & OPTYPE_REG))
                   && (next->op[i + MAX_OPERANDS] & OPTYPE_REG))
            return 1;
            return 1;
        if (next->op[i] == prev->op[i]
        if (next->op[i] == prev->op[i]
            && (next->op[i + MAX_OPERANDS] & OPTYPE_REG)
            && (next->op[i + MAX_OPERANDS] & OPTYPE_REG)
            && (type & OPTYPE_REG))
            && (type & OPTYPE_REG))
          return 1;
          return 1;
        i++;
        i++;
      }
      }
    else
    else
      i++;
      i++;
  return 0;
  return 0;
}
}
 
 
/* Implementation specific.
/* Implementation specific.
   Parses and returns operands. */
   Parses and returns operands. */
 
 
static void
static void
eval_operands (unsigned long insn, int insn_index, int* breakpoint)
eval_operands (unsigned long insn, int insn_index, int* breakpoint)
{
{
  struct insn_op_struct *opd = op_start[insn_index];
  struct insn_op_struct *opd = op_start[insn_index];
  unsigned long data = 0;
  unsigned long data = 0;
  int dis = 0;
  int dis = 0;
  int no = 0;
  int no = 0;
 
 
  while (1)
  while (1)
    {
    {
      unsigned long tmp = 0, nbits = 0;
      unsigned long tmp = 0, nbits = 0;
      while (1)
      while (1)
        {
        {
          tmp |= ((insn  >> (opd->type & OPTYPE_SHR)) & ((1 << opd->data) - 1)) << nbits;
          tmp |= ((insn  >> (opd->type & OPTYPE_SHR)) & ((1 << opd->data) - 1)) << nbits;
          nbits += opd->data;
          nbits += opd->data;
          if (opd->type & OPTYPE_OP)
          if (opd->type & OPTYPE_OP)
            break;
            break;
          opd++;
          opd++;
        }
        }
 
 
      /* Do we have to sign extend? */
      /* Do we have to sign extend? */
      if (opd->type & OPTYPE_SIG)
      if (opd->type & OPTYPE_SIG)
        {
        {
          int sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
          int sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
          if (tmp & (1 << sbit))
          if (tmp & (1 << sbit))
            tmp |= 0xFFFFFFFF << sbit;
            tmp |= 0xFFFFFFFF << sbit;
        }
        }
      if (opd->type & OPTYPE_DIS) {
      if (opd->type & OPTYPE_DIS) {
        /* We have to read register later.  */
        /* We have to read register later.  */
        data += tmp;
        data += tmp;
        dis = 1;
        dis = 1;
      } else
      } else
        {
        {
          if (dis && (opd->type & OPTYPE_REG))
          if (dis && (opd->type & OPTYPE_REG))
            op[no] = data + eval_reg32 (tmp);
            op[no] = data + eval_reg32 (tmp);
          else
          else
            op[no] = tmp;
            op[no] = tmp;
          op[no + MAX_OPERANDS] = opd->type | (dis ? OPTYPE_DIS : 0);
          op[no + MAX_OPERANDS] = opd->type | (dis ? OPTYPE_DIS : 0);
          no++;
          no++;
          data = 0;
          data = 0;
          dis = 0;
          dis = 0;
        }
        }
      if(opd->type & OPTYPE_LAST)
      if(opd->type & OPTYPE_LAST)
        return;
        return;
      opd++;
      opd++;
    }
    }
  num_op = no;
  num_op = no;
}
}
 
 
/* Implementation specific.
/* Implementation specific.
   Evaluates source operand op_no. */
   Evaluates source operand op_no. */
 
 
inline static unsigned long eval_operand32 (int op_no, int *breakpoint)
inline static unsigned long eval_operand32 (int op_no, int *breakpoint)
{
{
  debug (9, "%i %08X\n", op_no, op[op_no + MAX_OPERANDS]);
  debug (9, "%i %08X\n", op_no, op[op_no + MAX_OPERANDS]);
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS)
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS)
    /* memory accesses are not cached */
    /* memory accesses are not cached */
    return eval_mem32 (op[op_no], breakpoint);
    return eval_mem32 (op[op_no], breakpoint);
  else if (op[op_no + MAX_OPERANDS] & OPTYPE_REG) {
  else if (op[op_no + MAX_OPERANDS] & OPTYPE_REG) {
    return eval_reg32 (op[op_no]);
    return eval_reg32 (op[op_no]);
  } else {
  } else {
    return op[op_no];
    return op[op_no];
  }
  }
}
}
 
 
/* Implementation specific.
/* Implementation specific.
   Evaluates source operand op_no. */
   Evaluates source operand op_no. */
 
 
static unsigned long eval_operand16 (int op_no, int *breakpoint)
static unsigned long eval_operand16 (int op_no, int *breakpoint)
{
{
  debug (9, "%i %08X\n", op_no, op[op_no + MAX_OPERANDS]);
  debug (9, "%i %08X\n", op_no, op[op_no + MAX_OPERANDS]);
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) {
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) {
    return eval_mem16 (op[op_no], breakpoint);
    return eval_mem16 (op[op_no], breakpoint);
  }
  }
  else {
  else {
    fprintf (stderr, "Invalid operand type.\n");
    fprintf (stderr, "Invalid operand type.\n");
    exit (1);
    exit (1);
  }
  }
}
}
 
 
/* Implementation specific.
/* Implementation specific.
   Evaluates source operand op_no. */
   Evaluates source operand op_no. */
 
 
static unsigned long eval_operand8 (int op_no, int *breakpoint)
static unsigned long eval_operand8 (int op_no, int *breakpoint)
{
{
  debug (9, "%i %08X\n", op_no, op[op_no + MAX_OPERANDS]);
  debug (9, "%i %08X\n", op_no, op[op_no + MAX_OPERANDS]);
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS)
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS)
    return eval_mem8 (op[op_no], breakpoint);
    return eval_mem8 (op[op_no], breakpoint);
  else {
  else {
    fprintf (stderr, "Invalid operand type.\n");
    fprintf (stderr, "Invalid operand type.\n");
    exit (1);
    exit (1);
  }
  }
}
}
 
 
/* Implementation specific.
/* Implementation specific.
   Set destination operand (register direct, register indirect
   Set destination operand (register direct, register indirect
   (with displacement) with value. */
   (with displacement) with value. */
 
 
inline static void set_operand32(int op_no, unsigned long value, int* breakpoint)
inline static void set_operand32(int op_no, unsigned long value, int* breakpoint)
{
{
  /* Mark this as destination operand.  */
  /* Mark this as destination operand.  */
  IFF (config.cpu.dependstats) op[op_no + MAX_OPERANDS] |= OPTYPE_DST;
  IFF (config.cpu.dependstats) op[op_no + MAX_OPERANDS] |= OPTYPE_DST;
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) {
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) {
    set_mem32(op[op_no], value, breakpoint);
    set_mem32(op[op_no], value, breakpoint);
  } else if (op[op_no + MAX_OPERANDS] & OPTYPE_REG) {
  } else if (op[op_no + MAX_OPERANDS] & OPTYPE_REG) {
    set_reg32(op[op_no], value);
    set_reg32(op[op_no], value);
  } else {
  } else {
    fprintf (stderr, "Invalid operand type.\n");
    fprintf (stderr, "Invalid operand type.\n");
    exit (1);
    exit (1);
  }
  }
}
}
 
 
/* Implementation specific.
/* Implementation specific.
   Set destination operand (register direct, register indirect
   Set destination operand (register direct, register indirect
   (with displacement) with value. */
   (with displacement) with value. */
 
 
void set_operand16(int op_no, unsigned long value, int* breakpoint)
void set_operand16(int op_no, unsigned long value, int* breakpoint)
{
{
  /* Mark this as destination operand.  */
  /* Mark this as destination operand.  */
  op[op_no + MAX_OPERANDS] |= OPTYPE_DST;
  op[op_no + MAX_OPERANDS] |= OPTYPE_DST;
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) {
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) {
    set_mem16(op[op_no], value, breakpoint);
    set_mem16(op[op_no], value, breakpoint);
  }
  }
  else
  else
    {
    {
      fprintf (stderr, "Invalid operand type.\n");
      fprintf (stderr, "Invalid operand type.\n");
      exit (1);
      exit (1);
    }
    }
}
}
 
 
/* Implementation specific.
/* Implementation specific.
   Set destination operand (register direct, register indirect
   Set destination operand (register direct, register indirect
   (with displacement) with value. */
   (with displacement) with value. */
 
 
void set_operand8(int op_no, unsigned long value, int* breakpoint)
void set_operand8(int op_no, unsigned long value, int* breakpoint)
{
{
  /* Mark this as destination operand.  */
  /* Mark this as destination operand.  */
  op[op_no + MAX_OPERANDS] |= OPTYPE_DST;
  op[op_no + MAX_OPERANDS] |= OPTYPE_DST;
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS)
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS)
    set_mem8(op[op_no], value, breakpoint);
    set_mem8(op[op_no], value, breakpoint);
  else
  else
    {
    {
      fprintf (stderr, "Invalid operand type.\n");
      fprintf (stderr, "Invalid operand type.\n");
      exit (1);
      exit (1);
    }
    }
}
}
 
 
/* Sets a new SPR_SR_OV value, based on next register value */
/* Sets a new SPR_SR_OV value, based on next register value */
static inline unsigned long set_ov_flag (unsigned long value)
static inline unsigned long set_ov_flag (unsigned long value)
{
{
#if SET_OV_FLAG
#if SET_OV_FLAG
  value & 0x80000000 ? setsprbits (SPR_SR, SPR_SR_OV, 1) : setsprbits (SPR_SR, SPR_SR_OV, 0);
  value & 0x80000000 ? setsprbits (SPR_SR, SPR_SR_OV, 1) : setsprbits (SPR_SR, SPR_SR_OV, 0);
#endif
#endif
  return value;
  return value;
}
}
 
 
/* Modified by CZ 26/05/01 for new mode execution */
/* Modified by CZ 26/05/01 for new mode execution */
/* Fetch returns nonzero if instruction should NOT be executed.  */
/* Fetch returns nonzero if instruction should NOT be executed.  */
static inline int fetch()
static inline int fetch()
{
{
  struct mem_entry *entry;
  struct mem_entry *entry;
  debug(5, "fetch()\n");
  debug(5, "fetch()\n");
 
 
  /* Update the pc for pending exceptions, or get physical pc */
  /* Update the pc for pending exceptions, or get physical pc */
  if (!pending.valid)
  if (!pending.valid)
    pc_phy = immu_translate(pc, 0);
    pc_phy = immu_translate(pc, 0);
 
 
  if(pending.valid)
  if(pending.valid)
    except_handle_backend(pending.type, pending.address, pending.saved);
    except_handle_backend(pending.type, pending.address, pending.saved);
 
 
  if (CHECK_BREAKPOINTS) {
  if (CHECK_BREAKPOINTS) {
    /* MM: Check for breakpoint.  This has to be done in fetch cycle,
    /* MM: Check for breakpoint.  This has to be done in fetch cycle,
       because of peripheria.
       because of peripheria.
       MM1709: if we cannot access the memory entry, we could not set the
       MM1709: if we cannot access the memory entry, we could not set the
       breakpoint earlier, so just chech the breakpoint list.  */
       breakpoint earlier, so just chech the breakpoint list.  */
    if (has_breakpoint (pc_phy) && !break_just_hit) {
    if (has_breakpoint (pc_phy) && !break_just_hit) {
      break_just_hit = 1;
      break_just_hit = 1;
      return 1; /* Breakpoint set. */
      return 1; /* Breakpoint set. */
    }
    }
    break_just_hit = 0;
    break_just_hit = 0;
  }
  }
  instructions++;
  instructions++;
 
 
  pc_phy &= ~0x03;
  pc_phy &= ~0x03;
 
 
  /* Fetch instruction. */
  /* Fetch instruction. */
  iqueue[0].insn_addr = pc;
  iqueue[0].insn_addr = pc;
  iqueue[0].insn = eval_insn (pc_phy, &breakpoint);;
  iqueue[0].insn = eval_insn (pc_phy, &breakpoint);;
 
 
  /* update_pc will be called after execution */
  /* update_pc will be called after execution */
 
 
  return 0;
  return 0;
}
}
 
 
/* This code actually updates the PC value.  */
/* This code actually updates the PC value.  */
static inline void update_pc ()
static inline void update_pc ()
{
{
  pcprev = pc; /* Store value for later */
  pcprev = pc; /* Store value for later */
  pc = pcnext;
  pc = pcnext;
  pcnext = delay_insn ? pcdelay : pcnext + 4;
  pcnext = delay_insn ? pcdelay : pcnext + 4;
}
}
 
 
static inline void analysis ()
static inline void analysis ()
{
{
  if (config.cpu.dependstats)
  if (config.cpu.dependstats)
    /* Instruction waits in completition buffer until retired. */
    /* Instruction waits in completition buffer until retired. */
    memcpy (&icomplet[0], &iqueue[0], sizeof (struct iqueue_entry));
    memcpy (&icomplet[0], &iqueue[0], sizeof (struct iqueue_entry));
 
 
  if (config.sim.history) {
  if (config.sim.history) {
    int i;
    int i;
 
 
    /* History of execution */
    /* History of execution */
    for (i = HISTEXEC_LEN - 1; i; i--)
    for (i = HISTEXEC_LEN - 1; i; i--)
      histexec[i] = histexec[i - 1];
      histexec[i] = histexec[i - 1];
    histexec[0] = icomplet[0].insn_addr;        /* add last insn */
    histexec[0] = icomplet[0].insn_addr;        /* add last insn */
  }
  }
}
}
 
 
/* Store buffer analysis - stores are accumulated and commited when IO is idle */
/* Store buffer analysis - stores are accumulated and commited when IO is idle */
static inline sbuf_store (int cyc) {
static inline sbuf_store (int cyc) {
  int delta = cycles - sbuf_prev_cycles;
  int delta = cycles - sbuf_prev_cycles;
  sbuf_total_cyc += cyc;
  sbuf_total_cyc += cyc;
  sbuf_prev_cycles = cycles;
  sbuf_prev_cycles = cycles;
 
 
  //printf (">STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
  //printf (">STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
  //printf ("|%i,%i\n", sbuf_total_cyc, sbuf_wait_cyc);
  //printf ("|%i,%i\n", sbuf_total_cyc, sbuf_wait_cyc);
  /* Take stores from buffer, that occured meanwhile */
  /* Take stores from buffer, that occured meanwhile */
  while (sbuf_count && delta >= sbuf_buf[sbuf_tail]) {
  while (sbuf_count && delta >= sbuf_buf[sbuf_tail]) {
    delta -= sbuf_buf[sbuf_tail];
    delta -= sbuf_buf[sbuf_tail];
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
    sbuf_count--;
    sbuf_count--;
  }
  }
  if (sbuf_count)
  if (sbuf_count)
    sbuf_buf[sbuf_tail] -= delta;
    sbuf_buf[sbuf_tail] -= delta;
 
 
  /* Store buffer is full, take one out */
  /* Store buffer is full, take one out */
  if (sbuf_count >= config.cpu.sbuf_len) {
  if (sbuf_count >= config.cpu.sbuf_len) {
    sbuf_wait_cyc += sbuf_buf[sbuf_tail];
    sbuf_wait_cyc += sbuf_buf[sbuf_tail];
    mem_cycles += sbuf_buf[sbuf_tail];
    mem_cycles += sbuf_buf[sbuf_tail];
    sbuf_prev_cycles += sbuf_buf[sbuf_tail];
    sbuf_prev_cycles += sbuf_buf[sbuf_tail];
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
    sbuf_count--;
    sbuf_count--;
  }
  }
  /* Put newest store in the buffer */
  /* Put newest store in the buffer */
  sbuf_buf[sbuf_head] = cyc;
  sbuf_buf[sbuf_head] = cyc;
  sbuf_head = (sbuf_head + 1) % MAX_SBUF_LEN;
  sbuf_head = (sbuf_head + 1) % MAX_SBUF_LEN;
  sbuf_count++;
  sbuf_count++;
  //printf ("|STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
  //printf ("|STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
}
}
 
 
/* Store buffer analysis - previous stores should commit, before any load */
/* Store buffer analysis - previous stores should commit, before any load */
static inline sbuf_load () {
static inline sbuf_load () {
  int delta = cycles - sbuf_prev_cycles;
  int delta = cycles - sbuf_prev_cycles;
  sbuf_prev_cycles = cycles;
  sbuf_prev_cycles = cycles;
 
 
  //printf (">LOAD  %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
  //printf (">LOAD  %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
  //printf ("|%i,%i\n", sbuf_total_cyc, sbuf_wait_cyc);
  //printf ("|%i,%i\n", sbuf_total_cyc, sbuf_wait_cyc);
  /* Take stores from buffer, that occured meanwhile */
  /* Take stores from buffer, that occured meanwhile */
  while (sbuf_count && delta >= sbuf_buf[sbuf_tail]) {
  while (sbuf_count && delta >= sbuf_buf[sbuf_tail]) {
    delta -= sbuf_buf[sbuf_tail];
    delta -= sbuf_buf[sbuf_tail];
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
    sbuf_count--;
    sbuf_count--;
  }
  }
  if (sbuf_count)
  if (sbuf_count)
    sbuf_buf[sbuf_tail] -= delta;
    sbuf_buf[sbuf_tail] -= delta;
 
 
  /* Wait for all stores to complete */
  /* Wait for all stores to complete */
  while (sbuf_count > 0) {
  while (sbuf_count > 0) {
    sbuf_wait_cyc += sbuf_buf[sbuf_tail];
    sbuf_wait_cyc += sbuf_buf[sbuf_tail];
    mem_cycles += sbuf_buf[sbuf_tail];
    mem_cycles += sbuf_buf[sbuf_tail];
    sbuf_prev_cycles += sbuf_buf[sbuf_tail];
    sbuf_prev_cycles += sbuf_buf[sbuf_tail];
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
    sbuf_count--;
    sbuf_count--;
  }
  }
  //printf ("|LOAD  %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
  //printf ("|LOAD  %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
}
}
 
 
/* Execution logger.  */
/* Execution logger.  */
inline void dump_exe_log()
inline void dump_exe_log()
{
{
  unsigned long i = iqueue[0].insn_addr;
  unsigned long i = iqueue[0].insn_addr;
 
 
  if (i == 0xffffffff) return;
  if (i == 0xffffffff) return;
  if (config.sim.exe_log_marker && instructions % config.sim.exe_log_marker == 0) {
  if (config.sim.exe_log_marker && instructions % config.sim.exe_log_marker == 0) {
    fprintf (runtime.sim.fexe_log, "--------------------- %8i instruction ---------------------\n");
    fprintf (runtime.sim.fexe_log, "--------------------- %8i instruction ---------------------\n", instructions);
  }
  }
  if (config.sim.exe_log_start <= instructions && (config.sim.exe_log_end <= 0 || instructions <= config.sim.exe_log_end)) {
  if (config.sim.exe_log_start <= instructions && (config.sim.exe_log_end <= 0 || instructions <= config.sim.exe_log_end)) {
    switch (config.sim.exe_log_type) {
    switch (config.sim.exe_log_type) {
    case EXE_LOG_HARDWARE:
    case EXE_LOG_HARDWARE:
      fprintf (runtime.sim.fexe_log, "\nEXECUTED(): %.8lx:  ", i);
      fprintf (runtime.sim.fexe_log, "\nEXECUTED(): %.8lx:  ", i);
      fprintf (runtime.sim.fexe_log, "%.2x%.2x", evalsim_mem8(i), evalsim_mem8(i + 1));
      fprintf (runtime.sim.fexe_log, "%.2x%.2x", evalsim_mem8(i), evalsim_mem8(i + 1));
      fprintf (runtime.sim.fexe_log, "%.2x%.2x", evalsim_mem8(i + 2), evalsim_mem8(i + 3));
      fprintf (runtime.sim.fexe_log, "%.2x%.2x", evalsim_mem8(i + 2), evalsim_mem8(i + 3));
      for(i = 0; i < MAX_GPRS; i++) {
      for(i = 0; i < MAX_GPRS; i++) {
        if (i % 4 == 0)
        if (i % 4 == 0)
          fprintf(runtime.sim.fexe_log, "\n");
          fprintf(runtime.sim.fexe_log, "\n");
        fprintf (runtime.sim.fexe_log, "GPR%2u: %.8lx  ", i, reg[i]);
        fprintf (runtime.sim.fexe_log, "GPR%2u: %.8lx  ", i, reg[i]);
      }
      }
      fprintf (runtime.sim.fexe_log, "\n");
      fprintf (runtime.sim.fexe_log, "\n");
      fprintf (runtime.sim.fexe_log, "SR   : %.8lx  ", mfspr(SPR_SR));
      fprintf (runtime.sim.fexe_log, "SR   : %.8lx  ", mfspr(SPR_SR));
      fprintf (runtime.sim.fexe_log, "EPCR0: %.8lx  ", mfspr(SPR_EPCR_BASE));
      fprintf (runtime.sim.fexe_log, "EPCR0: %.8lx  ", mfspr(SPR_EPCR_BASE));
      fprintf (runtime.sim.fexe_log, "EEAR0: %.8lx  ", mfspr(SPR_EEAR_BASE));
      fprintf (runtime.sim.fexe_log, "EEAR0: %.8lx  ", mfspr(SPR_EEAR_BASE));
      fprintf (runtime.sim.fexe_log, "ESR0 : %.8lx\n", mfspr(SPR_ESR_BASE));
      fprintf (runtime.sim.fexe_log, "ESR0 : %.8lx\n", mfspr(SPR_ESR_BASE));
      break;
      break;
    case EXE_LOG_SIMPLE:
    case EXE_LOG_SIMPLE:
    case EXE_LOG_SOFTWARE:
    case EXE_LOG_SOFTWARE:
      {
      {
        int labels = 0;
        int labels = 0;
        if (verify_memoryarea(i)) {
        if (verify_memoryarea(i)) {
          struct label_entry *entry;
          struct label_entry *entry;
          entry = get_label(i);
          entry = get_label(i);
          if (entry) {
          if (entry) {
            fprintf (runtime.sim.fexe_log, "%s: ", entry->name);
            fprintf (runtime.sim.fexe_log, "%s: ", entry->name);
            labels++;
            labels++;
          }
          }
        } else {
        } else {
          fprintf (runtime.sim.fexe_log, "<invalid addr>: ");
          fprintf (runtime.sim.fexe_log, "<invalid addr>: ");
          labels++;
          labels++;
        }
        }
 
 
        if (labels) fprintf (runtime.sim.fexe_log, "\n");
        if (labels) fprintf (runtime.sim.fexe_log, "\n");
 
 
        if (config.sim.exe_log_type == EXE_LOG_SOFTWARE) {
        if (config.sim.exe_log_type == EXE_LOG_SOFTWARE) {
          int i, nregs = 0;
          int i;
          for (i = 0; i < 3; i++)
          for (i = 0; i < num_op; i++)
            if (op[i + MAX_OPERANDS] & OPTYPE_DIS) {
            if (op[i + MAX_OPERANDS] & OPTYPE_DIS) {
              fprintf (runtime.sim.fexe_log, "EA =%08x ", op[i]);
              fprintf (runtime.sim.fexe_log, "EA =%08x ", op[i]);
              nregs++;
 
            } else if ((op[i + MAX_OPERANDS] & OPTYPE_REG) && op[i]) {
            } else if ((op[i + MAX_OPERANDS] & OPTYPE_REG) && op[i]) {
              fprintf (runtime.sim.fexe_log, "r%-2i=%08x ", op[i], evalsim_reg32 (op[i]));
              fprintf (runtime.sim.fexe_log, "r%-2i=%08x ", op[i], evalsim_reg32 (op[i]));
              nregs++;
 
            } else
            } else
            fprintf (runtime.sim.fexe_log, "             ");
            fprintf (runtime.sim.fexe_log, "             ");
 
          for (; i < 3; i++)
 
            fprintf (runtime.sim.fexe_log, "             ");
        }
        }
 
 
        fprintf (runtime.sim.fexe_log, "%.8lx ", i);
        fprintf (runtime.sim.fexe_log, "%.8lx ", i);
        if (index >= 0) {
        if (index >= 0) {
          extern char *disassembled;
          extern char *disassembled;
          disassemble_insn (iqueue[0].insn);
          disassemble_insn (iqueue[0].insn);
          fprintf (runtime.sim.fexe_log, "%s\n", disassembled);
          fprintf (runtime.sim.fexe_log, "%s\n", disassembled);
        } else
        } else
          fprintf (runtime.sim.fexe_log, "<invalid>\n");
          fprintf (runtime.sim.fexe_log, "<invalid>\n");
      }
      }
    }
    }
  }
  }
}
}
 
 
#if 0
#if 0
void print_time (int cycles, char *output)
void print_time (int cycles, char *output)
{
{
  int i = 0, c_ps = config.sim.clkcycle_ps;
  int i = 0, c_ps = config.sim.clkcycle_ps;
  while (c_ps % 1000 == 0 && i < 2) {
  while (c_ps % 1000 == 0 && i < 2) {
    c_ps /= 1000;
    c_ps /= 1000;
    i++;
    i++;
  }
  }
  c_ps *= cycles;
  c_ps *= cycles;
  sprintf (output, "%i%cs", cycles, i == 0 ? 'p' : i == 1 ? 'n': 'u');
  sprintf (output, "%i%cs", cycles, i == 0 ? 'p' : i == 1 ? 'n': 'u');
}
}
#endif
#endif
 
 
void dumpreg()
void dumpreg()
{
{
  int i;
  int i;
  char temp[100];
  char temp[100];
 
 
  dumpmemory(iqueue[0].insn_addr, iqueue[0].insn_addr + 4, 1, 0);
  dumpmemory(iqueue[0].insn_addr, iqueue[0].insn_addr + 4, 1, 0);
  generate_time_pretty (temp, cycles);
  generate_time_pretty (temp, cycles);
  printf(" (executed) [time %s, #%i]\n", temp, instructions);
  printf(" (executed) [time %s, #%i]\n", temp, instructions);
  if (config.cpu.superscalar)
  if (config.cpu.superscalar)
    printf ("Superscalar CYCLES: %u", supercycles);
    printf ("Superscalar CYCLES: %u", supercycles);
  if (config.cpu.hazards)
  if (config.cpu.hazards)
    printf ("  HAZARDWAIT: %u\n", hazardwait);
    printf ("  HAZARDWAIT: %u\n", hazardwait);
  else
  else
    if (config.cpu.superscalar)
    if (config.cpu.superscalar)
      printf ("\n");
      printf ("\n");
 
 
  dumpmemory(pc, pc + 4, 1, 0);
  dumpmemory(pc, pc + 4, 1, 0);
  printf(" (next insn) %s", (delay_insn?"(delay insn)":""));
  printf(" (next insn) %s", (delay_insn?"(delay insn)":""));
  for(i = 0; i < MAX_GPRS; i++) {
  for(i = 0; i < MAX_GPRS; i++) {
    if (i % 4 == 0)
    if (i % 4 == 0)
      printf("\n");
      printf("\n");
    printf("GPR%.2u: %.8lx  ", i, evalsim_reg32(i));
    printf("GPR%.2u: %.8lx  ", i, evalsim_reg32(i));
  }
  }
  printf("flag: %u\n", flag);
  printf("flag: %u\n", flag);
}
}
 
 
/* Address calculation changed by CZ on 27/05/01 */
/* Address calculation changed by CZ on 27/05/01 */
static inline void decode_execute(struct iqueue_entry *current)
static inline void decode_execute(struct iqueue_entry *current)
{
{
  int insn_index;
  int insn_index;
  next_delay_insn = 0;
  next_delay_insn = 0;
  breakpoint = 0;
  breakpoint = 0;
 
 
  if(config.debug.enabled && CheckDebugUnit(DebugInstructionFetch, pc_phy))
  if(config.debug.enabled && CheckDebugUnit(DebugInstructionFetch, pc_phy))
    breakpoint++;
    breakpoint++;
 
 
  IFF (config.cpu.dependstats) current->func_unit = it_unknown;
  IFF (config.cpu.dependstats) current->func_unit = it_unknown;
 
 
  current->insn_index = insn_index = insn_decode(current->insn);
  current->insn_index = insn_index = insn_decode(current->insn);
 
 
#ifndef HAS_EXECUTION
#ifndef HAS_EXECUTION
#error HAS_EXECUTION has to be defined in order to execute programs.
#error HAS_EXECUTION has to be defined in order to execute programs.
#endif
#endif
 
 
  cur = current;  /* globals; needed by eval/set_operand */
  cur = current;  /* globals; needed by eval/set_operand */
 
 
  if (insn_index < 0)
  if (insn_index < 0)
    l_invalid();
    l_invalid();
  else {
  else {
    op = &cur->op[0];
    op = &cur->op[0];
    eval_operands (cur->insn, insn_index, &breakpoint);
    eval_operands (cur->insn, insn_index, &breakpoint);
    or32_opcodes[insn_index].exec();
    or32_opcodes[insn_index].exec();
  }
  }
 
 
  /* Check for range exception */
  /* Check for range exception */
  if (testsprbits (SPR_SR, SPR_SR_OVE) && testsprbits (SPR_SR, SPR_SR_OV))
  if (testsprbits (SPR_SR, SPR_SR_OVE) && testsprbits (SPR_SR, SPR_SR_OV))
    except_handle (EXCEPT_RANGE, mfspr(SPR_EEAR_BASE));
    except_handle (EXCEPT_RANGE, mfspr(SPR_EEAR_BASE));
 
 
  if (config.cpu.dependstats) {
  if (config.cpu.dependstats) {
    iqueue[0].insn_index = insn_index;
    iqueue[0].insn_index = insn_index;
    /* Dynamic, dependency stats. */
    /* Dynamic, dependency stats. */
    adddstats(icomplet[0].insn_index, iqueue[0].insn_index, 1, check_depend());
    adddstats(icomplet[0].insn_index, iqueue[0].insn_index, 1, check_depend());
 
 
    /* Dynamic, functional units stats. */
    /* Dynamic, functional units stats. */
    addfstats(icomplet[0].func_unit, iqueue[0].func_unit, 1, check_depend());
    addfstats(icomplet[0].func_unit, iqueue[0].func_unit, 1, check_depend());
 
 
    /* Dynamic, single stats. */
    /* Dynamic, single stats. */
    addsstats(iqueue[0].insn_index, 1);
    addsstats(iqueue[0].insn_index, 1);
  }
  }
 
 
  if (config.cpu.superscalar) {
  if (config.cpu.superscalar) {
    if ((cur->func_unit == it_branch) || (cur->func_unit == it_jump))
    if ((cur->func_unit == it_branch) || (cur->func_unit == it_jump))
      storecycles += 0;
      storecycles += 0;
 
 
    if (cur->func_unit == it_store)
    if (cur->func_unit == it_store)
      storecycles += 1;
      storecycles += 1;
 
 
    if (cur->func_unit == it_load)
    if (cur->func_unit == it_load)
      loadcycles += 1;
      loadcycles += 1;
#if 0        
#if 0        
    if ((icomplet[0].func_unit == it_load) && check_depend())
    if ((icomplet[0].func_unit == it_load) && check_depend())
      loadcycles++;
      loadcycles++;
#endif
#endif
 
 
    /* Pseudo multiple issue benchmark */
    /* Pseudo multiple issue benchmark */
    if ((multissue[cur->func_unit] < 1) || (check_depend())
    if ((multissue[cur->func_unit] < 1) || (check_depend())
     || (issued_per_cycle < 1)) {
     || (issued_per_cycle < 1)) {
      int i;
      int i;
      for (i = 0; i < 20; i++)
      for (i = 0; i < 20; i++)
        multissue[i] = 2;
        multissue[i] = 2;
      issued_per_cycle = 2;
      issued_per_cycle = 2;
      supercycles++;
      supercycles++;
      if (check_depend())
      if (check_depend())
        hazardwait++;
        hazardwait++;
      multissue[it_unknown] = 2;
      multissue[it_unknown] = 2;
      multissue[it_shift] = 2;
      multissue[it_shift] = 2;
      multissue[it_compare] = 1;
      multissue[it_compare] = 1;
      multissue[it_branch] = 1;
      multissue[it_branch] = 1;
      multissue[it_jump] = 1;
      multissue[it_jump] = 1;
      multissue[it_extend] = 2;
      multissue[it_extend] = 2;
      multissue[it_nop] = 2;
      multissue[it_nop] = 2;
      multissue[it_move] = 2;
      multissue[it_move] = 2;
      multissue[it_movimm] = 2;
      multissue[it_movimm] = 2;
      multissue[it_arith] = 2;
      multissue[it_arith] = 2;
      multissue[it_store] = 2;
      multissue[it_store] = 2;
      multissue[it_load] = 2;
      multissue[it_load] = 2;
    }
    }
    multissue[cur->func_unit]--;
    multissue[cur->func_unit]--;
    issued_per_cycle--;
    issued_per_cycle--;
  }
  }
  delay_insn = next_delay_insn;
  delay_insn = next_delay_insn;
 
 
  if(breakpoint)
  if(breakpoint)
    except_handle(EXCEPT_TRAP, mfspr(SPR_EEAR_BASE));
    except_handle(EXCEPT_TRAP, mfspr(SPR_EEAR_BASE));
}
}
 
 
void cpu_reset()
void cpu_reset()
{
{
  int i;
  int i;
  cycles = 0;
  cycles = 0;
  instructions = 0;
  instructions = 0;
  supercycles = 0;
  supercycles = 0;
  loadcycles = 0;
  loadcycles = 0;
  storecycles = 0;
  storecycles = 0;
  for (i = 0; i < MAX_GPRS; i++)
  for (i = 0; i < MAX_GPRS; i++)
    set_reg32 (i, 0);
    set_reg32 (i, 0);
  memset(iqueue, 0, sizeof(iqueue));
  memset(iqueue, 0, sizeof(iqueue));
  memset(icomplet, 0, sizeof(icomplet));
  memset(icomplet, 0, sizeof(icomplet));
 
 
  sbuf_head = 0;
  sbuf_head = 0;
  sbuf_tail = 0;
  sbuf_tail = 0;
  sbuf_count = 0;
  sbuf_count = 0;
  sbuf_prev_cycles = 0;
  sbuf_prev_cycles = 0;
 
 
  /* Cpu configuration */
  /* Cpu configuration */
  mtspr(SPR_UPR, config.cpu.upr);
  mtspr(SPR_UPR, config.cpu.upr);
  setsprbits(SPR_VR, SPR_VR_VER, config.cpu.ver);
  setsprbits(SPR_VR, SPR_VR_VER, config.cpu.ver);
  setsprbits(SPR_VR, SPR_VR_REV, config.cpu.rev);
  setsprbits(SPR_VR, SPR_VR_REV, config.cpu.rev);
  mtspr(SPR_SR, config.cpu.sr);
  mtspr(SPR_SR, config.cpu.sr);
 
 
  pcnext = 0x0; /* MM1409: All programs should start at reset vector entry!  */
  pcnext = 0x0; /* MM1409: All programs should start at reset vector entry!  */
  printf ("Starting at 0x%08x\n", pcnext);
  printf ("Starting at 0x%08x\n", pcnext);
  pc = pcnext;
  pc = pcnext;
  pc_phy = pc;
  pc_phy = pc;
  pcnext += 4;
  pcnext += 4;
  debug(1, "reset ...\n");
  debug(1, "reset ...\n");
 
 
  /* MM1409: All programs should set their stack pointer!  */
  /* MM1409: All programs should set their stack pointer!  */
  except_handle(EXCEPT_RESET, 0);
  except_handle(EXCEPT_RESET, 0);
}
}
 
 
inline int cpu_clock ()
inline int cpu_clock ()
{
{
  if(fetch()) {
  if(fetch()) {
    printf ("Breakpoint hit.\n");
    printf ("Breakpoint hit.\n");
    cont_run = 0; /* memory breakpoint encountered */
    cont_run = 0; /* memory breakpoint encountered */
    return 1;
    return 1;
  }
  }
  decode_execute(&iqueue[0]);
  decode_execute(&iqueue[0]);
  update_pc();
  update_pc();
  analysis();
  analysis();
  if (config.sim.exe_log) dump_exe_log();
  if (config.sim.exe_log) dump_exe_log();
  return 0;
  return 0;
}
}
 
 
/******************************************
/******************************************
 *    Instruction specific functions.     *
 *    Instruction specific functions.     *
 ******************************************/
 ******************************************/
 
 
void l_add() {
void l_add() {
  signed long temp1;
  signed long temp1;
  signed char temp4;
  signed char temp4;
 
 
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  temp1 = (signed long)eval_operand32(2, &breakpoint)+(signed long)eval_operand32(1, &breakpoint);
  temp1 = (signed long)eval_operand32(2, &breakpoint)+(signed long)eval_operand32(1, &breakpoint);
  set_operand32(0, temp1, &breakpoint);
  set_operand32(0, temp1, &breakpoint);
  set_ov_flag (temp1);
  set_ov_flag (temp1);
  if (ARITH_SET_FLAG) {
  if (ARITH_SET_FLAG) {
    flag = temp1 == 0;
    flag = temp1 == 0;
    setsprbits(SPR_SR, SPR_SR_F, flag);
    setsprbits(SPR_SR, SPR_SR_F, flag);
  }
  }
 
 
  temp4 = temp1;
  temp4 = temp1;
  if (temp4 == temp1)
  if (temp4 == temp1)
    mstats.byteadd++;
    mstats.byteadd++;
}
}
void l_sw() {
void l_sw() {
  int old_cyc = 0;
  int old_cyc = 0;
  IFF (config.cpu.dependstats) cur->func_unit = it_store;
  IFF (config.cpu.dependstats) cur->func_unit = it_store;
  IFF (config.cpu.sbuf_len) old_cyc = mem_cycles;
  IFF (config.cpu.sbuf_len) old_cyc = mem_cycles;
  set_operand32(0, eval_operand32(1, &breakpoint), &breakpoint);
  set_operand32(0, eval_operand32(1, &breakpoint), &breakpoint);
  if (config.cpu.sbuf_len) {
  if (config.cpu.sbuf_len) {
    int t = mem_cycles;
    int t = mem_cycles;
    mem_cycles = old_cyc;
    mem_cycles = old_cyc;
    sbuf_store (t - old_cyc);
    sbuf_store (t - old_cyc);
  }
  }
}
}
void l_sb() {
void l_sb() {
  int old_cyc = 0;
  int old_cyc = 0;
  IFF (config.cpu.dependstats) cur->func_unit = it_store;
  IFF (config.cpu.dependstats) cur->func_unit = it_store;
  IFF (config.cpu.sbuf_len) old_cyc = mem_cycles;
  IFF (config.cpu.sbuf_len) old_cyc = mem_cycles;
  set_operand8(0, eval_operand32(1, &breakpoint), &breakpoint);
  set_operand8(0, eval_operand32(1, &breakpoint), &breakpoint);
  if (config.cpu.sbuf_len) {
  if (config.cpu.sbuf_len) {
    int t = mem_cycles;
    int t = mem_cycles;
    mem_cycles = old_cyc;
    mem_cycles = old_cyc;
    sbuf_store (t- old_cyc);
    sbuf_store (t- old_cyc);
  }
  }
}
}
void l_sh() {
void l_sh() {
  int old_cyc = 0;
  int old_cyc = 0;
  IFF (config.cpu.dependstats) cur->func_unit = it_store;
  IFF (config.cpu.dependstats) cur->func_unit = it_store;
  IFF (config.cpu.sbuf_len) old_cyc = mem_cycles;
  IFF (config.cpu.sbuf_len) old_cyc = mem_cycles;
  set_operand16(0, eval_operand32(1, &breakpoint), &breakpoint);
  set_operand16(0, eval_operand32(1, &breakpoint), &breakpoint);
  if (config.cpu.sbuf_len) {
  if (config.cpu.sbuf_len) {
    int t = mem_cycles;
    int t = mem_cycles;
    mem_cycles = old_cyc;
    mem_cycles = old_cyc;
    sbuf_store (t - old_cyc);
    sbuf_store (t - old_cyc);
  }
  }
}
}
void l_lwz() {
void l_lwz() {
  unsigned long val;
  unsigned long val;
  IFF (config.cpu.dependstats) cur->func_unit = it_load;
  IFF (config.cpu.dependstats) cur->func_unit = it_load;
  if (config.cpu.sbuf_len) sbuf_load ();
  if (config.cpu.sbuf_len) sbuf_load ();
  val = eval_operand32(1, &breakpoint);
  val = eval_operand32(1, &breakpoint);
  /* If eval operand produced exception don't set anything */
  /* If eval operand produced exception don't set anything */
  if (!pending.valid)
  if (!pending.valid)
    set_operand32(0, val, &breakpoint);
    set_operand32(0, val, &breakpoint);
}
}
void l_lbs() {
void l_lbs() {
  signed char val;
  signed char val;
  IFF (config.cpu.dependstats) cur->func_unit = it_load;
  IFF (config.cpu.dependstats) cur->func_unit = it_load;
  if (config.cpu.sbuf_len) sbuf_load ();
  if (config.cpu.sbuf_len) sbuf_load ();
  val = eval_operand8(1, &breakpoint);
  val = eval_operand8(1, &breakpoint);
  /* If eval opreand produced exception don't set anything */
  /* If eval opreand produced exception don't set anything */
  if (!pending.valid)
  if (!pending.valid)
    set_operand32(0, val, &breakpoint);
    set_operand32(0, val, &breakpoint);
}
}
void l_lbz() {
void l_lbz() {
  unsigned char val;
  unsigned char val;
  IFF (config.cpu.dependstats) cur->func_unit = it_load;
  IFF (config.cpu.dependstats) cur->func_unit = it_load;
  if (config.cpu.sbuf_len) sbuf_load ();
  if (config.cpu.sbuf_len) sbuf_load ();
  val = eval_operand8(1, &breakpoint);
  val = eval_operand8(1, &breakpoint);
  /* If eval opreand produced exception don't set anything */
  /* If eval opreand produced exception don't set anything */
  if (!pending.valid)
  if (!pending.valid)
    set_operand32(0, val, &breakpoint);
    set_operand32(0, val, &breakpoint);
}
}
void l_lhs() {
void l_lhs() {
  signed short val;
  signed short val;
  IFF (config.cpu.dependstats) cur->func_unit = it_load;
  IFF (config.cpu.dependstats) cur->func_unit = it_load;
  if (config.cpu.sbuf_len) sbuf_load ();
  if (config.cpu.sbuf_len) sbuf_load ();
  val = eval_operand16(1, &breakpoint);
  val = eval_operand16(1, &breakpoint);
  /* If eval opreand produced exception don't set anything */
  /* If eval opreand produced exception don't set anything */
  if (!pending.valid)
  if (!pending.valid)
    set_operand32(0, val, &breakpoint);
    set_operand32(0, val, &breakpoint);
}
}
void l_lhz() {
void l_lhz() {
  unsigned short val;
  unsigned short val;
  IFF (config.cpu.dependstats) cur->func_unit = it_load;
  IFF (config.cpu.dependstats) cur->func_unit = it_load;
  if (config.cpu.sbuf_len) sbuf_load ();
  if (config.cpu.sbuf_len) sbuf_load ();
  val = eval_operand16(1, &breakpoint);
  val = eval_operand16(1, &breakpoint);
  /* If eval opreand produced exception don't set anything */
  /* If eval opreand produced exception don't set anything */
  if (!pending.valid)
  if (!pending.valid)
    set_operand32(0, val, &breakpoint);
    set_operand32(0, val, &breakpoint);
}
}
void l_movhi() {
void l_movhi() {
  IFF (config.cpu.dependstats) cur->func_unit = it_movimm;
  IFF (config.cpu.dependstats) cur->func_unit = it_movimm;
  set_operand32(0, eval_operand32(1, &breakpoint) << 16, &breakpoint);
  set_operand32(0, eval_operand32(1, &breakpoint) << 16, &breakpoint);
}
}
void l_and() {
void l_and() {
  unsigned long temp1;
  unsigned long temp1;
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  set_operand32(0, temp1 = set_ov_flag (eval_operand32(1, &breakpoint) & (unsigned)eval_operand32(2, &breakpoint)), &breakpoint);
  set_operand32(0, temp1 = set_ov_flag (eval_operand32(1, &breakpoint) & (unsigned)eval_operand32(2, &breakpoint)), &breakpoint);
  if (ARITH_SET_FLAG) {
  if (ARITH_SET_FLAG) {
    flag = temp1 == 0;
    flag = temp1 == 0;
    setsprbits(SPR_SR, SPR_SR_F, flag);
    setsprbits(SPR_SR, SPR_SR_F, flag);
  }
  }
}
}
void l_or() {
void l_or() {
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  set_operand32(0, set_ov_flag (eval_operand32(1, &breakpoint) | (unsigned)eval_operand32(2, &breakpoint)), &breakpoint);
  set_operand32(0, set_ov_flag (eval_operand32(1, &breakpoint) | (unsigned)eval_operand32(2, &breakpoint)), &breakpoint);
}
}
void l_xor() {
void l_xor() {
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  set_operand32(0, set_ov_flag (eval_operand32(1, &breakpoint) ^ (signed)eval_operand32(2, &breakpoint)), &breakpoint);
  set_operand32(0, set_ov_flag (eval_operand32(1, &breakpoint) ^ (signed)eval_operand32(2, &breakpoint)), &breakpoint);
}
}
void l_sub() {
void l_sub() {
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  set_operand32(0, set_ov_flag ((signed long)eval_operand32(1, &breakpoint) - (signed long)eval_operand32(2, &breakpoint)), &breakpoint);
  set_operand32(0, set_ov_flag ((signed long)eval_operand32(1, &breakpoint) - (signed long)eval_operand32(2, &breakpoint)), &breakpoint);
}
}
/*int mcount = 0;*/
/*int mcount = 0;*/
void l_mul() {
void l_mul() {
  signed long temp3, temp2, temp1;
  signed long temp3, temp2, temp1;
 
 
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  set_operand32(0, set_ov_flag ((signed long)eval_operand32(1, &breakpoint) * (signed long)eval_operand32(2, &breakpoint)), &breakpoint);
  set_operand32(0, set_ov_flag ((signed long)eval_operand32(1, &breakpoint) * (signed long)eval_operand32(2, &breakpoint)), &breakpoint);
  /*if (!(mcount++ & 1023)) {
  /*if (!(mcount++ & 1023)) {
    printf ("[%i]\n",mcount);
    printf ("[%i]\n",mcount);
    }*/
    }*/
}
}
void l_div() {
void l_div() {
  signed long temp3, temp2, temp1;
  signed long temp3, temp2, temp1;
 
 
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  temp3 = eval_operand32(2, &breakpoint);
  temp3 = eval_operand32(2, &breakpoint);
  temp2 = eval_operand32(1, &breakpoint);
  temp2 = eval_operand32(1, &breakpoint);
  if (temp3)
  if (temp3)
    temp1 = temp2 / temp3;
    temp1 = temp2 / temp3;
  else {
  else {
    except_handle(EXCEPT_ILLEGAL, iqueue[0].insn_addr);
    except_handle(EXCEPT_ILLEGAL, iqueue[0].insn_addr);
    return;
    return;
  }
  }
  set_operand32(0, set_ov_flag (temp1), &breakpoint);
  set_operand32(0, set_ov_flag (temp1), &breakpoint);
}
}
void l_divu() {
void l_divu() {
  unsigned long temp3, temp2, temp1;
  unsigned long temp3, temp2, temp1;
 
 
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  IFF (config.cpu.dependstats) cur->func_unit = it_arith;
  temp3 = eval_operand32(2, &breakpoint);
  temp3 = eval_operand32(2, &breakpoint);
  temp2 = eval_operand32(1, &breakpoint);
  temp2 = eval_operand32(1, &breakpoint);
  temp1 = temp2 / temp3;
  temp1 = temp2 / temp3;
  /* cycles += 16; */
  /* cycles += 16; */
  set_operand32(0, set_ov_flag (temp1), &breakpoint);
  set_operand32(0, set_ov_flag (temp1), &breakpoint);
}
}
void l_sll() {
void l_sll() {
  int sign = 1;
  int sign = 1;
  IFF (config.cpu.dependstats) cur->func_unit = it_shift;
  IFF (config.cpu.dependstats) cur->func_unit = it_shift;
  if ((signed)eval_operand32(1, &breakpoint) < 0)
  if ((signed)eval_operand32(1, &breakpoint) < 0)
    sign = -1;
    sign = -1;
  /* cycles += 2; */
  /* cycles += 2; */
  set_operand32(0, set_ov_flag (eval_operand32(1, &breakpoint) << eval_operand32(2, &breakpoint)), &breakpoint);
  set_operand32(0, set_ov_flag (eval_operand32(1, &breakpoint) << eval_operand32(2, &breakpoint)), &breakpoint);
}
}
void l_sra() {
void l_sra() {
  unsigned long sign = 0;
  unsigned long sign = 0;
  IFF (config.cpu.dependstats) cur->func_unit = it_shift;
  IFF (config.cpu.dependstats) cur->func_unit = it_shift;
 
 
  if ((signed)eval_operand32(1, &breakpoint) < 0)
  if ((signed)eval_operand32(1, &breakpoint) < 0)
    sign = -1;
    sign = -1;
  /* cycles += 2; */
  /* cycles += 2; */
  set_operand32(0, set_ov_flag ((signed)eval_operand32(1, &breakpoint) >> eval_operand32(2, &breakpoint)), &breakpoint);
  set_operand32(0, set_ov_flag ((signed)eval_operand32(1, &breakpoint) >> eval_operand32(2, &breakpoint)), &breakpoint);
}
}
void l_srl() {
void l_srl() {
  IFF (config.cpu.dependstats) cur->func_unit = it_shift;
  IFF (config.cpu.dependstats) cur->func_unit = it_shift;
  /* cycles += 2; */
  /* cycles += 2; */
  set_operand32(0, set_ov_flag (eval_operand32(1, &breakpoint) >> eval_operand32(2, &breakpoint)), &breakpoint);
  set_operand32(0, set_ov_flag (eval_operand32(1, &breakpoint) >> eval_operand32(2, &breakpoint)), &breakpoint);
}
}
void l_bf() {
void l_bf() {
  if (config.bpb.enabled) {
  if (config.bpb.enabled) {
    int fwd = (eval_operand32(0, &breakpoint) >= pc) ? 1 : 0;
    int fwd = (eval_operand32(0, &breakpoint) >= pc) ? 1 : 0;
    IFF (config.cpu.dependstats) cur->func_unit = it_branch;
    IFF (config.cpu.dependstats) cur->func_unit = it_branch;
    mstats.bf[flag][fwd]++;
    mstats.bf[flag][fwd]++;
    bpb_update(cur->insn_addr, flag);
    bpb_update(cur->insn_addr, flag);
  }
  }
  if (flag) {
  if (flag) {
    debug(5, "\nl.bf relative: pc=%x pcnext=%x\n", pc, pcnext);
    debug(5, "\nl.bf relative: pc=%x pcnext=%x\n", pc, pcnext);
    pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4;
    pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4;
    btic_update(pcnext);
    btic_update(pcnext);
    next_delay_insn = 1;
    next_delay_insn = 1;
  } else {
  } else {
    btic_update(pc);
    btic_update(pc);
  }
  }
}
}
void l_bnf() {
void l_bnf() {
  if (config.bpb.enabled) {
  if (config.bpb.enabled) {
    int fwd = (eval_operand32(0, &breakpoint) >= pc) ? 1 : 0;
    int fwd = (eval_operand32(0, &breakpoint) >= pc) ? 1 : 0;
    IFF (config.cpu.dependstats) cur->func_unit = it_branch;
    IFF (config.cpu.dependstats) cur->func_unit = it_branch;
    mstats.bnf[!flag][fwd]++;
    mstats.bnf[!flag][fwd]++;
    bpb_update(cur->insn_addr, flag == 0);
    bpb_update(cur->insn_addr, flag == 0);
  }
  }
  if (flag == 0) {
  if (flag == 0) {
    debug(5, "\nl.bnf relative: pc=%x pcnext=%x\n", pc, pcnext);
    debug(5, "\nl.bnf relative: pc=%x pcnext=%x\n", pc, pcnext);
    pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4;
    pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4;
    btic_update(pcnext);
    btic_update(pcnext);
    next_delay_insn = 1;
    next_delay_insn = 1;
  } else {
  } else {
    btic_update(pc);
    btic_update(pc);
  }
  }
}
}
void l_j() {
void l_j() {
  debug(5, "\nl.j relative: pc=%x pcnext=%x\n", pc, pcnext);
  debug(5, "\nl.j relative: pc=%x pcnext=%x\n", pc, pcnext);
  pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4;
  pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4;
  IFF (config.cpu.dependstats) cur->func_unit = it_jump;
  IFF (config.cpu.dependstats) cur->func_unit = it_jump;
  next_delay_insn = 1;
  next_delay_insn = 1;
}
}
void l_jal() {
void l_jal() {
  debug(5, "\nl.jal relative: pc=%x pcnext=%x\n", pc, pcnext);
  debug(5, "\nl.jal relative: pc=%x pcnext=%x\n", pc, pcnext);
  pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4;
  pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4;
 
 
  IFF (config.cpu.dependstats) cur->func_unit = it_jump;
  IFF (config.cpu.dependstats) cur->func_unit = it_jump;
  set_reg32(LINK_REGNO, pc + 8);
  set_reg32(LINK_REGNO, pc + 8);
  next_delay_insn = 1;
  next_delay_insn = 1;
  if (config.sim.profile) {
  if (config.sim.profile) {
    struct mem_entry *entry;
    struct mem_entry *entry;
    struct label_entry *tmp;
    struct label_entry *tmp;
    if (verify_memoryarea(pcdelay) && (tmp = get_label (pcdelay)))
    if (verify_memoryarea(pcdelay) && (tmp = get_label (pcdelay)))
      fprintf (runtime.sim.fprof, "+%08X %08X %08X %s\n", cycles, pc + 8, pcdelay, tmp->name);
      fprintf (runtime.sim.fprof, "+%08X %08X %08X %s\n", cycles, pc + 8, pcdelay, tmp->name);
    else
    else
      fprintf (runtime.sim.fprof, "+%08X %08X %08X @%08X\n", cycles, pc + 8, pcdelay, pcdelay);
      fprintf (runtime.sim.fprof, "+%08X %08X %08X @%08X\n", cycles, pc + 8, pcdelay, pcdelay);
  }
  }
}
}
void l_jalr() {
void l_jalr() {
  IFF (config.cpu.dependstats) cur->func_unit = it_jump;
  IFF (config.cpu.dependstats) cur->func_unit = it_jump;
  pcdelay = eval_operand32(0, &breakpoint);
  pcdelay = eval_operand32(0, &breakpoint);
  set_reg32(LINK_REGNO, pc + 8);
  set_reg32(LINK_REGNO, pc + 8);
  next_delay_insn = 1;
  next_delay_insn = 1;
}
}
void l_jr() {
void l_jr() {
  IFF (config.cpu.dependstats) cur->func_unit = it_jump;
  IFF (config.cpu.dependstats) cur->func_unit = it_jump;
  pcdelay = eval_operand32(0, &breakpoint);
  pcdelay = eval_operand32(0, &breakpoint);
  next_delay_insn = 1;
  next_delay_insn = 1;
  if (config.sim.profile)
  if (config.sim.profile)
    fprintf (runtime.sim.fprof, "-%08X %08X\n", cycles, pcdelay);
    fprintf (runtime.sim.fprof, "-%08X %08X\n", cycles, pcdelay);
}
}
void l_rfe() {
void l_rfe() {
  IFF (config.cpu.dependstats) cur->func_unit = it_exception;
  IFF (config.cpu.dependstats) cur->func_unit = it_exception;
  pcnext = mfspr(SPR_EPCR_BASE);
  pcnext = mfspr(SPR_EPCR_BASE);
  mtspr(SPR_SR, mfspr(SPR_ESR_BASE));
  mtspr(SPR_SR, mfspr(SPR_ESR_BASE));
}
}
void l_nop() {
void l_nop() {
  unsigned long stackaddr;
  unsigned long stackaddr;
  int k = eval_operand32(0, &breakpoint);
  int k = eval_operand32(0, &breakpoint);
  IFF (config.cpu.dependstats) cur->func_unit = it_nop;
  IFF (config.cpu.dependstats) cur->func_unit = it_nop;
  switch (k) {
  switch (k) {
    case NOP_NOP:
    case NOP_NOP:
      break;
      break;
    case NOP_EXIT:
    case NOP_EXIT:
      printf("exit(%d)\n", evalsim_reg32 (3));
      printf("exit(%d)\n", evalsim_reg32 (3));
      if (config.debug.gdb_enabled)
      if (config.debug.gdb_enabled)
        set_stall_state (1);
        set_stall_state (1);
      else
      else
        cont_run = 0;
        cont_run = 0;
      break;
      break;
    case NOP_PRINTF:
    case NOP_PRINTF:
      stackaddr = evalsim_reg32(4);
      stackaddr = evalsim_reg32(4);
      simprintf(stackaddr, evalsim_reg32(3));
      simprintf(stackaddr, evalsim_reg32(3));
      debug(5, "simprintf %x\n", stackaddr);
      debug(5, "simprintf %x\n", stackaddr);
      break;
      break;
    case NOP_REPORT:
    case NOP_REPORT:
      printf("report(0x%x);\n", evalsim_reg32(3));
      printf("report(0x%x);\n", evalsim_reg32(3));
    default:
    default:
      if (k >= NOP_REPORT_FIRST && k <= NOP_REPORT_LAST)
      if (k >= NOP_REPORT_FIRST && k <= NOP_REPORT_LAST)
      printf("report %i (0x%x);\n", k - NOP_REPORT_FIRST, evalsim_reg32(3));
      printf("report %i (0x%x);\n", k - NOP_REPORT_FIRST, evalsim_reg32(3));
      break;
      break;
  }
  }
}
}
void l_sfeq() {
void l_sfeq() {
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  flag = eval_operand32(0, &breakpoint) == eval_operand32(1, &breakpoint);
  flag = eval_operand32(0, &breakpoint) == eval_operand32(1, &breakpoint);
  setsprbits(SPR_SR, SPR_SR_F, flag);
  setsprbits(SPR_SR, SPR_SR_F, flag);
}
}
void l_sfne() {
void l_sfne() {
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  flag = eval_operand32(0, &breakpoint) != eval_operand32(1, &breakpoint);
  flag = eval_operand32(0, &breakpoint) != eval_operand32(1, &breakpoint);
  setsprbits(SPR_SR, SPR_SR_F, flag);
  setsprbits(SPR_SR, SPR_SR_F, flag);
}
}
void l_sfgts() {
void l_sfgts() {
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  flag = (signed)eval_operand32(0, &breakpoint) > (signed)eval_operand32(1, &breakpoint);
  flag = (signed)eval_operand32(0, &breakpoint) > (signed)eval_operand32(1, &breakpoint);
  setsprbits(SPR_SR, SPR_SR_F, flag);
  setsprbits(SPR_SR, SPR_SR_F, flag);
}
}
void l_sfges() {
void l_sfges() {
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  flag = (signed)eval_operand32(0, &breakpoint) >= (signed)eval_operand32(1, &breakpoint);
  flag = (signed)eval_operand32(0, &breakpoint) >= (signed)eval_operand32(1, &breakpoint);
  setsprbits(SPR_SR, SPR_SR_F, flag);
  setsprbits(SPR_SR, SPR_SR_F, flag);
}
}
void l_sflts() {
void l_sflts() {
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  flag = (signed)eval_operand32(0, &breakpoint) < (signed)eval_operand32(1, &breakpoint);
  flag = (signed)eval_operand32(0, &breakpoint) < (signed)eval_operand32(1, &breakpoint);
  setsprbits(SPR_SR, SPR_SR_F, flag);
  setsprbits(SPR_SR, SPR_SR_F, flag);
}
}
void l_sfles() {
void l_sfles() {
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  flag = (signed)eval_operand32(0, &breakpoint) <= (signed)eval_operand32(1, &breakpoint);
  flag = (signed)eval_operand32(0, &breakpoint) <= (signed)eval_operand32(1, &breakpoint);
  setsprbits(SPR_SR, SPR_SR_F, flag);
  setsprbits(SPR_SR, SPR_SR_F, flag);
}
}
void l_sfgtu() {
void l_sfgtu() {
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  flag = (unsigned)eval_operand32(0, &breakpoint) > (unsigned)eval_operand32(1, &breakpoint);
  flag = (unsigned)eval_operand32(0, &breakpoint) > (unsigned)eval_operand32(1, &breakpoint);
  setsprbits(SPR_SR, SPR_SR_F, flag);
  setsprbits(SPR_SR, SPR_SR_F, flag);
}
}
void l_sfgeu() {
void l_sfgeu() {
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  flag = (unsigned)eval_operand32(0, &breakpoint) >= (unsigned) eval_operand32(1, &breakpoint);
  flag = (unsigned)eval_operand32(0, &breakpoint) >= (unsigned) eval_operand32(1, &breakpoint);
  setsprbits(SPR_SR, SPR_SR_F, flag);
  setsprbits(SPR_SR, SPR_SR_F, flag);
}
}
void l_sfltu() {
void l_sfltu() {
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  flag = (unsigned)eval_operand32(0, &breakpoint) < (unsigned)eval_operand32(1, &breakpoint);
  flag = (unsigned)eval_operand32(0, &breakpoint) < (unsigned)eval_operand32(1, &breakpoint);
  setsprbits(SPR_SR, SPR_SR_F, flag);
  setsprbits(SPR_SR, SPR_SR_F, flag);
}
}
void l_sfleu() {
void l_sfleu() {
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  IFF (config.cpu.dependstats) cur->func_unit = it_compare;
  flag = (unsigned)eval_operand32(0, &breakpoint) <= (unsigned)eval_operand32(1, &breakpoint);
  flag = (unsigned)eval_operand32(0, &breakpoint) <= (unsigned)eval_operand32(1, &breakpoint);
  setsprbits(SPR_SR, SPR_SR_F, flag);
  setsprbits(SPR_SR, SPR_SR_F, flag);
}
}
void l_extbs() {
void l_extbs() {
  unsigned char x;
  unsigned char x;
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  x = eval_operand32(1, &breakpoint);
  x = eval_operand32(1, &breakpoint);
  set_operand32(0, (signed long)x, &breakpoint);
  set_operand32(0, (signed long)x, &breakpoint);
}
}
void l_extbz() {
void l_extbz() {
  unsigned char x;
  unsigned char x;
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  x = eval_operand32(1, &breakpoint);
  x = eval_operand32(1, &breakpoint);
  set_operand32(0, (unsigned long)x, &breakpoint);
  set_operand32(0, (unsigned long)x, &breakpoint);
}
}
void l_exths() {
void l_exths() {
  unsigned short x;
  unsigned short x;
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  x = eval_operand32(1, &breakpoint);
  x = eval_operand32(1, &breakpoint);
  set_operand32(0, (signed long)x, &breakpoint);
  set_operand32(0, (signed long)x, &breakpoint);
}
}
void l_exthz() {
void l_exthz() {
  unsigned short x;
  unsigned short x;
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  x = eval_operand32(1, &breakpoint);
  x = eval_operand32(1, &breakpoint);
  set_operand32(0, (unsigned long)x, &breakpoint);
  set_operand32(0, (unsigned long)x, &breakpoint);
}
}
void l_extws() {
void l_extws() {
  unsigned int x;
  unsigned int x;
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  x = eval_operand32(1, &breakpoint);
  x = eval_operand32(1, &breakpoint);
  set_operand32(0, (signed long)x, &breakpoint);
  set_operand32(0, (signed long)x, &breakpoint);
}
}
void l_extwz() {
void l_extwz() {
  unsigned int x;
  unsigned int x;
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  x = eval_operand32(1, &breakpoint);
  x = eval_operand32(1, &breakpoint);
  set_operand32(0, (unsigned long)x, &breakpoint);
  set_operand32(0, (unsigned long)x, &breakpoint);
}
}
void l_mtspr() {
void l_mtspr() {
  unsigned long regno = eval_operand32(0, &breakpoint) + eval_operand32(2, &breakpoint);
  unsigned long regno = eval_operand32(0, &breakpoint) + eval_operand32(2, &breakpoint);
  unsigned long value = eval_operand32(1, &breakpoint);
  unsigned long value = eval_operand32(1, &breakpoint);
 
 
  if (runtime.sim.fspr_log) {
  if (runtime.sim.fspr_log) {
    fprintf(runtime.sim.fspr_log, "Write to SPR  : [%08lX] <- [%08lX]\n", regno, value);
    fprintf(runtime.sim.fspr_log, "Write to SPR  : [%08lX] <- [%08lX]\n", regno, value);
  }
  }
 
 
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  if (mfspr(SPR_SR) & SPR_SR_SM)
  if (mfspr(SPR_SR) & SPR_SR_SM)
    mtspr(regno, value);
    mtspr(regno, value);
  else {
  else {
    printf("WARNING: trying to write SPR while SR[SUPV] is cleared.\n");
    printf("WARNING: trying to write SPR while SR[SUPV] is cleared.\n");
    cont_run = 0;
    cont_run = 0;
  }
  }
}
}
void l_mfspr() {
void l_mfspr() {
  unsigned long regno = eval_operand32(1, &breakpoint) + eval_operand32(2, &breakpoint);
  unsigned long regno = eval_operand32(1, &breakpoint) + eval_operand32(2, &breakpoint);
  unsigned long value = mfspr(regno);
  unsigned long value = mfspr(regno);
 
 
  if (runtime.sim.fspr_log) {
  if (runtime.sim.fspr_log) {
    fprintf(runtime.sim.fspr_log, "Read from SPR : [%08lX] -> [%08lX]\n", regno, value);
    fprintf(runtime.sim.fspr_log, "Read from SPR : [%08lX] -> [%08lX]\n", regno, value);
  }
  }
 
 
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  if (mfspr(SPR_SR) & SPR_SR_SM)
  if (mfspr(SPR_SR) & SPR_SR_SM)
    set_operand32(0, value, &breakpoint);
    set_operand32(0, value, &breakpoint);
  else {
  else {
    set_operand32(0, 0, &breakpoint);
    set_operand32(0, 0, &breakpoint);
    printf("WARNING: trying to read SPR while SR[SUPV] is cleared.\n");
    printf("WARNING: trying to read SPR while SR[SUPV] is cleared.\n");
    cont_run = 0;
    cont_run = 0;
  }
  }
}
}
void l_sys() {
void l_sys() {
  except_handle(EXCEPT_SYSCALL, mfspr(SPR_EEAR_BASE));
  except_handle(EXCEPT_SYSCALL, mfspr(SPR_EEAR_BASE));
}
}
void l_trap() {
void l_trap() {
  /* TODO: some SR related code here! */
  /* TODO: some SR related code here! */
  except_handle(EXCEPT_TRAP, mfspr(SPR_EEAR_BASE));
  except_handle(EXCEPT_TRAP, mfspr(SPR_EEAR_BASE));
}
}
void l_mac() {
void l_mac() {
  sprword lo, hi;
  sprword lo, hi;
  LONGEST l;
  LONGEST l;
  long x, y;
  long x, y;
  IFF (config.cpu.dependstats) cur->func_unit = it_mac;
  IFF (config.cpu.dependstats) cur->func_unit = it_mac;
  lo = mfspr (SPR_MACLO);
  lo = mfspr (SPR_MACLO);
  hi = mfspr (SPR_MACHI);
  hi = mfspr (SPR_MACHI);
  x = eval_operand32(0, &breakpoint);
  x = eval_operand32(0, &breakpoint);
  y = eval_operand32(1, &breakpoint);
  y = eval_operand32(1, &breakpoint);
  printf ("[%08x,%08x]\t", (unsigned long)(x), (unsigned long)(y));
  printf ("[%08x,%08x]\t", (unsigned long)(x), (unsigned long)(y));
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
  l += (LONGEST) x * (LONGEST) y;
  l += (LONGEST) x * (LONGEST) y;
 
 
  /* This implementation is very fast - it needs only one cycle for mac.  */
  /* This implementation is very fast - it needs only one cycle for mac.  */
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
  hi = ((LONGEST)l) >> 32;
  hi = ((LONGEST)l) >> 32;
  mtspr (SPR_MACLO, lo);
  mtspr (SPR_MACLO, lo);
  mtspr (SPR_MACHI, hi);
  mtspr (SPR_MACHI, hi);
  printf ("(%08x,%08x)\n", hi, lo);
  printf ("(%08x,%08x)\n", hi, lo);
}
}
void l_msb() {
void l_msb() {
  sprword lo, hi;
  sprword lo, hi;
  LONGEST l;
  LONGEST l;
  long x, y;
  long x, y;
  IFF (config.cpu.dependstats) cur->func_unit = it_mac;
  IFF (config.cpu.dependstats) cur->func_unit = it_mac;
  lo = mfspr (SPR_MACLO);
  lo = mfspr (SPR_MACLO);
  hi = mfspr (SPR_MACHI);
  hi = mfspr (SPR_MACHI);
  x = eval_operand32(0, &breakpoint);
  x = eval_operand32(0, &breakpoint);
  y = eval_operand32(1, &breakpoint);
  y = eval_operand32(1, &breakpoint);
  printf ("[%08x,%08x]\t", (unsigned long)(x), (unsigned long)(y));
  printf ("[%08x,%08x]\t", (unsigned long)(x), (unsigned long)(y));
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
  l -= (LONGEST) eval_operand32(0, &breakpoint) * (LONGEST)eval_operand32(1, &breakpoint);
  l -= (LONGEST) eval_operand32(0, &breakpoint) * (LONGEST)eval_operand32(1, &breakpoint);
 
 
  /* This implementation is very fast - it needs only one cycle for msb.  */
  /* This implementation is very fast - it needs only one cycle for msb.  */
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
  hi = ((LONGEST)l) >> 32;
  hi = ((LONGEST)l) >> 32;
  mtspr (SPR_MACLO, lo);
  mtspr (SPR_MACLO, lo);
  mtspr (SPR_MACHI, hi);
  mtspr (SPR_MACHI, hi);
  printf ("(%08x,%08x)\n", hi, lo);
  printf ("(%08x,%08x)\n", hi, lo);
}
}
void l_macrc() {
void l_macrc() {
  sprword lo, hi;
  sprword lo, hi;
  LONGEST l;
  LONGEST l;
  IFF (config.cpu.dependstats) cur->func_unit = it_mac;
  IFF (config.cpu.dependstats) cur->func_unit = it_mac;
  /* No need for synchronization here -- all MAC instructions are 1 cycle long.  */
  /* No need for synchronization here -- all MAC instructions are 1 cycle long.  */
  lo =  mfspr (SPR_MACLO);
  lo =  mfspr (SPR_MACLO);
  hi =  mfspr (SPR_MACHI);
  hi =  mfspr (SPR_MACHI);
  l = (ULONGEST) lo | ((LONGEST)hi << 32);
  l = (ULONGEST) lo | ((LONGEST)hi << 32);
  l >>= 28;
  l >>= 28;
  //printf ("<%08x>\n", (unsigned long)l);
  //printf ("<%08x>\n", (unsigned long)l);
  set_operand32(0, (long)l, &breakpoint);
  set_operand32(0, (long)l, &breakpoint);
  mtspr (SPR_MACLO, 0);
  mtspr (SPR_MACLO, 0);
  mtspr (SPR_MACHI, 0);
  mtspr (SPR_MACHI, 0);
}
}
void l_cmov() {
void l_cmov() {
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  IFF (config.cpu.dependstats) cur->func_unit = it_move;
  set_operand32 (0, flag ? eval_operand32(1, &breakpoint) : eval_operand32(2, &breakpoint), &breakpoint);
  set_operand32 (0, flag ? eval_operand32(1, &breakpoint) : eval_operand32(2, &breakpoint), &breakpoint);
}
}
void l_cust1() {
void l_cust1() {
  /*int destr = cur->insn >> 21;
  /*int destr = cur->insn >> 21;
    int src1r = cur->insn >> 15;
    int src1r = cur->insn >> 15;
    int src2r = cur->insn >> 9;*/
    int src2r = cur->insn >> 9;*/
}
}
void l_cust2() {
void l_cust2() {
}
}
void l_cust3() {
void l_cust3() {
}
}
void l_cust4() {
void l_cust4() {
}
}
void l_invalid() {
void l_invalid() {
  except_handle(EXCEPT_ILLEGAL, iqueue[0].insn_addr);
  except_handle(EXCEPT_ILLEGAL, iqueue[0].insn_addr);
}
}
 
 

powered by: WebSVN 2.1.0

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