1 /*-------------------------------------------------------------------------
2 _mullong.c - routine for multiplication of 32 bit (unsigned) long
4 Written By - Jean Louis VERN jlvern@writeme.com (1999)
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
7 This library is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Library General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 In other words, you are welcome to use, share and improve this program.
22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
26 /* Signed and unsigned multiplication are the same - as long as the output
27 has the same precision as the input.
29 Assembler-functions are provided for:
31 mcs51 small stack-auto
34 #if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
35 # if defined(SDCC_mcs51)
36 # if defined(SDCC_MODEL_SMALL)
37 # if defined(SDCC_STACK_AUTO) && !defined(SDCC_PARMS_IN_BANK1)
38 # define _MULLONG_ASM_SMALL_AUTO
40 # define _MULLONG_ASM_SMALL
42 # elif defined(SDCC_MODEL_LARGE)
43 # if !defined(SDCC_STACK_AUTO)
44 # define _MULLONG_ASM_LARGE
50 #if defined(_MULLONG_ASM_SMALL) || defined(_MULLONG_ASM_SMALL_AUTO)
53 _mullong_dummy (void) _naked
61 ; the result c will be stored in r4...r7
73 ; c1 a1 * b0 + a0 * b1
74 ; c2 a2 * b0 + a1 * b1 + a0 * b2
75 ; c3 a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3
77 #if !defined(SDCC_STACK_AUTO) || defined(SDCC_PARMS_IN_BANK1)
78 #if defined(SDCC_PARMS_IN_BANK1)
84 #if defined(SDCC_NOOVERLAY)
92 .globl __mullong_PARM_2
97 b1 = (__mullong_PARM_2+1)
98 b2 = (__mullong_PARM_2+2)
99 b3 = (__mullong_PARM_2+3)
104 ; parameter a comes in a, b, dph, dpl
105 mov r2,b ; save parameter a
195 #else // SDCC_STACK_AUTO
197 ; parameter a comes in a, b, dph, dpl
198 mov r2,b ; save parameter a
208 mov a,#-2-3 ; 1 return address 2 bytes, b 4 bytes
210 mov r0,a ; 1 r0 points to b0
215 mov b0,b ; we need b0 several times
216 inc r0 ; r0 points to b1
306 #endif // SDCC_STACK_AUTO
312 #elif defined(_MULLONG_ASM_LARGE)
315 _mullong_dummy (void) _naked
323 ; the result c will be stored in r4...r7
330 ; c1 a1 * b0 + a0 * b1
331 ; c2 a2 * b0 + a1 * b1 + a0 * b2
332 ; c3 a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3
334 #if !defined(SDCC_PARMS_IN_BANK1)
339 .globl __mullong_PARM_2
345 ; parameter a comes in a, b, dph, dpl
346 mov r0,dpl ; save parameter a
358 #if defined(SDCC_PARMS_IN_BANK1)
361 mov dptr,#__mullong_PARM_2
370 #if defined(SDCC_PARMS_IN_BANK1)
384 #if defined(SDCC_PARMS_IN_BANK1)
402 #if defined(SDCC_PARMS_IN_BANK1)
415 #if defined(SDCC_PARMS_IN_BANK1)
429 #if defined(SDCC_PARMS_IN_BANK1)
432 mov dptr,#__mullong_PARM_2
444 #if defined(SDCC_PARMS_IN_BANK1)
454 #if defined(SDCC_PARMS_IN_BANK1)
465 #if defined(SDCC_PARMS_IN_BANK1)
476 #if defined(SDCC_PARMS_IN_BANK1)
493 #elif defined(SDCC_USE_XSTACK) && defined(SDCC_STACK_AUTO)
496 _mullong_dummy (void) _naked
504 ; the result c will be stored in r4...r7
518 ; c1 a1 * b0 + a0 * b1
519 ; c2 a2 * b0 + a1 * b1 + a0 * b2
520 ; c3 a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3
523 ; parameter a comes in a, b, dph, dpl
524 mov r2,b ; save parameter a
527 mov a,#-4 ; 1 b 4 bytes
529 mov r0,a ; 1 r0 points to b0
533 mov b0,a ; we need b0 several times
534 inc r0 ; r0 points to b1
628 #else // _MULLONG_ASM
634 #if defined(SDCC_hc08)
635 /* big endian order */
637 struct {unsigned char b3,b2,b1,b0 ;} b;
638 struct {unsigned short hi,lo ;} i;
640 struct { unsigned char b3; unsigned short i12; unsigned char b0;} bi;
643 /* little endian order */
645 struct {unsigned char b0,b1,b2,b3 ;} b;
646 struct {unsigned short lo,hi ;} i;
648 struct { unsigned char b0; unsigned short i12; unsigned char b3;} bi;
652 #if defined(SDCC_USE_XSTACK) || defined(SDCC_MODEL_MEDIUM)
653 # define bcast(x) ((union bil pdata *)&(x))
654 #elif (defined(SDCC_MODEL_LARGE) || defined (SDCC_ds390) || defined (SDCC_ds400)) && !defined(SDCC_STACK_AUTO)
655 # define bcast(x) ((union bil xdata *)&(x))
656 #elif defined(__z80) || defined(__gbz80)
657 # define bcast(x) ((union bil *)&(x))
659 # define bcast(x) ((union bil near *)&(x))
665 ----------------------------
670 ----------------------------
678 |-------> only this side 32 x 32 -> 32
680 #if defined(SDCC_USE_XSTACK)
681 // currently the original code without u fails with --xstack
682 // it runs out of pointer registers
684 _mullong (long a, long b)
688 t.i.hi = bcast(a)->b.b0 * bcast(b)->b.b2; // A
689 t.i.lo = bcast(a)->b.b0 * bcast(b)->b.b0; // A
690 u.bi.b3 = bcast(a)->b.b0 * bcast(b)->b.b3; // B
691 u.bi.i12 = bcast(a)->b.b0 * bcast(b)->b.b1; // B
695 t.b.b3 += bcast(a)->b.b3 * bcast(b)->b.b0; // G
696 t.b.b3 += bcast(a)->b.b2 * bcast(b)->b.b1; // F
697 t.i.hi += bcast(a)->b.b2 * bcast(b)->b.b0; // E
698 t.i.hi += bcast(a)->b.b1 * bcast(b)->b.b1; // D
700 u.bi.b3 = bcast(a)->b.b1 * bcast(b)->b.b2; // C
701 u.bi.i12 = bcast(a)->b.b1 * bcast(b)->b.b0; // C
709 _mullong (long a, long b)
713 t.i.hi = bcast(a)->b.b0 * bcast(b)->b.b2; // A
714 t.i.lo = bcast(a)->b.b0 * bcast(b)->b.b0; // A
715 t.b.b3 += bcast(a)->b.b3 * bcast(b)->b.b0; // G
716 t.b.b3 += bcast(a)->b.b2 * bcast(b)->b.b1; // F
717 t.i.hi += bcast(a)->b.b2 * bcast(b)->b.b0; // E <- b lost in .lst
718 // bcast(a)->i.hi is free !
719 t.i.hi += bcast(a)->b.b1 * bcast(b)->b.b1; // D <- b lost in .lst
721 bcast(a)->bi.b3 = bcast(a)->b.b1 * bcast(b)->b.b2; // C
722 bcast(a)->bi.i12 = bcast(a)->b.b1 * bcast(b)->b.b0; // C
724 bcast(b)->bi.b3 = bcast(a)->b.b0 * bcast(b)->b.b3; // B
725 bcast(b)->bi.i12 = bcast(a)->b.b0 * bcast(b)->b.b1; // B
727 bcast(b)->bi.b0 = 0; // B
728 bcast(a)->bi.b0 = 0; // C
735 #endif // _MULLONG_ASM