avy@yugas.UUCP (Avy MOISE) (07/30/87)
July 30, 1987
Program Name:
C68 (C Compiler/Assembly generation pass) Version 2.0 from Microware
Systems Corporation.
Operating System:
OS-9/68000 V2.0 or earlier.
Computer System:
QT+2 from F.H.L, Atari ST.
Application Affected:
VirTeX/IniTex - OSKTeX typesetting system V2.1 for OS-9/68000 Release 2.
Problem description:
Zero divide trap at end of page 4 in 'barry.tex'.
Problem does not occur when processing files with 10 or 11 points fonts.
The zero divide was generated as a result of running latex,
$ latex barry.tex
using '\documentstyle[12pt]{report}'
Diagnosis:
The problem originates in the routine 'zbadness()' (see code below).
We have traced it to a bug in the Microware C compiler V2.0.
The C compiler generates bad code when register variables are in use.
Two consecutive calls are made to the _T$UDiv routine without a
divisor reassignment (register D1) before the second call.
Solution:
Remove all register declarations in 'zbadness()' (See assembly output
below). Increase version number to 2.11 and recompile virtex and initex.
Additional Action:
Report to Microware.
Inform all OSKTeX users.
Provide free IniTeX/VirTeX upgrades to all licensed OSKTeX users.
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
/*********** Original C code for test.c *************/
typedef unsigned short halfword;
typedef int integer;
typedef integer scaled;
/* #define register /* added for debug and bug fix */
halfword zbadness ( t , s )
register scaled t ;
register scaled s ;
{
register integer r ;
if ( t == 0 ) return ( 0 ) ;
else if ( s <= 0 ) return ( 10000 ) ;
else
{
if ( t <= 7230584 ) r = ( t * 297 ) / s ;
else if ( s >= 1663497 ) r = t / ( s / 297 ) ; /* PROBLEM HERE */
else r = t ;
if ( r > 1290 ) return ( 10000 ) ;
else return ( ( r * r * r + 131072 ) / 262144 ) ;
}
}
/***** Assembler output ***** $cc -xias test.c **************************/
/************** look for the OOPS line ... *****************************/
psect test_c,0,0,0,0,0
nam test_c
* typedef unsigned short halfword;
* typedef int integer;
* typedef integer scaled;
*
* halfword zbadness ( t , s )
* register scaled t ;
* register scaled s ;
* {
ttl zbadness
zbadness: movem.l #_1!3,-(sp)
move.l d0,d4
move.l d1,d5
* register integer r ;
* if ( t == 0 ) return ( 0 ) ;
tst.l d4 :2
bne _5
_4
moveq.l #0,d0 :2
bra _3
* else if ( s <= 0 ) return ( 10000 ) ;
bra _6
_5
tst.l d5 :2
bgt _8
_7
move.l #10000,d0 :6
bra _3
* else
* {
bra _9
_8
* if ( t <= 7230584 ) r = ( t * 297 ) / s ;
cmpi.l #7230584,d4 :6
bgt _11
_10
move.l d4,d0 :2
move.l #297,d1 :6
bsr _T$UMul
move.l d5,d1 :2
bsr _T$LDiv
move.l d0,d6 :2
* else if ( s >= 1663497 ) r = t / ( s / 297 ) ;
bra _12
_11
cmpi.l #1663497,d5 :6
blt _14
_13
move.l d5,d0 :2
move.l #297,d1 :6
bsr _T$LDiv
bsr _T$LDiv ************ OOPS no parameters ??? **************
move.l d0,d6 :2
* else r = t ;
bra _15
_14
move.l d4,d6 :2
* if ( r > 1290 ) return ( 10000 ) ;
_15
_12
cmpi.l #1290,d6 :6
ble _17
_16
move.l #10000,d0 :6
bra _3
* else return ( ( r * r * r + 131072 ) / 262144 ) ;
bra _18
_17
move.l d6,d0 :2
move.l d6,d1 :2
bsr _T$UMul
move.l d6,d1 :2
bsr _T$UMul
addi.l #131072,d0 :6
move.l #262144,d1 :6
bsr _T$LDiv
bra _3
* }
_18
* }
_9
_6
_3
addq.l #8,sp :2
movem.l (sp)+,#_1
rts :2
_1 equ 0x00000070 :0
_2 equ 0x00000018 :0
ends
/*******************************************************************/
/* Now define register to be a no op and recompile to assembly */
/***** look for the PROPER CODE PRODUCED line ***********************/
psect test_c,0,0,0,0,0
nam test_c
* typedef unsigned short halfword;
* typedef int integer;
* typedef integer scaled;
* #define register /* register is a no op */
* halfword zbadness ( t , s )
* register scaled t ;
* register scaled s ;
* {
ttl zbadness
zbadness: movem.l #_1!3,-(sp)
* register integer r ;
* if ( t == 0 ) return ( 0 ) ;
subq.l #4,sp :2
tst.l 4(sp)
bne _5
_4
moveq.l #0,d0 :2
addq.l #4,sp :2
bra _3
* else if ( s <= 0 ) return ( 10000 ) ;
bra _6
_5
tst.l 8(sp)
bgt _8
_7
move.l #10000,d0 :6
addq.l #4,sp :2
bra _3
* else
* {
bra _9
_8
* if ( t <= 7230584 ) r = ( t * 297 ) / s ;
cmpi.l #7230584,4(sp) :8
bgt _11
_10
move.l 4(sp),d0
move.l #297,d1 :6
bsr _T$UMul
move.l 8(sp),d1
bsr _T$LDiv
move.l d0,(sp) :2
* else if ( s >= 1663497 ) r = t / ( s / 297 ) ;
bra _12
_11
cmpi.l #1663497,8(sp) :8
blt _14
_13
move.l 8(sp),d0 ********* PROPER CODE PRODUCED ************
move.l #297,d1 :6
bsr _T$LDiv
move.l d0,d1 :2
move.l 4(sp),d0
bsr _T$LDiv ****** Yes I Like It, It is Much Better - avy@yugas
move.l d0,(sp) :2
* else r = t ;
bra _15
_14
move.l 4(sp),(sp)
* if ( r > 1290 ) return ( 10000 ) ;
_15
_12
cmpi.l #1290,(sp) :6
ble _17
_16
move.l #10000,d0 :6
addq.l #4,sp :2
bra _3
* else return ( ( r * r * r + 131072 ) / 262144 ) ;
bra _18
_17
move.l (sp),d0 :2
move.l (sp),d1 :2
bsr _T$UMul
move.l (sp),d1 :2
bsr _T$UMul
addi.l #131072,d0 :6
move.l #262144,d1 :6
bsr _T$LDiv
addq.l #4,sp :2
bra _3
* }
_18
* }
_9
_6
addq.l #4,sp :2
_3
addq.l #8,sp :2
movem.l (sp)+,#_1
rts :2
_1 equ 0x00000000 :0
_2 equ 0x0000000c :0
ends