/*-------------------------------------------------------------------------
-
- _mulint.c :- routine for (unsigned) int (16 bit) multiplication
+ _mulint.c :- routine for (unsigned) int (16 bit) multiplication
Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
-
- This program is distributed in the hope that it will be useful,
+
+ This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding!
+ what you give them. Help stamp out software-hoarding!
-------------------------------------------------------------------------*/
/* Signed and unsigned multiplication are the same - as long as the output
has the same precision as the input.
- To do: _muluint and _mulsint should be replaced by _mulint.
-
- bernhard@bernhardheld.de
-
Assembler-functions are provided for:
ds390
mcs51 small
mcs51 large
*/
-#if !defined(SDCC_USE_XSTACK) || defined(_SDCC_NO_ASM_LIB_FUNCS)
- #if defined(SDCC_ds390)
- #if !defined(SDCC_STACK_AUTO)
- #define _MULINT_ASM_LARGE
- #endif
- #elif defined(SDCC_mcs51)
- #if defined(SDCC_MODEL_SMALL)
- #if defined(SDCC_STACK_AUTO)
- #define _MULINT_ASM_SMALL_AUTO
- #else
- #define _MULINT_ASM_SMALL
- #endif
- #else // must be SDCC_MODEL_LARGE
- #if !defined(SDCC_STACK_AUTO)
- #define _MULINT_ASM_LARGE
- #endif
- #endif
- #endif
+#if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
+# if defined(SDCC_ds390)
+# if !defined(SDCC_STACK_AUTO)
+# define _MULINT_ASM_LARGE
+# endif
+# elif defined(SDCC_mcs51)
+# if defined(SDCC_MODEL_SMALL)
+# if defined(SDCC_STACK_AUTO) && !defined(SDCC_PARMS_IN_BANK1)
+# define _MULINT_ASM_SMALL_AUTO
+# else
+# define _MULINT_ASM_SMALL
+# endif
+# else // must be SDCC_MODEL_LARGE
+# if !defined(SDCC_STACK_AUTO)
+# define _MULINT_ASM_LARGE
+# endif
+# endif
+# endif
#endif
-#ifdef _MULINT_ASM_LARGE
+#if defined(_MULINT_ASM_LARGE)
-unsigned int
-_muluint (unsigned int a, unsigned int b) // in future: _mulint
+#pragma save
+#pragma less_pedantic
+int
+_mulint (int a, int b)
{
a*b; // hush the compiler
(char)(lsb_a*msb_b)<<8
*/
- _asm
+ __asm
mov r2,dph ; msb_a
mov r3,dpl ; lsb_a
mov b,r3 ; lsb_a
- mov dptr,#__muluint_PARM_2
+#if defined(SDCC_PARMS_IN_BANK1)
+ mov a,b1_0
+#else
+ mov dptr,#__mulint_PARM_2
movx a,@dptr ; lsb_b
+#endif
mul ab ; lsb_a*lsb_b
mov r0,a
mov r1,b
mov b,r2 ; msb_a
+#if defined(SDCC_PARMS_IN_BANK1)
+ mov a,b1_0
+#else
movx a,@dptr ; lsb_b
+#endif
mul ab ; msb_a*lsb_b
add a,r1
mov r1,a
mov b,r3 ; lsb_a
+#if defined(SDCC_PARMS_IN_BANK1)
+ mov a,b1_1
+#else
inc dptr
movx a,@dptr ; msb_b
+#endif
mul ab ; lsb_a*msb_b
add a,r1
mov dph,a
mov dpl,r0
ret
- _endasm;
+ __endasm;
}
+#pragma restore
-int
-_mulsint (int a, int b) // obsolete
-{
- return _muluint (a, b);
-}
-
-#elif defined _MULINT_ASM_SMALL || defined _MULINT_ASM_SMALL_AUTO
+#elif defined(_MULINT_ASM_SMALL) || defined(_MULINT_ASM_SMALL_AUTO)
-void
-_mulint_dummy (void) _naked
+#pragma save
+#pragma less_pedantic
+int
+_mulint_dummy (void) __naked
{
- _asm
+ __asm
- __mulint:
- __muluint: ; obsolete
- __mulsint: ; obsolete
+__mulint:
- .globl __mulint
- .globl __muluint ; obsolete
- .globl __mulsint ; obsolete
+ .globl __mulint
-#if !defined(SDCC_STACK_AUTO)
+#if !defined(SDCC_STACK_AUTO) || defined(SDCC_PARMS_IN_BANK1)
-#if defined(SDCC_NOOVERLAY) // BUG SDCC_NOOVERLAY is not set by -no-overlay
- .area DSEG (DATA)
+#if defined(SDCC_NOOVERLAY)
+ .area DSEG (DATA)
#else
- .area OSEG (OVR,DATA)
+ .area OSEG (OVR,DATA)
#endif
+#if defined(SDCC_PARMS_IN_BANK1)
+ #define bl (b1_0)
+ #define bh (b1_1)
+#else
+ #define bl (__mulint_PARM_2)
+ #define bh (__mulint_PARM_2 + 1)
+__mulint_PARM_2:
- __mulint_PARM_2:
- __muluint_PARM_2: ; obsolete
- __mulsint_PARM_2: ; obsolete
-
- .globl __mulint_PARM_2
- .globl __muluint_PARM_2 ; obsolete
- .globl __mulsint_PARM_2 ; obsolete
+ .globl __mulint_PARM_2
- .ds 2
+ .ds 2
+#endif
- .area CSEG (CODE)
+ .area CSEG (CODE)
- ; globbered registers none
+ ; globbered registers none
- mov a,dpl ; 1 al
- mov b,__mulint_PARM_2 ; 2 bl
- mul ab ; 4 al * bl
- xch a,dpl ; 1 store low-byte of return value, fetch al
- push b ; 2
+ mov a,dpl ; 1 al
+ mov b,bl ; 2 bl
+ mul ab ; 4 al * bl
+ xch a,dpl ; 1 store low-byte of return value, fetch al
+ push b ; 2
- mov b,__mulint_PARM_2 + 1 ; 2 bh
- mul ab ; 4 al * bh
- pop b ; 2
- add a,b ; 1
- xch a,dph ; 1 ah -> acc
+ mov b,bh ; 2 bh
+ mul ab ; 4 al * bh
+ pop b ; 2
+ add a,b ; 1
+ xch a,dph ; 1 ah -> acc
- mov b,__mulint_PARM_2 ; 2 bl
- mul ab ; 4 ah * bl
- add a,dph ; 1
- mov dph,a ; 1
- ret ; 2
- ; 30
+ mov b,bl ; 2 bl
+ mul ab ; 4 ah * bl
+ add a,dph ; 1
+ mov dph,a ; 1
+ ret ; 2
+ ; 30
#else // SDCC_STACK_AUTO
- ; globbered registers r0
+ ; globbered registers r0
+
+ mov a,#-2 ; 1 return address 2 bytes
+ add a,sp ; 1
+ mov r0,a ; 1 r0 points to bh
- mov a,#-2 ; 1 return address 2 bytes
- add a,sp ; 1
- mov r0,a ; 1 r0 points to bh
+ mov a,@r0 ; 1 bh
+ mov b,dpl ; 2 al
+ mul ab ; 4 al * bh
+ push acc ; 2
- mov a,@r0 ; 1 bh
- mov b,dpl ; 2 al
- mul ab ; 4 al * bh
- push acc ; 2
+ mov b,dpl ; 2 al
+ dec r0 ; 1
+ mov a,@r0 ; 1 bl
+ mul ab ; 4 al * bl
- mov b,dpl ; 2 al
- dec r0 ; 1
- mov a,@r0 ; 1 bl
- mul ab ; 4 al * bl
+ mov dpl,a ; 1 low-byte of return-value
- mov dpl,a ; 1 low-byte of return-value
+ pop acc ; 2
+ add a,b ; 1
+ xch a,dph ; 1 ah -> acc
- pop acc ; 2
- add a,b ; 1
- xch a,dph ; 1 ah -> acc
+ mov b,@r0 ; 2 bl
+ mul ab ; 4 ah * bl
+ add a,dph ; 1
+ mov dph,a ; 1
- mov b,@r0 ; 2 bl
- mul ab ; 4 ah * bl
- add a,dph ; 1
- mov dph,a ; 1
+ ret
- ret
-
#endif // SDCC_STACK_AUTO
- _endasm ;
+ __endasm;
}
+#pragma restore
#else
unsigned int t;
} ;
-unsigned int
-_muluint (unsigned int a, unsigned int b) // in future: _mulint
+int
+_mulint (int a, int b)
{
-#ifdef SDCC_MODEL_LARGE // still needed for large + stack-auto
- union uu _xdata *x;
- union uu _xdata *y;
+#if !defined(SDCC_STACK_AUTO) && (defined(SDCC_MODEL_LARGE) || defined(SDCC_ds390)) // still needed for large
+ union uu __xdata *x;
+ union uu __xdata *y;
union uu t;
- x = (union uu _xdata *)&a;
- y = (union uu _xdata *)&b;
+ x = (union uu __xdata *)&a;
+ y = (union uu __xdata *)&b;
#else
register union uu *x;
- register union uu *y;
+ register union uu *y;
union uu t;
x = (union uu *)&a;
y = (union uu *)&b;
t.s.hi += (x->s.lo * y->s.hi) + (x->s.hi * y->s.lo);
return t.t;
-}
-
-int
-_mulsint (int a, int b) // obsolete
-{
- return _muluint (a, b);
}
#endif