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

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [gdb-7.2/] [gdb-7.2-or32-1.0rc1/] [sim/] [erc32/] [exec.c] - Diff between revs 330 and 341

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

Rev 330 Rev 341
/*
/*
 * This file is part of SIS.
 * This file is part of SIS.
 *
 *
 * SIS, SPARC instruction simulator V1.8 Copyright (C) 1995 Jiri Gaisler,
 * SIS, SPARC instruction simulator V1.8 Copyright (C) 1995 Jiri Gaisler,
 * European Space Agency
 * European Space Agency
 *
 *
 * This program is free software; you can redistribute it and/or modify it under
 * 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 the Free
 * the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 * any later version.
 *
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 * more details.
 *
 *
 * You should have received a copy of the GNU General Public License along with
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 675
 * this program; if not, write to the Free Software Foundation, Inc., 675
 * Mass Ave, Cambridge, MA 02139, USA.
 * Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 */
 */
 
 
#include "sis.h"
#include "sis.h"
#include "end.h"
#include "end.h"
#include <math.h>
#include <math.h>
#include <stdio.h>
#include <stdio.h>
 
 
extern int32    sis_verbose, sparclite;
extern int32    sis_verbose, sparclite;
int ext_irl = 0;
int ext_irl = 0;
 
 
/* Load/store interlock delay */
/* Load/store interlock delay */
#define FLSTHOLD 1
#define FLSTHOLD 1
 
 
/* Load delay (delete if unwanted - speeds up simulation) */
/* Load delay (delete if unwanted - speeds up simulation) */
#define LOAD_DEL 1
#define LOAD_DEL 1
 
 
#define T_LD    2
#define T_LD    2
#define T_LDD   3
#define T_LDD   3
#define T_ST    3
#define T_ST    3
#define T_STD   4
#define T_STD   4
#define T_LDST  4
#define T_LDST  4
#define T_JMPL  2
#define T_JMPL  2
#define T_RETT  2
#define T_RETT  2
 
 
#define FSR_QNE         0x2000
#define FSR_QNE         0x2000
#define FP_EXE_MODE 0
#define FP_EXE_MODE 0
#define FP_EXC_PE   1
#define FP_EXC_PE   1
#define FP_EXC_MODE 2
#define FP_EXC_MODE 2
 
 
#define FBA     8
#define FBA     8
#define FBN     0
#define FBN     0
#define FBNE    1
#define FBNE    1
#define FBLG    2
#define FBLG    2
#define FBUL    3
#define FBUL    3
#define FBL     4
#define FBL     4
#define FBUG    5
#define FBUG    5
#define FBG     6
#define FBG     6
#define FBU     7
#define FBU     7
#define FBA     8
#define FBA     8
#define FBE     9
#define FBE     9
#define FBUE    10
#define FBUE    10
#define FBGE    11
#define FBGE    11
#define FBUGE   12
#define FBUGE   12
#define FBLE    13
#define FBLE    13
#define FBULE   14
#define FBULE   14
#define FBO     15
#define FBO     15
 
 
#define FCC_E   0
#define FCC_E   0
#define FCC_L   1
#define FCC_L   1
#define FCC_G   2
#define FCC_G   2
#define FCC_U   3
#define FCC_U   3
 
 
#define PSR_ET 0x20
#define PSR_ET 0x20
#define PSR_EF 0x1000
#define PSR_EF 0x1000
#define PSR_PS 0x40
#define PSR_PS 0x40
#define PSR_S  0x80
#define PSR_S  0x80
#define PSR_N  0x0800000
#define PSR_N  0x0800000
#define PSR_Z  0x0400000
#define PSR_Z  0x0400000
#define PSR_V  0x0200000
#define PSR_V  0x0200000
#define PSR_C  0x0100000
#define PSR_C  0x0100000
#define PSR_CC 0x0F00000
#define PSR_CC 0x0F00000
#define PSR_CWP 0x7
#define PSR_CWP 0x7
#define PSR_PIL 0x0f00
#define PSR_PIL 0x0f00
 
 
#define ICC_N   (icc >> 3)
#define ICC_N   (icc >> 3)
#define ICC_Z   (icc >> 2)
#define ICC_Z   (icc >> 2)
#define ICC_V   (icc >> 1)
#define ICC_V   (icc >> 1)
#define ICC_C   (icc)
#define ICC_C   (icc)
 
 
#define FP_PRES (sregs->fpu_pres)
#define FP_PRES (sregs->fpu_pres)
 
 
#define TRAP_IEXC 1
#define TRAP_IEXC 1
#define TRAP_UNIMP 2
#define TRAP_UNIMP 2
#define TRAP_PRIVI 3
#define TRAP_PRIVI 3
#define TRAP_FPDIS 4
#define TRAP_FPDIS 4
#define TRAP_WOFL 5
#define TRAP_WOFL 5
#define TRAP_WUFL 6
#define TRAP_WUFL 6
#define TRAP_UNALI 7
#define TRAP_UNALI 7
#define TRAP_FPEXC 8
#define TRAP_FPEXC 8
#define TRAP_DEXC 9
#define TRAP_DEXC 9
#define TRAP_TAG 10
#define TRAP_TAG 10
#define TRAP_DIV0 0x2a
#define TRAP_DIV0 0x2a
 
 
#define FSR_TT          0x1C000
#define FSR_TT          0x1C000
#define FP_IEEE         0x04000
#define FP_IEEE         0x04000
#define FP_UNIMP        0x0C000
#define FP_UNIMP        0x0C000
#define FP_SEQ_ERR      0x10000
#define FP_SEQ_ERR      0x10000
 
 
#define BICC_BN         0
#define BICC_BN         0
#define BICC_BE         1
#define BICC_BE         1
#define BICC_BLE        2
#define BICC_BLE        2
#define BICC_BL         3
#define BICC_BL         3
#define BICC_BLEU       4
#define BICC_BLEU       4
#define BICC_BCS        5
#define BICC_BCS        5
#define BICC_NEG        6
#define BICC_NEG        6
#define BICC_BVS        7
#define BICC_BVS        7
#define BICC_BA         8
#define BICC_BA         8
#define BICC_BNE        9
#define BICC_BNE        9
#define BICC_BG         10
#define BICC_BG         10
#define BICC_BGE        11
#define BICC_BGE        11
#define BICC_BGU        12
#define BICC_BGU        12
#define BICC_BCC        13
#define BICC_BCC        13
#define BICC_POS        14
#define BICC_POS        14
#define BICC_BVC        15
#define BICC_BVC        15
 
 
#define INST_SIMM13 0x1fff
#define INST_SIMM13 0x1fff
#define INST_RS2    0x1f
#define INST_RS2    0x1f
#define INST_I      0x2000
#define INST_I      0x2000
#define ADD     0x00
#define ADD     0x00
#define ADDCC   0x10
#define ADDCC   0x10
#define ADDX    0x08
#define ADDX    0x08
#define ADDXCC  0x18
#define ADDXCC  0x18
#define TADDCC  0x20
#define TADDCC  0x20
#define TSUBCC  0x21
#define TSUBCC  0x21
#define TADDCCTV 0x22
#define TADDCCTV 0x22
#define TSUBCCTV 0x23
#define TSUBCCTV 0x23
#define IAND    0x01
#define IAND    0x01
#define IANDCC  0x11
#define IANDCC  0x11
#define IANDN   0x05
#define IANDN   0x05
#define IANDNCC 0x15
#define IANDNCC 0x15
#define MULScc  0x24
#define MULScc  0x24
#define DIVScc  0x1D
#define DIVScc  0x1D
#define SMUL    0x0B
#define SMUL    0x0B
#define SMULCC  0x1B
#define SMULCC  0x1B
#define UMUL    0x0A
#define UMUL    0x0A
#define UMULCC  0x1A
#define UMULCC  0x1A
#define SDIV    0x0F
#define SDIV    0x0F
#define SDIVCC  0x1F
#define SDIVCC  0x1F
#define UDIV    0x0E
#define UDIV    0x0E
#define UDIVCC  0x1E
#define UDIVCC  0x1E
#define IOR     0x02
#define IOR     0x02
#define IORCC   0x12
#define IORCC   0x12
#define IORN    0x06
#define IORN    0x06
#define IORNCC  0x16
#define IORNCC  0x16
#define SLL     0x25
#define SLL     0x25
#define SRA     0x27
#define SRA     0x27
#define SRL     0x26
#define SRL     0x26
#define SUB     0x04
#define SUB     0x04
#define SUBCC   0x14
#define SUBCC   0x14
#define SUBX    0x0C
#define SUBX    0x0C
#define SUBXCC  0x1C
#define SUBXCC  0x1C
#define IXNOR   0x07
#define IXNOR   0x07
#define IXNORCC 0x17
#define IXNORCC 0x17
#define IXOR    0x03
#define IXOR    0x03
#define IXORCC  0x13
#define IXORCC  0x13
#define SETHI   0x04
#define SETHI   0x04
#define BICC    0x02
#define BICC    0x02
#define FPBCC   0x06
#define FPBCC   0x06
#define RDY     0x28
#define RDY     0x28
#define RDPSR   0x29
#define RDPSR   0x29
#define RDWIM   0x2A
#define RDWIM   0x2A
#define RDTBR   0x2B
#define RDTBR   0x2B
#define SCAN    0x2C
#define SCAN    0x2C
#define WRY     0x30
#define WRY     0x30
#define WRPSR   0x31
#define WRPSR   0x31
#define WRWIM   0x32
#define WRWIM   0x32
#define WRTBR   0x33
#define WRTBR   0x33
#define JMPL    0x38
#define JMPL    0x38
#define RETT    0x39
#define RETT    0x39
#define TICC    0x3A
#define TICC    0x3A
#define SAVE    0x3C
#define SAVE    0x3C
#define RESTORE 0x3D
#define RESTORE 0x3D
#define LDD     0x03
#define LDD     0x03
#define LDDA    0x13
#define LDDA    0x13
#define LD      0x00
#define LD      0x00
#define LDA     0x10
#define LDA     0x10
#define LDF     0x20
#define LDF     0x20
#define LDDF    0x23
#define LDDF    0x23
#define LDSTUB  0x0D
#define LDSTUB  0x0D
#define LDSTUBA 0x1D
#define LDSTUBA 0x1D
#define LDUB    0x01
#define LDUB    0x01
#define LDUBA   0x11
#define LDUBA   0x11
#define LDSB    0x09
#define LDSB    0x09
#define LDSBA   0x19
#define LDSBA   0x19
#define LDUH    0x02
#define LDUH    0x02
#define LDUHA   0x12
#define LDUHA   0x12
#define LDSH    0x0A
#define LDSH    0x0A
#define LDSHA   0x1A
#define LDSHA   0x1A
#define LDFSR   0x21
#define LDFSR   0x21
#define ST      0x04
#define ST      0x04
#define STA     0x14
#define STA     0x14
#define STB     0x05
#define STB     0x05
#define STBA    0x15
#define STBA    0x15
#define STD     0x07
#define STD     0x07
#define STDA    0x17
#define STDA    0x17
#define STF     0x24
#define STF     0x24
#define STDFQ   0x26
#define STDFQ   0x26
#define STDF    0x27
#define STDF    0x27
#define STFSR   0x25
#define STFSR   0x25
#define STH     0x06
#define STH     0x06
#define STHA    0x16
#define STHA    0x16
#define SWAP    0x0F
#define SWAP    0x0F
#define SWAPA   0x1F
#define SWAPA   0x1F
#define FLUSH   0x3B
#define FLUSH   0x3B
 
 
#define SIGN_BIT 0x80000000
#define SIGN_BIT 0x80000000
 
 
/* # of cycles overhead when a trap is taken */
/* # of cycles overhead when a trap is taken */
#define TRAP_C  3
#define TRAP_C  3
 
 
/* Forward declarations */
/* Forward declarations */
 
 
static uint32   sub_cc PARAMS ((uint32 psr, int32 operand1, int32 operand2,
static uint32   sub_cc PARAMS ((uint32 psr, int32 operand1, int32 operand2,
                                int32 result));
                                int32 result));
static uint32   add_cc PARAMS ((uint32 psr, int32 operand1, int32 operand2,
static uint32   add_cc PARAMS ((uint32 psr, int32 operand1, int32 operand2,
                                int32 result));
                                int32 result));
static void     log_cc PARAMS ((int32 result, struct pstate *sregs));
static void     log_cc PARAMS ((int32 result, struct pstate *sregs));
static int      fpexec PARAMS ((uint32 op3, uint32 rd, uint32 rs1, uint32 rs2,
static int      fpexec PARAMS ((uint32 op3, uint32 rd, uint32 rs1, uint32 rs2,
                                struct pstate *sregs));
                                struct pstate *sregs));
