File:  [Repository ATC2] / ADD_ver_10 / Attic / CalcularCiclos.c
Revision 1.1: download - view: text, annotated - select for diffs
Thu Jan 19 17:16:29 2006 UTC (18 years, 9 months ago) by rico
Branches: MAIN
CVS tags: HEAD
*** empty log message ***

/********************************************************************/
/*  CalcularCiclos.c                                                */
/*                                                                  */
/*  Copyright (c) 1997-2006 Rafael Rico      (rafael.rico@uah.es)   */
/*                                                                  */
/*  This file is part of ADD version 5.10.                          */
/*                                                                  */
/*  ADD 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.             */
/*                                                                  */
/*  ADD 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.                    */
/*                                                                  */
/*  You should have received a copy of the GNU General Public       */
/*  License along with ADD; if not, write to the Free Software      */
/*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA        */
/*  02111-1307  USA                                                 */
/*                                                                  */
/*  --------------------------- History --------------------------- */
/*                                                                  */
/*  Revision 1.2. 01/2006                                           */
/*  Added GPL License and JavaDoc style documentation               */
/*                                                                  */
/*  Revision 1.1. 09/2005                                           */
/*  Initial Revision                                                */
/*                                                                  */
/********************************************************************/

/******************************************************************************/
/* MÓDULO: CalcularCiclos.c                                                   */
/*                                                                            */
/* Este módulo calcula el tiempo de ejecución en ciclos de cada instrucción   */
/* a partir de la operación, el tipo de operando, el tipo de acceso (lectura  */
/* o escritura), el tipo de cómputo de direcciones de memoria (en su caso) y  */
/* si el salto se toma o no (en su caso).                                     */
/******************************************************************************/
/* Fecha: 16 de septiembre de 2005                                            */
/******************************************************************************/

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include "defines.h"
#include "tipos.h"
#include "calcularciclos.h"

/* bases de datos */
extern unsigned int num_nemonicos;
extern operacion *nemonicos;
extern unsigned int num_simbolos;
extern operando *simbolos;
extern unsigned int num_tiempos;
extern tiempo *ciclos;

/* contador de instrucciones */
extern unsigned long instruccion;

/* otros resultados */
extern double cpimedio;


/* esta función devuelve el número de ciclos invertido en calcular la dirección efectiva */
/* y normaliza la cadena según el timpo de operando y acceso */

char ComputarDireccion(char *cadena)
{
    int id;
	char ciclos_tiempo;
	int desplazamiento = NO;
	char mensaje[MAX_LINE];

	switch(cadena[0])
    {
        case '\0':    /* sin operando; aquí se supone que no debería entrar */
		ciclos_tiempo = 0;
        break;

        case '[':    /* operando memoria */
        if(isxdigit(cadena[2])) strcpy(cadena, "[XXXX]");    /* es un desplazamiento absoluto */
		else		/* ubicaciones de memoria basadas en registros */
        {
			if(cadena[3]==']')		/* registro base o índice solamente */
			{
				if(cadena[4]=='\0') desplazamiento = NO;
				else desplazamiento = SI;
				cadena[4]='\0';		/* termino la cadena sin del posible desplazamiento */
			}
			else
			{
				if(cadena[6]=='\0') desplazamiento = NO;
				else desplazamiento = SI;
				cadena[6]='\0';		/* termino la cadena sin del posible desplazamiento */
			}
        }

		id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, cadena);
    
		if(id == -1)
	    {
			/* emito un error al fichero de log */ 
			sprintf(mensaje, "[ComputarDireccion] La cadena '%s' no se ha encontrado en Tabla Ciclos", cadena);
			Notificar(mensaje, ERROR_SALIR, ECO_NO);
		}
		ciclos_tiempo = ciclos[id].ciclos;
		
		if(desplazamiento == SI)	/* si hay desplzamiento añado su tiempo */
		{
			id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, "DESPLZ");
    
			if(id == -1)
			{
				/* emito un error al fichero de log */ 
				sprintf(mensaje, "[ComputarDireccion] La cadena '%s' no se ha encontrado en Tabla Ciclos", "DESPLZ");
				Notificar(mensaje, ERROR_SALIR, ECO_NO);
			}
			ciclos_tiempo += ciclos[id].ciclos;
		}
		strcpy(cadena, "MEM");	/* cambio la cadena por la de acceso a MEMORIA */
		break;

        default:    /* registros, inmediatos, o direcciones físicas */
        if(isxdigit(cadena[1]))    /* es un número hexadecimal */
        {
            switch(strlen(cadena))
            {
                case 2:    /* inmediato de 1 byte */
                strcpy(cadena, "INM8");
                break;

                case 4:    /* inmediato de 2 bytes */
                strcpy(cadena, "INM16");
                break;

                case 9:    /* dirección física */
                strcpy(cadena, "B:D");
                break;
            }
        }
		else
		{
			if(cadena[1]=='L' || cadena[1]=='H') strcpy(cadena, "REG8");
			else strcpy(cadena, "REG16");
		}
		ciclos_tiempo = 0;
        break;
    }
	return ciclos_tiempo;
}


/* esta función asigna los ciclos ALU y los ciclos BIU correspondientes */
/* a partir de la ficha de la instrucción */

