* device/lib/mcs51/crtxclear.asm: pdata segment of 256 byte would not be cleared...
[fw/sdcc] / device / lib / _mullong.c
index 61dfaa446c18648a7c03a17dd35d3ad9baeddc17..dee5a51ecf546ee3233b22c90d79d15093da8b1a 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.
-   
+
    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
@@ -51,7 +47,7 @@
 #  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
@@ -59,12 +55,8 @@ _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
@@ -96,12 +88,8 @@ _mullong_dummy (void) _naked
 #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
 
@@ -133,7 +121,7 @@ _mullong_dummy (void) _naked
                clr     a
                addc    a,b
                mov     c2,a
-               
+
 
                mov     a,a0
                mov     b,b1
@@ -239,7 +227,7 @@ _mullong_dummy (void) _naked
                clr     a
                addc    a,b
                mov     c2,a
-               
+
 
                mov     a,a0
                mov     b,@r0           ; b1
@@ -321,7 +309,7 @@ _mullong_dummy (void) _naked
 }
 
 
-#elif defined _MULLONG_ASM_LARGE
+#elif defined(_MULLONG_ASM_LARGE)
 
 void
 _mullong_dummy (void) _naked
@@ -329,12 +317,8 @@ _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
@@ -351,12 +335,8 @@ _mullong_dummy (void) _naked
                .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
@@ -376,7 +356,7 @@ _mullong_dummy (void) _naked
                                        ;       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
@@ -388,7 +368,7 @@ _mullong_dummy (void) _naked
                                        ;       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
@@ -398,7 +378,7 @@ _mullong_dummy (void) _naked
                clr     a
                addc    a,b
                mov     c2,a
-               
+
 
                mov     b,a0
 #if defined(SDCC_PARMS_IN_BANK1)
@@ -510,34 +490,183 @@ _mullong_dummy (void) _naked
        _endasm ;
 }
 
+#elif defined(SDCC_USE_XSTACK) && defined(SDCC_STACK_AUTO)
+
+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
+
+               #define a0 dpl
+               #define a1 dph
+               #define a2 r2
+               #define a3 r3
+
+               #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
+
+
+                                       ; 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 {
-       int a ;
+       short a ;
        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;
-        struct {unsigned int lo,hi ;} i;
+        struct {unsigned short lo,hi ;} i;
         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)
-#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
@@ -548,41 +677,59 @@ union bil {
                         |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;
 
-        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
+        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 !
-        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;
 }
-
-long
-_mulslong (long a, long b)     // obsolete
-{
-  return _mululong (a, b);
-}
+#endif
 
 #endif // _MULLONG_ASM