/*

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: Brian Evans
Version: @(#)state.cc	1.13	01/19/98

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

*/

#include <stdio.h>
#include <ctype.h>
#include "state.h"

/*
Returns TRUE if two processor representations are compatible.
Two processor representations are compatible if they are identical
or if either of them represents the C3x family.
*/
int C30SimProcessorCompatibility(c30ProcType proc1, c30ProcType proc2) {
   return ((proc1 == proc2) || (proc1 == __c3x) || (proc2 == __c3x));
}

/*
Return the processor identification number for the given processor name.
*/
int C30SimProcessorType(const char* procName, c30ProcType* c30procPtr) {
  int valid =
      (procName && (tolower(procName[0]) == 'c') && (procName[1] == '3'));

  if (valid) {
    switch (procName[2]) {
      case '0':
        *c30procPtr = __c30;
	break;
      case '1':
        *c30procPtr = __c31;
	break;
      case '2':
        *c30procPtr = __c32;
	break;
      case 'X':
      case 'x':
        *c30procPtr = __c3x;
	break;
      default:
        valid = 0;
	break;
    }
  }

  return valid;
}

/*
Print the name of the C3x processor.
*/
int C30SimPrintProcessorType(c30ProcType c30proc) {
  switch (c30proc) {
    case __c3x:
      printf("c3x");
      break;
    case __c30:
      printf("c30");
      break;
    case __c31:
      printf("c31");
      break;
    case __c32:
      printf("c32");
      break;
  } 
  return 1;
}

/*
Print the name and value of a register in the form name=value
where value is printed in hexadecimal format.
*/
int C30SimPrintRegister(const char* regName, uint32 regValue) {
    printf("%s=", regName);
    printf(C30_MEMORY_PRINTF_NEWLINE, regValue);
    return 1;
}

/*
Print the C30 state.  Print all register values.
*/
int C30SimPrintState(const state* st) {

    /* extended precision registers (lower 32 bits) and */
    /* their floating point exponents (upper 8 bits) */
    C30SimPrintRegister("r0", st->Sregs[__r0]);
    C30SimPrintRegister("rx0", st->Sregs[__rx0]) ;
    C30SimPrintRegister("r1", st->Sregs[__r1]);
    C30SimPrintRegister("rx1", st->Sregs[__rx1]) ;
    C30SimPrintRegister("r2", st->Sregs[__r2]);
    C30SimPrintRegister("rx2", st->Sregs[__rx2]) ;
    C30SimPrintRegister("r3", st->Sregs[__r3]);
    C30SimPrintRegister("rx3", st->Sregs[__rx3]) ;
    C30SimPrintRegister("r4", st->Sregs[__r4]);
    C30SimPrintRegister("rx4", st->Sregs[__rx4]) ;
    C30SimPrintRegister("r5", st->Sregs[__r5]);
    C30SimPrintRegister("rx5", st->Sregs[__rx5]) ;
    C30SimPrintRegister("r6", st->Sregs[__r6]);
    C30SimPrintRegister("rx6", st->Sregs[__rx6]) ;
    C30SimPrintRegister("r7", st->Sregs[__r7]);
    C30SimPrintRegister("rx7", st->Sregs[__rx7]) ;
    fflush(stdout);

    /* auxiliary registers */
    C30SimPrintRegister("ar0", st->ar0);
    C30SimPrintRegister("ar1", st->ar1);
    C30SimPrintRegister("ar2", st->ar2);
    C30SimPrintRegister("ar3", st->ar3);
    C30SimPrintRegister("ar4", st->ar4);
    C30SimPrintRegister("ar5", st->ar5);
    C30SimPrintRegister("ar6", st->ar6);
    C30SimPrintRegister("ar7", st->ar7);
    fflush(stdout);

    /* index registers */
    C30SimPrintRegister("ir0", st->ir0);
    C30SimPrintRegister("ir1", st->ir1);
    fflush(stdout);

    /* miscellaneous registers */
    C30SimPrintRegister("bk", st->bk);
    C30SimPrintRegister("pc", st->pc);
    C30SimPrintRegister("st", st->st);
    C30SimPrintRegister("rs", st->rs);
    C30SimPrintRegister("re", st->re);
    C30SimPrintRegister("rc", st->rc);
    C30SimPrintRegister("dp", st->dp);
    C30SimPrintRegister("sp", st->sp);
    C30SimPrintRegister("ie", st->ie);
    C30SimPrintRegister("if_", st->if_);
    C30SimPrintRegister("iof", st->iof);
    fflush(stdout);

    /* memory is not dumped */

    return 1;
}

/*
Print the values of the registers which have changed between the
old C30 state and the new C30 state.
*/
int C30SimPrintChangesInState(const state* oldst, const state* newst) {

    /* extended precision registers (lower 32 bits) and */
    /* their floating point exponents (upper 8 bits) */
    if ( oldst->Sregs[__r0] != newst->Sregs[__r0] )
        C30SimPrintRegister("r0", newst->Sregs[__r0]);
    if ( oldst->Sregs[__rx0] != newst->Sregs[__rx0] )
        C30SimPrintRegister("rx0", newst->Sregs[__rx0] );
    if ( oldst->Sregs[__r1] != newst->Sregs[__r1] )
	C30SimPrintRegister("r1", newst->Sregs[__r1]);
    if ( oldst->Sregs[__rx1] != newst->Sregs[__rx1] )
	C30SimPrintRegister("rx1", newst->Sregs[__rx1] );
    if ( oldst->Sregs[__r2] != newst->Sregs[__r2] )
	C30SimPrintRegister("r2", newst->Sregs[__r2]);
    if ( oldst->Sregs[__rx2] != newst->Sregs[__rx2] )
	C30SimPrintRegister("rx2", newst->Sregs[__rx2] );
    if ( oldst->Sregs[__r3] != newst->Sregs[__r3] )
	C30SimPrintRegister("r3", newst->Sregs[__r3]);
    if ( oldst->Sregs[__rx3] != newst->Sregs[__rx3] )
	C30SimPrintRegister("rx3", newst->Sregs[__rx3] );
    if ( oldst->Sregs[__r4] != newst->Sregs[__r4] )
	C30SimPrintRegister("r4", newst->Sregs[__r4]);
    if ( oldst->Sregs[__rx4] != newst->Sregs[__rx4] )
	C30SimPrintRegister("rx4", newst->Sregs[__rx4] );
    if ( oldst->Sregs[__r5] != newst->Sregs[__r5] )
	C30SimPrintRegister("r5", newst->Sregs[__r5]);
    if ( oldst->Sregs[__rx5] != newst->Sregs[__rx5] )
	C30SimPrintRegister("rx5", newst->Sregs[__rx5] );
    if ( oldst->Sregs[__r6] != newst->Sregs[__r6] )
	C30SimPrintRegister("r6", newst->Sregs[__r6]);
    if ( oldst->Sregs[__rx6] != newst->Sregs[__rx6] )
	C30SimPrintRegister("rx6", newst->Sregs[__rx6] );
    if ( oldst->Sregs[__r7] != newst->Sregs[__r7] )
	C30SimPrintRegister("r7", newst->Sregs[__r7]);
    if ( oldst->Sregs[__rx7] != newst->Sregs[__rx7] )
	C30SimPrintRegister("rx7", newst->Sregs[__rx7] );
    fflush(stdout);

    /* auxiliary registers */
    if ( oldst->ar0 != newst->ar0 )
	C30SimPrintRegister("ar0", newst->ar0);
    if ( oldst->ar1 != newst->ar1 )
	C30SimPrintRegister("ar1", newst->ar1);
    if ( oldst->ar2 != newst->ar2 )
	C30SimPrintRegister("ar2", newst->ar2);
    if ( oldst->ar3 != newst->ar3 )
	C30SimPrintRegister("ar3", newst->ar3);
    if ( oldst->ar4 != newst->ar4 )
	C30SimPrintRegister("ar4", newst->ar4);
    if ( oldst->ar5 != newst->ar5 )
	C30SimPrintRegister("ar5", newst->ar5);
    if ( oldst->ar6 != newst->ar6 )
	C30SimPrintRegister("ar6", newst->ar6);
    if ( oldst->ar7 != newst->ar7 )
	C30SimPrintRegister("ar7", newst->ar7);
    fflush(stdout);

    /* index registers */
    if ( oldst->ir0 != newst->ir0 )
	C30SimPrintRegister("ir0", newst->ir0);
    if ( oldst->ir1 != newst->ir1 )
	C30SimPrintRegister("ir1", newst->ir1);
    fflush(stdout);

    /* miscellaneous registers */
    if ( oldst->bk != newst->bk )
	C30SimPrintRegister("bk", newst->bk);
    if ( oldst->pc != newst->pc )
	C30SimPrintRegister("pc", newst->pc);
    if ( oldst->st != newst->st)
	C30SimPrintRegister("st", newst->st);
    if ( oldst->rs != newst->rs )
	C30SimPrintRegister("rs", newst->rs);
    if ( oldst->re != newst->re )
	C30SimPrintRegister("re", newst->re);
    if ( oldst->rc != newst->rc )
	C30SimPrintRegister("rc", newst->rc);
    if ( oldst->dp != newst->dp )
	C30SimPrintRegister("dp", newst->dp);
    if ( oldst->sp != newst->sp )
	C30SimPrintRegister("sp", newst->sp);
    if ( oldst->ie != newst->ie )
	C30SimPrintRegister("ie", newst->ie);
    if ( oldst->if_ != newst->if_ )
	C30SimPrintRegister("if_", newst->if_);
    if ( oldst->iof != newst->iof )
	C30SimPrintRegister("iof", newst->iof);
    fflush(stdout);

    /* memory is not dumped */

    return 1;
}
