[comp.sys.mac.programmer] compiler bug, THINK 4.0.2

wdh@well.sf.ca.us (Bill Hofmann) (06/13/90)

Ran into a little code generation bug in THINK 4.0.2, in which two shorts
are multiplied (producing a long result) and stored into a double.  Alas,
the compiler only moves the low word, producing data-specific wierdness.
See the commented code below.  Rich?  Can you pass this on?

-Bill Hofmann

                               param6    VEQU  8    ; Word
                               param5    VEQU  10   ; Word
                               param4    VEQU  12   ; Word
                               param3    VEQU  14   ; Word
                               param2    VEQU  16   ; Word
                               param1    VEQU  18   ; Word
                                        VEND    
;#  
;#  short /* 5/28/90 wdh */
;#  Visible(Point what, Point P1, Point P2)
;#  { /* return:
;#     *  <0 if what is invisible
;#     *  =0 if what is on the edge of the line
;#     *  >0 if what is visible
;#     */
;#    register double   temp1,temp2,temp3;
;#  
     0:                        Visible  LINK    A6,#0
     4$  470  @2B1CD5        E          FMOVEM  FP0/FP5-FP7,-(A7)
;#    temp1 = (what.h - P1.h)*(P2.v - P1.v);
     8:  561  @2B1CE0      16F          MOVE    param5(A6),D0
     C:  561  @2B1CE4      228          SUB     param3(A6),D0
    10:  561  @2B1CE6      180          MOVE    param2(A6),D1
    14:  561  @2B1CE2       C1          SUB     param4(A6),D1
    18:  011                BF          MULS    D1,D0
    1A$  000                F9          FMOVE.W D0,FP7
######################## MULS produces a LONG result, not a WORD result!!!!
;#    temp2 = (what.v - P1.v)*(P2.h - P1.h);
    1E:  561  @2B1CDE       F2          MOVE    param6(A6),D0
    22:                                 SUB     param4(A6),D0
    26:                                 MOVE    param1(A6),D1
    2A:                                 SUB     param3(A6),D1
    2E:                                 MULS    D1,D0
    30$                                 FMOVE.W D0,FP6
;#    temp3 = temp1 - temp2;
    34$                                 FMOVE   FP7,FP0
    38$                                 FSUB    FP6,FP0
    3C$                                 FMOVE   FP0,FP5
;#    if (temp3 == 0)   return(0);
    40$                                 FCMP.W  #$0000,FP5
    46$                                 FBSNE   mci_1
    4A:                                 MOVEQ   #0,D0
    4C:                                 BRA.S   mci_3
;#    else if (temp3 > 0) return(-1);
    4E$                        mci_1    FCMP.W  #$0000,FP5
    54$                                 FBNGT   mci_2
    58:                                 MOVEQ   #-1,D0
    5A:                                 BRA.S   mci_3
;#    else        return(1);
    5C:                        mci_2    MOVEQ   #1,D0
;#  }
    5E$                        mci_3    FMOVEM  (A7)+,FP0/FP5-FP7
    62:                                 UNLK    A6
    64:                                 RTS     

siegel@endor.harvard.edu (Rich Siegel) (06/13/90)

In article <18473@well.sf.ca.us> wdh@well.sf.ca.us (Bill Hofmann) writes:
>Ran into a little code generation bug in THINK 4.0.2, in which two shorts
>are multiplied (producing a long result) and stored into a double.  Alas,
>the compiler only moves the low word, producing data-specific wierdness.
	
	I'm fairly sure this isn't a bug, since the C semantics don't require
sign-extension to a long unless the target or one of the operands is a long.
You can force this sign-extension by placing a (long) in front of one of the
operands in your expression.

R.
~~~~~~~~~~~~~~~
 Rich Siegel
 Staff Software Developer
 Symantec Corporation, Language Products Group
 Internet: siegel@endor.harvard.edu
 UUCP: ..harvard!endor!siegel

"It's not the years, honey, it's the mileage."

~~~~~~~~~~~~~~~