1 /*-------------------------------------------------------------------------
2 _mullong.c - routine for multiplication of 32 bit (unsigned) long
4 Written By - Jean Louis VERN jlvern@writeme.com (1999)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 /* Signed and unsigned multiplication are the same - as long as the output
26 has the same precision as the input.
28 To do: _mululong and _mulslong should be replaced by _mullong.
30 bernhard@bernhardheld.de
32 Assembler-functions are provided for:
34 mcs51 small stack-auto
37 #if !defined(SDCC_USE_XSTACK) || defined(_SDCC_NO_ASM_LIB_FUNCS)
38 # if defined(SDCC_mcs51)
39 # if defined(SDCC_MODEL_SMALL)
40 # if defined(SDCC_STACK_AUTO)
41 # define _MULLONG_ASM_SMALL_AUTO
43 # define _MULLONG_ASM_SMALL
49 #if defined _MULLONG_ASM_SMALL || defined _MULLONG_ASM_SMALL_AUTO
52 _mullong_dummy (void) _naked
57 __mululong: ; obsolete
58 __mulslong: ; obsolete
61 .globl __mululong ; obsolete
62 .globl __mulslong ; obsolete
64 ; the result c will be stored in r4...r7
71 ; c1 a1 * b0 + a0 * b1
72 ; c2 a2 * b0 + a1 * b1 + a0 * b2
73 ; c3 a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3
75 #if !defined SDCC_STACK_AUTO
77 #if defined(SDCC_NOOVERLAY) // BUG SDCC_NOOVERLAY is not set by -no-overlay
84 __mululong_PARM_2: ; obsolete
85 __mulslong_PARM_2: ; obsolete
87 .globl __mullong_PARM_2
88 .globl __mululong_PARM_2 ; obsolete
89 .globl __mulslong_PARM_2 ; obsolete
95 ; parameter a comes in a, b, dph, dpl
96 mov r2,b ; save parameter a
104 b0 = __mullong_PARM_2
105 b1 = (__mullong_PARM_2+1)
106 b2 = (__mullong_PARM_2+2)
107 b3 = (__mullong_PARM_2+3)
196 #else // SDCC_STACK_AUTO
198 ; parameter a comes in a, b, dph, dpl
199 mov r2,b ; save parameter a
209 mov a,#-2-3 ; 1 return address 2 bytes, b 4 bytes
211 mov r0,a ; 1 r0 points to b0
216 mov b0,b ; we need b0 several times
217 inc r0 ; r0 points to b1
307 #endif // SDCC_STACK_AUTO
312 #else // _MULLONG_ASM_SMALL || _MULLONG_ASM_SMALL_AUTO
319 struct {unsigned char b0,b1,b2,b3 ;} b;
320 struct {unsigned int lo,hi ;} i;
322 struct { unsigned char b0; unsigned int i12; unsigned char b3;} bi;
324 #if defined(SDCC_MODEL_LARGE) || defined (SDCC_ds390)
325 #define bcast(x) ((union bil _xdata *)&(x))
326 #elif defined(__z80) || defined(__gbz80)
327 #define bcast(x) ((union bil *)&(x))
329 #define bcast(x) ((union bil _near *)&(x))
335 ----------------------------
340 ----------------------------
348 |-------> only this side 32 x 32 -> 32
351 _mululong (unsigned long a, unsigned long b) // in future: _mullong
355 t.i.hi = bcast(a)->b.b0 * bcast(b)->b.b2; // A
356 t.i.lo = bcast(a)->b.b0 * bcast(b)->b.b0; // A
358 t.b.b3 += bcast(a)->b.b3 *
360 t.b.b3 += bcast(a)->b.b2 *
362 t.i.hi += bcast(a)->b.b2 * bcast(b)->b.b0; // E <- b lost in .lst
363 // bcast(a)->i.hi is free !
364 t.i.hi += bcast(a)->b.b1 * bcast(b)->b.b1; // D <- b lost in .lst
366 bcast(a)->bi.b3 = bcast(a)->b.b1 *
368 bcast(a)->bi.i12 = bcast(a)->b.b1 *
371 bcast(b)->bi.b3 = bcast(a)->b.b0 *
373 bcast(b)->bi.i12 = bcast(a)->b.b0 *
375 bcast(b)->bi.b0 = 0; // B
376 bcast(a)->bi.b0 = 0; // C
383 _mulslong (long a, long b) // obsolete
388 #endif // _MULLONG_ASM_SMALL || _MULLONG_ASM_SMALL_AUTO