����11-8 linux/kernel/math/mul.c


  1 /*

  2  * linux/kernel/math/mul.c

  3  *

  4  * (C) 1991 Linus Torvalds

  5  */

  6

  7 /*

  8  * temporary real multiplication routine.

  9  */

    /*

     * ��ʱʵ���˷��ӳ���

     */

 10

 11 #include <linux/math_emu.h> // Э������ͷ�ļ���������ʱʵ���ṹ��387�Ĵ���������ȡ�

 12

    // ��cָ�봦��16�ֽ�ֵ����1λ����2����

 13 static void shift(int * c)

 14 {

 15         __asm__("movl (%0),%%eax ; addl %%eax,(%0)\n\t"

 16                 "movl 4(%0),%%eax ; adcl %%eax,4(%0)\n\t"

 17                 "movl 8(%0),%%eax ; adcl %%eax,8(%0)\n\t"

 18                 "movl 12(%0),%%eax ; adcl %%eax,12(%0)"

 19                 ::"r" ((long) c):"ax");

 20 }

 21

    // 2����ʱʵ����ˣ��������cָ�봦��16�ֽڣ���

 22 static void mul64(const temp_real * a, const temp_real * b, int * c)

 23 {

 24         __asm__("movl (%0),%%eax\n\t"

 25                 "mull (%1)\n\t"

 26                 "movl %%eax,(%2)\n\t"

 27                 "movl %%edx,4(%2)\n\t"

 28                 "movl 4(%0),%%eax\n\t"

 29                 "mull 4(%1)\n\t"

 30                 "movl %%eax,8(%2)\n\t"

 31                 "movl %%edx,12(%2)\n\t"

 32                 "movl (%0),%%eax\n\t"

 33                 "mull 4(%1)\n\t"

 34                 "addl %%eax,4(%2)\n\t"

 35                 "adcl %%edx,8(%2)\n\t"

 36                 "adcl $0,12(%2)\n\t"

 37                 "movl 4(%0),%%eax\n\t"

 38                 "mull (%1)\n\t"

 39                 "addl %%eax,4(%2)\n\t"

 40                 "adcl %%edx,8(%2)\n\t"

 41                 "adcl $0,12(%2)"

 42                 ::"b" ((long) a),"c" ((long) b),"D" ((long) c)

 43                 :"ax","dx");

 44 }

 45

    // ���渡��ָ��FMUL��

    // ��ʱʵ��src1 * scr2 �� result����

 46 void fmul(const temp_real * src1, const temp_real * src2, temp_real * result)

 47 {

 48         int i,sign;

 49         int tmp[4] = {0,0,0,0};

 50

    // ����ȷ��������˵ķ��š�����ֵ�������߷���λ���ֵ��Ȼ�����˺��ָ��ֵ�����ʱ

    // ָ��ֵ��Ҫ��ӡ���������ָ��ʹ��ƫִ����ʽ���棬��������ָ�����ʱƫ����Ҳ������

    // ���Σ������Ҫ����һ��ƫ����ֵ����ʱʵ����ƫ������16383����

 51         sign = (src1->exponent ^ src2->exponent) & 0x8000;

 52         i = (src1->exponent & 0x7fff) + (src2->exponent & 0x7fff) - 16383 + 1;

    // ������ָ������˸�ֵ����ʾ������˺�������硣����ֱ�ӷ��ش����ŵ���ֵ��

    // ������ָ������0x7fff����ʾ�������磬��������״̬������쳣��־λ�������ء�

 53         if (i<0) {

 54                 result->exponent = sign;

 55                 result->a = result->b = 0;

 56                 return;

 57         }

 58         if (i>0x7fff) {

 59                 set_OE();

 60                 return;

 61         }

    // �������β����˺�����Ϊ0����Խ��β�����й�񻯴����������ƽ��β��ֵ��ʹ��

    // �����ЧλΪ1��ͬʱ��Ӧ�ص���ָ��ֵ�����������β����˺�16�ֽڵĽ��β��Ϊ0��

    // ��Ҳ����ָ��ֵΪ0��������˽����������ʱʵ������result�С�

 62         mul64(src1,src2,tmp);

 63         if (tmp[0] || tmp[1] || tmp[2] || tmp[3])

 64                 while (i && tmp[3] >= 0) {

 65                         i--;

 66                         shift(tmp);

 67                 }

 68         else

 69                 i = 0;

 70         result->exponent = i | sign;

 71         result->a = tmp[2];

 72         result->b = tmp[3];

 73 }

 74