[comp.sys.m68k.pc] Bug Report and Fix to OSKTeX V2.0 - TeX for OS-9/68000.

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