static int      chk_asi PARAMS ((struct pstate *sregs, uint32 *asi, uint32 op3));
static int      chk_asi PARAMS ((struct pstate *sregs, uint32 *asi, uint32 op3));
 
 
 
 
extern struct estate ebase;
extern struct estate ebase;
extern int32    nfp,ift;
extern int32    nfp,ift;
 
 
#ifdef ERRINJ
#ifdef ERRINJ
extern uint32 errtt, errftt;
extern uint32 errtt, errftt;
#endif
#endif
 
 
static uint32
static uint32
sub_cc(psr, operand1, operand2, result)
sub_cc(psr, operand1, operand2, result)
    uint32          psr;
    uint32          psr;
    int32           operand1;
    int32           operand1;
    int32           operand2;
    int32           operand2;
    int32           result;
    int32           result;
{
{
    psr = ((psr & ~PSR_N) | ((result >> 8) & PSR_N));
    psr = ((psr & ~PSR_N) | ((result >> 8) & PSR_N));
    if (result)
    if (result)
        psr &= ~PSR_Z;
        psr &= ~PSR_Z;
    else
    else
        psr |= PSR_Z;
        psr |= PSR_Z;
    psr = (psr & ~PSR_V) | ((((operand1 & ~operand2 & ~result) |
    psr = (psr & ~PSR_V) | ((((operand1 & ~operand2 & ~result) |
                           (~operand1 & operand2 & result)) >> 10) & PSR_V);
                           (~operand1 & operand2 & result)) >> 10) & PSR_V);
    psr = (psr & ~PSR_C) | ((((~operand1 & operand2) |
    psr = (psr & ~PSR_C) | ((((~operand1 & operand2) |
                         ((~operand1 | operand2) & result)) >> 11) & PSR_C);
                         ((~operand1 | operand2) & result)) >> 11) & PSR_C);
    return (psr);
    return (psr);
}
}
 
 
uint32
uint32
add_cc(psr, operand1, operand2, result)
add_cc(psr, operand1, operand2, result)
    uint32          psr;
    uint32          psr;
    int32           operand1;
    int32           operand1;
    int32           operand2;
    int32           operand2;
    int32           result;
    int32           result;
{
{
    psr = ((psr & ~PSR_N) | ((result >> 8) & PSR_N));
    psr = ((psr & ~PSR_N) | ((result >> 8) & PSR_N));
    if (result)
    if (result)
        psr &= ~PSR_Z;
        psr &= ~PSR_Z;
    else
    else
        psr |= PSR_Z;
        psr |= PSR_Z;
    psr = (psr & ~PSR_V) | ((((operand1 & operand2 & ~result) |
    psr = (psr & ~PSR_V) | ((((operand1 & operand2 & ~result) |
                          (~operand1 & ~operand2 & result)) >> 10) & PSR_V);
                          (~operand1 & ~operand2 & result)) >> 10) & PSR_V);
    psr = (psr & ~PSR_C) | ((((operand1 & operand2) |
    psr = (psr & ~PSR_C) | ((((operand1 & operand2) |
                         ((operand1 | operand2) & ~result)) >> 11) & PSR_C);
                         ((operand1 | operand2) & ~result)) >> 11) & PSR_C);
    return(psr);
    return(psr);
}
}
 
 
static void
static void
log_cc(result, sregs)
log_cc(result, sregs)
    int32           result;
    int32           result;
    struct pstate  *sregs;
    struct pstate  *sregs;
{
{
    sregs->psr &= ~(PSR_CC);    /* Zero CC bits */
    sregs->psr &= ~(PSR_CC);    /* Zero CC bits */
    sregs->psr = (sregs->psr | ((result >> 8) & PSR_N));
    sregs->psr = (sregs->psr | ((result >> 8) & PSR_N));
    if (result == 0)
    if (result == 0)
        sregs->psr |= PSR_Z;
        sregs->psr |= PSR_Z;
}
}
 
 
/* Add two unsigned 32-bit integers, and calculate the carry out. */
/* Add two unsigned 32-bit integers, and calculate the carry out. */
 
 
static uint32
static uint32
add32 (uint32 n1, uint32 n2, int *carry)
add32 (uint32 n1, uint32 n2, int *carry)
{
{
  uint32 result = n1 + n2;
  uint32 result = n1 + n2;
 
 
  *carry = result < n1 || result < n1;
  *carry = result < n1 || result < n1;
  return(result);
  return(result);
}
}
 
 
/* Multiply two 32-bit integers.  */
/* Multiply two 32-bit integers.  */
 
 
static void
static void
mul64 (uint32 n1, uint32 n2, uint32 *result_hi, uint32 *result_lo, int msigned)
mul64 (uint32 n1, uint32 n2, uint32 *result_hi, uint32 *result_lo, int msigned)
{
{
  uint32 lo, mid1, mid2, hi, reg_lo, reg_hi;
  uint32 lo, mid1, mid2, hi, reg_lo, reg_hi;
  int carry;
  int carry;
  int sign = 0;
  int sign = 0;
 
 
  /* If this is a signed multiply, calculate the sign of the result
  /* If this is a signed multiply, calculate the sign of the result
     and make the operands positive.  */
     and make the operands positive.  */
  if (msigned)
  if (msigned)
    {
    {
      sign = (n1 ^ n2) & SIGN_BIT;
      sign = (n1 ^ n2) & SIGN_BIT;
      if (n1 & SIGN_BIT)
      if (n1 & SIGN_BIT)
        n1 = -n1;
        n1 = -n1;
      if (n2 & SIGN_BIT)
      if (n2 & SIGN_BIT)
        n2 = -n2;
        n2 = -n2;
 
 
    }
    }
 
 
  /* We can split the 32x32 into four 16x16 operations. This ensures
  /* We can split the 32x32 into four 16x16 operations. This ensures
     that we do not lose precision on 32bit only hosts: */
     that we do not lose precision on 32bit only hosts: */
  lo =   ((n1 & 0xFFFF) * (n2 & 0xFFFF));
  lo =   ((n1 & 0xFFFF) * (n2 & 0xFFFF));
  mid1 = ((n1 & 0xFFFF) * ((n2 >> 16) & 0xFFFF));
  mid1 = ((n1 & 0xFFFF) * ((n2 >> 16) & 0xFFFF));
  mid2 = (((n1 >> 16) & 0xFFFF) * (n2 & 0xFFFF));
  mid2 = (((n1 >> 16) & 0xFFFF) * (n2 & 0xFFFF));
  hi =   (((n1 >> 16) & 0xFFFF) * ((n2 >> 16) & 0xFFFF));
  hi =   (((n1 >> 16) & 0xFFFF) * ((n2 >> 16) & 0xFFFF));
 
 
  /* We now need to add all of these results together, taking care
  /* We now need to add all of these results together, taking care
     to propogate the carries from the additions: */
     to propogate the carries from the additions: */
  reg_lo = add32 (lo, (mid1 << 16), &carry);
  reg_lo = add32 (lo, (mid1 << 16), &carry);
  reg_hi = carry;
  reg_hi = carry;
  reg_lo = add32 (reg_lo, (mid2 << 16), &carry);
  reg_lo = add32 (reg_lo, (mid2 << 16), &carry);
  reg_hi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
  reg_hi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
 
 
  /* Negate result if necessary. */
  /* Negate result if necessary. */
  if (sign)
  if (sign)
    {
    {
      reg_hi = ~ reg_hi;
      reg_hi = ~ reg_hi;
      reg_lo = - reg_lo;
      reg_lo = - reg_lo;
      if (reg_lo == 0)
      if (reg_lo == 0)
        reg_hi++;
        reg_hi++;
    }
    }
 
 
  *result_lo = reg_lo;
  *result_lo = reg_lo;
  *result_hi = reg_hi;
  *result_hi = reg_hi;
}
}
 
 
 
 
/* Divide a 64-bit integer by a 32-bit integer.  We cheat and assume
/* Divide a 64-bit integer by a 32-bit integer.  We cheat and assume
   that the host compiler supports long long operations.  */
   that the host compiler supports long long operations.  */
 
 
static void
static void
div64 (uint32 n1_hi, uint32 n1_low, uint32 n2, uint32 *result, int msigned)
div64 (uint32 n1_hi, uint32 n1_low, uint32 n2, uint32 *result, int msigned)
{
{
  uint64 n1;
  uint64 n1;
 
 
  n1 = ((uint64) n1_hi) << 32;
  n1 = ((uint64) n1_hi) << 32;
  n1 |= ((uint64) n1_low) & 0xffffffff;
  n1 |= ((uint64) n1_low) & 0xffffffff;
 
 
  if (msigned)
  if (msigned)
    {
    {
      int64 n1_s = (int64) n1;
      int64 n1_s = (int64) n1;
      int32 n2_s = (int32) n2;
      int32 n2_s = (int32) n2;
      n1_s = n1_s / n2_s;
      n1_s = n1_s / n2_s;
      n1 = (uint64) n1_s;
      n1 = (uint64) n1_s;
    }
    }
  else
  else
    n1 = n1 / n2;
    n1 = n1 / n2;
 
 
  *result = (uint32) (n1 & 0xffffffff);
  *result = (uint32) (n1 & 0xffffffff);
}
}
 
 
 
 
int
int
dispatch_instruction(sregs)
dispatch_instruction(sregs)
    struct pstate  *sregs;
    struct pstate  *sregs;
{
{
 
 
    uint32          cwp, op, op2, op3, asi, rd, cond, rs1,
    uint32          cwp, op, op2, op3, asi, rd, cond, rs1,
                    rs2;
                    rs2;
    uint32          ldep, icc;
    uint32          ldep, icc;
    int32           operand1, operand2, *rdd, result, eicc,
    int32           operand1, operand2, *rdd, result, eicc,
                    new_cwp;
                    new_cwp;
    int32           pc, npc, data, address, ws, mexc, fcc;
    int32           pc, npc, data, address, ws, mexc, fcc;
    int32           ddata[2];
    int32           ddata[2];
 
 
    sregs->ninst++;
    sregs->ninst++;
    cwp = ((sregs->psr & PSR_CWP) << 4);
    cwp = ((sregs->psr & PSR_CWP) << 4);
    op = sregs->inst >> 30;
    op = sregs->inst >> 30;
    pc = sregs->npc;
    pc = sregs->npc;
    npc = sregs->npc + 4;
    npc = sregs->npc + 4;
    op3 = rd = rs1 = operand2 = eicc = 0;
    op3 = rd = rs1 = operand2 = eicc = 0;
    rdd = 0;
    rdd = 0;
    if (op & 2) {
    if (op & 2) {
 
 
        op3 = (sregs->inst >> 19) & 0x3f;
        op3 = (sregs->inst >> 19) & 0x3f;
        rs1 = (sregs->inst >> 14) & 0x1f;
        rs1 = (sregs->inst >> 14) & 0x1f;
        rd = (sregs->inst >> 25) & 0x1f;
        rd = (sregs->inst >> 25) & 0x1f;
 
 
#ifdef LOAD_DEL
#ifdef LOAD_DEL
 
 
        /* Check if load dependecy is possible */
        /* Check if load dependecy is possible */
        if (ebase.simtime <= sregs->ildtime)
        if (ebase.simtime <= sregs->ildtime)
            ldep = (((op3 & 0x38) != 0x28) && ((op3 & 0x3e) != 0x34) && (sregs->ildreg != 0));
            ldep = (((op3 & 0x38) != 0x28) && ((op3 & 0x3e) != 0x34) && (sregs->ildreg != 0));
        else
        else
            ldep = 0;
            ldep = 0;
        if (sregs->inst & INST_I) {
        if (sregs->inst & INST_I) {
            if (ldep && (sregs->ildreg == rs1))
            if (ldep && (sregs->ildreg == rs1))
                sregs->hold++;
                sregs->hold++;
            operand2 = sregs->inst;
            operand2 = sregs->inst;
            operand2 = ((operand2 << 19) >> 19);        /* sign extend */
            operand2 = ((operand2 << 19) >> 19);        /* sign extend */
        } else {
        } else {
            rs2 = sregs->inst & INST_RS2;
            rs2 = sregs->inst & INST_RS2;
            if (rs2 > 7)
            if (rs2 > 7)
                operand2 = sregs->r[(cwp + rs2) & 0x7f];
                operand2 = sregs->r[(cwp + rs2) & 0x7f];
            else
            else
                operand2 = sregs->g[rs2];
                operand2 = sregs->g[rs2];
            if (ldep && ((sregs->ildreg == rs1) || (sregs->ildreg == rs2)))
            if (ldep && ((sregs->ildreg == rs1) || (sregs->ildreg == rs2)))
                sregs->hold++;
                sregs->hold++;
        }
        }
#else
#else
        if (sregs->inst & INST_I) {
        if (sregs->inst & INST_I) {
            operand2 = sregs->inst;
            operand2 = sregs->inst;
            operand2 = ((operand2 << 19) >> 19);        /* sign extend */
            operand2 = ((operand2 << 19) >> 19);        /* sign extend */
        } else {
        } else {
            rs2 = sregs->inst & INST_RS2;
            rs2 = sregs->inst & INST_RS2;
            if (rs2 > 7)
            if (rs2 > 7)
                operand2 = sregs->r[(cwp + rs2) & 0x7f];
                operand2 = sregs->r[(cwp + rs2) & 0x7f];
            else
            else
                operand2 = sregs->g[rs2];
                operand2 = sregs->g[rs2];
        }
        }
#endif
#endif
 
 
        if (rd > 7)
        if (rd > 7)
            rdd = &(sregs->r[(cwp + rd) & 0x7f]);
            rdd = &(sregs->r[(cwp + rd) & 0x7f]);
        else
        else
            rdd = &(sregs->g[rd]);
            rdd = &(sregs->g[rd]);
        if (rs1 > 7)
        if (rs1 > 7)
            rs1 = sregs->r[(cwp + rs1) & 0x7f];
            rs1 = sregs->r[(cwp + rs1) & 0x7f];
        else
        else
            rs1 = sregs->g[rs1];
            rs1 = sregs->g[rs1];
    }
    }
    switch (op) {
    switch (op) {
    case 0:
    case 0:
        op2 = (sregs->inst >> 22) & 0x7;
        op2 = (sregs->inst >> 22) & 0x7;
        switch (op2) {
        switch (op2) {
        case SETHI:
        case SETHI:
            rd = (sregs->inst >> 25) & 0x1f;
            rd = (sregs->inst >> 25) & 0x1f;
            if (rd > 7)
            if (rd > 7)
                rdd = &(sregs->r[(cwp + rd) & 0x7f]);
                rdd = &(sregs->r[(cwp + rd) & 0x7f]);
            else
            else
                rdd = &(sregs->g[rd]);
                rdd = &(sregs->g[rd]);
            *rdd = sregs->inst << 10;
            *rdd = sregs->inst << 10;
            break;
            break;
        case BICC:
        case BICC:
#ifdef STAT
#ifdef STAT
            sregs->nbranch++;
            sregs->nbranch++;
#endif
#endif
            icc = sregs->psr >> 20;
            icc = sregs->psr >> 20;
            cond = ((sregs->inst >> 25) & 0x0f);
            cond = ((sregs->inst >> 25) & 0x0f);
            switch (cond) {
            switch (cond) {
            case BICC_BN:
            case BICC_BN:
                eicc = 0;
                eicc = 0;
                break;
                break;
            case BICC_BE:
            case BICC_BE:
                eicc = ICC_Z;
                eicc = ICC_Z;
                break;
                break;
            case BICC_BLE:
            case BICC_BLE:
                eicc = ICC_Z | (ICC_N ^ ICC_V);
                eicc = ICC_Z | (ICC_N ^ ICC_V);
                break;
                break;
            case BICC_BL:
            case BICC_BL:
                eicc = (ICC_N ^ ICC_V);
                eicc = (ICC_N ^ ICC_V);
                break;
                break;
            case BICC_BLEU:
            case BICC_BLEU:
                eicc = ICC_C | ICC_Z;
                eicc = ICC_C | ICC_Z;
                break;
                break;
            case BICC_BCS:
            case BICC_BCS:
                eicc = ICC_C;
                eicc = ICC_C;
                break;
                break;
            case BICC_NEG:
            case BICC_NEG:
                eicc = ICC_N;
                eicc = ICC_N;
                break;
                break;
            case BICC_BVS:
            case BICC_BVS:
                eicc = ICC_V;
                eicc = ICC_V;
                break;
                break;
            case BICC_BA:
            case BICC_BA:
                eicc = 1;
                eicc = 1;
                if (sregs->inst & 0x20000000)
                if (sregs->inst & 0x20000000)
                    sregs->annul = 1;
                    sregs->annul = 1;
                break;
                break;
            case BICC_BNE:
            case BICC_BNE:
                eicc = ~(ICC_Z);
                eicc = ~(ICC_Z);
                break;
                break;
            case BICC_BG:
            case BICC_BG:
                eicc = ~(ICC_Z | (ICC_N ^ ICC_V));
                eicc = ~(ICC_Z | (ICC_N ^ ICC_V));
                break;
                break;
            case BICC_BGE:
            case BICC_BGE:
                eicc = ~(ICC_N ^ ICC_V);
                eicc = ~(ICC_N ^ ICC_V);
                break;
                break;
            case BICC_BGU:
            case BICC_BGU:
                eicc = ~(ICC_C | ICC_Z);
                eicc = ~(ICC_C | ICC_Z);
                break;
                break;
            case BICC_BCC:
            case BICC_BCC:
                eicc = ~(ICC_C);
                eicc = ~(ICC_C);
                break;
                break;
            case BICC_POS:
            case BICC_POS:
                eicc = ~(ICC_N);
                eicc = ~(ICC_N);
                break;
                break;
            case BICC_BVC:
            case BICC_BVC:
                eicc = ~(ICC_V);
                eicc = ~(ICC_V);
                break;
                break;
            }
            }
            if (eicc & 1) {
            if (eicc & 1) {
                operand1 = sregs->inst;
                operand1 = sregs->inst;
                operand1 = ((operand1 << 10) >> 8);     /* sign extend */
                operand1 = ((operand1 << 10) >> 8);     /* sign extend */
                npc = sregs->pc + operand1;
                npc = sregs->pc + operand1;
            } else {
            } else {
                if (sregs->inst & 0x20000000)
                if (sregs->inst & 0x20000000)
                    sregs->annul = 1;
                    sregs->annul = 1;
            }
            }
            break;
            break;
        case FPBCC:
        case FPBCC:
#ifdef STAT
#ifdef STAT
            sregs->nbranch++;
            sregs->nbranch++;
#endif
#endif
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
                sregs->trap = TRAP_FPDIS;
                sregs->trap = TRAP_FPDIS;
                break;
                break;
            }
            }
            if (ebase.simtime < sregs->ftime) {
            if (ebase.simtime < sregs->ftime) {
                sregs->ftime = ebase.simtime + sregs->hold;
                sregs->ftime = ebase.simtime + sregs->hold;
            }
            }
            cond = ((sregs->inst >> 25) & 0x0f);
            cond = ((sregs->inst >> 25) & 0x0f);
            fcc = (sregs->fsr >> 10) & 0x3;
            fcc = (sregs->fsr >> 10) & 0x3;
            switch (cond) {
            switch (cond) {
            case FBN:
            case FBN:
                eicc = 0;
                eicc = 0;
                break;
                break;
            case FBNE:
            case FBNE:
                eicc = (fcc != FCC_E);
                eicc = (fcc != FCC_E);
                break;
                break;
            case FBLG:
            case FBLG:
                eicc = (fcc == FCC_L) || (fcc == FCC_G);
                eicc = (fcc == FCC_L) || (fcc == FCC_G);
                break;
                break;
            case FBUL:
            case FBUL:
                eicc = (fcc == FCC_L) || (fcc == FCC_U);
                eicc = (fcc == FCC_L) || (fcc == FCC_U);
                break;
                break;
            case FBL:
            case FBL:
                eicc = (fcc == FCC_L);
                eicc = (fcc == FCC_L);
                break;
                break;
            case FBUG:
            case FBUG:
                eicc = (fcc == FCC_G) || (fcc == FCC_U);
                eicc = (fcc == FCC_G) || (fcc == FCC_U);
                break;
                break;
            case FBG:
            case FBG:
                eicc = (fcc == FCC_G);
                eicc = (fcc == FCC_G);
                break;
                break;
            case FBU:
            case FBU:
                eicc = (fcc == FCC_U);
                eicc = (fcc == FCC_U);
                break;
                break;
            case FBA:
            case FBA:
                eicc = 1;
                eicc = 1;
                if (sregs->inst & 0x20000000)
                if (sregs->inst & 0x20000000)
                    sregs->annul = 1;
                    sregs->annul = 1;
                break;
                break;
            case FBE:
            case FBE:
                eicc = !(fcc != FCC_E);
                eicc = !(fcc != FCC_E);
                break;
                break;
            case FBUE:
            case FBUE:
                eicc = !((fcc == FCC_L) || (fcc == FCC_G));
                eicc = !((fcc == FCC_L) || (fcc == FCC_G));
                break;
                break;
            case FBGE:
            case FBGE:
                eicc = !((fcc == FCC_L) || (fcc == FCC_U));
                eicc = !((fcc == FCC_L) || (fcc == FCC_U));
                break;
                break;
            case FBUGE:
            case FBUGE:
                eicc = !(fcc == FCC_L);
                eicc = !(fcc == FCC_L);
                break;
                break;
            case FBLE:
            case FBLE:
                eicc = !((fcc == FCC_G) || (fcc == FCC_U));
                eicc = !((fcc == FCC_G) || (fcc == FCC_U));
                break;
                break;
            case FBULE:
            case FBULE:
                eicc = !(fcc == FCC_G);
                eicc = !(fcc == FCC_G);
                break;
                break;
            case FBO:
            case FBO:
                eicc = !(fcc == FCC_U);
                eicc = !(fcc == FCC_U);
                break;
                break;
            }
            }
            if (eicc) {
            if (eicc) {
                operand1 = sregs->inst;
                operand1 = sregs->inst;
                operand1 = ((operand1 << 10) >> 8);     /* sign extend */
                operand1 = ((operand1 << 10) >> 8);     /* sign extend */
                npc = sregs->pc + operand1;
                npc = sregs->pc + operand1;
            } else {
            } else {
                if (sregs->inst & 0x20000000)
                if (sregs->inst & 0x20000000)
                    sregs->annul = 1;
                    sregs->annul = 1;
            }
            }
            break;
            break;
 
 
        default:
        default:
            sregs->trap = TRAP_UNIMP;
            sregs->trap = TRAP_UNIMP;
            break;
            break;
        }
        }
        break;
        break;
    case 1:                     /* CALL */
    case 1:                     /* CALL */
#ifdef STAT
#ifdef STAT
        sregs->nbranch++;
        sregs->nbranch++;
#endif
#endif
        sregs->r[(cwp + 15) & 0x7f] = sregs->pc;
        sregs->r[(cwp + 15) & 0x7f] = sregs->pc;
        npc = sregs->pc + (sregs->inst << 2);
        npc = sregs->pc + (sregs->inst << 2);
        break;
        break;
 
 
    case 2:
    case 2:
        if ((op3 >> 1) == 0x1a) {
        if ((op3 >> 1) == 0x1a) {
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
                sregs->trap = TRAP_FPDIS;
                sregs->trap = TRAP_FPDIS;
            } else {
            } else {
                rs1 = (sregs->inst >> 14) & 0x1f;
                rs1 = (sregs->inst >> 14) & 0x1f;
                rs2 = sregs->inst & 0x1f;
                rs2 = sregs->inst & 0x1f;
                sregs->trap = fpexec(op3, rd, rs1, rs2, sregs);
                sregs->trap = fpexec(op3, rd, rs1, rs2, sregs);
            }
            }
        } else {
        } else {
 
 
            switch (op3) {
            switch (op3) {
            case TICC:
            case TICC:
                icc = sregs->psr >> 20;
                icc = sregs->psr >> 20;
                cond = ((sregs->inst >> 25) & 0x0f);
                cond = ((sregs->inst >> 25) & 0x0f);
                switch (cond) {
                switch (cond) {
                case BICC_BN:
                case BICC_BN:
                    eicc = 0;
                    eicc = 0;
                    break;
                    break;
                case BICC_BE:
                case BICC_BE:
                    eicc = ICC_Z;
                    eicc = ICC_Z;
                    break;
                    break;
                case BICC_BLE:
                case BICC_BLE:
                    eicc = ICC_Z | (ICC_N ^ ICC_V);
                    eicc = ICC_Z | (ICC_N ^ ICC_V);
                    break;
                    break;
                case BICC_BL:
                case BICC_BL:
                    eicc = (ICC_N ^ ICC_V);
                    eicc = (ICC_N ^ ICC_V);
                    break;
                    break;
                case BICC_BLEU:
                case BICC_BLEU:
                    eicc = ICC_C | ICC_Z;
                    eicc = ICC_C | ICC_Z;
                    break;
                    break;
                case BICC_BCS:
                case BICC_BCS:
                    eicc = ICC_C;
                    eicc = ICC_C;
                    break;
                    break;
                case BICC_NEG:
                case BICC_NEG:
                    eicc = ICC_N;
                    eicc = ICC_N;
                    break;
                    break;
                case BICC_BVS:
                case BICC_BVS:
                    eicc = ICC_V;
                    eicc = ICC_V;
                    break;
                    break;
                case BICC_BA:
                case BICC_BA:
                    eicc = 1;
                    eicc = 1;
                    break;
                    break;
                case BICC_BNE:
                case BICC_BNE:
                    eicc = ~(ICC_Z);
                    eicc = ~(ICC_Z);
                    break;
                    break;
                case BICC_BG:
                case BICC_BG:
                    eicc = ~(ICC_Z | (ICC_N ^ ICC_V));
                    eicc = ~(ICC_Z | (ICC_N ^ ICC_V));
                    break;
                    break;
                case BICC_BGE:
                case BICC_BGE:
                    eicc = ~(ICC_N ^ ICC_V);
                    eicc = ~(ICC_N ^ ICC_V);
                    break;
                    break;
                case BICC_BGU:
                case BICC_BGU:
                    eicc = ~(ICC_C | ICC_Z);
                    eicc = ~(ICC_C | ICC_Z);
                    break;
                    break;
                case BICC_BCC:
                case BICC_BCC:
                    eicc = ~(ICC_C);
                    eicc = ~(ICC_C);
                    break;
                    break;
                case BICC_POS:
                case BICC_POS:
                    eicc = ~(ICC_N);
                    eicc = ~(ICC_N);
                    break;
                    break;
                case BICC_BVC:
                case BICC_BVC:
                    eicc = ~(ICC_V);
                    eicc = ~(ICC_V);
                    break;
                    break;
                }
                }
                if (eicc & 1) {
                if (eicc & 1) {
                    sregs->trap = (0x80 | ((rs1 + operand2) & 0x7f));
                    sregs->trap = (0x80 | ((rs1 + operand2) & 0x7f));
                }
                }
                break;
                break;
 
 
            case MULScc:
            case MULScc:
                operand1 =
                operand1 =
                    (((sregs->psr & PSR_V) ^ ((sregs->psr & PSR_N) >> 2))
                    (((sregs->psr & PSR_V) ^ ((sregs->psr & PSR_N) >> 2))
                     << 10) | (rs1 >> 1);
                     << 10) | (rs1 >> 1);
                if ((sregs->y & 1) == 0)
                if ((sregs->y & 1) == 0)
                    operand2 = 0;
                    operand2 = 0;
                *rdd = operand1 + operand2;
                *rdd = operand1 + operand2;
                sregs->y = (rs1 << 31) | (sregs->y >> 1);
                sregs->y = (rs1 << 31) | (sregs->y >> 1);
                sregs->psr = add_cc(sregs->psr, operand1, operand2, *rdd);
                sregs->psr = add_cc(sregs->psr, operand1, operand2, *rdd);
                break;
                break;
            case DIVScc:
            case DIVScc:
                {
                {
                  int sign;
                  int sign;
                  uint32 result, remainder;
                  uint32 result, remainder;
                  int c0, y31;
                  int c0, y31;
 
 
                  if (!sparclite) {
                  if (!sparclite) {
                     sregs->trap = TRAP_UNIMP;
                     sregs->trap = TRAP_UNIMP;
                     break;
                     break;
                  }
                  }
 
 
                  sign = ((sregs->psr & PSR_V) != 0) ^ ((sregs->psr & PSR_N) != 0);
                  sign = ((sregs->psr & PSR_V) != 0) ^ ((sregs->psr & PSR_N) != 0);
 
 
                  remainder = (sregs->y << 1) | (rs1 >> 31);
                  remainder = (sregs->y << 1) | (rs1 >> 31);
 
 
                  /* If true sign is positive, calculate remainder - divisor.
                  /* If true sign is positive, calculate remainder - divisor.
                     Otherwise, calculate remainder + divisor.  */
                     Otherwise, calculate remainder + divisor.  */
                  if (sign == 0)
                  if (sign == 0)
                    operand2 = ~operand2 + 1;
                    operand2 = ~operand2 + 1;
                  result = remainder + operand2;
                  result = remainder + operand2;
 
 
                  /* The SPARClite User's Manual is not clear on how
                  /* The SPARClite User's Manual is not clear on how
                     the "carry out" of the above ALU operation is to
                     the "carry out" of the above ALU operation is to
                     be calculated.  From trial and error tests
                     be calculated.  From trial and error tests
                     on the the chip itself, it appears that it is
                     on the the chip itself, it appears that it is
                     a normal addition carry, and not a subtraction borrow,
                     a normal addition carry, and not a subtraction borrow,
                     even in cases where the divisor is subtracted
                     even in cases where the divisor is subtracted
                     from the remainder.  FIXME: get the true story
                     from the remainder.  FIXME: get the true story
                     from Fujitsu. */
                     from Fujitsu. */
                  c0 = result < (uint32) remainder
                  c0 = result < (uint32) remainder
                       || result < (uint32) operand2;
                       || result < (uint32) operand2;
 
 
                  if (result & 0x80000000)
                  if (result & 0x80000000)
                    sregs->psr |= PSR_N;
                    sregs->psr |= PSR_N;
                  else
                  else
                    sregs->psr &= ~PSR_N;
                    sregs->psr &= ~PSR_N;
 
 
                  y31 = (sregs->y & 0x80000000) == 0x80000000;
                  y31 = (sregs->y & 0x80000000) == 0x80000000;
 
 
                  if (result == 0 && sign == y31)
                  if (result == 0 && sign == y31)
                    sregs->psr |= PSR_Z;
                    sregs->psr |= PSR_Z;
                  else
                  else
                    sregs->psr &= ~PSR_Z;
                    sregs->psr &= ~PSR_Z;
 
 
                  sign = (sign && !y31) || (!c0 && (sign || !y31));
                  sign = (sign && !y31) || (!c0 && (sign || !y31));
 
 
                  if (sign ^ (result >> 31))
                  if (sign ^ (result >> 31))
                    sregs->psr |= PSR_V;
                    sregs->psr |= PSR_V;
                  else
                  else
                    sregs->psr &= ~PSR_V;
                    sregs->psr &= ~PSR_V;
 
 
                  if (!sign)
                  if (!sign)
                    sregs->psr |= PSR_C;
                    sregs->psr |= PSR_C;
                  else
                  else
                    sregs->psr &= ~PSR_C;
                    sregs->psr &= ~PSR_C;
 
 
                  sregs->y = result;
                  sregs->y = result;
 
 
                  if (rd != 0)
                  if (rd != 0)
                    *rdd = (rs1 << 1) | !sign;
                    *rdd = (rs1 << 1) | !sign;
                }
                }
                break;
                break;
            case SMUL:
            case SMUL:
                {
                {
                  mul64 (rs1, operand2, &sregs->y, rdd, 1);
                  mul64 (rs1, operand2, &sregs->y, rdd, 1);
                }
                }
                break;
                break;
            case SMULCC:
            case SMULCC:
                {
                {
                  uint32 result;
                  uint32 result;
 
 
                  mul64 (rs1, operand2, &sregs->y, &result, 1);
                  mul64 (rs1, operand2, &sregs->y, &result, 1);
 
 
                  if (result & 0x80000000)
                  if (result & 0x80000000)
                    sregs->psr |= PSR_N;
                    sregs->psr |= PSR_N;
                  else
                  else
                    sregs->psr &= ~PSR_N;
                    sregs->psr &= ~PSR_N;
 
 
                  if (result == 0)
                  if (result == 0)
                    sregs->psr |= PSR_Z;
                    sregs->psr |= PSR_Z;
                  else
                  else
                    sregs->psr &= ~PSR_Z;
                    sregs->psr &= ~PSR_Z;
 
 
                  *rdd = result;
                  *rdd = result;
                }
                }
                break;
                break;
            case UMUL:
            case UMUL:
                {
                {
                  mul64 (rs1, operand2, &sregs->y, rdd, 0);
                  mul64 (rs1, operand2, &sregs->y, rdd, 0);
                }
                }
                break;
                break;
            case UMULCC:
            case UMULCC:
                {
                {
                  uint32 result;
                  uint32 result;
 
 
                  mul64 (rs1, operand2, &sregs->y, &result, 0);
                  mul64 (rs1, operand2, &sregs->y, &result, 0);
 
 
                  if (result & 0x80000000)
                  if (result & 0x80000000)
                    sregs->psr |= PSR_N;
                    sregs->psr |= PSR_N;
                  else
                  else
                    sregs->psr &= ~PSR_N;
                    sregs->psr &= ~PSR_N;
 
 
                  if (result == 0)
                  if (result == 0)
                    sregs->psr |= PSR_Z;
                    sregs->psr |= PSR_Z;
                  else
                  else
                    sregs->psr &= ~PSR_Z;
                    sregs->psr &= ~PSR_Z;
 
 
                  *rdd = result;
                  *rdd = result;
                }
                }
                break;
                break;
            case SDIV:
            case SDIV:
                {
                {
                  if (sparclite) {
                  if (sparclite) {
                     sregs->trap = TRAP_UNIMP;
                     sregs->trap = TRAP_UNIMP;
                     break;
                     break;
                  }
                  }
 
 
                  if (operand2 == 0) {
                  if (operand2 == 0) {
                    sregs->trap = TRAP_DIV0;
                    sregs->trap = TRAP_DIV0;
                    break;
                    break;
                  }
                  }
 
 
                  div64 (sregs->y, rs1, operand2, rdd, 1);
                  div64 (sregs->y, rs1, operand2, rdd, 1);
                }
                }
                break;
                break;
            case SDIVCC:
            case SDIVCC:
                {
                {
                  uint32 result;
                  uint32 result;
 
 
                  if (sparclite) {
                  if (sparclite) {
                     sregs->trap = TRAP_UNIMP;
                     sregs->trap = TRAP_UNIMP;
                     break;
                     break;
                  }
                  }
 
 
                  if (operand2 == 0) {
                  if (operand2 == 0) {
                    sregs->trap = TRAP_DIV0;
                    sregs->trap = TRAP_DIV0;
                    break;
                    break;
                  }
                  }
 
 
                  div64 (sregs->y, rs1, operand2, &result, 1);
                  div64 (sregs->y, rs1, operand2, &result, 1);
 
 
                  if (result & 0x80000000)
                  if (result & 0x80000000)
                    sregs->psr |= PSR_N;
                    sregs->psr |= PSR_N;
                  else
                  else
                    sregs->psr &= ~PSR_N;
                    sregs->psr &= ~PSR_N;
 
 
                  if (result == 0)
                  if (result == 0)
                    sregs->psr |= PSR_Z;
                    sregs->psr |= PSR_Z;
                  else
                  else
                    sregs->psr &= ~PSR_Z;
                    sregs->psr &= ~PSR_Z;
 
 
                  /* FIXME: should set overflow flag correctly.  */
                  /* FIXME: should set overflow flag correctly.  */
                  sregs->psr &= ~(PSR_C | PSR_V);
                  sregs->psr &= ~(PSR_C | PSR_V);
 
 
                  *rdd = result;
                  *rdd = result;
                }
                }
                break;
                break;
            case UDIV:
            case UDIV:
                {
                {
                  if (sparclite) {
                  if (sparclite) {
                     sregs->trap = TRAP_UNIMP;
                     sregs->trap = TRAP_UNIMP;
                     break;
                     break;
                  }
                  }
 
 
                  if (operand2 == 0) {
                  if (operand2 == 0) {
                    sregs->trap = TRAP_DIV0;
                    sregs->trap = TRAP_DIV0;
                    break;
                    break;
                  }
                  }
 
 
                  div64 (sregs->y, rs1, operand2, rdd, 0);
                  div64 (sregs->y, rs1, operand2, rdd, 0);
                }
                }
                break;
                break;
            case UDIVCC:
            case UDIVCC:
                {
                {
                  uint32 result;
                  uint32 result;
 
 
                  if (sparclite) {
                  if (sparclite) {
                     sregs->trap = TRAP_UNIMP;
                     sregs->trap = TRAP_UNIMP;
                     break;
                     break;
                  }
                  }
 
 
                  if (operand2 == 0) {
                  if (operand2 == 0) {
                    sregs->trap = TRAP_DIV0;
                    sregs->trap = TRAP_DIV0;
                    break;
                    break;
                  }
                  }
 
 
                  div64 (sregs->y, rs1, operand2, &result, 0);
                  div64 (sregs->y, rs1, operand2, &result, 0);
 
 
                  if (result & 0x80000000)
                  if (result & 0x80000000)
                    sregs->psr |= PSR_N;
                    sregs->psr |= PSR_N;
                  else
                  else
                    sregs->psr &= ~PSR_N;
                    sregs->psr &= ~PSR_N;
 
 
                  if (result == 0)
                  if (result == 0)
                    sregs->psr |= PSR_Z;
                    sregs->psr |= PSR_Z;
                  else
                  else
                    sregs->psr &= ~PSR_Z;
                    sregs->psr &= ~PSR_Z;
 
 
                  /* FIXME: should set overflow flag correctly.  */
                  /* FIXME: should set overflow flag correctly.  */
                  sregs->psr &= ~(PSR_C | PSR_V);
                  sregs->psr &= ~(PSR_C | PSR_V);
 
 
                  *rdd = result;
                  *rdd = result;
                }
                }
                break;
                break;
            case IXNOR:
            case IXNOR:
                *rdd = rs1 ^ ~operand2;
                *rdd = rs1 ^ ~operand2;
                break;
                break;
            case IXNORCC:
            case IXNORCC:
                *rdd = rs1 ^ ~operand2;
                *rdd = rs1 ^ ~operand2;
                log_cc(*rdd, sregs);
                log_cc(*rdd, sregs);
                break;
                break;
            case IXOR:
            case IXOR:
                *rdd = rs1 ^ operand2;
                *rdd = rs1 ^ operand2;
                break;
                break;
            case IXORCC:
            case IXORCC:
                *rdd = rs1 ^ operand2;
                *rdd = rs1 ^ operand2;
                log_cc(*rdd, sregs);
                log_cc(*rdd, sregs);
                break;
                break;
            case IOR:
            case IOR:
                *rdd = rs1 | operand2;
                *rdd = rs1 | operand2;
                break;
                break;
            case IORCC:
            case IORCC:
                *rdd = rs1 | operand2;
                *rdd = rs1 | operand2;
                log_cc(*rdd, sregs);
                log_cc(*rdd, sregs);
                break;
                break;
            case IORN:
            case IORN:
                *rdd = rs1 | ~operand2;
                *rdd = rs1 | ~operand2;
                break;
                break;
            case IORNCC:
            case IORNCC:
                *rdd = rs1 | ~operand2;
                *rdd = rs1 | ~operand2;
                log_cc(*rdd, sregs);
                log_cc(*rdd, sregs);
                break;
                break;
            case IANDNCC:
            case IANDNCC:
                *rdd = rs1 & ~operand2;
                *rdd = rs1 & ~operand2;
                log_cc(*rdd, sregs);
                log_cc(*rdd, sregs);
                break;
                break;
            case IANDN:
            case IANDN:
                *rdd = rs1 & ~operand2;
                *rdd = rs1 & ~operand2;
                break;
                break;
            case IAND:
            case IAND:
                *rdd = rs1 & operand2;
                *rdd = rs1 & operand2;
                break;
                break;
            case IANDCC:
            case IANDCC:
                *rdd = rs1 & operand2;
                *rdd = rs1 & operand2;
                log_cc(*rdd, sregs);
                log_cc(*rdd, sregs);
                break;
                break;
            case SUB:
            case SUB:
                *rdd = rs1 - operand2;
                *rdd = rs1 - operand2;
                break;
                break;
            case SUBCC:
            case SUBCC:
                *rdd = rs1 - operand2;
                *rdd = rs1 - operand2;
                sregs->psr = sub_cc(sregs->psr, rs1, operand2, *rdd);
                sregs->psr = sub_cc(sregs->psr, rs1, operand2, *rdd);
                break;
                break;
            case SUBX:
            case SUBX:
                *rdd = rs1 - operand2 - ((sregs->psr >> 20) & 1);
                *rdd = rs1 - operand2 - ((sregs->psr >> 20) & 1);
                break;
                break;
            case SUBXCC:
            case SUBXCC:
                *rdd = rs1 - operand2 - ((sregs->psr >> 20) & 1);
                *rdd = rs1 - operand2 - ((sregs->psr >> 20) & 1);
                sregs->psr = sub_cc(sregs->psr, rs1, operand2, *rdd);
                sregs->psr = sub_cc(sregs->psr, rs1, operand2, *rdd);
                break;
                break;
            case ADD:
            case ADD:
                *rdd = rs1 + operand2;
                *rdd = rs1 + operand2;
                break;
                break;
            case ADDCC:
            case ADDCC:
                *rdd = rs1 + operand2;
                *rdd = rs1 + operand2;
                sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd);
                sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd);
                break;
                break;
            case ADDX:
            case ADDX:
                *rdd = rs1 + operand2 + ((sregs->psr >> 20) & 1);
                *rdd = rs1 + operand2 + ((sregs->psr >> 20) & 1);
                break;
                break;
            case ADDXCC:
            case ADDXCC:
                *rdd = rs1 + operand2 + ((sregs->psr >> 20) & 1);
                *rdd = rs1 + operand2 + ((sregs->psr >> 20) & 1);
                sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd);
                sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd);
                break;
                break;
            case TADDCC:
            case TADDCC:
                *rdd = rs1 + operand2;
                *rdd = rs1 + operand2;
                sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd);
                sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd);
                if ((rs1 | operand2) & 0x3)
                if ((rs1 | operand2) & 0x3)
                    sregs->psr |= PSR_V;
                    sregs->psr |= PSR_V;
                break;
                break;
            case TSUBCC:
            case TSUBCC:
                *rdd = rs1 - operand2;
                *rdd = rs1 - operand2;
                sregs->psr = sub_cc (sregs->psr, rs1, operand2, *rdd);
                sregs->psr = sub_cc (sregs->psr, rs1, operand2, *rdd);
                if ((rs1 | operand2) & 0x3)
                if ((rs1 | operand2) & 0x3)
                    sregs->psr |= PSR_V;
                    sregs->psr |= PSR_V;
                break;
                break;
            case TADDCCTV:
            case TADDCCTV:
                *rdd = rs1 + operand2;
                *rdd = rs1 + operand2;
                result = add_cc(0, rs1, operand2, *rdd);
                result = add_cc(0, rs1, operand2, *rdd);
                if ((rs1 | operand2) & 0x3)
                if ((rs1 | operand2) & 0x3)
                    result |= PSR_V;
                    result |= PSR_V;
                if (result & PSR_V) {
                if (result & PSR_V) {
                    sregs->trap = TRAP_TAG;
                    sregs->trap = TRAP_TAG;
                } else {
                } else {
                    sregs->psr = (sregs->psr & ~PSR_CC) | result;
                    sregs->psr = (sregs->psr & ~PSR_CC) | result;
                }
                }
                break;
                break;
            case TSUBCCTV:
            case TSUBCCTV:
                *rdd = rs1 - operand2;
                *rdd = rs1 - operand2;
                result = add_cc (0, rs1, operand2, *rdd);
                result = add_cc (0, rs1, operand2, *rdd);
                if ((rs1 | operand2) & 0x3)
                if ((rs1 | operand2) & 0x3)
                    result |= PSR_V;
                    result |= PSR_V;
                if (result & PSR_V)
                if (result & PSR_V)
                  {
                  {
                      sregs->trap = TRAP_TAG;
                      sregs->trap = TRAP_TAG;
                  }
                  }
                else
                else
                  {
                  {
                      sregs->psr = (sregs->psr & ~PSR_CC) | result;
                      sregs->psr = (sregs->psr & ~PSR_CC) | result;
                  }
                  }
                break;
                break;
            case SLL:
            case SLL:
                *rdd = rs1 << (operand2 & 0x1f);
                *rdd = rs1 << (operand2 & 0x1f);
                break;
                break;
            case SRL:
            case SRL:
                *rdd = rs1 >> (operand2 & 0x1f);
                *rdd = rs1 >> (operand2 & 0x1f);
                break;
                break;
            case SRA:
            case SRA:
                *rdd = ((int) rs1) >> (operand2 & 0x1f);
                *rdd = ((int) rs1) >> (operand2 & 0x1f);
                break;
                break;
            case FLUSH:
            case FLUSH:
                if (ift) sregs->trap = TRAP_UNIMP;
                if (ift) sregs->trap = TRAP_UNIMP;
                break;
                break;
            case SAVE:
            case SAVE:
                new_cwp = ((sregs->psr & PSR_CWP) - 1) & PSR_CWP;
                new_cwp = ((sregs->psr & PSR_CWP) - 1) & PSR_CWP;
                if (sregs->wim & (1 << new_cwp)) {
                if (sregs->wim & (1 << new_cwp)) {
                    sregs->trap = TRAP_WOFL;
                    sregs->trap = TRAP_WOFL;
                    break;
                    break;
                }
                }
                if (rd > 7)
                if (rd > 7)
                    rdd = &(sregs->r[((new_cwp << 4) + rd) & 0x7f]);
                    rdd = &(sregs->r[((new_cwp << 4) + rd) & 0x7f]);
                *rdd = rs1 + operand2;
                *rdd = rs1 + operand2;
                sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp;
                sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp;
                break;
                break;
            case RESTORE:
            case RESTORE:
 
 
                new_cwp = ((sregs->psr & PSR_CWP) + 1) & PSR_CWP;
                new_cwp = ((sregs->psr & PSR_CWP) + 1) & PSR_CWP;
                if (sregs->wim & (1 << new_cwp)) {
                if (sregs->wim & (1 << new_cwp)) {
                    sregs->trap = TRAP_WUFL;
                    sregs->trap = TRAP_WUFL;
                    break;
                    break;
                }
                }
                if (rd > 7)
                if (rd > 7)
                    rdd = &(sregs->r[((new_cwp << 4) + rd) & 0x7f]);
                    rdd = &(sregs->r[((new_cwp << 4) + rd) & 0x7f]);
                *rdd = rs1 + operand2;
                *rdd = rs1 + operand2;
                sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp;
                sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp;
                break;
                break;
            case RDPSR:
            case RDPSR:
                if (!(sregs->psr & PSR_S)) {
                if (!(sregs->psr & PSR_S)) {
                    sregs->trap = TRAP_PRIVI;
                    sregs->trap = TRAP_PRIVI;
                    break;
                    break;
                }
                }
                *rdd = sregs->psr;
                *rdd = sregs->psr;
                break;
                break;
            case RDY:
            case RDY:
                if (!sparclite)
                if (!sparclite)
                    *rdd = sregs->y;
                    *rdd = sregs->y;
                else {
                else {
                    int rs1_is_asr = (sregs->inst >> 14) & 0x1f;
                    int rs1_is_asr = (sregs->inst >> 14) & 0x1f;
                    if ( 0 == rs1_is_asr )
                    if ( 0 == rs1_is_asr )
                        *rdd = sregs->y;
                        *rdd = sregs->y;
                    else if ( 17 == rs1_is_asr )
                    else if ( 17 == rs1_is_asr )
                        *rdd = sregs->asr17;
                        *rdd = sregs->asr17;
                    else {
                    else {
                        sregs->trap = TRAP_UNIMP;
                        sregs->trap = TRAP_UNIMP;
                        break;
                        break;
                    }
                    }
                }
                }
                break;
                break;
            case RDWIM:
            case RDWIM:
                if (!(sregs->psr & PSR_S)) {
                if (!(sregs->psr & PSR_S)) {
                    sregs->trap = TRAP_PRIVI;
                    sregs->trap = TRAP_PRIVI;
                    break;
                    break;
                }
                }
                *rdd = sregs->wim;
                *rdd = sregs->wim;
                break;
                break;
            case RDTBR:
            case RDTBR:
                if (!(sregs->psr & PSR_S)) {
                if (!(sregs->psr & PSR_S)) {
                    sregs->trap = TRAP_PRIVI;
                    sregs->trap = TRAP_PRIVI;
                    break;
                    break;
                }
                }
                *rdd = sregs->tbr;
                *rdd = sregs->tbr;
                break;
                break;
            case WRPSR:
            case WRPSR:
                if ((sregs->psr & 0x1f) > 7) {
                if ((sregs->psr & 0x1f) > 7) {
                    sregs->trap = TRAP_UNIMP;
                    sregs->trap = TRAP_UNIMP;
                    break;
                    break;
                }
                }
                if (!(sregs->psr & PSR_S)) {
                if (!(sregs->psr & PSR_S)) {
                    sregs->trap = TRAP_PRIVI;
                    sregs->trap = TRAP_PRIVI;
                    break;
                    break;
                }
                }
                sregs->psr = (rs1 ^ operand2) & 0x00f03fff;
                sregs->psr = (rs1 ^ operand2) & 0x00f03fff;
                break;
                break;
            case WRWIM:
            case WRWIM:
                if (!(sregs->psr & PSR_S)) {
                if (!(sregs->psr & PSR_S)) {
                    sregs->trap = TRAP_PRIVI;
                    sregs->trap = TRAP_PRIVI;
                    break;
                    break;
                }
                }
                sregs->wim = (rs1 ^ operand2) & 0x0ff;
                sregs->wim = (rs1 ^ operand2) & 0x0ff;
                break;
                break;
            case WRTBR:
            case WRTBR:
                if (!(sregs->psr & PSR_S)) {
                if (!(sregs->psr & PSR_S)) {
                    sregs->trap = TRAP_PRIVI;
                    sregs->trap = TRAP_PRIVI;
                    break;
                    break;
                }
                }
                sregs->tbr = (sregs->tbr & 0x00000ff0) |
                sregs->tbr = (sregs->tbr & 0x00000ff0) |
                    ((rs1 ^ operand2) & 0xfffff000);
                    ((rs1 ^ operand2) & 0xfffff000);
                break;
                break;
            case WRY:
            case WRY:
                if (!sparclite)
                if (!sparclite)
                    sregs->y = (rs1 ^ operand2);
                    sregs->y = (rs1 ^ operand2);
                else {
                else {
                    if ( 0 == rd )
                    if ( 0 == rd )
                        sregs->y = (rs1 ^ operand2);
                        sregs->y = (rs1 ^ operand2);
                    else if ( 17 == rd )
                    else if ( 17 == rd )
                        sregs->asr17 = (rs1 ^ operand2);
                        sregs->asr17 = (rs1 ^ operand2);
                    else {
                    else {
                        sregs->trap = TRAP_UNIMP;
                        sregs->trap = TRAP_UNIMP;
                        break;
                        break;
                    }
                    }
                }
                }
                break;
                break;
            case JMPL:
            case JMPL:
 
 
#ifdef STAT
#ifdef STAT
                sregs->nbranch++;
                sregs->nbranch++;
#endif
#endif
                sregs->icnt = T_JMPL;   /* JMPL takes two cycles */
                sregs->icnt = T_JMPL;   /* JMPL takes two cycles */
                if (rs1 & 0x3) {
                if (rs1 & 0x3) {
                    sregs->trap = TRAP_UNALI;
                    sregs->trap = TRAP_UNALI;
                    break;
                    break;
                }
                }
                *rdd = sregs->pc;
                *rdd = sregs->pc;
                npc = rs1 + operand2;
                npc = rs1 + operand2;
                break;
                break;
            case RETT:
            case RETT:
                address = rs1 + operand2;
                address = rs1 + operand2;
                new_cwp = ((sregs->psr & PSR_CWP) + 1) & PSR_CWP;
                new_cwp = ((sregs->psr & PSR_CWP) + 1) & PSR_CWP;
                sregs->icnt = T_RETT;   /* RETT takes two cycles */
                sregs->icnt = T_RETT;   /* RETT takes two cycles */
                if (sregs->psr & PSR_ET) {
                if (sregs->psr & PSR_ET) {
                    sregs->trap = TRAP_UNIMP;
                    sregs->trap = TRAP_UNIMP;
                    break;
                    break;
                }
                }
                if (!(sregs->psr & PSR_S)) {
                if (!(sregs->psr & PSR_S)) {
                    sregs->trap = TRAP_PRIVI;
                    sregs->trap = TRAP_PRIVI;
                    break;
                    break;
                }
                }
                if (sregs->wim & (1 << new_cwp)) {
                if (sregs->wim & (1 << new_cwp)) {
                    sregs->trap = TRAP_WUFL;
                    sregs->trap = TRAP_WUFL;
                    break;
                    break;
                }
                }
                if (address & 0x3) {
                if (address & 0x3) {
                    sregs->trap = TRAP_UNALI;
                    sregs->trap = TRAP_UNALI;
                    break;
                    break;
                }
                }
                sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp | PSR_ET;
                sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp | PSR_ET;
                sregs->psr =
                sregs->psr =
                    (sregs->psr & ~PSR_S) | ((sregs->psr & PSR_PS) << 1);
                    (sregs->psr & ~PSR_S) | ((sregs->psr & PSR_PS) << 1);
                npc = address;
                npc = address;
                break;
                break;
 
 
            case SCAN:
            case SCAN:
                {
                {
                  uint32 result, mask;
                  uint32 result, mask;
                  int i;
                  int i;
 
 
                  if (!sparclite) {
                  if (!sparclite) {
                     sregs->trap = TRAP_UNIMP;
                     sregs->trap = TRAP_UNIMP;
                     break;
                     break;
                  }
                  }
                  mask = (operand2 & 0x80000000) | (operand2 >> 1);
                  mask = (operand2 & 0x80000000) | (operand2 >> 1);
                  result = rs1 ^ mask;
                  result = rs1 ^ mask;
 
 
                  for (i = 0; i < 32; i++) {
                  for (i = 0; i < 32; i++) {
                    if (result & 0x80000000)
                    if (result & 0x80000000)
                      break;
                      break;
                    result <<= 1;
                    result <<= 1;
                  }
                  }
 
 
                  *rdd = i == 32 ? 63 : i;
                  *rdd = i == 32 ? 63 : i;
                }
                }
                break;
                break;
 
 
            default:
            default:
                sregs->trap = TRAP_UNIMP;
                sregs->trap = TRAP_UNIMP;
                break;
                break;
            }
            }
        }
        }
        break;
        break;
    case 3:                     /* Load/store instructions */
    case 3:                     /* Load/store instructions */
 
 
        address = rs1 + operand2;
        address = rs1 + operand2;
 
 
        if (sregs->psr & PSR_S)
        if (sregs->psr & PSR_S)
            asi = 11;
            asi = 11;
         else
         else
            asi = 10;
            asi = 10;
 
 
        if (op3 & 4) {
        if (op3 & 4) {
            sregs->icnt = T_ST; /* Set store instruction count */
            sregs->icnt = T_ST; /* Set store instruction count */
#ifdef STAT
#ifdef STAT
            sregs->nstore++;
            sregs->nstore++;
#endif
#endif
        } else {
        } else {
            sregs->icnt = T_LD; /* Set load instruction count */
            sregs->icnt = T_LD; /* Set load instruction count */
#ifdef STAT
#ifdef STAT
            sregs->nload++;
            sregs->nload++;
#endif
#endif
        }
        }
 
 
        /* Decode load/store instructions */
        /* Decode load/store instructions */
 
 
        switch (op3) {
        switch (op3) {
        case LDDA:
        case LDDA:
            if (!chk_asi(sregs, &asi, op3)) break;
            if (!chk_asi(sregs, &asi, op3)) break;
        case LDD:
        case LDD:
            if (address & 0x7) {
            if (address & 0x7) {
                sregs->trap = TRAP_UNALI;
                sregs->trap = TRAP_UNALI;
                break;
                break;
            }
            }
            if (rd & 1) {
            if (rd & 1) {
                rd &= 0x1e;
                rd &= 0x1e;
                if (rd > 7)
                if (rd > 7)
                    rdd = &(sregs->r[(cwp + rd) & 0x7f]);
                    rdd = &(sregs->r[(cwp + rd) & 0x7f]);
                else
                else
                    rdd = &(sregs->g[rd]);
                    rdd = &(sregs->g[rd]);
            }
            }
            mexc = memory_read(asi, address, ddata, 3, &ws);
            mexc = memory_read(asi, address, ddata, 3, &ws);
            sregs->hold += ws * 2;
            sregs->hold += ws * 2;
            sregs->icnt = T_LDD;
            sregs->icnt = T_LDD;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
            } else {
            } else {
                rdd[0] = ddata[0];
                rdd[0] = ddata[0];
                rdd[1] = ddata[1];
                rdd[1] = ddata[1];
#ifdef STAT
#ifdef STAT
                sregs->nload++; /* Double load counts twice */
                sregs->nload++; /* Double load counts twice */
#endif
#endif
            }
            }
            break;
            break;
 
 
        case LDA:
        case LDA:
            if (!chk_asi(sregs, &asi, op3)) break;
            if (!chk_asi(sregs, &asi, op3)) break;
        case LD:
        case LD:
            if (address & 0x3) {
            if (address & 0x3) {
                sregs->trap = TRAP_UNALI;
                sregs->trap = TRAP_UNALI;
                break;
                break;
            }
            }
            mexc = memory_read(asi, address, &data, 2, &ws);
            mexc = memory_read(asi, address, &data, 2, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
            } else {
            } else {
                *rdd = data;
                *rdd = data;
            }
            }
            break;
            break;
        case LDSTUBA:
        case LDSTUBA:
            if (!chk_asi(sregs, &asi, op3)) break;
            if (!chk_asi(sregs, &asi, op3)) break;
        case LDSTUB:
        case LDSTUB:
            mexc = memory_read(asi, address, &data, 0, &ws);
            mexc = memory_read(asi, address, &data, 0, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            sregs->icnt = T_LDST;
            sregs->icnt = T_LDST;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
                break;
                break;
            }
            }
            *rdd = data;
            *rdd = data;
            data = 0x0ff;
            data = 0x0ff;
            mexc = memory_write(asi, address, &data, 0, &ws);
            mexc = memory_write(asi, address, &data, 0, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
            }
            }
