Annotation of ADD_ver_10/CalcularCiclos.c, revision 1.2
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;
1.2 ! rico 41: char ciclos_tiempo;
! 42: int desplazamiento = NO;
! 43: char mensaje[MAX_LINE];
1.1 rico 44:
1.2 ! rico 45: switch(cadena[0])
1.1 rico 46: {
47: case '\0': /* sin operando; aquí se supone que no debería entrar */
1.2 ! rico 48: ciclos_tiempo = 0;
1.1 rico 49: break;
50:
51: case '[': /* operando memoria */
52: if(isxdigit(cadena[2])) strcpy(cadena, "[XXXX]"); /* es un desplazamiento absoluto */
1.2 ! rico 53: else /* ubicaciones de memoria basadas en registros */
1.1 rico 54: {
1.2 ! rico 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: }
1.1 rico 67: }
68:
1.2 ! rico 69: id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, cadena);
1.1 rico 70:
1.2 ! rico 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");
1.1 rico 82:
1.2 ! rico 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;
1.1 rico 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: }
1.2 ! rico 112: else
! 113: {
! 114: if(cadena[1]=='L' || cadena[1]=='H') strcpy(cadena, "REG8");
! 115: else strcpy(cadena, "REG16");
! 116: }
! 117: ciclos_tiempo = 0;
1.1 rico 118: break;
119: }
1.2 ! rico 120: return ciclos_tiempo;
1.1 rico 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;
1.2 ! rico 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];
1.1 rico 134:
135:
1.2 ! rico 136: /* TIEMPO DEBIDO A LA OPERACIÓN */
1.1 rico 137:
1.2 ! rico 138: /* busco en la tabla de ciclos */
1.1 rico 139:
140: id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, tarjetaoperandos->nemonico);
141:
1.2 ! rico 142: if(id == -1)
1.1 rico 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);
1.2 ! rico 146: Notificar(mensaje, ERROR_SALIR, ECO_NO);
1.1 rico 147: }
148:
1.2 ! rico 149: tarjetaoperandos->ciclosALU = ciclos[id].ciclos;
1.1 rico 150:
1.2 ! rico 151: /* ahora busco en la tabla de nemónicos */
1.1 rico 152:
153: id = BDBuscarCadena(TABLA_NEMONICOS, CAMPO_NEMONICO, tarjetaoperandos->nemonico);
154:
1.2 ! rico 155: if(id == -1)
1.1 rico 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);
1.2 ! rico 159: Notificar(mensaje, ERROR_SALIR, ECO_NO);
1.1 rico 160: }
161:
1.2 ! rico 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 */
1.1 rico 179: switch(nemonicos[id].modo_op2)
180: {
181: case LEIDO: /* leido */
1.2 ! rico 182: strcat(op2, "L");
! 183: break;
! 184:
! 185: case ESCRITO: /* escrito */
! 186: strcat(op2, "E");
1.1 rico 187: break;
188:
189: case LEIDOYESCRITO: /* leido y escrito */
1.2 ! rico 190: strcat(op2, "LE");
1.1 rico 191: break;
192: }
1.2 ! rico 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 */
1.1 rico 199: switch(nemonicos[id].modo_op1)
200: {
201: case LEIDO: /* leido */
1.2 ! rico 202: strcat(op1, "L");
! 203: break;
! 204:
! 205: case ESCRITO: /* escrito */
! 206: strcat(op1, "E");
1.1 rico 207: break;
208:
209: case LEIDOYESCRITO: /* leido y escrito */
1.2 ! rico 210: strcat(op1, "LE");
1.1 rico 211: break;
212: }
1.2 ! rico 213: }
1.1 rico 214:
1.2 ! rico 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;
1.1 rico 218:
1.2 ! rico 219: /* busco en la tabla de ciclos los operandos normalizados */
1.1 rico 220:
1.2 ! rico 221: if(op2[0]!='\0') /* fuente */
! 222: {
! 223: id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, op2);
1.1 rico 224:
1.2 ! rico 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);
1.1 rico 238:
1.2 ! rico 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);
1.1 rico 255:
1.2 ! rico 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");
1.1 rico 273:
1.2 ! rico 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: }
1.1 rico 280:
1.2 ! rico 281: tarjetaoperandos->ciclosALU += ciclos[id].ciclos;
! 282: }
1.1 rico 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: {
1.2 ! rico 291: unsigned int ciclos;
1.1 rico 292:
1.2 ! rico 293: ciclos = ciclosALU + ciclosBIU;
1.1 rico 294:
1.2 ! rico 295: cpimedio = CalcularNuevoPromedio (cpimedio, (double)ciclos, instruccion);
1.1 rico 296: }
297:
298:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>