?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. /*-------------------------------------------------------------------------
  2.    _mullong.c - routine for multiplication of 32 bit (unsigned) long
  3.  
  4.    Copyright (C) 1999, Sandeep Dutta . sandeep.dutta@usa.net
  5.    Copyright (C) 1999, Jean Louis VERN jlvern@writeme.com
  6.  
  7.    This library is free software; you can redistribute it and/or modify it
  8.    under the terms of the GNU 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 General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with this library; see the file COPYING. If not, write to the
  19.    Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
  20.    MA 02110-1301, USA.
  21.  
  22.    As a special exception, if you link this library with other files,
  23.    some of which are compiled with SDCC, to produce an executable,
  24.    this library does not by itself cause the resulting executable to
  25.    be covered by the GNU General Public License. This exception does
  26.    not however invalidate any other reasons why the executable file
  27.    might be covered by the GNU General Public License.
  28. -------------------------------------------------------------------------*/
  29.  
  30. /* Signed and unsigned multiplication are the same - as long as the output
  31.    has the same precision as the input.
  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) && !defined(__SDCC_PARMS_IN_BANK1)
  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.  
  63.         .globl __mullong
  64.  
  65.                                 ; the result c will be stored in r4...r7
  66.         #define c0 r4
  67.         #define c1 r5
  68.         #define c2 r6
  69.         #define c3 r7
  70.  
  71.         #define a0 dpl
  72.         #define a1 dph
  73.         #define a2 r2
  74.         #define a3 r3
  75.  
  76.         ; c0  a0 * b0
  77.         ; c1  a1 * b0 + a0 * b1
  78.         ; c2  a2 * b0 + a1 * b1 + a0 * b2
  79.         ; c3  a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3
  80.  
  81. #if !defined(__SDCC_STACK_AUTO) || defined(__SDCC_PARMS_IN_BANK1)
  82. #if defined(__SDCC_PARMS_IN_BANK1)
  83.         #define b0  (b1_0)
  84.         #define b1  (b1_1)
  85.         #define b2  (b1_2)
  86.         #define b3  (b1_3)
  87. #else
  88. #if defined(__SDCC_NOOVERLAY)
  89.         .area DSEG    (DATA)
  90. #else
  91.         .area OSEG    (OVR,DATA)
  92. #endif
  93.  
  94. __mullong_PARM_2:
  95.  
  96.         .globl __mullong_PARM_2
  97.  
  98.         .ds     4
  99.  
  100.         b0 =  __mullong_PARM_2
  101.         b1 = (__mullong_PARM_2+1)
  102.         b2 = (__mullong_PARM_2+2)
  103.         b3 = (__mullong_PARM_2+3)
  104.  
  105. #endif
  106.         .area CSEG    (CODE)
  107.  
  108.                                 ; parameter a comes in a, b, dph, dpl
  109.         mov     r2,b            ; save parameter a
  110.         mov     r3,a
  111.  
  112.                                 ;       Byte 0
  113.         mov     a,a0
  114.         mov     b,b0
  115.         mul     ab              ; a0 * b0
  116.         mov     c0,a
  117.         mov     c1,b
  118.  
  119.                                 ;       Byte 1
  120.         mov     a,a1
  121.         mov     b,b0
  122.         mul     ab              ; a1 * b0
  123.         add     a,c1
  124.         mov     c1,a
  125.         clr     a
  126.         addc    a,b
  127.         mov     c2,a
  128.  
  129.         mov     a,a0
  130.         mov     b,b1
  131.         mul     ab              ; a0 * b1
  132.         add     a,c1
  133.         mov     c1,a
  134.         mov     a,b
  135.         addc    a,c2
  136.         mov     c2,a
  137.         clr     a
  138.         rlc     a
  139.         mov     c3,a
  140.  
  141.                                 ;       Byte 2
  142.         mov     a,a2
  143.         mov     b,b0
  144.         mul     ab              ; a2 * b0
  145.         add     a,c2
  146.         mov     c2,a
  147.         mov     a,b
  148.         addc    a,c3
  149.         mov     c3,a
  150.  
  151.         mov     a,a1
  152.         mov     b,b1
  153.         mul     ab              ; a1 * b1
  154.         add     a,c2
  155.         mov     c2,a
  156.         mov     a,b
  157.         addc    a,c3
  158.         mov     c3,a
  159.  
  160.         mov     a,a0
  161.         mov     b,b2
  162.         mul     ab              ; a0 * b2
  163.         add     a,c2
  164.         mov     c2,a
  165.         mov     a,b
  166.         addc    a,c3
  167.         mov     c3,a
  168.  
  169.                                 ;       Byte 3
  170.         mov     a,a3
  171.         mov     b,b0
  172.         mul     ab              ; a3 * b0
  173.         add     a,c3
  174.         mov     c3,a
  175.  
  176.         mov     a,a2
  177.         mov     b,b1
  178.         mul     ab              ; a2 * b1
  179.         add     a,c3
  180.         mov     c3,a
  181.  
  182.         mov     a,a1
  183.         mov     b,b2
  184.         mul     ab              ; a1 * b2
  185.         add     a,c3
  186.         mov     c3,a
  187.  
  188.         mov     a,a0
  189.         mov     b,b3
  190.         mul     ab              ; a0 * b3
  191.         add     a,c3
  192.  
  193.         mov     b,c2
  194.         mov     dph,c1
  195.         mov     dpl,c0
  196.         ret
  197.  
  198. #else // __SDCC_STACK_AUTO
  199.  
  200.                                 ; parameter a comes in a, b, dph, dpl
  201.         mov     r2,b            ; save parameter a
  202.         mov     r3,a
  203.  
  204.         #define a0 dpl
  205.         #define a1 dph
  206.         #define a2 r2
  207.         #define a3 r3
  208.  
  209.         #define b0 r1
  210.  
  211.         mov     a,#-2-3         ;  1  return address 2 bytes, b 4 bytes
  212.         add     a,sp            ;  1
  213.         mov     r0,a            ;  1  r0 points to b0
  214.  
  215.                                 ;       Byte 0
  216.         mov     a,a0
  217.         mov     b,@r0           ; b0
  218.         mov     b0,b            ; we need b0 several times
  219.         inc     r0              ; r0 points to b1
  220.         mul     ab              ; a0 * b0
  221.         mov     c0,a
  222.         mov     c1,b
  223.  
  224.                                 ;       Byte 1
  225.         mov     a,a1
  226.         mov     b,b0
  227.         mul     ab              ; a1 * b0
  228.         add     a,c1
  229.         mov     c1,a
  230.         clr     a
  231.         addc    a,b
  232.         mov     c2,a
  233.  
  234.         mov     a,a0
  235.         mov     b,@r0           ; b1
  236.         mul     ab              ; a0 * b1
  237.         add     a,c1
  238.         mov     c1,a
  239.         mov     a,b
  240.         addc    a,c2
  241.         mov     c2,a
  242.         clr     a
  243.         rlc     a
  244.         mov     c3,a
  245.  
  246.                                 ;       Byte 2
  247.         mov     a,a2
  248.         mov     b,b0
  249.         mul     ab              ; a2 * b0
  250.         add     a,c2
  251.         mov     c2,a
  252.         mov     a,b
  253.         addc    a,c3
  254.         mov     c3,a
  255.  
  256.         mov     a,a1
  257.         mov     b,@r0           ; b1
  258.         mul     ab              ; a1 * b1
  259.         add     a,c2
  260.         mov     c2,a
  261.         mov     a,b
  262.         addc    a,c3
  263.         mov     c3,a
  264.  
  265.         mov     a,a0
  266.         inc     r0
  267.         mov     b,@r0           ; b2
  268.         mul     ab              ; a0 * b2
  269.         add     a,c2
  270.         mov     c2,a
  271.         mov     a,b
  272.         addc    a,c3
  273.         mov     c3,a
  274.  
  275.                                 ;       Byte 3
  276.         mov     a,a3
  277.         mov     b,b0
  278.         mul     ab              ; a3 * b0
  279.         add     a,c3
  280.         mov     c3,a
  281.  
  282.         mov     a,a1
  283.         mov     b,@r0           ; b2
  284.         mul     ab              ; a1 * b2
  285.         add     a,c3
  286.         mov     c3,a
  287.  
  288.         mov     a,a2
  289.         dec     r0
  290.         mov     b,@r0           ; b1
  291.         mul     ab              ; a2 * b1
  292.         add     a,c3
  293.         mov     c3,a
  294.  
  295.         mov     a,a0
  296.         inc     r0
  297.         inc     r0
  298.         mov     b,@r0           ; b3
  299.         mul     ab              ; a0 * b3
  300.         add     a,c3
  301.  
  302.         mov     b,c2
  303.         mov     dph,c1
  304.         mov     dpl,c0
  305.  
  306.         ret
  307.  
  308. #endif // __SDCC_STACK_AUTO
  309.  
  310.         __endasm;
  311. }
  312.  
  313. #elif defined(_MULLONG_ASM_LARGE)
  314.  
  315. void
  316. _mullong_dummy (void) __naked
  317. {
  318.         __asm
  319.  
  320. __mullong:
  321.  
  322.         .globl __mullong
  323.  
  324.                                 ; the result c will be stored in r4...r7
  325.         #define c0 r4
  326.         #define c1 r5
  327.         #define c2 r6
  328.         #define c3 r7
  329.  
  330.         ; c0  a0 * b0
  331.         ; c1  a1 * b0 + a0 * b1
  332.         ; c2  a2 * b0 + a1 * b1 + a0 * b2
  333.         ; c3  a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3
  334.  
  335. #if !defined(__SDCC_PARMS_IN_BANK1)
  336.         .area XSEG    (XDATA)
  337.  
  338. __mullong_PARM_2:
  339.  
  340.         .globl __mullong_PARM_2
  341.  
  342.         .ds     4
  343. #endif
  344.         .area CSEG    (CODE)
  345.  
  346.                                 ; parameter a comes in a, b, dph, dpl
  347.         mov     r0,dpl          ; save parameter a
  348.         mov     r1,dph
  349.         mov     r2,b
  350.         mov     r3,a
  351.  
  352.         #define a0 r0
  353.         #define a1 r1
  354.         #define a2 r2
  355.         #define a3 r3
  356.  
  357.                                 ;       Byte 0
  358.         mov     b,a0
  359. #if defined(__SDCC_PARMS_IN_BANK1)
  360.         mov     a,b1_0          ; b0
  361. #else
  362.         mov     dptr,#__mullong_PARM_2
  363.         movx    a,@dptr         ; b0
  364. #endif
  365.         mul     ab              ; a0 * b0
  366.         mov     c0,a
  367.         mov     c1,b
  368.  
  369.                                 ;       Byte 1
  370.         mov     b,a1
  371. #if defined(__SDCC_PARMS_IN_BANK1)
  372.         mov     a,b1_0          ; b0
  373. #else
  374.         movx    a,@dptr         ; b0
  375. #endif
  376.         mul     ab              ; a1 * b0
  377.         add     a,c1
  378.         mov     c1,a
  379.         clr     a
  380.         addc    a,b
  381.         mov     c2,a
  382.  
  383.         mov     b,a0
  384. #if defined(__SDCC_PARMS_IN_BANK1)
  385.         mov     a,b1_1          ; b1
  386. #else
  387.         inc     dptr            ; b1
  388.         movx    a,@dptr
  389. #endif
  390.         mul     ab              ; a0 * b1
  391.         add     a,c1
  392.         mov     c1,a
  393.         mov     a,b
  394.         addc    a,c2
  395.         mov     c2,a
  396.         clr     a
  397.         rlc     a
  398.         mov     c3,a
  399.  
  400.                                 ;       Byte 2
  401.         mov     b,a1
  402. #if defined(__SDCC_PARMS_IN_BANK1)
  403.         mov     a,b1_1          ; b1
  404. #else
  405.         movx    a,@dptr         ; b1
  406. #endif
  407.         mul     ab              ; a1 * b1
  408.         add     a,c2
  409.         mov     c2,a
  410.         mov     a,b
  411.         addc    a,c3
  412.         mov     c3,a
  413.  
  414.         mov     b,a0
  415. #if defined(__SDCC_PARMS_IN_BANK1)
  416.         mov     a,b1_2          ; b2
  417. #else
  418.         inc     dptr            ; b2
  419.         movx    a,@dptr
  420. #endif
  421.         mul     ab              ; a0 * b2
  422.         add     a,c2
  423.         mov     c2,a
  424.         mov     a,b
  425.         addc    a,c3
  426.         mov     c3,a
  427.  
  428.         mov     b,a2
  429. #if defined(__SDCC_PARMS_IN_BANK1)
  430.         mov     a,b1_0          ; b0
  431. #else
  432.         mov     dptr,#__mullong_PARM_2
  433.         movx    a,@dptr         ; b0
  434. #endif
  435.         mul     ab              ; a2 * b0
  436.         add     a,c2
  437.         mov     c2,a
  438.         mov     a,b
  439.         addc    a,c3
  440.         mov     c3,a
  441.  
  442.                                 ;       Byte 3
  443.         mov     b,a3
  444. #if defined(__SDCC_PARMS_IN_BANK1)
  445.         mov     a,b1_0          ; b0
  446. #else
  447.         movx    a,@dptr         ; b0
  448. #endif
  449.         mul     ab              ; a3 * b0
  450.         add     a,c3
  451.         mov     c3,a
  452.  
  453.         mov     b,a2
  454. #if defined(__SDCC_PARMS_IN_BANK1)
  455.         mov     a,b1_1          ; b1
  456. #else
  457.         inc     dptr            ; b1
  458.         movx    a,@dptr
  459. #endif
  460.         mul     ab              ; a2 * b1
  461.         add     a,c3
  462.         mov     c3,a
  463.  
  464.         mov     b,a1
  465. #if defined(__SDCC_PARMS_IN_BANK1)
  466.         mov     a,b1_2          ; b2
  467. #else
  468.         inc     dptr            ; b2
  469.         movx    a,@dptr
  470. #endif
  471.         mul     ab              ; a1 * b2
  472.         add     a,c3
  473.         mov     c3,a
  474.  
  475.         mov     b,a0
  476. #if defined(__SDCC_PARMS_IN_BANK1)
  477.         mov     a,b1_3          ; b3
  478. #else
  479.         inc     dptr            ; b3
  480.         movx    a,@dptr
  481. #endif
  482.         mul     ab              ; a0 * b3
  483.         add     a,c3
  484.  
  485.         mov     b,c2
  486.         mov     dph,c1
  487.         mov     dpl,c0
  488.         ret
  489.  
  490.         __endasm;
  491. }
  492.  
  493. #elif defined(__SDCC_USE_XSTACK) && defined(__SDCC_STACK_AUTO)
  494.  
  495. void
  496. _mullong_dummy (void) __naked
  497. {
  498.         __asm
  499.  
  500. __mullong:
  501.  
  502.         .globl __mullong
  503.  
  504.                                 ; the result c will be stored in r4...r7
  505.         #define c0 r4
  506.         #define c1 r5
  507.         #define c2 r6
  508.         #define c3 r7
  509.  
  510.         #define a0 dpl
  511.         #define a1 dph
  512.         #define a2 r2
  513.         #define a3 r3
  514.  
  515.         #define b0 r1
  516.  
  517.         ; c0  a0 * b0
  518.         ; c1  a1 * b0 + a0 * b1
  519.         ; c2  a2 * b0 + a1 * b1 + a0 * b2
  520.         ; c3  a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3
  521.  
  522.                                 ; parameter a comes in a, b, dph, dpl
  523.         mov     r2,b            ; save parameter a
  524.         mov     r3,a
  525.  
  526.         mov     a,#-4           ;  1  b 4 bytes
  527.         add     a,_spx          ;  1
  528.         mov     r0,a            ;  1  r0 points to b0
  529.  
  530.                                 ;       Byte 0
  531.         movx    a,@r0           ; b0
  532.         mov     b0,a            ; we need b0 several times
  533.         inc     r0              ; r0 points to b1
  534.         mov     b,a0
  535.         mul     ab              ; a0 * b0
  536.         mov     c0,a
  537.         mov     c1,b
  538.  
  539.                                 ;       Byte 1
  540.         mov     a,a1
  541.         mov     b,b0
  542.         mul     ab              ; a1 * b0
  543.         add     a,c1
  544.         mov     c1,a
  545.         clr     a
  546.         addc    a,b
  547.         mov     c2,a
  548.  
  549.         mov     b,a0
  550.         movx    a,@r0           ; b1
  551.         mul     ab              ; a0 * b1
  552.         add     a,c1
  553.         mov     c1,a
  554.         mov     a,b
  555.         addc    a,c2
  556.         mov     c2,a
  557.         clr     a
  558.         rlc     a
  559.         mov     c3,a
  560.  
  561.                                 ;       Byte 2
  562.         mov     a,a2
  563.         mov     b,b0
  564.         mul     ab              ; a2 * b0
  565.         add     a,c2
  566.         mov     c2,a
  567.         mov     a,b
  568.         addc    a,c3
  569.         mov     c3,a
  570.  
  571.         mov     b,a1
  572.         movx    a,@r0           ; b1
  573.         mul     ab              ; a1 * b1
  574.         add     a,c2
  575.         mov     c2,a
  576.         mov     a,b
  577.         addc    a,c3
  578.         mov     c3,a
  579.  
  580.         mov     b,a0
  581.         inc     r0
  582.         movx    a,@r0           ; b2
  583.         mul     ab              ; a0 * b2
  584.         add     a,c2
  585.         mov     c2,a
  586.         mov     a,b
  587.         addc    a,c3
  588.         mov     c3,a
  589.  
  590.                                 ;       Byte 3
  591.         mov     a,a3
  592.         mov     b,b0
  593.         mul     ab              ; a3 * b0
  594.         add     a,c3
  595.         mov     c3,a
  596.  
  597.         mov     b,a1
  598.         movx    a,@r0           ; b2
  599.         mul     ab              ; a1 * b2
  600.         add     a,c3
  601.         mov     c3,a
  602.  
  603.         mov     b,a2
  604.         dec     r0
  605.         movx    a,@r0           ; b1
  606.         mul     ab              ; a2 * b1
  607.         add     a,c3
  608.         mov     c3,a
  609.  
  610.         mov     b,a0
  611.         inc     r0
  612.         inc     r0
  613.         movx    a,@r0           ; b3
  614.         mul     ab              ; a0 * b3
  615.         add     a,c3
  616.  
  617.         mov     b,c2
  618.         mov     dph,c1
  619.         mov     dpl,c0
  620.  
  621.         ret
  622.  
  623.         __endasm;
  624. }
  625.  
  626. #else // _MULLONG_ASM
  627.  
  628. struct some_struct {
  629.         short a ;
  630.         char b;
  631.         long c ;};
  632. #if defined(__SDCC_hc08) || defined(__SDCC_s08) || defined(__SDCC_stm8)
  633. /* big endian order */
  634. union bil {
  635.         struct {unsigned char b3,b2,b1,b0 ;} b;
  636.         struct {unsigned short hi,lo ;} i;
  637.         unsigned long l;
  638.         struct { unsigned char b3; unsigned short i12; unsigned char b0;} bi;
  639. } ;
  640. #else
  641. /* little endian order */
  642. union bil {
  643.         struct {unsigned char b0,b1,b2,b3 ;} b;
  644.         struct {unsigned short lo,hi ;} i;
  645.         unsigned long l;
  646.         struct { unsigned char b0; unsigned short i12; unsigned char b3;} bi;
  647. } ;
  648. #endif
  649.  
  650. #if defined(__SDCC)
  651.  #include <sdcc-lib.h>
  652. #endif
  653.  
  654. #define bcast(x) ((union bil _AUTOMEM *)&(x))
  655.  
  656. /*
  657.                      3   2   1   0
  658.        X             3   2   1   0
  659.        ----------------------------
  660.                    0.3 0.2 0.1 0.0
  661.                1.3 1.2 1.1 1.0
  662.            2.3 2.2 2.1 2.0
  663.        3.3 3.2 3.1 3.0
  664.        ----------------------------
  665.                   |3.3|1.3|0.2|0.0|   A
  666.                     |2.3|0.3|0.1|     B
  667.                     |3.2|1.2|1.0|     C
  668.                       |2.2|1.1|       D
  669.                       |3.1|2.0|       E
  670.                         |2.1|         F
  671.                         |3.0|         G
  672.                           |-------> only this side 32 x 32 -> 32
  673. */
  674. #if defined(__SDCC_USE_XSTACK)
  675. // currently the original code without u fails with --xstack
  676. // it runs out of pointer registers
  677. long
  678. _mullong (long a, long b)
  679. {
  680.         union bil t, u;
  681.  
  682.         t.i.hi   = bcast(a)->b.b0 * bcast(b)->b.b2;          // A
  683.         t.i.lo   = bcast(a)->b.b0 * bcast(b)->b.b0;          // A
  684.         u.bi.b3  = bcast(a)->b.b0 * bcast(b)->b.b3;          // B
  685.         u.bi.i12 = bcast(a)->b.b0 * bcast(b)->b.b1;          // B
  686.         u.bi.b0  = 0;                                        // B
  687.         t.l += u.l;
  688.  
  689.         t.b.b3  += bcast(a)->b.b3 * bcast(b)->b.b0;          // G
  690.         t.b.b3  += bcast(a)->b.b2 * bcast(b)->b.b1;          // F
  691.         t.i.hi  += bcast(a)->b.b2 * bcast(b)->b.b0;          // E
  692.         t.i.hi  += bcast(a)->b.b1 * bcast(b)->b.b1;          // D
  693.  
  694.         u.bi.b3  = bcast(a)->b.b1 * bcast(b)->b.b2;          // C
  695.         u.bi.i12 = bcast(a)->b.b1 * bcast(b)->b.b0;          // C
  696.         u.bi.b0  = 0;                                        // C
  697.         t.l += u.l;
  698.  
  699.         return t.l;
  700. }
  701. #elif defined(__SDCC_z80) || defined(__SDCC_gbz80) || defined(__SDCC_r2k) || defined(__SDCC_r3k)
  702. /* 32x32->32 multiplication to be used
  703.    if 16x16->16 is faster than three 8x8->16.
  704.    2009, by M.Bodrato ( http://bodrato.it/ )
  705.  
  706.    z80 and gbz80 don't have any hardware multiplication.
  707.    r2k and r3k have 16x16 hardware multiplication.
  708.  */
  709. long
  710. _mullong (long a, long b)
  711. {
  712.   unsigned short i12;
  713.  
  714.   bcast(a)->i.hi *= bcast(b)->i.lo;
  715.   bcast(a)->i.hi += bcast(b)->i.hi * bcast(a)->i.lo;
  716.  
  717.   /* only (a->i.lo * b->i.lo) 16x16->32 to do. asm? */
  718.   bcast(a)->i.hi += bcast(a)->b.b1 * bcast(b)->b.b1;
  719.  
  720.   i12 = bcast(b)->b.b0 * bcast(a)->b.b1;
  721.   bcast(b)->bi.i12 = bcast(a)->b.b0 * bcast(b)->b.b1;
  722.  
  723.   /* add up the two partial result, store carry in b3 */
  724.   bcast(b)->b.b3 = ((bcast(b)->bi.i12 += i12) < i12);
  725.  
  726.   bcast(a)->i.lo  = bcast(a)->b.b0 * bcast(b)->b.b0;
  727.  
  728.   bcast(b)->bi.b0 = 0;
  729.  
  730.   return a + b;
  731. }
  732. #else
  733. long
  734. _mullong (long a, long b)
  735. {
  736.         union bil t;
  737.  
  738.         t.i.hi = bcast(a)->b.b0 * bcast(b)->b.b2;           // A
  739.         t.i.lo = bcast(a)->b.b0 * bcast(b)->b.b0;           // A
  740.         t.b.b3 += bcast(a)->b.b3 * bcast(b)->b.b0;          // G
  741.         t.b.b3 += bcast(a)->b.b2 * bcast(b)->b.b1;          // F
  742.         t.i.hi += bcast(a)->b.b2 * bcast(b)->b.b0;          // E <- b lost in .lst
  743.         // bcast(a)->i.hi is free !
  744.         t.i.hi += bcast(a)->b.b1 * bcast(b)->b.b1;          // D <- b lost in .lst
  745.  
  746.         bcast(a)->bi.b3 = bcast(a)->b.b1 * bcast(b)->b.b2;  // C
  747.         bcast(a)->bi.i12 = bcast(a)->b.b1 * bcast(b)->b.b0; // C
  748.  
  749.         bcast(b)->bi.b3 = bcast(a)->b.b0 * bcast(b)->b.b3;  // B
  750.         bcast(b)->bi.i12 = bcast(a)->b.b0 * bcast(b)->b.b1; // B
  751.  
  752.         bcast(b)->bi.b0 = 0;                                // B
  753.         bcast(a)->bi.b0 = 0;                                // C
  754.         t.l += a;
  755.  
  756.         return t.l + b;
  757. }
  758. #endif
  759.  
  760. #endif // _MULLONG_ASM
  761.