viernes, 28 de noviembre de 2008

Indicaciones para escribir un editor de excepciones de FPU

Como escribí en el capítulo "Unidad en punto flotante", la IA soporta 2 formas de acceso a editores de excepciones para manipular excepciones no enmascaradas de la FPU; el modo nativo y el compatible con MS-DOS. Lo primero de todo: ¿Por qué MS-DOS no entra en el 'modo nativo'? Los primeros procesadores no tenían unidad de punto flotante integrado en el mismo chip, la tenían en un chip coprocesador numérico separado. El primer coprocesador de ese tipo fue el Intel 8087. Para la salida de la señal de excepciones en punto flotante, este chip tiene un pin de salida INT que los diseñadores del 8087 recomendaron que fuera rutado a través de un controlador de interrupciones programable (PIC) hacia el pin INTR del procesador. Entonces el número del vector de interrupciones que lo acompaña podía ser usado para el acceso al editor de excepciones en punto flotante. Sin embargo, el diseño original del PC de IBM y del sistema operativo MS-DOS usaron un mecanismo diferente para editar la salida INT del 8087. Lo conectaban directamente al pin NMI de entrada del procesador. Entonces el editor de interrupciones de NMI tenía que diferenciar entre interrupciones producidas por una excepción en punto flotante, o por algún otro evento NMI.
Cuando la compatibilidad MS-DOS está activa para los procesadores Intel486 y Pentium y el pin de entrada IGNNE# se activa, la señal FERR# se genera así: 1º, cuando una instrucción FPU causa una excepción FPU no enmascarada, el procesador usa un método "a plazos" para reportar el error, es decir que el procesador no responde inmediatamente (está un tiempo 'congelado'); 2º Cuando se congela, activa la salida FERR#; 3º El procesador congelado espera a una interrupción externa, producida por un hardware en respuesta a la salida FERR#; 4º En sistemas compatibles con MS-DOS, FERR# está conectada a la entrada IRQ13 en la cascada del PIC, y éste genera una interrupción 75H. El método de comunicar el error "a plazos" es usado por todas las excepciones causadas por instrucciones básicas de aritmética, para las demás las guarda en memoria. Sin embargo algunas instrucciones de la FPU con algunas excepciones, usa un método inmediato para comunicar los errores.
Algunas implementaciones hardware han sido menos robustas porque dependían del editor de excepciones para borrar la excepción de petición de interrupción de la FPU en el PIC ANTES de que el editor causara FERR# por no ser confirmado por el borrado de la excepción de la misma FPU.
Si la compatibilidad está activa para procesadores de la familia P6, todo es casi idéntico a lo anterior, salvo que aquí todas las excepciones para todas las instrucciones de FPU causan un error que se comunica inmediatamente; FERR# se activa tan pronto como la FPU detecta un error no enmascarado, no hay esperas. El problema es que puede ser que la interrupción sea servida después de la siguiente instrucción de la secuencia del código, por lo tanto habrá un retraso que depende de la implementación del hardware externo.
Dependiendo de opciones determinadas por el software de diseño de sistemas, el procesador escoge una de dos opciones para actuar en caso de excepción numérica: La 1ª es que selecciona las excepciones por sí mismo produciendo un fix-up por defecto, que en la mayoría de las ocasiones es lo más razonable. Esto permite al programa numérico continuar sin molestias. Cuando detecta una excepción enmascarada, se establece una bandera en el registro numérico de estado pero no se especifica cuándo ocurrió ni dónde fue provocada; En la 2ª un software editor de excepciones puede ser invocado para editarla. Cuando una excepción numérica no está enmascarada y ocurre la excepción, la FPU para la ejecución de las instrucciones numéricas posteriores y provoca una llamada a un software editor de excepciones, que puede implementar cualquier procedimiento de recuperación.
La administración de sincronización requiere un control para las excepciones antes de dejar al procesador que cambie el valor usado por la FPU. Es importante recordar que casi todas las instrucciones numéricas pueden producir excepciones numéricas en determinadas circunstancias. La sincronización de excepciones se refiere a que el editor de excepciones inspecciona y se ocupa de la excepción en el contexto donde se ocurrió. Si la ejecución simultánea está permitida, la reserva del procesador cuando reconoce la excepción a veces no está en el contexto en el que se dio. Pudo haber cambiado sus registros internos y ejecutado un programa completamente diferente en el tiempo en el que ocurrió la excepción. Si el editor de excepciones no puede recapturar el contexto original, no se puede determinar la causa de la excepción ni se puede recuperar completamente de ella. Para resolver este problema, la FPU tiene registros especiales actualizados en el inicio de cada instrucción numérica, para describir la reserva del programa numérico cuando se intenta ejecutar la instrucción que provoca el fallo. Esto proporciona herramientas de ayuda al editor de excepciones para recapturar el contexto original, pero el código de la aplicación debe estar pensado con esta sincronización. Sin embargo, los compiladores de lenguajes de alto nivel ya proporcionan automáticamente toda sincronización requerida; sin embargo, en los lenguajes de bajo nivel es responsabilidad del programador.

No hay comentarios: