* device/lib/pic/libdev/Makefile.in: build device-specific
[fw/sdcc] / device / lib / _mullong.c
index de42c9b0e252428e204c72fd8375a4630bc55781..92ec722b3ea1d4b5d564fa574e1852c5bcde27f7 100644 (file)
@@ -8,28 +8,24 @@
    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.
    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.
    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.
    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
    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.
 
 -------------------------------------------------------------------------*/
 
 /* 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
    Assembler-functions are provided for:
      mcs51 small
      mcs51 small stack-auto
@@ -38,7 +34,7 @@
 #if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
 #  if defined(SDCC_mcs51)
 #    if defined(SDCC_MODEL_SMALL)
 #if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
 #  if defined(SDCC_mcs51)
 #    if defined(SDCC_MODEL_SMALL)
-#      if defined(SDCC_STACK_AUTO)
+#      if defined(SDCC_STACK_AUTO) && !defined(SDCC_PARMS_IN_BANK1)
 #        define _MULLONG_ASM_SMALL_AUTO
 #      else
 #        define _MULLONG_ASM_SMALL
 #        define _MULLONG_ASM_SMALL_AUTO
 #      else
 #        define _MULLONG_ASM_SMALL
 #  endif
 #endif
 
 #  endif
 #endif
 
-#if defined _MULLONG_ASM_SMALL || defined _MULLONG_ASM_SMALL_AUTO
+#if defined(_MULLONG_ASM_SMALL) || defined(_MULLONG_ASM_SMALL_AUTO)
 
 void
 
 void
-_mullong_dummy (void) _naked
+_mullong_dummy (void) __naked
 {
 {
-       _asm
+       __asm
 
 
-       __mullong:
-       __mululong:                     ; obsolete
-       __mulslong:                     ; obsolete
+__mullong:
 
 
-               .globl __mullong
-               .globl __mululong       ; obsolete
-               .globl __mulslong       ; obsolete
+       .globl __mullong
 
 
-                                       ; the result c will be stored in r4...r7
-               #define c0 r4
-               #define c1 r5
-               #define c2 r6
-               #define c3 r7
+                               ; the result c will be stored in r4...r7
+       #define c0 r4
+       #define c1 r5
+       #define c2 r6
+       #define c3 r7
+
+       #define a0 dpl
+       #define a1 dph
+       #define a2 r2
+       #define a3 r3
 
        ; c0  a0 * b0
        ; c1  a1 * b0 + a0 * b1
        ; c2  a2 * b0 + a1 * b1 + a0 * b2
        ; c3  a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3
 
 
        ; c0  a0 * b0
        ; c1  a1 * b0 + a0 * b1
        ; c2  a2 * b0 + a1 * b1 + a0 * b2
        ; c3  a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3
 
-#if !defined SDCC_STACK_AUTO
-
-#if defined(SDCC_NOOVERLAY)            // BUG SDCC_NOOVERLAY is not set by -no-overlay
-               .area DSEG    (DATA)
+#if !defined(SDCC_STACK_AUTO) || defined(SDCC_PARMS_IN_BANK1)
+#if defined(SDCC_PARMS_IN_BANK1)
+       #define b0  (b1_0)
+       #define b1  (b1_1)
+       #define b2  (b1_2)
+       #define b3  (b1_3)
+#else
+#if defined(SDCC_NOOVERLAY)
+       .area DSEG    (DATA)
 #else
 #else
-               .area OSEG    (OVR,DATA)
+       .area OSEG    (OVR,DATA)
 #endif
 
 #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
-
-               .area CSEG    (CODE)
-
-                                       ; parameter a comes in a, b, dph, dpl
-               mov     r2,b            ; save parameter a
-               mov     r3,a
-
-               #define a0 dpl
-               #define a1 dph
-               #define a2 r2
-               #define a3 r3
-
-               b0 =  __mullong_PARM_2
-               b1 = (__mullong_PARM_2+1)
-               b2 = (__mullong_PARM_2+2)
-               b3 = (__mullong_PARM_2+3)
-
-                                       ;       Byte 0
-               mov     a,a0
-               mov     b,b0
-               mul     ab              ; a0 * b0
-               mov     c0,a
-               mov     c1,b
-
-                                       ;       Byte 1
-               mov     a,a1
-               mov     b,b0
-               mul     ab              ; a1 * b0
-               add     a,c1
-               mov     c1,a
-               clr     a
-               addc    a,b
-               mov     c2,a
-               
-
-               mov     a,a0
-               mov     b,b1
-               mul     ab              ; a0 * b1
-               add     a,c1
-               mov     c1,a
-               mov     a,b
-               addc    a,c2
-               mov     c2,a
-               clr     a
-               rlc     a
-               mov     c3,a
-
-                                       ;       Byte 2
-               mov     a,a2
-               mov     b,b0
-               mul     ab              ; a2 * b0
-               add     a,c2
-               mov     c2,a
-               mov     a,b
-               addc    a,c3
-               mov     c3,a
-
-               mov     a,a1
-               mov     b,b1
-               mul     ab              ; a1 * b1
-               add     a,c2
-               mov     c2,a
-               mov     a,b
-               addc    a,c3
-               mov     c3,a
-
-               mov     a,a0
-               mov     b,b2
-               mul     ab              ; a0 * b2
-               add     a,c2
-               mov     c2,a
-               mov     a,b
-               addc    a,c3
-               mov     c3,a
-
-                                       ;       Byte 3
-               mov     a,a3
-               mov     b,b0
-               mul     ab              ; a3 * b0
-               add     a,c3
-               mov     c3,a
-
-               mov     a,a2
-               mov     b,b1
-               mul     ab              ; a2 * b1
-               add     a,c3
-               mov     c3,a
-
-               mov     a,a1
-               mov     b,b2
-               mul     ab              ; a1 * b2
-               add     a,c3
-               mov     c3,a
-
-               mov     a,a0
-               mov     b,b3
-               mul     ab              ; a0 * b3
-               add     a,c3
-
-               mov     b,c2
-               mov     dph,c1
-               mov     dpl,c0
-               ret
+__mullong_PARM_2:
+
+       .globl __mullong_PARM_2
+
+       .ds     4
+
+       b0 =  __mullong_PARM_2
+       b1 = (__mullong_PARM_2+1)
+       b2 = (__mullong_PARM_2+2)
+       b3 = (__mullong_PARM_2+3)
+
+#endif
+       .area CSEG    (CODE)
+
+                               ; parameter a comes in a, b, dph, dpl
+       mov     r2,b            ; save parameter a
+       mov     r3,a
+
+                               ;       Byte 0
+       mov     a,a0
+       mov     b,b0
+       mul     ab              ; a0 * b0
+       mov     c0,a
+       mov     c1,b
+
+                               ;       Byte 1
+       mov     a,a1
+       mov     b,b0
+       mul     ab              ; a1 * b0
+       add     a,c1
+       mov     c1,a
+       clr     a
+       addc    a,b
+       mov     c2,a
+
+       mov     a,a0
+       mov     b,b1
+       mul     ab              ; a0 * b1
+       add     a,c1
+       mov     c1,a
+       mov     a,b
+       addc    a,c2
+       mov     c2,a
+       clr     a
+       rlc     a
+       mov     c3,a
+
+                               ;       Byte 2
+       mov     a,a2
+       mov     b,b0
+       mul     ab              ; a2 * b0
+       add     a,c2
+       mov     c2,a
+       mov     a,b
+       addc    a,c3
+       mov     c3,a
+
+       mov     a,a1
+       mov     b,b1
+       mul     ab              ; a1 * b1
+       add     a,c2
+       mov     c2,a
+       mov     a,b
+       addc    a,c3
+       mov     c3,a
+
+       mov     a,a0
+       mov     b,b2
+       mul     ab              ; a0 * b2
+       add     a,c2
+       mov     c2,a
+       mov     a,b
+       addc    a,c3
+       mov     c3,a
+
+                               ;       Byte 3
+       mov     a,a3
+       mov     b,b0
+       mul     ab              ; a3 * b0
+       add     a,c3
+       mov     c3,a
+
+       mov     a,a2
+       mov     b,b1
+       mul     ab              ; a2 * b1
+       add     a,c3
+       mov     c3,a
+
+       mov     a,a1
+       mov     b,b2
+       mul     ab              ; a1 * b2
+       add     a,c3
+       mov     c3,a
+
+       mov     a,a0
+       mov     b,b3
+       mul     ab              ; a0 * b3
+       add     a,c3
+
+       mov     b,c2
+       mov     dph,c1
+       mov     dpl,c0
+       ret
 
 #else // SDCC_STACK_AUTO
 
 
 #else // SDCC_STACK_AUTO
 
-                                       ; parameter a comes in a, b, dph, dpl
-               mov     r2,b            ; save parameter a
-               mov     r3,a
-
-               #define a0 dpl
-               #define a1 dph
-               #define a2 r2
-               #define a3 r3
-
-               #define b0 r1
-
-               mov     a,#-2-3         ;  1  return address 2 bytes, b 4 bytes
-               add     a,sp            ;  1
-               mov     r0,a            ;  1  r0 points to b0
-
-                                       ;       Byte 0
-               mov     a,a0
-               mov     b,@r0           ; b0
-               mov     b0,b            ; we need b0 several times
-               inc     r0              ; r0 points to b1
-               mul     ab              ; a0 * b0
-               mov     c0,a
-               mov     c1,b
-
-                                       ;       Byte 1
-               mov     a,a1
-               mov     b,b0
-               mul     ab              ; a1 * b0
-               add     a,c1
-               mov     c1,a
-               clr     a
-               addc    a,b
-               mov     c2,a
-               
-
-               mov     a,a0
-               mov     b,@r0           ; b1
-               mul     ab              ; a0 * b1
-               add     a,c1
-               mov     c1,a
-               mov     a,b
-               addc    a,c2
-               mov     c2,a
-               clr     a
-               rlc     a
-               mov     c3,a
-
-                                       ;       Byte 2
-               mov     a,a2
-               mov     b,b0
-               mul     ab              ; a2 * b0
-               add     a,c2
-               mov     c2,a
-               mov     a,b
-               addc    a,c3
-               mov     c3,a
-
-               mov     a,a1
-               mov     b,@r0           ; b1
-               mul     ab              ; a1 * b1
-               add     a,c2
-               mov     c2,a
-               mov     a,b
-               addc    a,c3
-               mov     c3,a
-
-               mov     a,a0
-               inc     r0
-               mov     b,@r0           ; b2
-               mul     ab              ; a0 * b2
-               add     a,c2
-               mov     c2,a
-               mov     a,b
-               addc    a,c3
-               mov     c3,a
-
-                                       ;       Byte 3
-               mov     a,a3
-               mov     b,b0
-               mul     ab              ; a3 * b0
-               add     a,c3
-               mov     c3,a
-
-               mov     a,a1
-               mov     b,@r0           ; b2
-               mul     ab              ; a1 * b2
-               add     a,c3
-               mov     c3,a
-
-               mov     a,a2
-               dec     r0
-               mov     b,@r0           ; b1
-               mul     ab              ; a2 * b1
-               add     a,c3
-               mov     c3,a
-
-               mov     a,a0
-               inc     r0
-               inc     r0
-               mov     b,@r0           ; b3
-               mul     ab              ; a0 * b3
-               add     a,c3
-
-               mov     b,c2
-               mov     dph,c1
-               mov     dpl,c0
-
-               ret
+                               ; parameter a comes in a, b, dph, dpl
+       mov     r2,b            ; save parameter a
+       mov     r3,a
+
+       #define a0 dpl
+       #define a1 dph
+       #define a2 r2
+       #define a3 r3
+
+       #define b0 r1
+
+       mov     a,#-2-3         ;  1  return address 2 bytes, b 4 bytes
+       add     a,sp            ;  1
+       mov     r0,a            ;  1  r0 points to b0
+
+                               ;       Byte 0
+       mov     a,a0
+       mov     b,@r0           ; b0
+       mov     b0,b            ; we need b0 several times
+       inc     r0              ; r0 points to b1
+       mul     ab              ; a0 * b0
+       mov     c0,a
+       mov     c1,b
+
+                               ;       Byte 1
+       mov     a,a1
+       mov     b,b0
+       mul     ab              ; a1 * b0
+       add     a,c1
+       mov     c1,a
+       clr     a
+       addc    a,b
+       mov     c2,a
+
+       mov     a,a0
+       mov     b,@r0           ; b1
+       mul     ab              ; a0 * b1
+       add     a,c1
+       mov     c1,a
+       mov     a,b
+       addc    a,c2
+       mov     c2,a
+       clr     a
+       rlc     a
+       mov     c3,a
+
+                               ;       Byte 2
+       mov     a,a2
+       mov     b,b0
+       mul     ab              ; a2 * b0
+       add     a,c2
+       mov     c2,a
+       mov     a,b
+       addc    a,c3
+       mov     c3,a
+
+       mov     a,a1
+       mov     b,@r0           ; b1
+       mul     ab              ; a1 * b1
+       add     a,c2
+       mov     c2,a
+       mov     a,b
+       addc    a,c3
+       mov     c3,a
+
+       mov     a,a0
+       inc     r0
+       mov     b,@r0           ; b2
+       mul     ab              ; a0 * b2
+       add     a,c2
+       mov     c2,a
+       mov     a,b
+       addc    a,c3
+       mov     c3,a
+
+                               ;       Byte 3
+       mov     a,a3
+       mov     b,b0
+       mul     ab              ; a3 * b0
+       add     a,c3
+       mov     c3,a
+
+       mov     a,a1
+       mov     b,@r0           ; b2
+       mul     ab              ; a1 * b2
+       add     a,c3
+       mov     c3,a
+
+       mov     a,a2
+       dec     r0
+       mov     b,@r0           ; b1
+       mul     ab              ; a2 * b1
+       add     a,c3
+       mov     c3,a
+
+       mov     a,a0
+       inc     r0
+       inc     r0
+       mov     b,@r0           ; b3
+       mul     ab              ; a0 * b3
+       add     a,c3
+
+       mov     b,c2
+       mov     dph,c1
+       mov     dpl,c0
+
+       ret
 
 #endif // SDCC_STACK_AUTO
 
 
 #endif // SDCC_STACK_AUTO
 
-       _endasm ;
+       __endasm;
 }
 
 }
 
+#elif defined(_MULLONG_ASM_LARGE)
+
+void
+_mullong_dummy (void) __naked
+{
+       __asm
+
+__mullong:
+
+       .globl __mullong
+
+                               ; the result c will be stored in r4...r7
+       #define c0 r4
+       #define c1 r5
+       #define c2 r6
+       #define c3 r7
+
+       ; c0  a0 * b0
+       ; c1  a1 * b0 + a0 * b1
+       ; c2  a2 * b0 + a1 * b1 + a0 * b2
+       ; c3  a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3
+
+#if !defined(SDCC_PARMS_IN_BANK1)
+       .area XSEG    (XDATA)
+
+__mullong_PARM_2:
+
+       .globl __mullong_PARM_2
+
+       .ds     4
+#endif
+       .area CSEG    (CODE)
+
+                               ; parameter a comes in a, b, dph, dpl
+       mov     r0,dpl          ; save parameter a
+       mov     r1,dph
+       mov     r2,b
+       mov     r3,a
+
+       #define a0 r0
+       #define a1 r1
+       #define a2 r2
+       #define a3 r3
+
+                               ;       Byte 0
+       mov     b,a0
+#if defined(SDCC_PARMS_IN_BANK1)
+       mov     a,b1_0          ; b0
+#else
+       mov     dptr,#__mullong_PARM_2
+       movx    a,@dptr         ; b0
+#endif
+       mul     ab              ; a0 * b0
+       mov     c0,a
+       mov     c1,b
+
+                               ;       Byte 1
+       mov     b,a1
+#if defined(SDCC_PARMS_IN_BANK1)
+       mov     a,b1_0          ; b0
+#else
+       movx    a,@dptr         ; b0
+#endif
+       mul     ab              ; a1 * b0
+       add     a,c1
+       mov     c1,a
+       clr     a
+       addc    a,b
+       mov     c2,a
+
+       mov     b,a0
+#if defined(SDCC_PARMS_IN_BANK1)
+       mov     a,b1_1          ; b1
+#else
+       inc     dptr            ; b1
+       movx    a,@dptr
+#endif
+       mul     ab              ; a0 * b1
+       add     a,c1
+       mov     c1,a
+       mov     a,b
+       addc    a,c2
+       mov     c2,a
+       clr     a
+       rlc     a
+       mov     c3,a
+
+                               ;       Byte 2
+       mov     b,a1
+#if defined(SDCC_PARMS_IN_BANK1)
+       mov     a,b1_1          ; b1
+#else
+       movx    a,@dptr         ; b1
+#endif
+       mul     ab              ; a1 * b1
+       add     a,c2
+       mov     c2,a
+       mov     a,b
+       addc    a,c3
+       mov     c3,a
+
+       mov     b,a0
+#if defined(SDCC_PARMS_IN_BANK1)
+       mov     a,b1_2          ; b2
+#else
+       inc     dptr            ; b2
+       movx    a,@dptr
+#endif
+       mul     ab              ; a0 * b2
+       add     a,c2
+       mov     c2,a
+       mov     a,b
+       addc    a,c3
+       mov     c3,a
+
+       mov     b,a2
+#if defined(SDCC_PARMS_IN_BANK1)
+       mov     a,b1_0          ; b0
+#else
+       mov     dptr,#__mullong_PARM_2
+       movx    a,@dptr         ; b0
+#endif
+       mul     ab              ; a2 * b0
+       add     a,c2
+       mov     c2,a
+       mov     a,b
+       addc    a,c3
+       mov     c3,a
+
+                               ;       Byte 3
+       mov     b,a3
+#if defined(SDCC_PARMS_IN_BANK1)
+       mov     a,b1_0          ; b0
+#else
+       movx    a,@dptr         ; b0
+#endif
+       mul     ab              ; a3 * b0
+       add     a,c3
+       mov     c3,a
+
+       mov     b,a2
+#if defined(SDCC_PARMS_IN_BANK1)
+       mov     a,b1_1          ; b1
+#else
+       inc     dptr            ; b1
+       movx    a,@dptr
+#endif
+       mul     ab              ; a2 * b1
+       add     a,c3
+       mov     c3,a
 
 
-#elif defined _MULLONG_ASM_LARGE
+       mov     b,a1
+#if defined(SDCC_PARMS_IN_BANK1)
+       mov     a,b1_2          ; b2
+#else
+       inc     dptr            ; b2
+       movx    a,@dptr
+#endif
+       mul     ab              ; a1 * b2
+       add     a,c3
+       mov     c3,a
+
+       mov     b,a0
+#if defined(SDCC_PARMS_IN_BANK1)
+       mov     a,b1_3          ; b3
+#else
+       inc     dptr            ; b3
+       movx    a,@dptr
+#endif
+       mul     ab              ; a0 * b3
+       add     a,c3
+
+       mov     b,c2
+       mov     dph,c1
+       mov     dpl,c0
+       ret
+
+       __endasm;
+}
+
+#elif defined(SDCC_USE_XSTACK) && defined(SDCC_STACK_AUTO)
 
 void
 
 void
-_mullong_dummy (void) _naked
+_mullong_dummy (void) __naked
 {
 {
-       _asm
+       __asm
+
+__mullong:
+
+       .globl __mullong
 
 
-       __mullong:
-       __mululong:                     ; obsolete
-       __mulslong:                     ; obsolete
+                               ; the result c will be stored in r4...r7
+       #define c0 r4
+       #define c1 r5
+       #define c2 r6
+       #define c3 r7
 
 
-               .globl __mullong
-               .globl __mululong       ; obsolete
-               .globl __mulslong       ; obsolete
+       #define a0 dpl
+       #define a1 dph
+       #define a2 r2
+       #define a3 r3
 
 
-                                       ; the result c will be stored in r4...r7
-               #define c0 r4
-               #define c1 r5
-               #define c2 r6
-               #define c3 r7
+       #define b0 r1
 
        ; c0  a0 * b0
        ; c1  a1 * b0 + a0 * b1
        ; c2  a2 * b0 + a1 * b1 + a0 * b2
        ; c3  a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3
 
 
        ; c0  a0 * b0
        ; c1  a1 * b0 + a0 * b1
        ; c2  a2 * b0 + a1 * b1 + a0 * b2
        ; c3  a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3
 
-               .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
-
-               .area CSEG    (CODE)
-
-                                       ; parameter a comes in a, b, dph, dpl
-               mov     r0,dpl          ; save parameter a
-               mov     r1,dph
-               mov     r2,b
-               mov     r3,a
-
-               #define a0 r0
-               #define a1 r1
-               #define a2 r2
-               #define a3 r3
-
-                                       ;       Byte 0
-               mov     b,a0
-               mov     dptr,#__mullong_PARM_2
-               movx    a,@dptr         ; b0
-               mul     ab              ; a0 * b0
-               mov     c0,a
-               mov     c1,b
-
-                                       ;       Byte 1
-               mov     b,a1
-               movx    a,@dptr         ; b0
-               mul     ab              ; a1 * b0
-               add     a,c1
-               mov     c1,a
-               clr     a
-               addc    a,b
-               mov     c2,a
-               
-
-               mov     b,a0
-               inc     dptr            ; b1
-               movx    a,@dptr
-               mul     ab              ; a0 * b1
-               add     a,c1
-               mov     c1,a
-               mov     a,b
-               addc    a,c2
-               mov     c2,a
-               clr     a
-               rlc     a
-               mov     c3,a
-
-                                       ;       Byte 2
-               mov     b,a1
-               movx    a,@dptr         ; b1
-               mul     ab              ; a1 * b1
-               add     a,c2
-               mov     c2,a
-               mov     a,b
-               addc    a,c3
-               mov     c3,a
-
-               mov     b,a0
-               inc     dptr            ; b2
-               movx    a,@dptr
-               mul     ab              ; a0 * b2
-               add     a,c2
-               mov     c2,a
-               mov     a,b
-               addc    a,c3
-               mov     c3,a
-
-               mov     b,a2
-               mov     dptr,#__mullong_PARM_2
-               movx    a,@dptr         ; b0
-               mul     ab              ; a2 * b0
-               add     a,c2
-               mov     c2,a
-               mov     a,b
-               addc    a,c3
-               mov     c3,a
-
-                                       ;       Byte 3
-               mov     b,a3
-               movx    a,@dptr         ; b0
-               mul     ab              ; a3 * b0
-               add     a,c3
-               mov     c3,a
-
-               mov     b,a2
-               inc     dptr            ; b1
-               movx    a,@dptr
-               mul     ab              ; a2 * b1
-               add     a,c3
-               mov     c3,a
-
-               mov     b,a1
-               inc     dptr            ; b2
-               movx    a,@dptr
-               mul     ab              ; a1 * b2
-               add     a,c3
-               mov     c3,a
-
-               mov     b,a0
-               inc     dptr            ; b3
-               movx    a,@dptr
-               mul     ab              ; a0 * b3
-               add     a,c3
-
-               mov     b,c2
-               mov     dph,c1
-               mov     dpl,c0
-               ret
-
-       _endasm ;
+                               ; parameter a comes in a, b, dph, dpl
+       mov     r2,b            ; save parameter a
+       mov     r3,a
+
+       mov     a,#-4           ;  1  b 4 bytes
+       add     a,_spx          ;  1
+       mov     r0,a            ;  1  r0 points to b0
+
+                               ;       Byte 0
+       movx    a,@r0           ; b0
+       mov     b0,a            ; we need b0 several times
+       inc     r0              ; r0 points to b1
+       mov     b,a0
+       mul     ab              ; a0 * b0
+       mov     c0,a
+       mov     c1,b
+
+                               ;       Byte 1
+       mov     a,a1
+       mov     b,b0
+       mul     ab              ; a1 * b0
+       add     a,c1
+       mov     c1,a
+       clr     a
+       addc    a,b
+       mov     c2,a
+
+       mov     b,a0
+       movx    a,@r0           ; b1
+       mul     ab              ; a0 * b1
+       add     a,c1
+       mov     c1,a
+       mov     a,b
+       addc    a,c2
+       mov     c2,a
+       clr     a
+       rlc     a
+       mov     c3,a
+
+                               ;       Byte 2
+       mov     a,a2
+       mov     b,b0
+       mul     ab              ; a2 * b0
+       add     a,c2
+       mov     c2,a
+       mov     a,b
+       addc    a,c3
+       mov     c3,a
+
+       mov     b,a1
+       movx    a,@r0           ; b1
+       mul     ab              ; a1 * b1
+       add     a,c2
+       mov     c2,a
+       mov     a,b
+       addc    a,c3
+       mov     c3,a
+
+       mov     b,a0
+       inc     r0
+       movx    a,@r0           ; b2
+       mul     ab              ; a0 * b2
+       add     a,c2
+       mov     c2,a
+       mov     a,b
+       addc    a,c3
+       mov     c3,a
+
+                               ;       Byte 3
+       mov     a,a3
+       mov     b,b0
+       mul     ab              ; a3 * b0
+       add     a,c3
+       mov     c3,a
+
+       mov     b,a1
+       movx    a,@r0           ; b2
+       mul     ab              ; a1 * b2
+       add     a,c3
+       mov     c3,a
+
+       mov     b,a2
+       dec     r0
+       movx    a,@r0           ; b1
+       mul     ab              ; a2 * b1
+       add     a,c3
+       mov     c3,a
+
+       mov     b,a0
+       inc     r0
+       inc     r0
+       movx    a,@r0           ; b3
+       mul     ab              ; a0 * b3
+       add     a,c3
+
+       mov     b,c2
+       mov     dph,c1
+       mov     dpl,c0
+
+       ret
+
+       __endasm;
 }
 
 #else // _MULLONG_ASM
 
 struct some_struct {
 }
 
 #else // _MULLONG_ASM
 
 struct some_struct {
-       int a ;
+       short a ;
        char b;
        long c ;};
        char b;
        long c ;};
+#if defined(SDCC_hc08)
+/* big endian order */
+union bil {
+        struct {unsigned char b3,b2,b1,b0 ;} b;
+        struct {unsigned short hi,lo ;} i;
+        unsigned long l;
+        struct { unsigned char b3; unsigned short i12; unsigned char b0;} bi;
+} ;
+#else
+/* little endian order */
 union bil {
         struct {unsigned char b0,b1,b2,b3 ;} b;
 union bil {
         struct {unsigned char b0,b1,b2,b3 ;} b;
-        struct {unsigned int lo,hi ;} i;
+        struct {unsigned short lo,hi ;} i;
         unsigned long l;
         unsigned long l;
-        struct { unsigned char b0; unsigned int i12; unsigned char b3;} bi;
+        struct { unsigned char b0; unsigned short i12; unsigned char b3;} bi;
 } ;
 } ;