#ifdef STAT
#ifdef STAT
            sregs->nload++;
            sregs->nload++;
#endif
#endif
            break;
            break;
        case LDSBA:
        case LDSBA:
        case LDUBA:
        case LDUBA:
            if (!chk_asi(sregs, &asi, op3)) break;
            if (!chk_asi(sregs, &asi, op3)) break;
        case LDSB:
        case LDSB:
        case LDUB:
        case LDUB:
            mexc = memory_read(asi, address, &data, 0, &ws);
            mexc = memory_read(asi, address, &data, 0, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
                break;
                break;
            }
            }
            if ((op3 == LDSB) && (data & 0x80))
            if ((op3 == LDSB) && (data & 0x80))
                data |= 0xffffff00;
                data |= 0xffffff00;
            *rdd = data;
            *rdd = data;
            break;
            break;
        case LDSHA:
        case LDSHA:
        case LDUHA:
        case LDUHA:
            if (!chk_asi(sregs, &asi, op3)) break;
            if (!chk_asi(sregs, &asi, op3)) break;
        case LDSH:
        case LDSH:
        case LDUH:
        case LDUH:
            if (address & 0x1) {
            if (address & 0x1) {
                sregs->trap = TRAP_UNALI;
                sregs->trap = TRAP_UNALI;
                break;
                break;
            }
            }
            mexc = memory_read(asi, address, &data, 1, &ws);
            mexc = memory_read(asi, address, &data, 1, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
                break;
                break;
            }
            }
            if ((op3 == LDSH) && (data & 0x8000))
            if ((op3 == LDSH) && (data & 0x8000))
                data |= 0xffff0000;
                data |= 0xffff0000;
            *rdd = data;
            *rdd = data;
            break;
            break;
        case LDF:
        case LDF:
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
                sregs->trap = TRAP_FPDIS;
                sregs->trap = TRAP_FPDIS;
                break;
                break;
            }
            }
            if (address & 0x3) {
            if (address & 0x3) {
                sregs->trap = TRAP_UNALI;
                sregs->trap = TRAP_UNALI;
                break;
                break;
            }
            }
            if (ebase.simtime < sregs->ftime) {
            if (ebase.simtime < sregs->ftime) {
                if ((sregs->frd == rd) || (sregs->frs1 == rd) ||
                if ((sregs->frd == rd) || (sregs->frs1 == rd) ||
                    (sregs->frs2 == rd))
                    (sregs->frs2 == rd))
                    sregs->fhold += (sregs->ftime - ebase.simtime);
                    sregs->fhold += (sregs->ftime - ebase.simtime);
            }
            }
            mexc = memory_read(asi, address, &data, 2, &ws);
            mexc = memory_read(asi, address, &data, 2, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            sregs->flrd = rd;
            sregs->flrd = rd;
            sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD +
            sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD +
                sregs->hold + sregs->fhold;
                sregs->hold + sregs->fhold;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
            } else {
            } else {
                sregs->fs[rd] = *((float32 *) & data);
                sregs->fs[rd] = *((float32 *) & data);
            }
            }
            break;
            break;
        case LDDF:
        case LDDF:
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
                sregs->trap = TRAP_FPDIS;
                sregs->trap = TRAP_FPDIS;
                break;
                break;
            }
            }
            if (address & 0x7) {
            if (address & 0x7) {
                sregs->trap = TRAP_UNALI;
                sregs->trap = TRAP_UNALI;
                break;
                break;
            }
            }
            if (ebase.simtime < sregs->ftime) {
            if (ebase.simtime < sregs->ftime) {
                if (((sregs->frd >> 1) == (rd >> 1)) ||
                if (((sregs->frd >> 1) == (rd >> 1)) ||
                    ((sregs->frs1 >> 1) == (rd >> 1)) ||
                    ((sregs->frs1 >> 1) == (rd >> 1)) ||
                    ((sregs->frs2 >> 1) == (rd >> 1)))
                    ((sregs->frs2 >> 1) == (rd >> 1)))
                    sregs->fhold += (sregs->ftime - ebase.simtime);
                    sregs->fhold += (sregs->ftime - ebase.simtime);
            }
            }
            mexc = memory_read(asi, address, ddata, 3, &ws);
            mexc = memory_read(asi, address, ddata, 3, &ws);
            sregs->hold += ws * 2;
            sregs->hold += ws * 2;
            sregs->icnt = T_LDD;
            sregs->icnt = T_LDD;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
            } else {
            } else {
                rd &= 0x1E;
                rd &= 0x1E;
                sregs->flrd = rd;
                sregs->flrd = rd;
                sregs->fs[rd] = *((float32 *) & ddata[0]);
                sregs->fs[rd] = *((float32 *) & ddata[0]);
#ifdef STAT
#ifdef STAT
                sregs->nload++; /* Double load counts twice */
                sregs->nload++; /* Double load counts twice */
#endif
#endif
                sregs->fs[rd + 1] = *((float32 *) & ddata[1]);
                sregs->fs[rd + 1] = *((float32 *) & ddata[1]);
                sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD +
                sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD +
                               sregs->hold + sregs->fhold;
                               sregs->hold + sregs->fhold;
            }
            }
            break;
            break;
        case LDFSR:
        case LDFSR:
            if (ebase.simtime < sregs->ftime) {
            if (ebase.simtime < sregs->ftime) {
                sregs->fhold += (sregs->ftime - ebase.simtime);
                sregs->fhold += (sregs->ftime - ebase.simtime);
            }
            }
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
                sregs->trap = TRAP_FPDIS;
                sregs->trap = TRAP_FPDIS;
                break;
                break;
            }
            }
            if (address & 0x3) {
            if (address & 0x3) {
                sregs->trap = TRAP_UNALI;
                sregs->trap = TRAP_UNALI;
                break;
                break;
            }
            }
            mexc = memory_read(asi, address, &data, 2, &ws);
            mexc = memory_read(asi, address, &data, 2, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
            } else {
            } else {
                sregs->fsr =
                sregs->fsr =
                    (sregs->fsr & 0x7FF000) | (data & ~0x7FF000);
                    (sregs->fsr & 0x7FF000) | (data & ~0x7FF000);
                set_fsr(sregs->fsr);
                set_fsr(sregs->fsr);
            }
            }
            break;
            break;
        case STFSR:
        case STFSR:
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
                sregs->trap = TRAP_FPDIS;
                sregs->trap = TRAP_FPDIS;
                break;
                break;
            }
            }
            if (address & 0x3) {
            if (address & 0x3) {
                sregs->trap = TRAP_UNALI;
                sregs->trap = TRAP_UNALI;
                break;
                break;
            }
            }
            if (ebase.simtime < sregs->ftime) {
            if (ebase.simtime < sregs->ftime) {
                sregs->fhold += (sregs->ftime - ebase.simtime);
                sregs->fhold += (sregs->ftime - ebase.simtime);
            }
            }
            mexc = memory_write(asi, address, &sregs->fsr, 2, &ws);
            mexc = memory_write(asi, address, &sregs->fsr, 2, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
            }
            }
            break;
            break;
 
 
        case STA:
        case STA:
            if (!chk_asi(sregs, &asi, op3)) break;
            if (!chk_asi(sregs, &asi, op3)) break;
        case ST:
        case ST:
            if (address & 0x3) {
            if (address & 0x3) {
                sregs->trap = TRAP_UNALI;
                sregs->trap = TRAP_UNALI;
                break;
                break;
            }
            }
            mexc = memory_write(asi, address, rdd, 2, &ws);
            mexc = memory_write(asi, address, rdd, 2, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
            }
            }
            break;
            break;
        case STBA:
        case STBA:
            if (!chk_asi(sregs, &asi, op3)) break;
            if (!chk_asi(sregs, &asi, op3)) break;
        case STB:
        case STB:
            mexc = memory_write(asi, address, rdd, 0, &ws);
            mexc = memory_write(asi, address, rdd, 0, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
            }
            }
            break;
            break;
        case STDA:
        case STDA:
            if (!chk_asi(sregs, &asi, op3)) break;
            if (!chk_asi(sregs, &asi, op3)) break;
        case STD:
        case STD:
            if (address & 0x7) {
            if (address & 0x7) {
                sregs->trap = TRAP_UNALI;
                sregs->trap = TRAP_UNALI;
                break;
                break;
            }
            }
            if (rd & 1) {
            if (rd & 1) {
                rd &= 0x1e;
                rd &= 0x1e;
                if (rd > 7)
                if (rd > 7)
                    rdd = &(sregs->r[(cwp + rd) & 0x7f]);
                    rdd = &(sregs->r[(cwp + rd) & 0x7f]);
                else
                else
                    rdd = &(sregs->g[rd]);
                    rdd = &(sregs->g[rd]);
            }
            }
            mexc = memory_write(asi, address, rdd, 3, &ws);
            mexc = memory_write(asi, address, rdd, 3, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            sregs->icnt = T_STD;
            sregs->icnt = T_STD;
#ifdef STAT
#ifdef STAT
            sregs->nstore++;    /* Double store counts twice */
            sregs->nstore++;    /* Double store counts twice */
#endif
#endif
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
                break;
                break;
            }
            }
            break;
            break;
        case STDFQ:
        case STDFQ:
            if ((sregs->psr & 0x1f) > 7) {
            if ((sregs->psr & 0x1f) > 7) {
                sregs->trap = TRAP_UNIMP;
                sregs->trap = TRAP_UNIMP;
                break;
                break;
            }
            }
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
                sregs->trap = TRAP_FPDIS;
                sregs->trap = TRAP_FPDIS;
                break;
                break;
            }
            }
            if (address & 0x7) {
            if (address & 0x7) {
                sregs->trap = TRAP_UNALI;
                sregs->trap = TRAP_UNALI;
                break;
                break;
            }
            }
            if (!(sregs->fsr & FSR_QNE)) {
            if (!(sregs->fsr & FSR_QNE)) {
                sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_SEQ_ERR;
                sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_SEQ_ERR;
                break;
                break;
            }
            }
            rdd = &(sregs->fpq[0]);
            rdd = &(sregs->fpq[0]);
            mexc = memory_write(asi, address, rdd, 3, &ws);
            mexc = memory_write(asi, address, rdd, 3, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            sregs->icnt = T_STD;
            sregs->icnt = T_STD;
#ifdef STAT
#ifdef STAT
            sregs->nstore++;    /* Double store counts twice */
            sregs->nstore++;    /* Double store counts twice */
#endif
#endif
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
                break;
                break;
            } else {
            } else {
                sregs->fsr &= ~FSR_QNE;
                sregs->fsr &= ~FSR_QNE;
                sregs->fpstate = FP_EXE_MODE;
                sregs->fpstate = FP_EXE_MODE;
            }
            }
            break;
            break;
        case STHA:
        case STHA:
            if (!chk_asi(sregs, &asi, op3)) break;
            if (!chk_asi(sregs, &asi, op3)) break;
        case STH:
        case STH:
            if (address & 0x1) {
            if (address & 0x1) {
                sregs->trap = TRAP_UNALI;
                sregs->trap = TRAP_UNALI;
                break;
                break;
            }
            }
            mexc = memory_write(asi, address, rdd, 1, &ws);
            mexc = memory_write(asi, address, rdd, 1, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
            }
            }
            break;
            break;
        case STF:
        case STF:
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
                sregs->trap = TRAP_FPDIS;
                sregs->trap = TRAP_FPDIS;
                break;
                break;
            }
            }
            if (address & 0x3) {
            if (address & 0x3) {
                sregs->trap = TRAP_UNALI;
                sregs->trap = TRAP_UNALI;
                break;
                break;
            }
            }
            if (ebase.simtime < sregs->ftime) {
            if (ebase.simtime < sregs->ftime) {
                if (sregs->frd == rd)
                if (sregs->frd == rd)
                    sregs->fhold += (sregs->ftime - ebase.simtime);
                    sregs->fhold += (sregs->ftime - ebase.simtime);
            }
            }
            mexc = memory_write(asi, address, &sregs->fsi[rd], 2, &ws);
            mexc = memory_write(asi, address, &sregs->fsi[rd], 2, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
            }
            }
            break;
            break;
        case STDF:
        case STDF:
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
                sregs->trap = TRAP_FPDIS;
                sregs->trap = TRAP_FPDIS;
                break;
                break;
            }
            }
            if (address & 0x7) {
            if (address & 0x7) {
                sregs->trap = TRAP_UNALI;
                sregs->trap = TRAP_UNALI;
                break;
                break;
            }
            }
            rd &= 0x1E;
            rd &= 0x1E;
            if (ebase.simtime < sregs->ftime) {
            if (ebase.simtime < sregs->ftime) {
                if ((sregs->frd == rd) || (sregs->frd + 1 == rd))
                if ((sregs->frd == rd) || (sregs->frd + 1 == rd))
                    sregs->fhold += (sregs->ftime - ebase.simtime);
                    sregs->fhold += (sregs->ftime - ebase.simtime);
            }
            }
            mexc = memory_write(asi, address, &sregs->fsi[rd], 3, &ws);
            mexc = memory_write(asi, address, &sregs->fsi[rd], 3, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            sregs->icnt = T_STD;
            sregs->icnt = T_STD;
#ifdef STAT
#ifdef STAT
            sregs->nstore++;    /* Double store counts twice */
            sregs->nstore++;    /* Double store counts twice */
#endif
#endif
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
            }
            }
            break;
            break;
        case SWAPA:
        case SWAPA:
            if (!chk_asi(sregs, &asi, op3)) break;
            if (!chk_asi(sregs, &asi, op3)) break;
        case SWAP:
        case SWAP:
            if (address & 0x3) {
            if (address & 0x3) {
                sregs->trap = TRAP_UNALI;
                sregs->trap = TRAP_UNALI;
                break;
                break;
            }
            }
            mexc = memory_read(asi, address, &data, 2, &ws);
            mexc = memory_read(asi, address, &data, 2, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
                break;
                break;
            }
            }
            mexc = memory_write(asi, address, rdd, 2, &ws);
            mexc = memory_write(asi, address, rdd, 2, &ws);
            sregs->hold += ws;
            sregs->hold += ws;
            sregs->icnt = T_LDST;
            sregs->icnt = T_LDST;
            if (mexc) {
            if (mexc) {
                sregs->trap = TRAP_DEXC;
                sregs->trap = TRAP_DEXC;
                break;
                break;
            } else
            } else
                *rdd = data;
                *rdd = data;
