/*

Freely Distributable C30 Simulator Package

Copyright (c) 1996-1998 The University of Texas
All Rights Reserved.

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 Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
The GNU Public License is available in the file LICENSE, or you
can write to the Free Software Foundation, Inc., 59 Temple Place -
Suite 330, Boston, MA 02111-1307, USA, or you can find it on the
World Wide Web at http://www.fsf.org.

Authors: Chi Duong, Brian Evans, and Chris Moy
Version: @(#)state.h	1.26	01/19/98 

Department of Electrical and Computer Engineering
The University of Texas, Austin, TX 78712-1084

*/

#ifndef _STATE_H
#define _STATE_H

/* FIXME: Platform dependent.  Move to a compatiblity file. */

typedef unsigned long uint32;
typedef long int32;
#define C30_NUMBER_OF_EXTENDED_REGISTERS 8
#define C30_MEMORY_PRINTF           "0x%08lx"
#define C30_MEMORY_PRINTF_NEWLINE   "0x%08lx\n"
#define C30_UINT32_PRINTF_DECIMAL   "%ld"
#define C30_MEMORY_SCANF            "%lx"

#define C30_VALUE_ZERO(s)    ((s) == 0L)
#define C30_VALUE_NONZERO(s) ((s) != 0L)

#define C30_MAX_UNSIGNED_INT 0xFFFFFFFFL
#define C30_MAX_SIGNED_INT   0x7FFFFFFFL
#define C30_MIN_SIGNED_INT   0x80000000L 

/* C30 Emulation */

/*
Two interpretations of 'step' will executing a C30 program:
-- C30SIM: "step" command is defined as 1 pipeline cycle (default)
-- DSK, "step" command is defined as a completion of current instruction
*/
#define C30_EMULATOR  0
#define DSK_DEBUGGER  1

/* C30 Architecture */

/* 1. Types of C3x processors supported */

enum c30ProcType {
  __c3x = 0,
  __c30 = 1,
  __c31 = 2,
  __c32 = 3
};

/* 2. Macros for eight-bit exponent registers */

#define C30_EXPONENT_REGISTER_PTR(s)    ((s) + 1)

/* 3. Definitions for the status register st */

#define C30_CONDFLAG_REPEAT_MODE        0x0100
#define C30_CONDFLAG_OVM                0x0080
 
#define C30_CONDFLAG_LATCHED_UNDERFLOW  0x0040
#define C30_CONDFLAG_LATCHED_OVERFLOW   0x0020
#define C30_CONDFLAG_UNDERFLOW          0x0010
  
#define C30_CONDFLAG_NEGATIVE           0x0008
#define C30_CONDFLAG_ZERO               0x0004
#define C30_CONDFLAG_OVERFLOW           0x0002
#define C30_CONDFLAG_CARRY              0x0001

#define C30_CONDFLAG_GIE                0x4000

/* 4. Maximum and minimum floating-point values */

#define C30_MAX_FLOAT                   3.4e38
#define C30_MIN_FLOAT                  -3.4e38
#define C30_EPSILON                     3.4e-38

#define POST_ADDR_MODE                  0
#define PRE_ADDR_MODE                   1

/* 5. Define registers: all need to be the same data type for consistency */

typedef uint32 c30reg;                                  /* 32-bit registers */
typedef uint32 c30expreg;        /* 8-bit floating point exponent registers */
typedef uint32 c30mem;                                /* ROM and RAM memory */

/*
The updateArn struct are to make sure ARn(s) get update the 2nd cycles
after the instruction causing the change in ARn(s) is decoded. 
*/

typedef struct {
  int     flag;            /* 1 when occupied; 0 then update value */
                           /* -1 then available to store new value */
  c30reg* arnAddr[2];      /* maximum 2 ARns get modified for an instruction */
  c30reg  arnVal[2];
} updateArn_t;

typedef struct {
  int flag;   /* decrement every cycle before execution cycle until = -1; */
              /* 1 when occupied; 0 then val is used by execute cycle */
  int val;
} saveCond_t;

typedef struct state {
  c30reg Sregs[C30_NUMBER_OF_EXTENDED_REGISTERS*2];        
  c30reg ar0_s;        /* auxiliary registers most update from read cycle*/
  c30reg ar1_s;
  c30reg ar2_s;
  c30reg ar3_s;
  c30reg ar4_s;
  c30reg ar5_s;
  c30reg ar6_s;
  c30reg ar7_s;
  c30reg ar0;          /* auxiliary registers */
  c30reg ar1;
  c30reg ar2;
  c30reg ar3;
  c30reg ar4;
  c30reg ar5;
  c30reg ar6;
  c30reg ar7;
  c30reg ir0;          /* index registers */
  c30reg ir1;
  c30reg bk;           /* circular addressing block size register */
  c30reg pc;           /* program counter */
  c30reg st;           /* status register */
  c30reg rs;           /* repeat start address register */
  c30reg re;           /* repeat end address register */
  c30reg rc;           /* repeat counter register (used to be of type long) */
  c30reg dp;           /* data page pointer */
  c30reg sp;           /* stack pointer */
  c30reg ie;           /* interrupt enable register */
  c30reg if_;          /* interrupt flag register */
  c30reg iof;          /* IO flags */

  int saveCond;        /* cond[saveCond] is available to store cond code */
  saveCond_t cond[2];  /* for conditional inst.: cond.val is (0-10, 12-20) */
  int ldm;             /* set to 1 when load LDM from memory */
  int saveArn;         /* updateArn[saveArn] stores the next arn set */
  updateArn_t updateArn[2];
  int outputMode;      /* value was assiged main, which is either */
                       /* C30_EMULATOR (default), or DSK_DEBUGGER */
  int DSKdebStep;      /* number of pipeline cycles in 1 DSK-debugger-step */
                       /* in DSK outputMode, always 0 in C30SIM outputMode */

  c30ProcType c30proc; /* member of C3x family */
  c30mem dummy;        /* safe storage area */
  c30mem *rom;         /* ROM block */
  c30mem *ram0;        /* first RAM block */
  c30mem *ram1;        /* second RAM block */
  c30mem *reserved0;   /* first block of reserved memory */
  c30mem *reserved1;   /* second block of reserved memory */
  c30mem *addrSpace;   /* dynamic memory */
  c30mem *romEnd;
  c30mem *ram0End;
  c30mem *ram1End;
} state;

/* 8 bits of the exponent will be stored in the 8MSBs of __rxn */

enum extended_registers {
        __r0=0, __rx0, __r1, __rx1, __r2, __rx2, __r3, __rx3,
        __r4,   __rx4, __r5, __rx5, __r6, __rx6, __r7, __rx7
};

/* Prototypes for functions in state.cc */
int C30SimProcessorCompatibility(c30ProcType proc1, c30ProcType proc2);
int C30SimProcessorType(const char* procName, c30ProcType* c30procPtr);
int C30SimPrintProcessorType(c30ProcType c30procPtr);
int C30SimPrintRegister(const char* regName, uint32 regValue); 
int C30SimPrintState(const state *st);
int C30SimPrintChangesInState(const state* oldst, const state* newst);

#endif
