📄 _mulint.c
字号:
/*------------------------------------------------------------------------- _mulint.c :- routine for (unsigned) int (16 bit) multiplication Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999) 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 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 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! -------------------------------------------------------------------------*//* 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 small stack-auto 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#endif#ifdef _MULINT_ASM_LARGEunsigned int_muluint (unsigned int a, unsigned int b) // in future: _mulint{ a*b; // hush the compiler /* mulint= (int)(lsb_a*lsb_b) + (char)(msb_a*lsb_b)<<8 + (char)(lsb_a*msb_b)<<8 */ _asm mov r2,dph ; msb_a mov r3,dpl ; lsb_a mov b,r3 ; lsb_a mov dptr,#__muluint_PARM_2 movx a,@dptr ; lsb_b mul ab ; lsb_a*lsb_b mov r0,a mov r1,b mov b,r2 ; msb_a movx a,@dptr ; lsb_b mul ab ; msb_a*lsb_b add a,r1 mov r1,a mov b,r3 ; lsb_a inc dptr movx a,@dptr ; msb_b mul ab ; lsb_a*msb_b add a,r1 mov dph,a mov dpl,r0 ret _endasm;}int_mulsint (int a, int b) // obsolete{ return _muluint (a, b);}#elif defined _MULINT_ASM_SMALL || defined _MULINT_ASM_SMALL_AUTOvoid_mulint_dummy (void) _naked{ _asm __mulint: __muluint: ; obsolete __mulsint: ; obsolete .globl __mulint .globl __muluint ; obsolete .globl __mulsint ; obsolete#if !defined(SDCC_STACK_AUTO)#if defined(SDCC_NOOVERLAY) // BUG SDCC_NOOVERLAY is not set by -no-overlay .area DSEG (DATA)#else .area OSEG (OVR,DATA)#endif __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 .ds 2 .area CSEG (CODE) ; 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 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,__mulint_PARM_2 ; 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 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 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 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 ret #endif // SDCC_STACK_AUTO _endasm ;}#elseunion uu { struct { unsigned char lo,hi ;} s; unsigned int t;} ;unsigned int_muluint (unsigned int a, unsigned int b) // in future: _mulint{#ifdef SDCC_MODEL_LARGE // still needed for large + stack-auto union uu xdata *x; union uu xdata *y; union uu t; x = (union uu xdata *)&a; y = (union uu xdata *)&b;#else register union uu *x; register union uu *y; union uu t; x = (union uu *)&a; y = (union uu *)&b;#endif t.t = x->s.lo * y->s.lo; 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#undef _MULINT_ASM
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -