Annotation of ADD_ver_10/CalcularCiclos.c, revision 1.1

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

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