;
    MACRO
    _FNMul16 $m1,$m2,$t1,$t2,$r
    ASSERT  $m1 <> $m2
    ASSERT  $m1 <> $t1
    ASSERT  $m1 <> $t2
    ASSERT  $m1 <> $r
    ASSERT  $m2 <> $t1
    ASSERT  $m2 <> $t2
    ASSERT  $m2 <> $r
    ASSERT  $t1 <> $t2
    ASSERT  $t1 <> $r
    ASSERT  $t2 <> $r
; High1*Low2
    MOV     $t1,$m1,ASR #16
    MOV     $t2,$m2,LSL #16
    MOV     $t2,$t2,LSR #16
    MUL     $r,$t1,$t2
; + Low1*Low2 >> 16
    MOV     $t1,$m1,LSL #16
    MOV     $t1,$t1,LSR #16
    MUL     $t2,$t1,$t2
    ADD     $r,$r,$t2,LSR #16
; + Low1*High2
    MOV     $t2,$m2,ASR #16
    MLA     $r,$t1,$t2,$r
; + High1*High2 << 16
    MOV     $t1,$m1,ASR #16
    MUL     $t1,$t2,$t1
    ADD     $r,$r,$t1,LSL #16
    MEND

    MACRO
    _FNMulH16 $m,$h,$t,$r
    ASSERT  $m <> $h
    ASSERT  $m <> $t
    ASSERT  $m <> $r
    ASSERT  $h <> $t
    ASSERT  $h <> $r
    ASSERT  $t <> $r
; High1*Val16
    MOV     $t,$m,ASR #16
    MUL     $r,$h,$t
; + Low1*Val16 >> 16
    MOV     $t,$m,LSL #16
    MOV     $t,$t,LSR #16
    MUL     $t,$h,$t
    ADD     $r,$r,$t,LSR #16
    MEND

    MACRO
    _FNMul32 $m,$h,$t1,$t2,$r
    ASSERT  $r <> $m
    ASSERT  $r <> $h
    ASSERT  $r <> $t1
    ASSERT  $r <> $t2
    ASSERT  $m <> $h
    ASSERT  $m <> $t1
    ASSERT  $m <> $t2
    ASSERT  $h <> $t1
    ASSERT  $h <> $t2
    ASSERT  $t1 <> $t2
; High1*High2
    MOV     $t1,$m,ASR #16
    MOV     $t2,$h,ASR #16
    MUL     $r,$t1,$t2
; + High1*Low2 >> 16
    MOV     $t2,$h,LSL #16
    MOV     $t2,$t2,LSR #16
    MUL     $t2,$t1,$t2
    ADD     $r,$r,$t2,ASR #16
; + Low1*High2 >> 16
    MOV     $t1,$m,LSL #16
    MOV     $t1,$t1,LSR #16
    MOV     $t2,$h,ASR #16
    MUL     $t2,$t1,$t2
    ADD     $r,$r,$t2,ASR #16
    MEND

 END
