home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / kaffe-0.5p4-src.tgz / tar.out / contrib / kaffe / config / i386 / win32 / md-soft.c next >
C/C++ Source or Header  |  1996-09-28  |  8KB  |  481 lines

  1. /*
  2.  * i386/win32/md-soft.c
  3.  * Windows'95 i386 extra soft functions.
  4.  *
  5.  * Copyright (c) 1996 Systems Architecture Research Centre,
  6.  *           City University, London, UK.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * Written by Tim Wilkinson <tim@sarc.city.ac.uk>, June 1996.
  12.  * Original assembly routines by Des Barry <desb@desb.demon.co.uk>.
  13.  */
  14.  
  15. #define DBG(s)
  16.  
  17. #include "config.h"
  18. #include "gtypes.h"
  19.  
  20. #if !defined(HAVE_NATIVE_INT64)
  21.  
  22. #define    plong(s) printf("%s = 0x%08x%08x\n", #s, s.jh, s.jl);
  23. #define    pint(s) printf("%s = 0x%08x\n", #s, s);
  24.  
  25. jlong
  26. soft_moveconst(jint s1)
  27. {
  28.     jlong d;
  29.  
  30.     d.jl = s1;
  31.     if (s1 >= 0) {
  32.         d.jh = 0;
  33.     }
  34.     else {
  35.         d.jh = -1;
  36.     }
  37.  
  38. DBG(    printf("soft_moveconst\n");
  39.     plong(d);                        )
  40.  
  41.     return (d);
  42. }
  43.  
  44. jlong
  45. soft_ladd(jlong s1, jlong s2)
  46. {
  47. DBG(    printf("soft_ladd\n");
  48.     plong(s1);
  49.     plong(s2);                        )
  50.  
  51.     asm {
  52.         mov esi, DWORD PTR s2.jl
  53.         mov edi, DWORD PTR s2.jh
  54.         add  DWORD PTR s1.jl,esi
  55.         adc  DWORD PTR s1.jh,edi
  56.     }
  57.  
  58. DBG(    plong(s1);                        )
  59.  
  60.     return (s1);
  61. }
  62.  
  63. jlong
  64. soft_lsub(jlong s1, jlong s2)
  65. {
  66. DBG(    printf("soft_lsub\n");
  67.     plong(s1);
  68.     plong(s2);                        )
  69.  
  70.     asm {
  71.         mov esi,DWORD PTR s2.jl
  72.         mov edi,DWORD PTR s2.jh
  73.         sub DWORD PTR s1.jl,esi
  74.         sbb DWORD PTR s1.jh,edi
  75.     }
  76.  
  77. DBG(    plong(s1);                        )
  78.  
  79.     return (s1);
  80. }
  81.  
  82. jlong
  83. soft_lneg(jlong s1)
  84. {
  85. DBG(    printf("soft_lneg\n");
  86.     plong(s1);                        )
  87.  
  88.     asm {
  89.         neg DWORD PTR s1.jl
  90.         adc DWORD PTR s1.jh,0
  91.         neg DWORD PTR s1.jh
  92.     }
  93.  
  94. DBG(    plong(s1);                        )
  95.  
  96.     return (s1);
  97. }
  98.  
  99. jlong
  100. soft_lmul(jlong s1, jlong s2)
  101. {
  102. DBG(    printf("soft_lmul\n");
  103.     plong(s1);
  104.     plong(s2);                        )
  105.  
  106.     asm {
  107.         push    eax
  108.         push    ecx
  109.         push    ebx
  110.         push    edx
  111.  
  112.         mov     eax,DWORD PTR s1.jh    /* high word of s2 */
  113.         mov     ecx,DWORD PTR s2.jh    /* high word of s1 */
  114.         or      ecx,eax             /* test for both hiwords zero. */
  115.         mov     ecx,DWORD PTR s1.jl    /* low word of s1 */
  116.         jnz     l4                /* both are zero, just mult low s2 and low s1 */
  117.         mov     eax,DWORD PTR s2.jl    /* low word of s2 */
  118.         mul     ecx
  119.         jmp    l5
  120.  
  121.     l4:
  122.         mul     ecx                    /* eax has high s2, ecx has low s1 */
  123.                         /* so high s2 * low s1 */
  124.         mov     ebx,eax            /* save result */
  125.         mov     eax,DWORD PTR s2.jl    /* low word of s2 */
  126.         mul     DWORD PTR s1.jh
  127.                         /* low s2 * high s1 */
  128.         add     ebx,eax
  129.         mov     eax,DWORD PTR s2.jl    /* low s2 - ecx already low s1 */
  130.         mul     ecx
  131.         add     edx,ebx
  132.     l5:
  133.         mov    DWORD PTR s1.jl,eax
  134.         mov    DWORD PTR s1.jh,edx
  135.  
  136.         pop    edx
  137.         pop    ebx
  138.         pop    ecx
  139.         pop    eax
  140.     }
  141.  
  142. DBG(    plong(s1);                        )
  143.  
  144.     return (s1);
  145. }
  146.  
  147. static
  148. void
  149. soft_ldivrem(jlong* v1, jlong* v2)
  150. {
  151.     jlong s1 = *v1;
  152.     jlong s2 = *v2;
  153.  
  154.     asm {
  155.  
  156.     push    eax
  157.     push    ecx
  158.     push    ebx
  159.     push    edx
  160.  
  161.     mov    eax,DWORD PTR s2.jh
  162.         or      eax,eax         /* check to see if divisor < 4194304K */
  163.         jnz     short dhard     /* nope, gotta do this the hard way */
  164.  
  165.         mov     ecx,DWORD PTR s2.jl    /* load divisor */
  166.         xor     edx,edx
  167.         mov     eax,DWORD PTR s1.jh    /* load high word of dividend */
  168.         div     ecx             /* eax <- high order bits of quotient */
  169.     mov    DWORD PTR s1.jh,eax    /* save high bits of quotient */
  170.         mov     eax,DWORD PTR s1.jl    /* edx:eax <- remainder:lo word of dividend */
  171.         div     ecx             /* eax <- low order bits of quotient */
  172.     mov    DWORD PTR s1.jl,eax    /* save low bits of quotient */
  173.     mov    DWORD PTR s2.jl,edx    /* save low bits of remainder - high bits = 0 */
  174.         jmp     short d4
  175.  
  176. /*
  177.  * Here we do it the hard way.
  178.  */
  179. dhard:
  180.         mov     ebx,DWORD PTR s2.jh       /* ebx:ecx <- divisor */
  181.         mov     ecx,DWORD PTR s2.jl
  182.         mov     edx,DWORD PTR s1.jh    /* edx:eax <- dividend */
  183.         mov     eax,DWORD PTR s1.jl
  184. d5:
  185.         shr     ebx,1           /* shift divisor right one bit */
  186.         rcr     ecx,1
  187.         shr     edx,1           /* shift dividend right one bit */
  188.         rcr     eax,1
  189.         or      ebx,ebx
  190.         jnz     short d5        /* loop until divisor < 4194304K */
  191.         div     ecx             /* now divide, ignore remainder */
  192. /*
  193.  * We may be off by one, so to check, we will multiply the quotient
  194.  * by the divisor and check the result against the orignal dividend
  195.  * Note that we must also check for overflow, which can occur if the
  196.  * dividend is close to 2**64 and the quotient is off by 1.
  197.  */
  198.         mov     esi,eax         /* save quotient */
  199.         mul     DWORD PTR s2.jh /* QUOT * s2.jh */
  200.         mov     ecx,eax
  201.     mov    eax,esi
  202.         mul     DWORD PTR s2.jl /* QUOT * s2.jl */
  203.         add     edx,ecx         /* EDX:EAX = QUOT * DVSR */
  204.         jc      short d6        /* carry means Quotient is off by 1 */
  205. /*
  206.  * do long compare here between original dividend and the result of the
  207.  * multiply in edx:eax.  If original is larger or equal, we are ok, otherwise
  208.  * subtract one (1) from the quotient.
  209.  */
  210.         cmp     edx,DWORD PTR s1.jh /* compare hi words of result and original */
  211.         ja      short d6        /* if result > original, do subtract */
  212.         jb      short d7        /* if result < original, we are ok */
  213.         cmp     eax,DWORD PTR s1.jl /* hi words are equal, compare lo words */
  214.         jbe     short d7        /* if less or equal we are ok, else subtract */
  215. d6:
  216.     dec    esi
  217.     sub    eax,DWORD PTR s2.jl /* Substract divisor from result */
  218.     sbb    edx,DWORD PTR s2.jh
  219. d7:
  220.     sub    eax,DWORD PTR s1.jl
  221.     sbb    edx,DWORD PTR s1.jh
  222.     neg    edx
  223.     neg    eax
  224.     sbb    edx,0
  225.     mov    DWORD PTR s2.jl,eax    /* s2 = s1 % s2 */
  226.     mov    DWORD PTR s2.jh,edx
  227.     mov    DWORD PTR s1.jl,esi    /* s1 = s1 / s2 */
  228.     mov    DWORD PTR s1.jh,0
  229. d4:
  230.     pop    edx
  231.     pop    ebx
  232.     pop    ecx
  233.     pop    eax
  234.  
  235.     }
  236.  
  237.     *v1 = s1;
  238.     *v2 = s2;
  239. }
  240.  
  241. jlong
  242. soft_ldiv(jlong s1, jlong s2)
  243. {
  244.     int sign = 1;
  245.  
  246. DBG(    printf("soft_ldiv\n");
  247.     plong(s1);
  248.     plong(s2);                        )
  249.  
  250.     if (s1.jh < 0) {
  251.         s1 = soft_lneg(s1);
  252.         sign = -sign;
  253.     }
  254.     if (s2.jh < 0) {
  255.         s2 = soft_lneg(s2);
  256.         sign = -sign;
  257.     }
  258.  
  259.     soft_ldivrem(&s1, &s2);
  260.  
  261.     if (sign == -1) {
  262.         s1 = soft_lneg(s1);
  263.     }
  264.  
  265. DBG(    plong(s1);                        )
  266.  
  267.     return (s1);
  268. }
  269.  
  270. jlong
  271. soft_lrem(jlong s1, jlong s2)
  272. {
  273.     int sign = 1;
  274.  
  275. DBG(    printf("soft_lrem\n");
  276.     plong(s1);
  277.     plong(s2);                        )
  278.  
  279.     if (s1.jh < 0) {
  280.         s1 = soft_lneg(s1);
  281.         sign = -sign;
  282.     }
  283.     if (s2.jh < 0) {
  284.         s2 = soft_lneg(s2);
  285.         sign = -sign;
  286.     }
  287.  
  288.     soft_ldivrem(&s1, &s2);
  289.  
  290.     if (sign == -1) {
  291.         s2 = soft_lneg(s2);
  292.     }
  293.  
  294. DBG(    plong(s2);                        )
  295.  
  296.     return (s2);
  297. }
  298.  
  299. jlong
  300. soft_land(jlong s1, jlong s2)
  301. {
  302.     jlong d;
  303.  
  304.     d.jl = s1.jl & s2.jl;
  305.     d.jh = s1.jh & s2.jh;
  306.  
  307.     return (d);
  308. }
  309.  
  310. jlong
  311. soft_lor(jlong s1, jlong s2)
  312. {
  313.     jlong d;
  314.  
  315.     d.jl = s1.jl | s2.jl;
  316.     d.jh = s1.jh | s2.jh;
  317.  
  318.     return (d);
  319. }
  320.  
  321. jlong
  322. soft_lxor(jlong s1, jlong s2)
  323. {
  324.     jlong d;
  325.  
  326.     d.jl = s1.jl ^ s2.jl;
  327.     d.jh = s1.jh ^ s2.jh;
  328.  
  329.     return (d);
  330. }
  331.  
  332. jlong
  333. soft_llshl(jlong s1, jint s2)
  334. {
  335. DBG(    printf("soft_llshl\n");
  336.     plong(s1);
  337.     pint(s2);                        )
  338.  
  339.     if (s2 > 0) {
  340.         asm {
  341.             push ecx
  342.             mov ecx,s2.jl
  343.         l1:
  344.             shl DWORD PTR s1.jl,1
  345.             rcl DWORD PTR s1.jh,1
  346.             loop l1
  347.             pop ecx
  348.         }
  349.     }
  350.  
  351. DBG(    plong(s1);                        )
  352.  
  353.     return (s1);
  354. }
  355.  
  356. jlong
  357. soft_lashr(jlong s1, jint s2)
  358. {
  359. DBG(    printf("soft_lashr\n");
  360.     plong(s1);
  361.     pint(s2);                        )
  362.  
  363.     if (s2 > 0) {
  364.         asm {
  365.             push ecx
  366.             mov ecx,s2.jl
  367.         l2:
  368.             sar DWORD PTR s1.jh,1
  369.             rcr DWORD PTR s1.jl,1
  370.             loop l2
  371.             pop ecx
  372.         }
  373.     }
  374.  
  375. DBG(    plong(s1);                        )
  376.  
  377.     return (s1);
  378. }
  379.  
  380. jlong
  381. soft_llshr(jlong s1, jint s2)
  382. {
  383. DBG(    printf("soft_llshr\n");
  384.     plong(s1);
  385.     pint(s2);                        )
  386.  
  387.     if (s2 > 0) {
  388.         asm {
  389.             push ecx
  390.             mov ecx,s2.jl
  391.         l3:
  392.             shr DWORD PTR s1.jh,1
  393.             rcr DWORD PTR s1.jl,1
  394.             loop l3
  395.             pop ecx
  396.         }
  397.     }
  398.  
  399. DBG(    plong(s1);                        )
  400.  
  401.     return (s1);
  402. }
  403.  
  404. jint
  405. soft_lcmp(jlong s1, jlong s2)
  406. {
  407.     if (s1.jh < s2.jh) {
  408.         return (-1);
  409.     }
  410.     else if (s1.jh > s2.jh) {
  411.         return (1);
  412.     }
  413.     else if (s1.jl < s2.jl) {
  414.         return (-1);
  415.     }
  416.     else if (s1.jl > s2.jl) {
  417.         return (1);
  418.     }
  419.     else {
  420.         return (0);
  421.     }
  422. }
  423.  
  424. jlong
  425. soft_cvtil(jint s1)
  426. {
  427.     return (soft_moveconst(s1));
  428. }
  429.  
  430. jint
  431. soft_cvtli(jlong s1)
  432. {
  433.     return (s1.jl);
  434. }
  435.  
  436. jfloat
  437. soft_cvtlf(jlong s1)
  438. {
  439.     jfloat d;
  440.     asm {
  441.         fild QWORD PTR s1
  442.         fstp DWORD PTR d
  443.     }
  444.     return (d);
  445. }
  446.  
  447. jdouble
  448. soft_cvtld(jlong s1)
  449. {
  450.     jdouble d;
  451.     asm {
  452.         fild QWORD PTR s1
  453.         fstp QWORD PTR d
  454.     }
  455.     return (d);
  456. }
  457.  
  458. jlong
  459. soft_cvtfl(jfloat s1)
  460. {
  461.     jlong d;
  462.     asm {
  463.         fld DWORD PTR s1
  464.         fistp QWORD PTR d
  465.     }
  466.     return (d);
  467. }
  468.  
  469. jlong
  470. soft_cvtdl(jdouble s1)
  471. {
  472.     jlong d;
  473.     asm {
  474.         fld QWORD PTR s1
  475.         fistp QWORD PTR d
  476.     }
  477.     return (d);
  478. }
  479.  
  480. #endif
  481.