/* 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
# endif
#endif
-#ifdef _MULINT_ASM_LARGE
+#if defined(_MULINT_ASM_LARGE)
#pragma SAVE
#pragma LESS_PEDANTIC
-unsigned int
-_muluint (unsigned int a, unsigned int b) // in future: _mulint
+int
+_mulint (int a, int b)
{
a*b; // hush the compiler
#if defined(SDCC_PARMS_IN_BANK1)
mov a,b1_0
#else
- mov dptr,#__muluint_PARM_2
+ mov dptr,#__mulint_PARM_2
movx a,@dptr ; lsb_b
#endif
mul ab ; lsb_a*lsb_b
}
#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)
#pragma SAVE
#pragma LESS_PEDANTIC
-unsigned int
+int
_mulint_dummy (void) _naked
{
_asm
__mulint:
- __muluint: ; obsolete
- __mulsint: ; obsolete
.globl __mulint
- .globl __muluint ; obsolete
- .globl __mulsint ; obsolete
#if !defined(SDCC_STACK_AUTO) || defined(SDCC_PARMS_IN_BANK1)
.area OSEG (OVR,DATA)
#endif
#if defined(SDCC_PARMS_IN_BANK1)
- #define bl (b1_0)
- #define bh (b1_1)
+ #define bl (b1_0)
+ #define bh (b1_1)
#else
- #define bl (__mulint_PARM_2)
- #define bh (__mulint_PARM_2 + 1)
+ #define bl (__mulint_PARM_2)
+ #define bh (__mulint_PARM_2 + 1)
__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
-#endif
+#endif
.area CSEG (CODE)
unsigned int t;
} ;
-unsigned int
-_muluint (unsigned int a, unsigned int b) // in future: _mulint
+int
+_mulint (int a, int b)
{
#if !defined(SDCC_STACK_AUTO) && (defined(SDCC_MODEL_LARGE) || defined(SDCC_ds390)) // still needed for large
union uu xdata *x;
return t.t;
}
-int
-_mulsint (int a, int b) // obsolete
-{
- return _muluint (a, b);
-}
-
#endif
#undef _MULINT_ASM
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!
+ 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: _mululong and _mulslong should be replaced by _mullong.
-
- bernhard@bernhardheld.de
-
Assembler-functions are provided for:
mcs51 small
mcs51 small stack-auto
# endif
#endif
-#if defined _MULLONG_ASM_SMALL || defined _MULLONG_ASM_SMALL_AUTO
+#if defined(_MULLONG_ASM_SMALL) || defined(_MULLONG_ASM_SMALL_AUTO)
void
_mullong_dummy (void) _naked
_asm
__mullong:
- __mululong: ; obsolete
- __mulslong: ; obsolete
.globl __mullong
- .globl __mululong ; obsolete
- .globl __mulslong ; obsolete
; the result c will be stored in r4...r7
#define c0 r4
#endif
__mullong_PARM_2:
- __mululong_PARM_2: ; obsolete
- __mulslong_PARM_2: ; obsolete
.globl __mullong_PARM_2
- .globl __mululong_PARM_2 ; obsolete
- .globl __mulslong_PARM_2 ; obsolete
.ds 4
clr a
addc a,b
mov c2,a
-
+
mov a,a0
mov b,b1
clr a
addc a,b
mov c2,a
-
+
mov a,a0
mov b,@r0 ; b1
}
-#elif defined _MULLONG_ASM_LARGE
+#elif defined(_MULLONG_ASM_LARGE)
void
_mullong_dummy (void) _naked
_asm
__mullong:
- __mululong: ; obsolete
- __mulslong: ; obsolete
.globl __mullong
- .globl __mululong ; obsolete
- .globl __mulslong ; obsolete
; the result c will be stored in r4...r7
#define c0 r4
.area XSEG (XDATA)
__mullong_PARM_2:
- __mululong_PARM_2: ; obsolete
- __mulslong_PARM_2: ; obsolete
.globl __mullong_PARM_2
- .globl __mululong_PARM_2 ; obsolete
- .globl __mulslong_PARM_2 ; obsolete
.ds 4
#endif
; Byte 0
mov b,a0
#if defined(SDCC_PARMS_IN_BANK1)
- mov a,b1_0 ; b0
+ mov a,b1_0 ; b0
#else
mov dptr,#__mullong_PARM_2
movx a,@dptr ; b0
; Byte 1
mov b,a1
#if defined(SDCC_PARMS_IN_BANK1)
- mov a,b1_0 ; b0
+ mov a,b1_0 ; b0
#else
movx a,@dptr ; b0
#endif
clr a
addc a,b
mov c2,a
-
+
mov b,a0
#if defined(SDCC_PARMS_IN_BANK1)
struct { unsigned char b0; unsigned int i12; unsigned char b3;} bi;
} ;
#if defined(SDCC_MODEL_LARGE) || defined (SDCC_ds390)
-#define bcast(x) ((union bil xdata *)&(x))
+# define bcast(x) ((union bil xdata *)&(x))
#elif defined(__z80) || defined(__gbz80)
-#define bcast(x) ((union bil *)&(x))
+# define bcast(x) ((union bil *)&(x))
#else
-#define bcast(x) ((union bil near *)&(x))
+# define bcast(x) ((union bil near *)&(x))
#endif
/*
3 2 1 0
X 3 2 1 0
----------------------------
- 0.3 0.2 0.1 0.0
- 1.3 1.2 1.1 1.0
- 2.3 2.2 2.1 2.0
- 3.3 3.2 3.1 3.0
+ 0.3 0.2 0.1 0.0
+ 1.3 1.2 1.1 1.0
+ 2.3 2.2 2.1 2.0
+ 3.3 3.2 3.1 3.0
----------------------------
|3.3|1.3|0.2|0.0| A
|2.3|0.3|0.1| B
|3.0| G
|-------> only this side 32 x 32 -> 32
*/
-unsigned long
-_mululong (unsigned long a, unsigned long b) // in future: _mullong
+long
+_mullong (long a, long b)
{
union bil t;
return t.l + b;
}
-long
-_mulslong (long a, long b) // obsolete
-{
- return _mululong (a, b);
-}
-
#endif // _MULLONG_ASM
ld d,a
ld b,a
- jp .mulu16
-
-__mulsint_rrx_s::
-__muluint_rrx_s::
+ jp .mul16
+
+__mulint_rrx_s::
ld hl,#2
add hl,sp
-
+
ld e,(hl)
inc hl
ld d,(hl)
ld l,a
;; Fall through
-
+
__muluchar_rrx_hds::
-__mulsint_rrx_hds::
-__muluint_rrx_hds::
+__mulint_rrx_hds::
;; Parameters:
;; HL, DE (left, right irrelivent)
ld b,h
ld c,l
-
+
;; 16-bit multiplication
- ;;
+ ;;
;; Entry conditions
;; BC = multiplicand
;; DE = multiplier
- ;;
+ ;;
;; Exit conditions
;; DE = less significant word of product
;;
;; Register used: AF,BC,DE,HL
.mul16:
-.mulu16:
ld hl,#0
ld a,b
; ld c,c
;; less. This is often the case with support address calls.
or a
jp nz,1$
-
+
ld b,#8
ld a,c
1$:
;; Return in DE
ld e,l
ld d,h
-
+
ret
;; Stubs to match between function names
.area _CODE
- .globl __mulslong
- .globl __mululong
+ .globl __mullong
.globl __modslong
.globl __modulong
.globl __divslong
.globl __divuchar_rrx_s
.globl __divuint_rrx_s
.globl __mulschar_rrx_s
- .globl __mulsint_rrx_s
.globl __muluchar_rrx_s
- .globl __muluint_rrx_s
+ .globl __mulint_rrx_s
.globl __moduchar_rrx_s
.globl __modschar_rrx_s
.globl __moduint_rrx_s
.globl __rrslong_rrx_s
.globl __rlulong_rrx_s
.globl __rlslong_rrx_s
-
-__mulslong_rrx_s::
-__mulslong_rrf_s::
- jp __mulslong
-
-__mululong_rrx_s::
-__mululong_rrf_s::
- jp __mululong
-
+
+__mullong_rrx_s::
+__mullong_rrf_s::
+ jp __mullong
+
__modslong_rrx_s::
__modslong_rrf_s::
jp __modslong
-
+
__modulong_rrx_s::
__modulong_rrf_s::
jp __modulong
-
+
__divslong_rrx_s::
__divslong_rrf_s::
jp __divslong
-
+
__divulong_rrx_s::
__divulong_rrf_s::
jp __divulong
-__mulsint_rrf_s::
+__mulint_rrf_s::
ld a,#5
rst 0x08
- jp __mulsint_rrx_s
+ jp __mulint_rrx_s
-__divsint_rrf_s::
+__divsint_rrf_s::
ld a,#5
rst 0x08
jp __divsint_rrx_s
-__muluint_rrf_s::
- ld a,#5
- rst 0x08
- jp __muluint_rrx_s
-
-__divuint_rrf_s::
+__divuint_rrf_s::
ld a,#5
rst 0x08
jp __divuint_rrx_s
-__mulschar_rrf_s::
+__mulschar_rrf_s::
ld a,#5
rst 0x08
jp __mulschar_rrx_s
-__divschar_rrf_s::
+__divschar_rrf_s::
ld a,#5
rst 0x08
jp __divschar_rrx_s
-__muluchar_rrf_s::
+__muluchar_rrf_s::
ld a,#5
rst 0x08
jp __muluchar_rrx_s
-__divuchar_rrf_s::
+__divuchar_rrf_s::
ld a,#5
rst 0x08
jp __divuchar_rrx_s
-__modschar_rrf_s::
+__modschar_rrf_s::
ld a,#5
rst 0x08
jp __modschar_rrx_s
-__moduchar_rrf_s::
+__moduchar_rrf_s::
ld a,#5
rst 0x08
jp __moduchar_rrx_s
-__modsint_rrf_s::
+__modsint_rrf_s::
ld a,#5
rst 0x08
jp __modsint_rrx_s
-__moduint_rrf_s::
+__moduint_rrf_s::
ld a,#5
rst 0x08
jp __moduint_rrx_s
-__rrulong_rrf_s::
+__rrulong_rrf_s::
ld a,#5
rst 0x08
jp __rrulong_rrx_s
rst 0x08
jp __rrslong_rrx_s
-__rlulong_rrf_s::
+__rlulong_rrf_s::
ld a,#5
rst 0x08
jp __rlulong_rrx_s
-__rlslong_rrf_s::
+__rlslong_rrf_s::
ld a,#5
rst 0x08
jp __rlslong_rrx_s
;; Originally from GBDK by Pascal Felber.
-
+
.area _CODE
__mulschar_rrx_s::
ld e,(hl)
inc hl
- ld l,(hl)
+ ld l,(hl)
;; Fall through
__mulschar_rrx_hds::
;; Need to sign extend before going in.
ld c,l
-
+
ld a,l
rla
sbc a,a
ld e,(hl)
inc hl
- ld c,(hl)
+ ld c,(hl)
;; Clear the top
xor a
ld d,a
ld b,a
-
- jp .mulu16
-
-__mulsint_rrx_s::
-__muluint_rrx_s::
+
+ jp .mul16
+
+__mulint_rrx_s::
ld hl,#2
add hl,sp
-
+
ld e,(hl)
inc hl
ld d,(hl)
ld l,a
;; Fall through
-
+
__muluchar_rrx_hds::
-__mulsint_rrx_hds::
-__muluint_rrx_hds::
+__mulint_rrx_hds::
;; Parameters:
;; HL, DE (left, right irrelivent)
ld b,h
ld c,l
-
+
;; 16-bit multiplication
- ;;
+ ;;
;; Entry conditions
;; BC = multiplicand
;; DE = multiplier
- ;;
+ ;;
;; Exit conditions
;; DE = less significant word of product
;;
;; Register used: AF,BC,DE,HL
.mul16:
-.mulu16:
ld hl,#0
ld a,b
; ld c,c
;; less. This is often the case with support address calls.
or a
jp nz,1$
-
+
ld b,#8
ld a,c
1$:
rla ;DLE 27/11/98
jr nc,2$
add hl,de
-2$:
+2$:
djnz 1$
ret
;; Stubs to match between function names
.area _CODE
- .globl __mulslong
- .globl __mululong
+ .globl __mullong
.globl __modslong
.globl __modulong
.globl __divslong
.globl __divuchar_rrx_s
.globl __divuint_rrx_s
.globl __mulschar_rrx_s
- .globl __mulsint_rrx_s
.globl __muluchar_rrx_s
- .globl __muluint_rrx_s
+ .globl __mulint_rrx_s
.globl __moduchar_rrx_s
.globl __modschar_rrx_s
.globl __moduint_rrx_s
.globl __rrslong_rrx_s
.globl __rlulong_rrx_s
.globl __rlslong_rrx_s
-
-__mulslong_rrx_s::
-__mulslong_rrf_s::
- jp __mulslong
-
-__mululong_rrx_s::
-__mululong_rrf_s::
- jp __mululong
-
+
+__mullong_rrx_s::
+__mullong_rrf_s::
+ jp __mullong
+
__modslong_rrx_s::
__modslong_rrf_s::
jp __modslong
-
+
__modulong_rrx_s::
__modulong_rrf_s::
jp __modulong
-
+
__divslong_rrx_s::
__divslong_rrf_s::
jp __divslong
-
+
__divulong_rrx_s::
__divulong_rrf_s::
jp __divulong
-__mulsint_rrf_s::
+__mulint_rrf_s::
ld a,#5
rst 0x08
- jp __mulsint_rrx_s
+ jp __mulint_rrx_s
-__divsint_rrf_s::
+__divsint_rrf_s::
ld a,#5
rst 0x08
jp __divsint_rrx_s
-__muluint_rrf_s::
- ld a,#5
- rst 0x08
- jp __muluint_rrx_s
-
-__divuint_rrf_s::
+__divuint_rrf_s::
ld a,#5
rst 0x08
jp __divuint_rrx_s
-__mulschar_rrf_s::
+__mulschar_rrf_s::
ld a,#5
rst 0x08
jp __mulschar_rrx_s
-__divschar_rrf_s::
+__divschar_rrf_s::
ld a,#5
rst 0x08
jp __divschar_rrx_s
-__muluchar_rrf_s::
+__muluchar_rrf_s::
ld a,#5
rst 0x08
jp __muluchar_rrx_s
-__divuchar_rrf_s::
+__divuchar_rrf_s::
ld a,#5
rst 0x08
jp __divuchar_rrx_s
-__modschar_rrf_s::
+__modschar_rrf_s::
ld a,#5
rst 0x08
jp __modschar_rrx_s
-__moduchar_rrf_s::
+__moduchar_rrf_s::
ld a,#5
rst 0x08
jp __moduchar_rrx_s
-__modsint_rrf_s::
+__modsint_rrf_s::
ld a,#5
rst 0x08
jp __modsint_rrx_s
-__moduint_rrf_s::
+__moduint_rrf_s::
ld a,#5
rst 0x08
jp __moduint_rrx_s
-__rrulong_rrf_s::
+__rrulong_rrf_s::
ld a,#5
rst 0x08
jp __rrulong_rrx_s
rst 0x08
jp __rrslong_rrx_s
-__rlulong_rrf_s::
+__rlulong_rrf_s::
ld a,#5
rst 0x08
jp __rlulong_rrx_s
-__rlslong_rrf_s::
+__rlslong_rrf_s::
ld a,#5
rst 0x08
jp __rlslong_rrx_s
}
}
+/*
for (muldivmod = 0; muldivmod < 3; muldivmod++)
{
for (bwd = 0; bwd < 3; bwd++)
{
for (su = 0; su < 2; su++)
{
- SNPRINTF (buffer, sizeof(buffer),
+ SNPRINTF (buffer, sizeof(buffer),
"_%s%s%s",
smuldivmod[muldivmod],
ssu[su],
}
}
+ muluint() and mulsint() resp. mululong() and mulslong() return the same result.
+ Therefore they've been merged into mulint() and mullong().
+*/
+
+ for (bwd = 0; bwd < 3; bwd++)
+ {
+ for (su = 0; su < 2; su++)
+ {
+ for (muldivmod = 1; muldivmod < 3; muldivmod++)
+ {
+ /* div and mod */
+ SNPRINTF (buffer, sizeof(buffer),
+ "_%s%s%s",
+ smuldivmod[muldivmod],
+ ssu[su],
+ sbwd[bwd]);
+ __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
+ FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
+ }
+ }
+ }
+ /* mul only */
+ muldivmod = 0;
+ /* byte */
+ bwd = 0;
+ for (su = 0; su < 2; su++)
+ {
+ /* muluchar and mulschar are still separate functions, because e.g. the z80
+ port is sign/zero-extending to int before calling mulint() */
+ SNPRINTF (buffer, sizeof(buffer),
+ "_%s%s%s",
+ smuldivmod[muldivmod],
+ ssu[su],
+ sbwd[bwd]);
+ __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
+ FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
+ }
+ /* signed only */
+ su = 0;
+ /* word and doubleword */
+ for (bwd = 1; bwd < 3; bwd++)
+ {
+ /* mul, int/long */
+ SNPRINTF (buffer, sizeof(buffer),
+ "_%s%s",
+ smuldivmod[muldivmod],
+ sbwd[bwd]);
+ __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
+ FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
+ /* signed = unsigned */
+ __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
+ }
+
for (rlrr = 0; rlrr < 2; rlrr++)
{
for (bwd = 0; bwd < 3; bwd++)
{
for (su = 0; su < 2; su++)
{
- SNPRINTF (buffer, sizeof(buffer),
+ SNPRINTF (buffer, sizeof(buffer),
"_%s%s%s",
srlrr[rlrr],
ssu[su],