Annotation of ADD_ver_10/Source Code/Source Files/CalcularCiclos.c, revision 1.2

1.2     ! rico        1: /********************************************************************/
        !             2: /*  CalcularCiclos.c                                                */
        !             3: /*                                                                  */
        !             4: /*                                                                  */
        !             5: /*  Copyright (c) 1997-2006 Rafael Rico      (rafael.rico@uah.es)   */
        !             6: /*                                                                  */
        !             7: /*  Este fichero forma parte de ADD                                 */
        !             8: /*  (Analizador de Dependencias de Datos)                           */
        !             9: /*  Version 5.10.                                                   */
        !            10: /*                                                                  */
        !            11: /*                                                                  */
        !            12: /*  ADD es software libre. Puede redistribuirlo y/o modificarlo     */
        !            13: /*  bajo los términos de la Licencia Pública General de GNU         */
        !            14: /*  según es publicada por la Free Software Foundation, bien bajo   */
        !            15: /*  la versión 2 de dicha Licencia o bien (según su elección)       */
        !            16: /*  bajo cualquier versión posterior.                               */
        !            17: /*                                                                  */
        !            18: /*  ADD se distribuye con la esperanza de que sea útil,             */
        !            19: /*  pero SIN NINGUNA GARANTÍA, incluso sin la garantía MERCANTIL    */
        !            20: /*  implícita y sin garantizar la CONVENIENCIA PARA UN PROPÓSITO    */
        !            21: /*  PARTICULAR. Véase la Licencia Pública General de GNU para       */
        !            22: /*  más detalles.                                                   */
        !            23: /*                                                                  */
        !            24: /*  Debería haber recibido una copia de la Licencia Pública General */
        !            25: /*  junto con ADD. Si no ha sido así, escriba a la Free Software    */
        !            26: /*  Foundation, Inc., 51 Franklin St, Fifth Floor,                  */
        !            27: /*  Boston, MA  02110-1301  EEUU.                                   */
        !            28: /*                                                                  */
        !            29: /*  -------------------------- Historia --------------------------- */
        !            30: /*                                                                  */
        !            31: /*  $Id$                                                            */
        !            32: /*                                                                  */
        !            33: /*  Revisión 1.2. 01/2006                                           */
        !            34: /*  Se añade la licencia GPL y documentación en estilo Javadoc      */
        !            35: /*                                                                  */
        !            36: /*  Revisión 1.1. 09/2005                                           */
        !            37: /*  Versión inicial                                                 */
        !            38: /*                                                                  */
        !            39: /********************************************************************/
        !            40: 
1.1       rico       41: /******************************************************************************/
                     42: /* MÓDULO: CalcularCiclos.c                                                   */
                     43: /*                                                                            */
                     44: /* Este módulo calcula el tiempo de ejecución en ciclos de cada instrucción   */
                     45: /* a partir de la operación, el tipo de operando, el tipo de acceso (lectura  */
                     46: /* o escritura), el tipo de cómputo de direcciones de memoria (en su caso) y  */
                     47: /* si el salto se toma o no (en su caso).                                     */
                     48: /******************************************************************************/
                     49: /* Fecha: 16 de septiembre de 2005                                            */
                     50: /******************************************************************************/
                     51: 
                     52: #include <stdio.h>
                     53: #include <string.h>
                     54: #include <ctype.h>
                     55: 
                     56: #include "defines.h"
                     57: #include "tipos.h"
                     58: #include "calcularciclos.h"
                     59: 
                     60: /* bases de datos */
                     61: extern unsigned int num_nemonicos;
                     62: extern operacion *nemonicos;
                     63: extern unsigned int num_simbolos;
                     64: extern operando *simbolos;
                     65: extern unsigned int num_tiempos;
                     66: extern tiempo *ciclos;
                     67: 
                     68: /* contador de instrucciones */
                     69: extern unsigned long instruccion;
                     70: 
                     71: /* otros resultados */
                     72: extern double cpimedio;
                     73: 
                     74: 
                     75: /* esta función devuelve el número de ciclos invertido en calcular la dirección efectiva */
                     76: /* y normaliza la cadena según el timpo de operando y acceso */
                     77: 
                     78: char ComputarDireccion(char *cadena)
                     79: {
                     80:     int id;
                     81:     char ciclos_tiempo;
                     82:     int desplazamiento = NO;
                     83:     char mensaje[MAX_LINE];
                     84: 
                     85:     switch(cadena[0])
                     86:     {
                     87:         case '\0':    /* sin operando; aquí se supone que no debería entrar */
                     88:         ciclos_tiempo = 0;
                     89:         break;
                     90: 
                     91:         case '[':    /* operando memoria */
                     92:         if(isxdigit(cadena[2])) strcpy(cadena, "[XXXX]");    /* es un desplazamiento absoluto */
                     93:         else        /* ubicaciones de memoria basadas en registros */
                     94:         {
                     95:             if(cadena[3]==']')        /* registro base o índice solamente */
                     96:             {
                     97:                 if(cadena[4]=='\0') desplazamiento = NO;
                     98:                 else desplazamiento = SI;
                     99:                 cadena[4]='\0';        /* termino la cadena sin del posible desplazamiento */
                    100:             }
                    101:             else
                    102:             {
                    103:                 if(cadena[6]=='\0') desplazamiento = NO;
                    104:                 else desplazamiento = SI;
                    105:                 cadena[6]='\0';        /* termino la cadena sin del posible desplazamiento */
                    106:             }
                    107:         }
                    108: 
                    109:         id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, cadena);
                    110:     
                    111:         if(id == -1)
                    112:         {
                    113:             /* emito un error al fichero de log */ 
                    114:             sprintf(mensaje, "[ComputarDireccion] La cadena '%s' no se ha encontrado en Tabla Ciclos", cadena);
                    115:             Notificar(mensaje, ERROR_SALIR, ECO_NO);
                    116:         }
                    117:         ciclos_tiempo = ciclos[id].ciclos;
                    118:         
                    119:         if(desplazamiento == SI)    /* si hay desplzamiento añado su tiempo */
                    120:         {
                    121:             id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, "DESPLZ");
                    122:     
                    123:             if(id == -1)
                    124:             {
                    125:                 /* emito un error al fichero de log */ 
                    126:                 sprintf(mensaje, "[ComputarDireccion] La cadena '%s' no se ha encontrado en Tabla Ciclos", "DESPLZ");
                    127:                 Notificar(mensaje, ERROR_SALIR, ECO_NO);
                    128:             }
                    129:             ciclos_tiempo += ciclos[id].ciclos;
                    130:         }
                    131:         strcpy(cadena, "MEM");    /* cambio la cadena por la de acceso a MEMORIA */
                    132:         break;
                    133: 
                    134:         default:    /* registros, inmediatos, o direcciones físicas */
                    135:         if(isxdigit(cadena[1]))    /* es un número hexadecimal */
                    136:         {
                    137:             switch(strlen(cadena))
                    138:             {
                    139:                 case 2:    /* inmediato de 1 byte */
                    140:                 strcpy(cadena, "INM8");
                    141:                 break;
                    142: 
                    143:                 case 4:    /* inmediato de 2 bytes */
                    144:                 strcpy(cadena, "INM16");
                    145:                 break;
                    146: 
                    147:                 case 9:    /* dirección física */
                    148:                 strcpy(cadena, "B:D");
                    149:                 break;
                    150:             }
                    151:         }
                    152:         else
                    153:         {
                    154:             if(cadena[1]=='L' || cadena[1]=='H') strcpy(cadena, "REG8");
                    155:             else strcpy(cadena, "REG16");
                    156:         }
                    157:         ciclos_tiempo = 0;
                    158:         break;
                    159:     }
                    160:     return ciclos_tiempo;
                    161: }
                    162: 
                    163: 
                    164: /* esta función asigna los ciclos ALU y los ciclos BIU correspondientes */
                    165: /* a partir de la ficha de la instrucción */
                    166: 
                    167: void CalcularCiclosInstruccion(fichainstruccion *tarjetaoperandos)
                    168: {
                    169:     int id;
                    170:     char op1[MAX_OPE], op2[MAX_OPE];
                    171:     char pesa_inm = SI;        /* indico si un inmediato pesa en ciclos o no */
                    172:     char ciclos_tiempo;
                    173:     char mensaje[MAX_LINE];
                    174: 
                    175: 
                    176:     /* TIEMPO DEBIDO A LA OPERACIÓN */
                    177: 
                    178:     /* busco en la tabla de ciclos */
                    179: 
                    180:     id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, tarjetaoperandos->nemonico);
                    181:     
                    182:     if(id == -1)
                    183:     {
                    184:         /* emito un error al fichero de log */ 
                    185:         sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Ciclos", tarjetaoperandos->nemonico);
                    186:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
                    187:     }
                    188: 
                    189:     tarjetaoperandos->ciclosALU = ciclos[id].ciclos;
                    190: 
                    191:     /* ahora busco en la tabla de nemónicos */
                    192: 
                    193:     id = BDBuscarCadena(TABLA_NEMONICOS, CAMPO_NEMONICO, tarjetaoperandos->nemonico);
                    194:     
                    195:     if(id == -1)
                    196:     {
                    197:         /* emito un error al fichero de log */ 
                    198:         sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Nemónicos", tarjetaoperandos->nemonico);
                    199:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
                    200:     }
                    201: 
                    202:     /* TIEMPO DEBIDO AL CÓMPUTO DE DIRECCIONES */
                    203:     strcpy(op2, tarjetaoperandos->op2);
                    204:     ciclos_tiempo = ComputarDireccion(op2); 
                    205: 
                    206:     strcpy(op1, tarjetaoperandos->op1);
                    207:     ciclos_tiempo += ComputarDireccion(op1); 
                    208: 
                    209:     /* he obtenido los operandos normalizados */
                    210: 
                    211:     /* TIEMPO DEBIDO AL TIPO DE OPERANDO Y TIPO DE ACCESO */
                    212: 
                    213:     /* tamaño de acceso a memoria y tipo de acceso */
                    214:     if(!strcmp(op2, "MEM"))
                    215:     {    
                    216:         if(strcmp(op1, "REG8") && strcmp(op1, "INM8")) strcat(op2, "16");
                    217:         else strcat(op2, "8");
                    218:         /* tipo de acceso: lectura o escritura */
                    219:         switch(nemonicos[id].modo_op2)
                    220:         {
                    221:             case LEIDO:    /* leido */
                    222:             strcat(op2, "L");
                    223:             break;
                    224:             
                    225:             case ESCRITO:    /* escrito */
                    226:             strcat(op2, "E");
                    227:             break;
                    228: 
                    229:             case LEIDOYESCRITO:    /* leido y escrito */
                    230:             strcat(op2, "LE");
                    231:             break;
                    232:         }
                    233:     }
                    234:     if(!strcmp(op1, "MEM"))
                    235:     {    
                    236:         if(strcmp(op2, "REG8") && strcmp(op2, "INM8")) strcat(op1, "16");
                    237:         else strcat(op1, "8");
                    238:         /* tipo de acceso: lectura o escritura */
                    239:         switch(nemonicos[id].modo_op1)
                    240:         {
                    241:             case LEIDO:    /* leido */
                    242:             strcat(op1, "L");
                    243:             break;
                    244:             
                    245:             case ESCRITO:    /* escrito */
                    246:             strcat(op1, "E");
                    247:             break;
                    248: 
                    249:             case LEIDOYESCRITO:    /* leido y escrito */
                    250:             strcat(op1, "LE");
                    251:             break;
                    252:         }
                    253:     }
                    254: 
                    255:     /* indico si los inmediatos pesan o no en ciclos (los de los saltos, etc. no pesan) */
                    256:     if(nemonicos[id].tipo < SALTO_INCONDICIONAL) pesa_inm = SI;
                    257:     else pesa_inm = NO;
                    258: 
                    259:     /* busco en la tabla de ciclos los operandos normalizados */
                    260: 
                    261:     if(op2[0]!='\0')        /* fuente */
                    262:     {
                    263:         id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, op2);
                    264:     
                    265:         if(id == -1)
                    266:         {
                    267:             /* emito un error al fichero de log */ 
                    268:             sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Ciclos", op2);
                    269:             Notificar(mensaje, ERROR_SALIR, ECO_NO);
                    270:         }
                    271: 
                    272:         ciclos_tiempo += ciclos[id].ciclos;
                    273:     }
                    274: 
                    275:     if(op1[0]!='\0')        /* destino */
                    276:     {
                    277:         id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, op1);
                    278:     
                    279:         if(id == -1)
                    280:         {
                    281:             /* emito un error al fichero de log */ 
                    282:             sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Ciclos", op1);
                    283:             Notificar(mensaje, ERROR_SALIR, ECO_NO);
                    284:         }
                    285: 
                    286:         /* los inmediatos que no pesan sólo pueden estar en el destino */
                    287:         if(pesa_inm == SI) ciclos_tiempo += ciclos[id].ciclos;
                    288:     }
                    289: 
                    290:     /* TIEMPO DEBIDO A LOS PREFIJOS */
                    291: 
                    292:     if(strcmp(tarjetaoperandos->prefijo, ""))
                    293:     {
                    294:         id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, tarjetaoperandos->prefijo);
                    295:     
                    296:         if(id == -1)
                    297:         {
                    298:             /* emito un error al fichero de log */ 
                    299:             sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Ciclos", tarjetaoperandos->prefijo);
                    300:             Notificar(mensaje, ERROR_SALIR, ECO_NO);
                    301:         }
                    302: 
                    303:         ciclos_tiempo += ciclos[id].ciclos;
                    304:     }
                    305: 
                    306:     tarjetaoperandos->ciclosBIU = ciclos_tiempo;
                    307: 
                    308:     /* TIEMPO ASOCIADO A LOS SALTOS CONDICIONALES */
                    309: 
                    310:     if(tarjetaoperandos->salto == 2)    /* salto condicional TOMADO */
                    311:     {
                    312:         id = BDBuscarCadena(TABLA_CICLOS, CAMPO_IDENTIFICADOR, "TOMADO");
                    313:     
                    314:         if(id == -1)
                    315:         {
                    316:             /* emito un error al fichero de log */ 
                    317:             sprintf(mensaje, "[CalcularCiclos] La cadena '%s' no se ha encontrado en Tabla Ciclos", "TOMADO");
                    318:             Notificar(mensaje, ERROR_SALIR, ECO_NO);
                    319:         }
                    320: 
                    321:         tarjetaoperandos->ciclosALU += ciclos[id].ciclos;
                    322:     }
                    323: }
                    324: 
                    325: 
                    326: /* esta función actualiza el promedio de CPI a partir del tiempo de */
                    327: /* ejecución en ciclos ALU + ciclos BIU de la instrucción en curso */
                    328: 
                    329: void ActualizarCPImedio(unsigned short int ciclosALU, unsigned short int ciclosBIU)
                    330: {
                    331:     unsigned int ciclos;
                    332: 
                    333:     ciclos = ciclosALU + ciclosBIU;
                    334: 
                    335:     cpimedio = CalcularNuevoPromedio (cpimedio, (double)ciclos, instruccion);
                    336: }
                    337: 
                    338: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>