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>