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 #else // _MULLONG_ASM
499 #if defined(SDCC_hc08)
500 /* big endian order */
502 struct {unsigned char b3,b2,b1,b0 ;} b;
503 struct {unsigned short hi,lo ;} i;
505 struct { unsigned char b3; unsigned short i12; unsigned char b0;} bi;
508 /* little endian order */
510 struct {unsigned char b0,b1,b2,b3 ;} b;
511 struct {unsigned short lo,hi ;} i;
513 struct { unsigned char b0; unsigned short i12; unsigned char b3;} bi;
517 #if defined(SDCC_USE_XSTACK)
518 # define bcast(x) ((union bil pdata *)&(x))
519 #elif (defined(SDCC_MODEL_LARGE) || defined (SDCC_ds390) || defined (SDCC_ds400)) && !defined(SDCC_STACK_AUTO)
520 # define bcast(x) ((union bil xdata *)&(x))
521 #elif defined(__z80) || defined(__gbz80)
522 # define bcast(x) ((union bil *)&(x))
524 # define bcast(x) ((union bil near *)&(x))
530 ----------------------------
535 ----------------------------
543 |-------> only this side 32 x 32 -> 32
545 #if defined(SDCC_USE_XSTACK)
546 // currently the original code without u fails with --xstack
547 // it runs out of pointer registers
549 _mullong (long a, long b)
553 t.i.hi = bcast(a)->b.b0 * bcast(b)->b.b2; // A
554 t.i.lo = bcast(a)->b.b0 * bcast(b)->b.b0; // A
555 u.bi.b3 = bcast(a)->b.b0 * bcast(b)->b.b3; // B
556 u.bi.i12 = bcast(a)->b.b0 * bcast(b)->b.b1; // B
560 t.b.b3 += bcast(a)->b.b3 * bcast(b)->b.b0; // G
561 t.b.b3 += bcast(a)->b.b2 * bcast(b)->b.b1; // F
562 t.i.hi += bcast(a)->b.b2 * bcast(b)->b.b0; // E
563 t.i.hi += bcast(a)->b.b1 * bcast(b)->b.b1; // D
565 u.bi.b3 = bcast(a)->b.b1 * bcast(b)->b.b2; // C
566 u.bi.i12 = bcast(a)->b.b1 * bcast(b)->b.b0; // C
574 _mullong (long a, long b)
578 t.i.hi = bcast(a)->b.b0 * bcast(b)->b.b2; // A
579 t.i.lo = bcast(a)->b.b0 * bcast(b)->b.b0; // A
580 t.b.b3 += bcast(a)->b.b3 *
582 t.b.b3 += bcast(a)->b.b2 *
584 t.i.hi += bcast(a)->b.b2 * bcast(b)->b.b0; // E <- b lost in .lst
585 // bcast(a)->i.hi is free !
586 t.i.hi += bcast(a)->b.b1 * bcast(b)->b.b1; // D <- b lost in .lst
588 bcast(a)->bi.b3 = bcast(a)->b.b1 *
590 bcast(a)->bi.i12 = bcast(a)->b.b1 *
593 bcast(b)->bi.b3 = bcast(a)->b.b0 *
595 bcast(b)->bi.i12 = bcast(a)->b.b0 *
597 bcast(b)->bi.b0 = 0; // B
598 bcast(a)->bi.b0 = 0; // C
605 #endif // _MULLONG_ASM