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>