Annotation of ADD_ver_10/CalcularCiclos.c, revision 1.1
1.1 ! rico 1: /********************************************************************/
! 2: /* CalcularCiclos.c */
! 3: /* */
! 4: /* Copyright (c) 1997-2006 Rafael Rico (rafael.rico@uah.es) */
! 5: /* */
! 6: /* This file is part of ADD version 5.10. */
! 7: /* */
! 8: /* ADD is free software; you can redistribute it and/or modify */
! 9: /* it under the terms of the GNU General Public License as */
! 10: /* published by the Free Software Foundation; either version 2 of */
! 11: /* the License, or (at your option) any later version. */
! 12: /* */
! 13: /* ADD is distributed in the hope that it will be useful, */
! 14: /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
! 15: /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
! 16: /* GNU General Public License for more details. */
! 17: /* */
! 18: /* You should have received a copy of the GNU General Public */
! 19: /* License along with ADD; if not, write to the Free Software */
! 20: /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */
! 21: /* 02111-1307 USA */
! 22: /* */
! 23: /* --------------------------- History --------------------------- */
! 24: /* */
! 25: /* Revision 1.2. 01/2006 */
! 26: /* Added GPL License and JavaDoc style documentation */
! 27: /* */
! 28: /* Revision 1.1. 09/2005 */
! 29: /* Initial Revision */
! 30: /* */
! 31: /********************************************************************/
! 32:
! 33: /******************************************************************************/
! 34: /* MÓDULO: CalcularCiclos.c */
! 35: /* */
! 36: /* Este módulo calcula el tiempo de ejecución en ciclos de cada instrucción */
! 37: /* a partir de la operación, el tipo de operando, el tipo de acceso (lectura */
! 38: /* o escritura), el tipo de cómputo de direcciones de memoria (en su caso) y */
! 39: /* si el salto se toma o no (en su caso). */
! 40: /******************************************************************************/
! 41: /* Fecha: 16 de septiembre de 2005 */
! 42: /******************************************************************************/
! 43:
! 44: #include <stdio.h>
! 45: #include <string.h>
! 46: #include <ctype.h>
! 47:
! 48: #include "defines.h"
! 49: #include "tipos.h"
! 50: #include "calcularciclos.h"
! 51:
! 52: /* bases de datos */
! 53: extern unsigned int num_nemonicos;
! 54: extern operacion *nemonicos;
! 55: extern unsigned int num_simbolos;
! 56: extern operando *simbolos;
! 57: extern unsigned int num_tiempos;
! 58: extern tiempo *ciclos;
! 59:
! 60: /* contador de instrucciones */
! 61: extern unsigned long instruccion;
! 62:
! 63: /* otros resultados */
! 64: extern double cpimedio;
! 65:
! 66:
! 67: /* esta función devuelve el número de ciclos invertido en calcular la dirección efectiva */
! 68: /* y normaliza la cadena según el timpo de operando y acceso */
! 69:
! 70: char ComputarDireccion(char *cadena)
! 71: {
! 72: int id;
! 73: char ciclos_tiempo;
! 74: int desplazamiento = NO;
! 75: char mensaje[MAX_LINE];
! 76:
! 77: switch(cadena[0])
! 78: {
! 79: case '\0': /* sin operando; aquí se supone que no debería entrar */
! 80: ciclos_tiempo = 0;
! 81: break;
! 82:
! 83: case '[': /* operando memoria */
! 84: if(isxdigit(cadena[2])) strcpy(cadena, "[XXXX]"); /* es un desplazamiento absoluto */
! 85: else /* ubicaciones de memoria basadas en registros */
! 86: {
! 87: if(cadena[3]==']') /* registro base o índice solamente */
! 88: {
! 89: if(cadena[4]=='\0') desplazamiento = NO;
! 90: else desplazamiento = SI;
! 91: cadena[4]='\0'; /* termino la cadena sin del posible desplazamiento */
! 92: }
! 93: else
! 94: {
! 95: if(cadena[6]=='\0') desplazamiento = NO;
! 96: else desplazamiento = SI;
! 97: cadena[6]='\0'; /* termino la cadena sin del posible desplazamiento */
! 98: }
! 99: }
! 100:
! 101: id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, cadena);
! 102:
! 103: if(id == -1)
! 104: {
! 105: /* emito un error al fichero de log */
! 106: sprintf(mensaje, "[ComputarDireccion] La cadena '%s' no se ha encontrado en Tabla Ciclos", cadena);
! 107: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 108: }
! 109: ciclos_tiempo = ciclos[id].ciclos;
! 110:
! 111: if(desplazamiento == SI) /* si hay desplzamiento añado su tiempo */
! 112: {
! 113: id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, "DESPLZ");
! 114:
! 115: if(id == -1)
! 116: {
! 117: /* emito un error al fichero de log */
! 118: sprintf(mensaje, "[ComputarDireccion] La cadena '%s' no se ha encontrado en Tabla Ciclos", "DESPLZ");
! 119: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 120: }
! 121: ciclos_tiempo += ciclos[id].ciclos;
! 122: }
! 123: strcpy(cadena, "MEM"); /* cambio la cadena por la de acceso a MEMORIA */
! 124: break;
! 125:
! 126: default: /* registros, inmediatos, o direcciones físicas */
! 127: if(isxdigit(cadena[1])) /* es un número hexadecimal */
! 128: {
! 129: switch(strlen(cadena))
! 130: {
! 131: case 2: /* inmediato de 1 byte */
! 132: strcpy(cadena, "INM8");
! 133: break;
! 134:
! 135: case 4: /* inmediato de 2 bytes */
! 136: strcpy(cadena, "INM16");
! 137: break;
! 138:
! 139: case 9: /* dirección física */
! 140: strcpy(cadena, "B:D");
! 141: break;
! 142: }
! 143: }
! 144: else
! 145: {
! 146: if(cadena[1]=='L' || cadena[1]=='H') strcpy(cadena, "REG8");
! 147: else strcpy(cadena, "REG16");
! 148: }
! 149: ciclos_tiempo = 0;
! 150: break;
! 151: }
! 152: return ciclos_tiempo;
! 153: }
! 154:
! 155:
! 156: /* esta función asigna los ciclos ALU y los ciclos BIU correspondientes */
! 157: /* a partir de la ficha de la instrucción */
! 158:
! 159: void CalcularCiclosInstruccion(fichainstruccion *tarjetaoperandos)
! 160: {
! 161: int id;
! 162: char op1[MAX_OPE], op2[MAX_OPE];
! 163: char pesa_inm = SI; /* indico si un inmediato pesa en ciclos o no */
! 164: char ciclos_tiempo;
! 165: char mensaje[MAX_LINE];
! 166:
! 167:
! 168: /* TIEMPO DEBIDO A LA OPERACIÓN */
! 169:
! 170: /* busco en la tabla de ciclos */
! 171:
! 172: id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, tarjetaoperandos->nemonico);
! 173:
! 174: if(id == -1)
! 175: {
! 176: /* emito un error al fichero de log */
! 177: sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Ciclos", tarjetaoperandos->nemonico);
! 178: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 179: }
! 180:
! 181: tarjetaoperandos->ciclosALU = ciclos[id].ciclos;
! 182:
! 183: /* ahora busco en la tabla de nemónicos */
! 184:
! 185: id = BDBuscarCadena(TABLA_NEMONICOS, CAMPO_NEMONICO, tarjetaoperandos->nemonico);
! 186:
! 187: if(id == -1)
! 188: {
! 189: /* emito un error al fichero de log */
! 190: sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Nemónicos", tarjetaoperandos->nemonico);
! 191: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 192: }
! 193:
! 194: /* TIEMPO DEBIDO AL CÓMPUTO DE DIRECCIONES */
! 195: strcpy(op2, tarjetaoperandos->op2);
! 196: ciclos_tiempo = ComputarDireccion(op2);
! 197:
! 198: strcpy(op1, tarjetaoperandos->op1);
! 199: ciclos_tiempo += ComputarDireccion(op1);
! 200:
! 201: /* he obtenido los operandos normalizados */
! 202:
! 203: /* TIEMPO DEBIDO AL TIPO DE OPERANDO Y TIPO DE ACCESO */
! 204:
! 205: /* tamaño de acceso a memoria y tipo de acceso */
! 206: if(!strcmp(op2, "MEM"))
! 207: {
! 208: if(strcmp(op1, "REG8") && strcmp(op1, "INM8")) strcat(op2, "16");
! 209: else strcat(op2, "8");
! 210: /* tipo de acceso: lectura o escritura */
! 211: switch(nemonicos[id].modo_op2)
! 212: {
! 213: case LEIDO: /* leido */
! 214: strcat(op2, "L");
! 215: break;
! 216:
! 217: case ESCRITO: /* escrito */
! 218: strcat(op2, "E");
! 219: break;
! 220:
! 221: case LEIDOYESCRITO: /* leido y escrito */
! 222: strcat(op2, "LE");
! 223: break;
! 224: }
! 225: }
! 226: if(!strcmp(op1, "MEM"))
! 227: {
! 228: if(strcmp(op2, "REG8") && strcmp(op2, "INM8")) strcat(op1, "16");
! 229: else strcat(op1, "8");
! 230: /* tipo de acceso: lectura o escritura */
! 231: switch(nemonicos[id].modo_op1)
! 232: {
! 233: case LEIDO: /* leido */
! 234: strcat(op1, "L");
! 235: break;
! 236:
! 237: case ESCRITO: /* escrito */
! 238: strcat(op1, "E");
! 239: break;
! 240:
! 241: case LEIDOYESCRITO: /* leido y escrito */
! 242: strcat(op1, "LE");
! 243: break;
! 244: }
! 245: }
! 246:
! 247: /* indico si los inmediatos pesan o no en ciclos (los de los saltos, etc. no pesan) */
! 248: if(nemonicos[id].tipo < SALTO_INCONDICIONAL) pesa_inm = SI;
! 249: else pesa_inm = NO;
! 250:
! 251: /* busco en la tabla de ciclos los operandos normalizados */
! 252:
! 253: if(op2[0]!='\0') /* fuente */
! 254: {
! 255: id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, op2);
! 256:
! 257: if(id == -1)
! 258: {
! 259: /* emito un error al fichero de log */
! 260: sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Ciclos", op2);
! 261: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 262: }
! 263:
! 264: ciclos_tiempo += ciclos[id].ciclos;
! 265: }
! 266:
! 267: if(op1[0]!='\0') /* destino */
! 268: {
! 269: id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, op1);
! 270:
! 271: if(id == -1)
! 272: {
! 273: /* emito un error al fichero de log */
! 274: sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Ciclos", op1);
! 275: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 276: }
! 277:
! 278: /* los inmediatos que no pesan sólo pueden estar en el destino */
! 279: if(pesa_inm == SI) ciclos_tiempo += ciclos[id].ciclos;
! 280: }
! 281:
! 282: /* TIEMPO DEBIDO A LOS PREFIJOS */
! 283:
! 284: if(strcmp(tarjetaoperandos->prefijo, ""))
! 285: {
! 286: id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, tarjetaoperandos->prefijo);
! 287:
! 288: if(id == -1)
! 289: {
! 290: /* emito un error al fichero de log */
! 291: sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Ciclos", tarjetaoperandos->prefijo);
! 292: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 293: }
! 294:
! 295: ciclos_tiempo += ciclos[id].ciclos;
! 296: }
! 297:
! 298: tarjetaoperandos->ciclosBIU = ciclos_tiempo;
! 299:
! 300: /* TIEMPO ASOCIADO A LOS SALTOS CONDICIONALES */
! 301:
! 302: if(tarjetaoperandos->salto == 2) /* salto condicional TOMADO */
! 303: {
! 304: id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, "TOMADO");
! 305:
! 306: if(id == -1)
! 307: {
! 308: /* emito un error al fichero de log */
! 309: sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Ciclos", "TOMADO");
! 310: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 311: }
! 312:
! 313: tarjetaoperandos->ciclosALU += ciclos[id].ciclos;
! 314: }
! 315: }
! 316:
! 317:
! 318: /* esta función actualiza el promedio de CPI a partir del tiempo de */
! 319: /* ejecución en ciclos ALU + ciclos BIU de la instrucción en curso */
! 320:
! 321: void ActualizarCPImedio(unsigned short int ciclosALU, unsigned short int ciclosBIU)
! 322: {
! 323: unsigned int ciclos;
! 324:
! 325: ciclos = ciclosALU + ciclosBIU;
! 326:
! 327: cpimedio = CalcularNuevoPromedio (cpimedio, (double)ciclos, instruccion);
! 328: }
! 329:
! 330:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>