Changed _xdata, _near, etc and removed _generic from library files
[fw/sdcc] / device / lib / _mullong.c
1 /*-------------------------------------------------------------------------
2    _mullong.c - routine for multiplication of 32 bit (unsigned) long
3
4              Written By -  Jean Louis VERN jlvern@writeme.com (1999)
5              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
6
7    This library is free software; you can redistribute it and/or modify it
8    under the terms of the GNU Library General Public License as published by the
9    Free Software Foundation; either version 2, or (at your option) any
10    later version.
11    
12    This library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU Library General Public License for more details.
16    
17    You should have received a copy of the GNU Library General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20    
21    In other words, you are welcome to use, share and improve this program.
22    You are forbidden to forbid anyone else to use, share and improve
23    what you give them.   Help stamp out software-hoarding!  
24 -------------------------------------------------------------------------*/
25
26 /* Signed and unsigned multiplication are the same - as long as the output
27    has the same precision as the input.
28
29    To do: _mululong and _mulslong should be replaced by _mullong.
30
31    bernhard@bernhardheld.de
32
33    Assembler-functions are provided for:
34      mcs51 small
35      mcs51 small stack-auto
36 */
37
38 #if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
39 #  if defined(SDCC_mcs51)
40 #    if defined(SDCC_MODEL_SMALL)
41 #      if defined(SDCC_STACK_AUTO)
42 #        define _MULLONG_ASM_SMALL_AUTO
43 #      else
44 #        define _MULLONG_ASM_SMALL
45 #      endif
46 #    elif defined(SDCC_MODEL_LARGE)
47 #      if !defined(SDCC_STACK_AUTO)
48 #        define _MULLONG_ASM_LARGE
49 #      endif
50 #    endif
51 #  endif
52 #endif
53
54 #if defined _MULLONG_ASM_SMALL || defined _MULLONG_ASM_SMALL_AUTO
55
56 void
57 _mullong_dummy (void) _naked
58 {
59         _asm
60
61         __mullong:
62         __mululong:                     ; obsolete
63         __mulslong:                     ; obsolete
64
65                 .globl __mullong
66                 .globl __mululong       ; obsolete
67                 .globl __mulslong       ; obsolete
68
69                                         ; the result c will be stored in r4...r7
70                 #define c0 r4
71                 #define c1 r5
72                 #define c2 r6
73                 #define c3 r7
74
75         ; c0  a0 * b0
76         ; c1  a1 * b0 + a0 * b1
77         ; c2  a2 * b0 + a1 * b1 + a0 * b2
78         ; c3  a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3
79
80 #if !defined SDCC_STACK_AUTO
81
82 #if defined(SDCC_NOOVERLAY)             // BUG SDCC_NOOVERLAY is not set by -no-overlay
83                 .area DSEG    (DATA)
84 #else
85                 .area OSEG    (OVR,DATA)
86 #endif
87
88         __mullong_PARM_2:
89         __mululong_PARM_2:                      ; obsolete
90         __mulslong_PARM_2:                      ; obsolete
91
92                 .globl __mullong_PARM_2
93                 .globl __mululong_PARM_2        ; obsolete
94                 .globl __mulslong_PARM_2        ; obsolete
95
96                 .ds     4
97
98                 .area CSEG    (CODE)
99
100                                         ; parameter a comes in a, b, dph, dpl
101                 mov     r2,b            ; save parameter a
102                 mov     r3,a
103
104                 #define a0 dpl
105                 #define a1 dph
106                 #define a2 r2
107                 #define a3 r3
108
109                 b0 =  __mullong_PARM_2
110                 b1 = (__mullong_PARM_2+1)
111                 b2 = (__mullong_PARM_2+2)
112                 b3 = (__mullong_PARM_2+3)
113
114                                         ;       Byte 0
115                 mov     a,a0
116                 mov     b,b0
117                 mul     ab              ; a0 * b0
118                 mov     c0,a
119                 mov     c1,b
120
121                                         ;       Byte 1
122                 mov     a,a1
123                 mov     b,b0
124                 mul     ab              ; a1 * b0
125                 add     a,c1
126                 mov     c1,a
127                 clr     a
128                 addc    a,b
129                 mov     c2,a
130                 
131
132                 mov     a,a0
133                 mov     b,b1
134                 mul     ab              ; a0 * b1
135                 add     a,c1
136                 mov     c1,a
137                 mov     a,b
138                 addc    a,c2
139                 mov     c2,a
140                 clr     a
141                 rlc     a
142                 mov     c3,a
143
144                                         ;       Byte 2
145                 mov     a,a2
146                 mov     b,b0
147                 mul     ab              ; a2 * b0
148                 add     a,c2
149                 mov     c2,a
150                 mov     a,b
151                 addc    a,c3
152                 mov     c3,a
153
154                 mov     a,a1
155                 mov     b,b1
156                 mul     ab              ; a1 * b1
157                 add     a,c2
158                 mov     c2,a
159                 mov     a,b
160                 addc    a,c3
161                 mov     c3,a
162
163                 mov     a,a0
164                 mov     b,b2
165                 mul     ab              ; a0 * b2
166                 add     a,c2
167                 mov     c2,a
168                 mov     a,b
169                 addc    a,c3
170                 mov     c3,a
171
172                                         ;       Byte 3
173                 mov     a,a3
174                 mov     b,b0
175                 mul     ab              ; a3 * b0
176                 add     a,c3
177                 mov     c3,a
178
179                 mov     a,a2
180                 mov     b,b1
181                 mul     ab              ; a2 * b1
182                 add     a,c3
183                 mov     c3,a
184
185                 mov     a,a1
186                 mov     b,b2
187                 mul     ab              ; a1 * b2
188                 add     a,c3
189                 mov     c3,a
190
191                 mov     a,a0
192                 mov     b,b3
193                 mul     ab              ; a0 * b3
194                 add     a,c3
195
196                 mov     b,c2
197                 mov     dph,c1
198                 mov     dpl,c0
199                 ret
200
201 #else // SDCC_STACK_AUTO
202
203                                         ; parameter a comes in a, b, dph, dpl
204                 mov     r2,b            ; save parameter a
205                 mov     r3,a
206
207                 #define a0 dpl
208                 #define a1 dph
209                 #define a2 r2
210                 #define a3 r3
211
212                 #define b0 r1
213
214                 mov     a,#-2-3         ;  1  return address 2 bytes, b 4 bytes
215                 add     a,sp            ;  1
216                 mov     r0,a            ;  1  r0 points to b0
217
218                                         ;       Byte 0
219                 mov     a,a0
220                 mov     b,@r0           ; b0
221                 mov     b0,b            ; we need b0 several times
222                 inc     r0              ; r0 points to b1
223                 mul     ab              ; a0 * b0
224                 mov     c0,a
225                 mov     c1,b
226
227                                         ;       Byte 1
228                 mov     a,a1
229                 mov     b,b0
230                 mul     ab              ; a1 * b0
231                 add     a,c1
232                 mov     c1,a
233                 clr     a
234                 addc    a,b
235                 mov     c2,a
236                 
237
238                 mov     a,a0
239                 mov     b,@r0           ; b1
240                 mul     ab              ; a0 * b1
241                 add     a,c1
242                 mov     c1,a
243                 mov     a,b
244                 addc    a,c2
245                 mov     c2,a
246                 clr     a
247                 rlc     a
248                 mov     c3,a
249
250                                         ;       Byte 2
251                 mov     a,a2
252                 mov     b,b0
253                 mul     ab              ; a2 * b0
254                 add     a,c2
255                 mov     c2,a
256                 mov     a,b
257                 addc    a,c3
258                 mov     c3,a
259
260                 mov     a,a1
261                 mov     b,@r0           ; b1
262                 mul     ab              ; a1 * b1
263                 add     a,c2
264                 mov     c2,a
265                 mov     a,b
266                 addc    a,c3
267                 mov     c3,a
268
269                 mov     a,a0
270                 inc     r0
271                 mov     b,@r0           ; b2
272                 mul     ab              ; a0 * b2
273                 add     a,c2
274                 mov     c2,a
275                 mov     a,b
276                 addc    a,c3
277                 mov     c3,a
278
279                                         ;       Byte 3
280                 mov     a,a3
281                 mov     b,b0
282                 mul     ab              ; a3 * b0
283                 add     a,c3
284                 mov     c3,a
285
286                 mov     a,a1
287                 mov     b,@r0           ; b2
288                 mul     ab              ; a1 * b2
289                 add     a,c3
290                 mov     c3,a
291
292                 mov     a,a2
293                 dec     r0
294                 mov     b,@r0           ; b1
295                 mul     ab              ; a2 * b1
296                 add     a,c3
297                 mov     c3,a
298
299                 mov     a,a0
300                 inc     r0
301                 inc     r0
302                 mov     b,@r0           ; b3
303                 mul     ab              ; a0 * b3
304                 add     a,c3
305
306                 mov     b,c2
307                 mov     dph,c1
308                 mov     dpl,c0
309
310                 ret
311
312 #endif // SDCC_STACK_AUTO
313
314         _endasm ;
315 }
316
317
318 #elif defined _MULLONG_ASM_LARGE
319
320 void
321 _mullong_dummy (void) _naked
322 {
323         _asm
324
325         __mullong:
326         __mululong:                     ; obsolete
327         __mulslong:                     ; obsolete
328
329                 .globl __mullong
330                 .globl __mululong       ; obsolete
331                 .globl __mulslong       ; obsolete
332
333                                         ; the result c will be stored in r4...r7
334                 #define c0 r4
335                 #define c1 r5
336                 #define c2 r6
337                 #define c3 r7
338
339         ; c0  a0 * b0
340         ; c1  a1 * b0 + a0 * b1
341         ; c2  a2 * b0 + a1 * b1 + a0 * b2
342         ; c3  a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3
343
344                 .area XSEG    (XDATA)
345
346         __mullong_PARM_2:
347         __mululong_PARM_2:                      ; obsolete
348         __mulslong_PARM_2:                      ; obsolete
349
350                 .globl __mullong_PARM_2
351                 .globl __mululong_PARM_2        ; obsolete
352                 .globl __mulslong_PARM_2        ; obsolete
353
354                 .ds     4
355
356                 .area CSEG    (CODE)
357
358                                         ; parameter a comes in a, b, dph, dpl
359                 mov     r0,dpl          ; save parameter a
360                 mov     r1,dph
361                 mov     r2,b
362                 mov     r3,a
363
364                 #define a0 r0
365                 #define a1 r1
366                 #define a2 r2
367                 #define a3 r3
368
369                                         ;       Byte 0
370                 mov     b,a0
371                 mov     dptr,#__mullong_PARM_2
372                 movx    a,@dptr         ; b0
373                 mul     ab              ; a0 * b0
374                 mov     c0,a
375                 mov     c1,b
376
377                                         ;       Byte 1
378                 mov     b,a1
379                 movx    a,@dptr         ; b0
380                 mul     ab              ; a1 * b0
381                 add     a,c1
382                 mov     c1,a
383                 clr     a
384                 addc    a,b
385                 mov     c2,a
386                 
387
388                 mov     b,a0
389                 inc     dptr            ; b1
390                 movx    a,@dptr
391                 mul     ab              ; a0 * b1
392                 add     a,c1
393                 mov     c1,a
394                 mov     a,b
395                 addc    a,c2
396                 mov     c2,a
397                 clr     a
398                 rlc     a
399                 mov     c3,a
400
401                                         ;       Byte 2
402                 mov     b,a1
403                 movx    a,@dptr         ; b1
404                 mul     ab              ; a1 * b1
405                 add     a,c2
406                 mov     c2,a
407                 mov     a,b
408                 addc    a,c3
409                 mov     c3,a
410
411                 mov     b,a0
412                 inc     dptr            ; b2
413                 movx    a,@dptr
414                 mul     ab              ; a0 * b2
415                 add     a,c2
416                 mov     c2,a
417                 mov     a,b
418                 addc    a,c3
419                 mov     c3,a
420
421                 mov     b,a2
422                 mov     dptr,#__mullong_PARM_2
423                 movx    a,@dptr         ; b0
424                 mul     ab              ; a2 * b0
425                 add     a,c2
426                 mov     c2,a
427                 mov     a,b
428                 addc    a,c3
429                 mov     c3,a
430
431                                         ;       Byte 3
432                 mov     b,a3
433                 movx    a,@dptr         ; b0
434                 mul     ab              ; a3 * b0
435                 add     a,c3
436                 mov     c3,a
437
438                 mov     b,a2
439                 inc     dptr            ; b1
440                 movx    a,@dptr
441                 mul     ab              ; a2 * b1
442                 add     a,c3
443                 mov     c3,a
444
445                 mov     b,a1
446                 inc     dptr            ; b2
447                 movx    a,@dptr
448                 mul     ab              ; a1 * b2
449                 add     a,c3
450                 mov     c3,a
451
452                 mov     b,a0
453                 inc     dptr            ; b3
454                 movx    a,@dptr
455                 mul     ab              ; a0 * b3
456                 add     a,c3
457
458                 mov     b,c2
459                 mov     dph,c1
460                 mov     dpl,c0
461                 ret
462
463         _endasm ;
464 }
465
466 #else // _MULLONG_ASM
467
468 struct some_struct {
469         int a ;
470         char b;
471         long c ;};
472 union bil {
473         struct {unsigned char b0,b1,b2,b3 ;} b;
474         struct {unsigned int lo,hi ;} i;
475         unsigned long l;
476         struct { unsigned char b0; unsigned int i12; unsigned char b3;} bi;
477 } ;
478 #if defined(SDCC_MODEL_LARGE) || defined (SDCC_ds390)
479 #define bcast(x) ((union bil xdata *)&(x))
480 #elif defined(__z80) || defined(__gbz80)
481 #define bcast(x) ((union bil *)&(x))
482 #else
483 #define bcast(x) ((union bil near *)&(x))
484 #endif
485
486 /*
487                      3   2   1   0
488        X             3   2   1   0
489        ----------------------------
490                    0.3 0.2 0.1 0.0 
491                1.3 1.2 1.1 1.0 
492            2.3 2.2 2.1 2.0 
493        3.3 3.2 3.1 3.0 
494        ----------------------------
495                   |3.3|1.3|0.2|0.0|   A
496                     |2.3|0.3|0.1|     B
497                     |3.2|1.2|1.0|     C
498                       |2.2|1.1|       D
499                       |3.1|2.0|       E
500                         |2.1|         F
501                         |3.0|         G
502                           |-------> only this side 32 x 32 -> 32
503 */
504 unsigned long
505 _mululong (unsigned long a, unsigned long b)    // in future: _mullong
506 {
507         union bil t;
508
509         t.i.hi = bcast(a)->b.b0 * bcast(b)->b.b2;       // A
510         t.i.lo = bcast(a)->b.b0 * bcast(b)->b.b0;       // A
511         _asm ;johan _endasm;
512         t.b.b3 += bcast(a)->b.b3 *
513                                   bcast(b)->b.b0;       // G
514         t.b.b3 += bcast(a)->b.b2 *
515                                   bcast(b)->b.b1;       // F
516         t.i.hi += bcast(a)->b.b2 * bcast(b)->b.b0;      // E <- b lost in .lst
517         // bcast(a)->i.hi is free !
518         t.i.hi += bcast(a)->b.b1 * bcast(b)->b.b1;      // D <- b lost in .lst
519
520         bcast(a)->bi.b3 = bcast(a)->b.b1 *
521                                           bcast(b)->b.b2;
522         bcast(a)->bi.i12 = bcast(a)->b.b1 *
523                            bcast(b)->b.b0;              // C
524
525         bcast(b)->bi.b3 = bcast(a)->b.b0 *
526                                           bcast(b)->b.b3;
527         bcast(b)->bi.i12 = bcast(a)->b.b0 *
528                            bcast(b)->b.b1;              // B
529         bcast(b)->bi.b0 = 0;                            // B
530         bcast(a)->bi.b0 = 0;                            // C
531         t.l += a;
532
533         return t.l + b;
534 }
535
536 long
537 _mulslong (long a, long b)      // obsolete
538 {
539   return _mululong (a, b);
540 }
541
542 #endif // _MULLONG_ASM