void CalcularCiclosInstruccion(fichainstruccion *tarjetaoperandos)
{
    int id;
	char op1[MAX_OPE], op2[MAX_OPE];
	char pesa_inm = SI;		/* indico si un inmediato pesa en ciclos o no */
	char ciclos_tiempo;
	char mensaje[MAX_LINE];


	/* TIEMPO DEBIDO A LA OPERACIÓN */

	/* busco en la tabla de ciclos */

    id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, tarjetaoperandos->nemonico);
    
	if(id == -1)
    {
        /* emito un error al fichero de log */ 
        sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Ciclos", tarjetaoperandos->nemonico);
		Notificar(mensaje, ERROR_SALIR, ECO_NO);
    }

	tarjetaoperandos->ciclosALU = ciclos[id].ciclos;

	/* ahora busco en la tabla de nemónicos */

    id = BDBuscarCadena(TABLA_NEMONICOS, CAMPO_NEMONICO, tarjetaoperandos->nemonico);
    
	if(id == -1)
    {
        /* emito un error al fichero de log */ 
        sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Nemónicos", tarjetaoperandos->nemonico);
		Notificar(mensaje, ERROR_SALIR, ECO_NO);
    }

	/* TIEMPO DEBIDO AL CÓMPUTO DE DIRECCIONES */
	strcpy(op2, tarjetaoperandos->op2);
	ciclos_tiempo = ComputarDireccion(op2); 

	strcpy(op1, tarjetaoperandos->op1);
	ciclos_tiempo += ComputarDireccion(op1); 

	/* he obtenido los operandos normalizados */

	/* TIEMPO DEBIDO AL TIPO DE OPERANDO Y TIPO DE ACCESO */

	/* tamaño de acceso a memoria y tipo de acceso */
	if(!strcmp(op2, "MEM"))
	{	
		if(strcmp(op1, "REG8") && strcmp(op1, "INM8")) strcat(op2, "16");
		else strcat(op2, "8");
		/* tipo de acceso: lectura o escritura */
        switch(nemonicos[id].modo_op2)
        {
            case LEIDO:    /* leido */
			strcat(op2, "L");
            break;
			
			case ESCRITO:    /* escrito */
			strcat(op2, "E");
			break;

            case LEIDOYESCRITO:    /* leido y escrito */
			strcat(op2, "LE");
            break;
        }
	}
	if(!strcmp(op1, "MEM"))
	{	
		if(strcmp(op2, "REG8") && strcmp(op2, "INM8")) strcat(op1, "16");
		else strcat(op1, "8");
		/* tipo de acceso: lectura o escritura */
        switch(nemonicos[id].modo_op1)
        {
            case LEIDO:    /* leido */
			strcat(op1, "L");
            break;
			
			case ESCRITO:    /* escrito */
			strcat(op1, "E");
			break;

            case LEIDOYESCRITO:    /* leido y escrito */
			strcat(op1, "LE");
            break;
        }
	}

	/* indico si los inmediatos pesan o no en ciclos (los de los saltos, etc. no pesan) */
	if(nemonicos[id].tipo < SALTO_INCONDICIONAL) pesa_inm = SI;
	else pesa_inm = NO;

	/* busco en la tabla de ciclos los operandos normalizados */

    if(op2[0]!='\0')		/* fuente */
	{
		id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, op2);
    
		if(id == -1)
		{
			/* emito un error al fichero de log */ 
			sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Ciclos", op2);
			Notificar(mensaje, ERROR_SALIR, ECO_NO);
		}

		ciclos_tiempo += ciclos[id].ciclos;
	}

	if(op1[0]!='\0')		/* destino */
	{
		id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, op1);
    
		if(id == -1)
		{
			/* emito un error al fichero de log */ 
			sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Ciclos", op1);
			Notificar(mensaje, ERROR_SALIR, ECO_NO);
		}

		/* los inmediatos que no pesan sólo pueden estar en el destino */
		if(pesa_inm == SI) ciclos_tiempo += ciclos[id].ciclos;
	}

	/* TIEMPO DEBIDO A LOS PREFIJOS */

	if(strcmp(tarjetaoperandos->prefijo, ""))
	{
		id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, tarjetaoperandos->prefijo);
    
		if(id == -1)
		{
			/* emito un error al fichero de log */ 
			sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Ciclos", tarjetaoperandos->prefijo);
			Notificar(mensaje, ERROR_SALIR, ECO_NO);
		}

		ciclos_tiempo += ciclos[id].ciclos;
	}

	tarjetaoperandos->ciclosBIU = ciclos_tiempo;

	/* TIEMPO ASOCIADO A LOS SALTOS CONDICIONALES */

	if(tarjetaoperandos->salto == 2)	/* salto condicional TOMADO */
	{
		id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, "TOMADO");
    
		if(id == -1)
		{
			/* emito un error al fichero de log */ 
			sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Ciclos", "TOMADO");
			Notificar(mensaje, ERROR_SALIR, ECO_NO);
		}

		tarjetaoperandos->ciclosALU += ciclos[id].ciclos;
	}
}


/* esta función actualiza el promedio de CPI a partir del tiempo de */
/* ejecución en ciclos ALU + ciclos BIU de la instrucción en curso */

void ActualizarCPImedio(unsigned short int ciclosALU, unsigned short int ciclosBIU)
{
	unsigned int ciclos;

	ciclos = ciclosALU + ciclosBIU;

	cpimedio = CalcularNuevoPromedio (cpimedio, (double)ciclos, instruccion);
}



FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>