#ifdef STAT
#ifdef STAT
            sregs->nload++;
            sregs->nload++;
#endif
#endif
            break;
            break;
 
 
 
 
        default:
        default:
            sregs->trap = TRAP_UNIMP;
            sregs->trap = TRAP_UNIMP;
            break;
            break;
        }
        }
 
 
#ifdef LOAD_DEL
#ifdef LOAD_DEL
 
 
        if (!(op3 & 4)) {
        if (!(op3 & 4)) {
            sregs->ildtime = ebase.simtime + sregs->hold + sregs->icnt;
            sregs->ildtime = ebase.simtime + sregs->hold + sregs->icnt;
            sregs->ildreg = rd;
            sregs->ildreg = rd;
            if ((op3 | 0x10) == 0x13)
            if ((op3 | 0x10) == 0x13)
                sregs->ildreg |= 1;     /* Double load, odd register loaded
                sregs->ildreg |= 1;     /* Double load, odd register loaded
                                         * last */
                                         * last */
        }
        }
#endif
#endif
        break;
        break;
 
 
    default:
    default:
        sregs->trap = TRAP_UNIMP;
        sregs->trap = TRAP_UNIMP;
        break;
        break;
    }
    }
    sregs->g[0] = 0;
    sregs->g[0] = 0;
    if (!sregs->trap) {
    if (!sregs->trap) {
        sregs->pc = pc;
        sregs->pc = pc;
        sregs->npc = npc;
        sregs->npc = npc;
    }
    }
    return (0);
    return (0);
}
}
 
 
#define T_FABSs         2
#define T_FABSs         2
#define T_FADDs         4
#define T_FADDs         4
#define T_FADDd         4
#define T_FADDd         4
#define T_FCMPs         4
#define T_FCMPs         4
#define T_FCMPd         4
#define T_FCMPd         4
#define T_FDIVs         20
#define T_FDIVs         20
#define T_FDIVd         35
#define T_FDIVd         35
#define T_FMOVs         2
#define T_FMOVs         2
#define T_FMULs         5
#define T_FMULs         5
#define T_FMULd         9
#define T_FMULd         9
#define T_FNEGs         2
#define T_FNEGs         2
#define T_FSQRTs        37
#define T_FSQRTs        37
#define T_FSQRTd        65
#define T_FSQRTd        65
#define T_FSUBs         4
#define T_FSUBs         4
#define T_FSUBd         4
#define T_FSUBd         4
#define T_FdTOi         7
#define T_FdTOi         7
#define T_FdTOs         3
#define T_FdTOs         3
#define T_FiTOs         6
#define T_FiTOs         6
#define T_FiTOd         6
#define T_FiTOd         6
#define T_FsTOi         6
#define T_FsTOi         6
#define T_FsTOd         2
#define T_FsTOd         2
 
 
#define FABSs   0x09
#define FABSs   0x09
#define FADDs   0x41
#define FADDs   0x41
#define FADDd   0x42
#define FADDd   0x42
#define FCMPs   0x51
#define FCMPs   0x51
#define FCMPd   0x52
#define FCMPd   0x52
#define FCMPEs  0x55
#define FCMPEs  0x55
#define FCMPEd  0x56
#define FCMPEd  0x56
#define FDIVs   0x4D
#define FDIVs   0x4D
#define FDIVd   0x4E
#define FDIVd   0x4E
#define FMOVs   0x01
#define FMOVs   0x01
#define FMULs   0x49
#define FMULs   0x49
#define FMULd   0x4A
#define FMULd   0x4A
#define FNEGs   0x05
#define FNEGs   0x05
#define FSQRTs  0x29
#define FSQRTs  0x29
#define FSQRTd  0x2A
#define FSQRTd  0x2A
#define FSUBs   0x45
#define FSUBs   0x45
#define FSUBd   0x46
#define FSUBd   0x46
#define FdTOi   0xD2
#define FdTOi   0xD2
#define FdTOs   0xC6
#define FdTOs   0xC6
#define FiTOs   0xC4
#define FiTOs   0xC4
#define FiTOd   0xC8
#define FiTOd   0xC8
#define FsTOi   0xD1
#define FsTOi   0xD1
#define FsTOd   0xC9
#define FsTOd   0xC9
 
 
 
 
static int
static int
fpexec(op3, rd, rs1, rs2, sregs)
fpexec(op3, rd, rs1, rs2, sregs)
    uint32          op3, rd, rs1, rs2;
    uint32          op3, rd, rs1, rs2;
    struct pstate  *sregs;
    struct pstate  *sregs;
{
{
    uint32          opf, tem, accex;
    uint32          opf, tem, accex;
    int32           fcc;
    int32           fcc;
    uint32          ldadj;
    uint32          ldadj;
 
 
    if (sregs->fpstate == FP_EXC_MODE) {
    if (sregs->fpstate == FP_EXC_MODE) {
        sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_SEQ_ERR;
        sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_SEQ_ERR;
        sregs->fpstate = FP_EXC_PE;
        sregs->fpstate = FP_EXC_PE;
        return (0);
        return (0);
    }
    }
    if (sregs->fpstate == FP_EXC_PE) {
    if (sregs->fpstate == FP_EXC_PE) {
        sregs->fpstate = FP_EXC_MODE;
        sregs->fpstate = FP_EXC_MODE;
        return (TRAP_FPEXC);
        return (TRAP_FPEXC);
    }
    }
    opf = (sregs->inst >> 5) & 0x1ff;
    opf = (sregs->inst >> 5) & 0x1ff;
 
 
    /*
    /*
     * Check if we already have an FPop in the pipe. If so, halt until it is
     * Check if we already have an FPop in the pipe. If so, halt until it is
     * finished by incrementing fhold with the remaining execution time
     * finished by incrementing fhold with the remaining execution time
     */
     */
 
 
    if (ebase.simtime < sregs->ftime) {
    if (ebase.simtime < sregs->ftime) {
        sregs->fhold = (sregs->ftime - ebase.simtime);
        sregs->fhold = (sregs->ftime - ebase.simtime);
    } else {
    } else {
        sregs->fhold = 0;
        sregs->fhold = 0;
 
 
        /* Check load dependencies. */
        /* Check load dependencies. */
 
 
        if (ebase.simtime < sregs->ltime) {
        if (ebase.simtime < sregs->ltime) {
 
 
            /* Don't check rs1 if single operand instructions */
            /* Don't check rs1 if single operand instructions */
 
 
            if (((opf >> 6) == 0) || ((opf >> 6) == 3))
            if (((opf >> 6) == 0) || ((opf >> 6) == 3))
                rs1 = 32;
                rs1 = 32;
 
 
            /* Adjust for double floats */
            /* Adjust for double floats */
 
 
            ldadj = opf & 1;
            ldadj = opf & 1;
            if (!(((sregs->flrd - rs1) >> ldadj) && ((sregs->flrd - rs2) >> ldadj)))
            if (!(((sregs->flrd - rs1) >> ldadj) && ((sregs->flrd - rs2) >> ldadj)))
                sregs->fhold++;
                sregs->fhold++;
        }
        }
    }
    }
 
 
    sregs->finst++;
    sregs->finst++;
 
 
    sregs->frs1 = rs1;          /* Store src and dst for dependecy check */
    sregs->frs1 = rs1;          /* Store src and dst for dependecy check */
    sregs->frs2 = rs2;
    sregs->frs2 = rs2;
    sregs->frd = rd;
    sregs->frd = rd;
 
 
    sregs->ftime = ebase.simtime + sregs->hold + sregs->fhold;
    sregs->ftime = ebase.simtime + sregs->hold + sregs->fhold;
 
 
    /* SPARC is big-endian - swap double floats if host is little-endian */
    /* SPARC is big-endian - swap double floats if host is little-endian */
    /* This is ugly - I know ... */
    /* This is ugly - I know ... */
 
 
    /* FIXME: should use (CURRENT_HOST_BYTE_ORDER == CURRENT_TARGET_BYTE_ORDER)
    /* FIXME: should use (CURRENT_HOST_BYTE_ORDER == CURRENT_TARGET_BYTE_ORDER)
       but what about machines where float values are different endianness
       but what about machines where float values are different endianness
       from integer values? */
       from integer values? */
 
 
#ifdef HOST_LITTLE_ENDIAN_FLOAT
#ifdef HOST_LITTLE_ENDIAN_FLOAT
    rs1 &= 0x1f;
    rs1 &= 0x1f;
    switch (opf) {
    switch (opf) {
        case FADDd:
        case FADDd:
        case FDIVd:
        case FDIVd:
        case FMULd:
        case FMULd:
        case FSQRTd:
        case FSQRTd:
        case FSUBd:
        case FSUBd:
        case FCMPd:
        case FCMPd:
        case FCMPEd:
        case FCMPEd:
        case FdTOi:
        case FdTOi:
        case FdTOs:
        case FdTOs:
            sregs->fdp[rs1 | 1] = sregs->fs[rs1 & ~1];
            sregs->fdp[rs1 | 1] = sregs->fs[rs1 & ~1];
            sregs->fdp[rs1 & ~1] = sregs->fs[rs1 | 1];
            sregs->fdp[rs1 & ~1] = sregs->fs[rs1 | 1];
            sregs->fdp[rs2 | 1] = sregs->fs[rs2 & ~1];
            sregs->fdp[rs2 | 1] = sregs->fs[rs2 & ~1];
            sregs->fdp[rs2 & ~1] = sregs->fs[rs2 | 1];
            sregs->fdp[rs2 & ~1] = sregs->fs[rs2 | 1];
    default:
    default:
      break;
      break;
    }
    }
#endif
#endif
 
 
    clear_accex();
    clear_accex();
 
 
    switch (opf) {
    switch (opf) {
    case FABSs:
    case FABSs:
        sregs->fs[rd] = fabs(sregs->fs[rs2]);
        sregs->fs[rd] = fabs(sregs->fs[rs2]);
        sregs->ftime += T_FABSs;
        sregs->ftime += T_FABSs;
        sregs->frs1 = 32;       /* rs1 ignored */
        sregs->frs1 = 32;       /* rs1 ignored */
        break;
        break;
    case FADDs:
    case FADDs:
        sregs->fs[rd] = sregs->fs[rs1] + sregs->fs[rs2];
        sregs->fs[rd] = sregs->fs[rs1] + sregs->fs[rs2];
        sregs->ftime += T_FADDs;
        sregs->ftime += T_FADDs;
        break;
        break;
    case FADDd:
    case FADDd:
        sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] + sregs->fd[rs2 >> 1];
        sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] + sregs->fd[rs2 >> 1];
        sregs->ftime += T_FADDd;
        sregs->ftime += T_FADDd;
        break;
        break;
    case FCMPs:
    case FCMPs:
    case FCMPEs:
    case FCMPEs:
        if (sregs->fs[rs1] == sregs->fs[rs2])
        if (sregs->fs[rs1] == sregs->fs[rs2])
            fcc = 3;
            fcc = 3;
        else if (sregs->fs[rs1] < sregs->fs[rs2])
        else if (sregs->fs[rs1] < sregs->fs[rs2])
            fcc = 2;
            fcc = 2;
        else if (sregs->fs[rs1] > sregs->fs[rs2])
        else if (sregs->fs[rs1] > sregs->fs[rs2])
            fcc = 1;
            fcc = 1;
        else
        else
            fcc = 0;
            fcc = 0;
        sregs->fsr |= 0x0C00;
        sregs->fsr |= 0x0C00;
        sregs->fsr &= ~(fcc << 10);
        sregs->fsr &= ~(fcc << 10);
        sregs->ftime += T_FCMPs;
        sregs->ftime += T_FCMPs;
        sregs->frd = 32;        /* rd ignored */
        sregs->frd = 32;        /* rd ignored */
        if ((fcc == 0) && (opf == FCMPEs)) {
        if ((fcc == 0) && (opf == FCMPEs)) {
            sregs->fpstate = FP_EXC_PE;
            sregs->fpstate = FP_EXC_PE;
            sregs->fsr = (sregs->fsr & ~0x1C000) | (1 << 14);
            sregs->fsr = (sregs->fsr & ~0x1C000) | (1 << 14);
        }
        }
        break;
        break;
    case FCMPd:
    case FCMPd:
    case FCMPEd:
    case FCMPEd:
        if (sregs->fd[rs1 >> 1] == sregs->fd[rs2 >> 1])
        if (sregs->fd[rs1 >> 1] == sregs->fd[rs2 >> 1])
            fcc = 3;
            fcc = 3;
        else if (sregs->fd[rs1 >> 1] < sregs->fd[rs2 >> 1])
        else if (sregs->fd[rs1 >> 1] < sregs->fd[rs2 >> 1])
            fcc = 2;
            fcc = 2;
        else if (sregs->fd[rs1 >> 1] > sregs->fd[rs2 >> 1])
        else if (sregs->fd[rs1 >> 1] > sregs->fd[rs2 >> 1])
            fcc = 1;
            fcc = 1;
        else
        else
            fcc = 0;
            fcc = 0;
        sregs->fsr |= 0x0C00;
        sregs->fsr |= 0x0C00;
        sregs->fsr &= ~(fcc << 10);
        sregs->fsr &= ~(fcc << 10);
        sregs->ftime += T_FCMPd;
        sregs->ftime += T_FCMPd;
        sregs->frd = 32;        /* rd ignored */
        sregs->frd = 32;        /* rd ignored */
        if ((fcc == 0) && (opf == FCMPEd)) {
        if ((fcc == 0) && (opf == FCMPEd)) {
            sregs->fpstate = FP_EXC_PE;
            sregs->fpstate = FP_EXC_PE;
            sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
            sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
        }
        }
        break;
        break;
    case FDIVs:
    case FDIVs:
        sregs->fs[rd] = sregs->fs[rs1] / sregs->fs[rs2];
        sregs->fs[rd] = sregs->fs[rs1] / sregs->fs[rs2];
        sregs->ftime += T_FDIVs;
        sregs->ftime += T_FDIVs;
        break;
        break;
    case FDIVd:
    case FDIVd:
        sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] / sregs->fd[rs2 >> 1];
        sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] / sregs->fd[rs2 >> 1];
        sregs->ftime += T_FDIVd;
        sregs->ftime += T_FDIVd;
        break;
        break;
    case FMOVs:
    case FMOVs:
        sregs->fs[rd] = sregs->fs[rs2];
        sregs->fs[rd] = sregs->fs[rs2];
        sregs->ftime += T_FMOVs;
        sregs->ftime += T_FMOVs;
        sregs->frs1 = 32;       /* rs1 ignored */
        sregs->frs1 = 32;       /* rs1 ignored */
        break;
        break;
    case FMULs:
    case FMULs:
        sregs->fs[rd] = sregs->fs[rs1] * sregs->fs[rs2];
        sregs->fs[rd] = sregs->fs[rs1] * sregs->fs[rs2];
        sregs->ftime += T_FMULs;
        sregs->ftime += T_FMULs;
        break;
        break;
    case FMULd:
    case FMULd:
        sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] * sregs->fd[rs2 >> 1];
        sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] * sregs->fd[rs2 >> 1];
        sregs->ftime += T_FMULd;
        sregs->ftime += T_FMULd;
        break;
        break;
    case FNEGs:
    case FNEGs:
        sregs->fs[rd] = -sregs->fs[rs2];
        sregs->fs[rd] = -sregs->fs[rs2];
        sregs->ftime += T_FNEGs;
        sregs->ftime += T_FNEGs;
        sregs->frs1 = 32;       /* rs1 ignored */
        sregs->frs1 = 32;       /* rs1 ignored */
        break;
        break;
    case FSQRTs:
    case FSQRTs:
        if (sregs->fs[rs2] < 0.0) {
        if (sregs->fs[rs2] < 0.0) {
            sregs->fpstate = FP_EXC_PE;
            sregs->fpstate = FP_EXC_PE;
            sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
            sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
            sregs->fsr = (sregs->fsr & 0x1f) | 0x10;
            sregs->fsr = (sregs->fsr & 0x1f) | 0x10;
            break;
            break;
        }
        }
        sregs->fs[rd] = sqrt(sregs->fs[rs2]);
        sregs->fs[rd] = sqrt(sregs->fs[rs2]);
        sregs->ftime += T_FSQRTs;
        sregs->ftime += T_FSQRTs;
        sregs->frs1 = 32;       /* rs1 ignored */
        sregs->frs1 = 32;       /* rs1 ignored */
        break;
        break;
    case FSQRTd:
    case FSQRTd:
        if (sregs->fd[rs2 >> 1] < 0.0) {
        if (sregs->fd[rs2 >> 1] < 0.0) {
            sregs->fpstate = FP_EXC_PE;
            sregs->fpstate = FP_EXC_PE;
            sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
            sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
            sregs->fsr = (sregs->fsr & 0x1f) | 0x10;
            sregs->fsr = (sregs->fsr & 0x1f) | 0x10;
            break;
            break;
        }
        }
        sregs->fd[rd >> 1] = sqrt(sregs->fd[rs2 >> 1]);
        sregs->fd[rd >> 1] = sqrt(sregs->fd[rs2 >> 1]);
        sregs->ftime += T_FSQRTd;
        sregs->ftime += T_FSQRTd;
        sregs->frs1 = 32;       /* rs1 ignored */
        sregs->frs1 = 32;       /* rs1 ignored */
        break;
        break;
    case FSUBs:
    case FSUBs:
        sregs->fs[rd] = sregs->fs[rs1] - sregs->fs[rs2];
        sregs->fs[rd] = sregs->fs[rs1] - sregs->fs[rs2];
        sregs->ftime += T_FSUBs;
        sregs->ftime += T_FSUBs;
        break;
        break;
    case FSUBd:
    case FSUBd:
        sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] - sregs->fd[rs2 >> 1];
        sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] - sregs->fd[rs2 >> 1];
        sregs->ftime += T_FSUBd;
        sregs->ftime += T_FSUBd;
        break;
        break;
    case FdTOi:
    case FdTOi:
        sregs->fsi[rd] = (int) sregs->fd[rs2 >> 1];
        sregs->fsi[rd] = (int) sregs->fd[rs2 >> 1];
        sregs->ftime += T_FdTOi;
        sregs->ftime += T_FdTOi;
        sregs->frs1 = 32;       /* rs1 ignored */
        sregs->frs1 = 32;       /* rs1 ignored */
        break;
        break;
    case FdTOs:
    case FdTOs:
        sregs->fs[rd] = (float32) sregs->fd[rs2 >> 1];
        sregs->fs[rd] = (float32) sregs->fd[rs2 >> 1];
        sregs->ftime += T_FdTOs;
        sregs->ftime += T_FdTOs;
        sregs->frs1 = 32;       /* rs1 ignored */
        sregs->frs1 = 32;       /* rs1 ignored */
        break;
        break;
    case FiTOs:
    case FiTOs:
        sregs->fs[rd] = (float32) sregs->fsi[rs2];
        sregs->fs[rd] = (float32) sregs->fsi[rs2];
        sregs->ftime += T_FiTOs;
        sregs->ftime += T_FiTOs;
        sregs->frs1 = 32;       /* rs1 ignored */
        sregs->frs1 = 32;       /* rs1 ignored */
        break;
        break;
    case FiTOd:
    case FiTOd:
        sregs->fd[rd >> 1] = (float64) sregs->fsi[rs2];
        sregs->fd[rd >> 1] = (float64) sregs->fsi[rs2];
        sregs->ftime += T_FiTOd;
        sregs->ftime += T_FiTOd;
        sregs->frs1 = 32;       /* rs1 ignored */
        sregs->frs1 = 32;       /* rs1 ignored */
        break;
        break;
    case FsTOi:
    case FsTOi:
        sregs->fsi[rd] = (int) sregs->fs[rs2];
        sregs->fsi[rd] = (int) sregs->fs[rs2];
        sregs->ftime += T_FsTOi;
        sregs->ftime += T_FsTOi;
        sregs->frs1 = 32;       /* rs1 ignored */
        sregs->frs1 = 32;       /* rs1 ignored */
        break;
        break;
    case FsTOd:
    case FsTOd:
        sregs->fd[rd >> 1] = sregs->fs[rs2];
        sregs->fd[rd >> 1] = sregs->fs[rs2];
        sregs->ftime += T_FsTOd;
        sregs->ftime += T_FsTOd;
        sregs->frs1 = 32;       /* rs1 ignored */
        sregs->frs1 = 32;       /* rs1 ignored */
        break;
        break;
 
 
    default:
    default:
        sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_UNIMP;
        sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_UNIMP;
        sregs->fpstate = FP_EXC_PE;
        sregs->fpstate = FP_EXC_PE;
    }
    }
 
 
