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