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>