#ifdef ERRINJ
#ifdef ERRINJ
    if (errftt) {
    if (errftt) {
        sregs->fsr = (sregs->fsr & ~FSR_TT) | (errftt << 14);
        sregs->fsr = (sregs->fsr & ~FSR_TT) | (errftt << 14);
        sregs->fpstate = FP_EXC_PE;
        sregs->fpstate = FP_EXC_PE;
        if (sis_verbose) printf("Inserted fpu error %X\n",errftt);
        if (sis_verbose) printf("Inserted fpu error %X\n",errftt);
        errftt = 0;
        errftt = 0;
    }
    }
#endif
#endif
 
 
    accex = get_accex();
    accex = get_accex();
 
 
#ifdef HOST_LITTLE_ENDIAN_FLOAT
#ifdef HOST_LITTLE_ENDIAN_FLOAT
    switch (opf) {
    switch (opf) {
    case FADDd:
    case FADDd:
    case FDIVd:
    case FDIVd:
    case FMULd:
    case FMULd:
    case FSQRTd:
    case FSQRTd:
    case FSUBd:
    case FSUBd:
    case FiTOd:
    case FiTOd:
    case FsTOd:
    case FsTOd:
        sregs->fs[rd & ~1] = sregs->fdp[rd | 1];
        sregs->fs[rd & ~1] = sregs->fdp[rd | 1];
        sregs->fs[rd | 1] = sregs->fdp[rd & ~1];
        sregs->fs[rd | 1] = sregs->fdp[rd & ~1];
    default:
    default:
      break;
      break;
    }
    }
#endif
#endif
    if (sregs->fpstate == FP_EXC_PE) {
    if (sregs->fpstate == FP_EXC_PE) {
        sregs->fpq[0] = sregs->pc;
        sregs->fpq[0] = sregs->pc;
        sregs->fpq[1] = sregs->inst;
        sregs->fpq[1] = sregs->inst;
        sregs->fsr |= FSR_QNE;
        sregs->fsr |= FSR_QNE;
    } else {
    } else {
        tem = (sregs->fsr >> 23) & 0x1f;
        tem = (sregs->fsr >> 23) & 0x1f;
        if (tem & accex) {
        if (tem & accex) {
            sregs->fpstate = FP_EXC_PE;
            sregs->fpstate = FP_EXC_PE;
            sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
            sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
            sregs->fsr = ((sregs->fsr & ~0x1f) | accex);
            sregs->fsr = ((sregs->fsr & ~0x1f) | accex);
        } else {
        } else {
            sregs->fsr = ((((sregs->fsr >> 5) | accex) << 5) | accex);
            sregs->fsr = ((((sregs->fsr >> 5) | accex) << 5) | accex);
        }
        }
        if (sregs->fpstate == FP_EXC_PE) {
        if (sregs->fpstate == FP_EXC_PE) {
            sregs->fpq[0] = sregs->pc;
            sregs->fpq[0] = sregs->pc;
            sregs->fpq[1] = sregs->inst;
            sregs->fpq[1] = sregs->inst;
            sregs->fsr |= FSR_QNE;
            sregs->fsr |= FSR_QNE;
        }
        }
    }
    }
    clear_accex();
    clear_accex();
 
 
    return (0);
    return (0);
 
 
 
 
}
}
 
 
static int
static int
chk_asi(sregs, asi, op3)
chk_asi(sregs, asi, op3)
    struct pstate  *sregs;
    struct pstate  *sregs;
    uint32 *asi, op3;
    uint32 *asi, op3;
 
 
{
{
    if (!(sregs->psr & PSR_S)) {
    if (!(sregs->psr & PSR_S)) {
        sregs->trap = TRAP_PRIVI;
        sregs->trap = TRAP_PRIVI;
        return (0);
        return (0);
    } else if (sregs->inst & INST_I) {
    } else if (sregs->inst & INST_I) {
        sregs->trap = TRAP_UNIMP;
        sregs->trap = TRAP_UNIMP;
        return (0);
        return (0);
    } else
    } else
        *asi = (sregs->inst >> 5) & 0x0ff;
        *asi = (sregs->inst >> 5) & 0x0ff;
    return(1);
    return(1);
}
}
 
 
int
int
execute_trap(sregs)
execute_trap(sregs)
    struct pstate  *sregs;
    struct pstate  *sregs;
{
{
    int32           cwp;
    int32           cwp;
 
 
    if (sregs->trap == 256) {
    if (sregs->trap == 256) {
        sregs->pc = 0;
        sregs->pc = 0;
        sregs->npc = 4;
        sregs->npc = 4;
        sregs->trap = 0;
        sregs->trap = 0;
    } else if (sregs->trap == 257) {
    } else if (sregs->trap == 257) {
            return (ERROR);
            return (ERROR);
    } else {
    } else {
 
 
        if ((sregs->psr & PSR_ET) == 0)
        if ((sregs->psr & PSR_ET) == 0)
            return (ERROR);
            return (ERROR);
 
 
        sregs->tbr = (sregs->tbr & 0xfffff000) | (sregs->trap << 4);
        sregs->tbr = (sregs->tbr & 0xfffff000) | (sregs->trap << 4);
        sregs->trap = 0;
        sregs->trap = 0;
        sregs->psr &= ~PSR_ET;
        sregs->psr &= ~PSR_ET;
        sregs->psr |= ((sregs->psr & PSR_S) >> 1);
        sregs->psr |= ((sregs->psr & PSR_S) >> 1);
        sregs->annul = 0;
        sregs->annul = 0;
        sregs->psr = (((sregs->psr & PSR_CWP) - 1) & 0x7) | (sregs->psr & ~PSR_CWP);
        sregs->psr = (((sregs->psr & PSR_CWP) - 1) & 0x7) | (sregs->psr & ~PSR_CWP);
        cwp = ((sregs->psr & PSR_CWP) << 4);
        cwp = ((sregs->psr & PSR_CWP) << 4);
        sregs->r[(cwp + 17) & 0x7f] = sregs->pc;
        sregs->r[(cwp + 17) & 0x7f] = sregs->pc;
        sregs->r[(cwp + 18) & 0x7f] = sregs->npc;
        sregs->r[(cwp + 18) & 0x7f] = sregs->npc;
        sregs->psr |= PSR_S;
        sregs->psr |= PSR_S;
        sregs->pc = sregs->tbr;
        sregs->pc = sregs->tbr;
        sregs->npc = sregs->tbr + 4;
        sregs->npc = sregs->tbr + 4;
 
 
        if ( 0 != (1 & sregs->asr17) ) {
        if ( 0 != (1 & sregs->asr17) ) {
            /* single vector trapping! */
            /* single vector trapping! */
            sregs->pc = sregs->tbr & 0xfffff000;
            sregs->pc = sregs->tbr & 0xfffff000;
            sregs->npc = sregs->pc + 4;
            sregs->npc = sregs->pc + 4;
        }
        }
 
 
        /* Increase simulator time */
        /* Increase simulator time */
        sregs->icnt = TRAP_C;
        sregs->icnt = TRAP_C;
 
 
    }
    }
 
 
 
 
    return (0);
    return (0);
 
 
}
}
 
 
extern struct irqcell irqarr[16];
extern struct irqcell irqarr[16];
 
 
int
int
check_interrupts(sregs)
check_interrupts(sregs)
    struct pstate  *sregs;
    struct pstate  *sregs;
{
{
#ifdef ERRINJ
#ifdef ERRINJ
    if (errtt) {
    if (errtt) {
        sregs->trap = errtt;
        sregs->trap = errtt;
        if (sis_verbose) printf("Inserted error trap 0x%02X\n",errtt);
        if (sis_verbose) printf("Inserted error trap 0x%02X\n",errtt);
        errtt = 0;
        errtt = 0;
    }
    }
#endif
#endif
 
 
    if ((ext_irl) && (sregs->psr & PSR_ET) &&
    if ((ext_irl) && (sregs->psr & PSR_ET) &&
        ((ext_irl == 15) || (ext_irl > (int) ((sregs->psr & PSR_PIL) >> 8)))) {
        ((ext_irl == 15) || (ext_irl > (int) ((sregs->psr & PSR_PIL) >> 8)))) {
        if (sregs->trap == 0) {
        if (sregs->trap == 0) {
            sregs->trap = 16 + ext_irl;
            sregs->trap = 16 + ext_irl;
            irqarr[ext_irl & 0x0f].callback(irqarr[ext_irl & 0x0f].arg);
            irqarr[ext_irl & 0x0f].callback(irqarr[ext_irl & 0x0f].arg);
            return(1);
            return(1);
        }
        }
    }
    }
    return(0);
    return(0);
}
}
 
 
void
void
init_regs(sregs)
init_regs(sregs)
    struct pstate  *sregs;
    struct pstate  *sregs;
{
{
    sregs->pc = 0;
    sregs->pc = 0;
    sregs->npc = 4;
    sregs->npc = 4;
    sregs->trap = 0;
    sregs->trap = 0;
    sregs->psr &= 0x00f03fdf;
    sregs->psr &= 0x00f03fdf;
    sregs->psr |= 0x080;        /* Set supervisor bit */
    sregs->psr |= 0x080;        /* Set supervisor bit */
    sregs->breakpoint = 0;
    sregs->breakpoint = 0;
    sregs->annul = 0;
    sregs->annul = 0;
    sregs->fpstate = FP_EXE_MODE;
    sregs->fpstate = FP_EXE_MODE;
    sregs->fpqn = 0;
    sregs->fpqn = 0;
    sregs->ftime = 0;
    sregs->ftime = 0;
    sregs->ltime = 0;
    sregs->ltime = 0;
    sregs->err_mode = 0;
    sregs->err_mode = 0;
    ext_irl = 0;
    ext_irl = 0;
    sregs->g[0] = 0;
    sregs->g[0] = 0;
#ifdef HOST_LITTLE_ENDIAN_FLOAT
#ifdef HOST_LITTLE_ENDIAN_FLOAT
    sregs->fdp = (float32 *) sregs->fd;
    sregs->fdp = (float32 *) sregs->fd;
    sregs->fsi = (int32 *) sregs->fs;
    sregs->fsi = (int32 *) sregs->fs;
#else
#else
    sregs->fs = (float32 *) sregs->fd;
    sregs->fs = (float32 *) sregs->fd;
    sregs->fsi = (int32 *) sregs->fd;
    sregs->fsi = (int32 *) sregs->fd;
#endif
#endif
    sregs->fsr = 0;
    sregs->fsr = 0;
    sregs->fpu_pres = !nfp;
    sregs->fpu_pres = !nfp;
    set_fsr(sregs->fsr);
    set_fsr(sregs->fsr);
    sregs->bphit = 0;
    sregs->bphit = 0;
    sregs->ildreg = 0;
    sregs->ildreg = 0;
    sregs->ildtime = 0;
    sregs->ildtime = 0;
 
 
    sregs->y = 0;
    sregs->y = 0;
    sregs->asr17 = 0;
    sregs->asr17 = 0;
 
 
    sregs->rett_err = 0;
    sregs->rett_err = 0;
    sregs->jmpltime = 0;
    sregs->jmpltime = 0;
}
}
 
 

powered by: WebSVN 2.1.0

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