I'm a bit out of practice with 6809 assembler and may not remember all the addressing modes and opcodes exactly, but at a rough approximation, it looks to me as if the code cmoc generates for this simple procedure could be almost halved. Am I grossly mistaken? G CMOC output: ; static short mul_short_by_fp2_14_returning_short(short num, fp2_14 fp) ; { _mul_short_by_fp2_14_returning_short EQU * PSHS U ; save U LEAU ,S ; set U to S int sign = 1; LEAS -2,S ; reserve 2 bytes for 'sign' CLRA LDB #$01 ; D = 1 STD -2,U ; sign = D if (num < 0) { num = -num; sign = -sign; } LDD 4,U ; D = num ADDD #0 ; set condition code BGE L00355 ; skip if >= LDD 4,U ; D = num (which you'll note it already contains...) COMA COMB ADDD #1 ; D = ~num + 1 (ie -num). OH. MY. GOD. Could have NEG'd. Could have CLR'd D and subtracted num. ANYTHING but this. ; (I wonder, is NEG [4,U] supported ? ) STD 4,U ; num = D LDD -2,U ; D = sign COMA COMB ADDD #1 ; D = ~sign + 1 (ie -sign) STD -2,U ; sign = D L00355 EQU * ; endif ; if (fp < 0) { fp = -fp; sign = -sign; } LDD 6,U ; similar code to previous statement ADDD #0 BGE L00358 LDD 6,U COMA COMB ADDD #1 STD 6,U LDD -2,U COMA COMB ADDD #1 STD -2,U L00358 EQU * ; return sign * muldiv(num, fp, ONE_POINT_ZERO); LDD -2,U ; D = sign PSHS B,A ; push sign on S LDY #$4000 ; Y = ONE_POINT_ZERO PSHS Y ; push ONE_POINT_ZERO on S LDX 6,U ; X = fp LDD 4,U ; D = num PSHS X,B,A ; push fp and num on S LBSR _muldiv ; muldiv(num, fp, ONE_POINT_ZERO) leaves result in D LEAS 6,S ; remove muldiv parameters from S PULS X ; pop 'sign' back to X LBSR MUL16 ; multiply X by D, presumably leaving result in D LEAS ,U ; return. Our result is probably in D PULS U,PC ; restore U. Caller must pop params off S. * END FUNCTION ; } ================================== What I would expect an average compiler to output - nothing too clever here... ; static short mul_short_by_fp2_14_returning_short(short num, fp2_14 fp) ; { _mul_short_by_fp2_14_returning_short EQU * ; int sign = 1; LEAU -2,U ; reserve 2 bytes for 'sign' LDB #$01 ; D = 1 SEX STD 0,U ; sign = D ; if (num < 0) { num = -num; sign = -sign; } TFR A,B ; D = 0 CMPD 2,U ; set condition code (reversed test) BLT L00355 ; skip if < SUBD 2,U ; D = 0-num STD 2,U ; num = D CLRA ; D = 0 TFR A,B SUBD 0,U ; D = 0-sign STD 0,U ; sign = D L00355 EQU * ; endif ; if (fp < 0) { fp = -fp; sign = -sign; } TFR A,B ; D = 0 CMPD 4,U ; set condition code (reversed test) BLT L00358 ; skip if < SUBD 4,U ; D = 0-fp STD 4,U ; fp = D CLRA ; D = 0 TFR A,B SUBD 0,U ; D = 0-sign STD 0,U ; sign = D L00358 EQU * ; endif ; return sign * muldiv(num, fp, ONE_POINT_ZERO); LDY #$4000 ; Y = ONE_POINT_ZERO LDX 4,U ; X = fp LDD 2,U ; D = num PSHU X,Y,B,A ; push ONE_POINT_ZERO, fp, and num on U LBSR _muldiv ; muldiv(num, fp, ONE_POINT_ZERO) leaves result in D LDX 0,U ; X = sign LBSR MUL16 ; multiply X by D, presumably leaving result in D LEAU 2,U ; remove local variables from stack RTS ; return * END FUNCTION ; }