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