-#if defined(SDCC_MODEL_LARGE) || defined (SDCC_ds390)
-#define bcast(x) ((union bil _xdata *)&(x))
+#endif
+
+#if defined(SDCC_USE_XSTACK) || defined(SDCC_MODEL_MEDIUM)
+#  define bcast(x) ((union bil __pdata *)&(x))
+#elif (defined(SDCC_MODEL_LARGE) || defined (SDCC_ds390) || defined (SDCC_ds400)) && !defined(SDCC_STACK_AUTO)
+#  define bcast(x) ((union bil __xdata *)&(x))
 #elif defined(__z80) || defined(__gbz80)
 #elif defined(__z80) || defined(__gbz80)
-#define bcast(x) ((union bil *)&(x))
+#  define bcast(x) ((union bil *)&(x))
 #else
 #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
        ----------------------------
 #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.3|1.3|0.2|0.0|   A
                     |2.3|0.3|0.1|     B
@@ -501,42 +671,59 @@ union bil {
                         |3.0|         G
                           |-------> only this side 32 x 32 -> 32
 */
                         |3.0|         G
                           |-------> only this side 32 x 32 -> 32
 */
-unsigned long
-_mululong (unsigned long a, unsigned long b)   // in future: _mullong
+#if defined(SDCC_USE_XSTACK)
+// currently the original code without u fails with --xstack
+// it runs out of pointer registers
+long
+_mullong (long a, long b)
+{
+        union bil t, u;
+
+        t.i.hi   = bcast(a)->b.b0 * bcast(b)->b.b2;          // A
+        t.i.lo   = bcast(a)->b.b0 * bcast(b)->b.b0;          // A
+        u.bi.b3  = bcast(a)->b.b0 * bcast(b)->b.b3;          // B
+        u.bi.i12 = bcast(a)->b.b0 * bcast(b)->b.b1;          // B
+        u.bi.b0  = 0;                                        // B
+        t.l += u.l;
+
+        t.b.b3  += bcast(a)->b.b3 * bcast(b)->b.b0;          // G
+        t.b.b3  += bcast(a)->b.b2 * bcast(b)->b.b1;          // F
+        t.i.hi  += bcast(a)->b.b2 * bcast(b)->b.b0;          // E
+        t.i.hi  += bcast(a)->b.b1 * bcast(b)->b.b1;          // D
+
+        u.bi.b3  = bcast(a)->b.b1 * bcast(b)->b.b2;          // C
+        u.bi.i12 = bcast(a)->b.b1 * bcast(b)->b.b0;          // C
+        u.bi.b0  = 0;                                        // C
+        t.l += u.l;
+
+        return t.l;
+}
+#else
+long
+_mullong (long a, long b)
 {
         union bil t;
 
 {
         union bil t;
 
-        t.i.hi = bcast(a)->b.b0 * bcast(b)->b.b2;       // A
-        t.i.lo = bcast(a)->b.b0 * bcast(b)->b.b0;       // A
-       _asm ;johan _endasm;
-        t.b.b3 += bcast(a)->b.b3 *
-                                  bcast(b)->b.b0;       // G
-        t.b.b3 += bcast(a)->b.b2 *
-                                  bcast(b)->b.b1;       // F
-        t.i.hi += bcast(a)->b.b2 * bcast(b)->b.b0;      // E <- b lost in .lst
+        t.i.hi = bcast(a)->b.b0 * bcast(b)->b.b2;           // A
+        t.i.lo = bcast(a)->b.b0 * bcast(b)->b.b0;           // A
+        t.b.b3 += bcast(a)->b.b3 * bcast(b)->b.b0;          // G
+        t.b.b3 += bcast(a)->b.b2 * bcast(b)->b.b1;          // F
+        t.i.hi += bcast(a)->b.b2 * bcast(b)->b.b0;          // E <- b lost in .lst
         // bcast(a)->i.hi is free !
         // bcast(a)->i.hi is free !
-        t.i.hi += bcast(a)->b.b1 * bcast(b)->b.b1;      // D <- b lost in .lst
-
-        bcast(a)->bi.b3 = bcast(a)->b.b1 *
-                                          bcast(b)->b.b2;
-        bcast(a)->bi.i12 = bcast(a)->b.b1 *
-                           bcast(b)->b.b0;              // C
-
-        bcast(b)->bi.b3 = bcast(a)->b.b0 *
-                                          bcast(b)->b.b3;
-        bcast(b)->bi.i12 = bcast(a)->b.b0 *
-                           bcast(b)->b.b1;              // B
-        bcast(b)->bi.b0 = 0;                            // B
-        bcast(a)->bi.b0 = 0;                            // C
+        t.i.hi += bcast(a)->b.b1 * bcast(b)->b.b1;          // D <- b lost in .lst
+
+        bcast(a)->bi.b3 = bcast(a)->b.b1 * bcast(b)->b.b2;  // C
+        bcast(a)->bi.i12 = bcast(a)->b.b1 * bcast(b)->b.b0; // C
+
+        bcast(b)->bi.b3 = bcast(a)->b.b0 * bcast(b)->b.b3;  // B
+        bcast(b)->bi.i12 = bcast(a)->b.b0 * bcast(b)->b.b1; // B
+
+        bcast(b)->bi.b0 = 0;                                // B
+        bcast(a)->bi.b0 = 0;                                // C
         t.l += a;
 
         return t.l + b;
 }
         t.l += a;
 
         return t.l + b;
 }
-
-long
-_mulslong (long a, long b)     // obsolete
-{
-  return _mululong (a, b);
-}
+#endif
 
 #endif // _MULLONG_ASM
 
 #endif // _MULLONG_ASM