����11-6 linux/kernel/math/compare.c


  1 /*

  2  * linux/kernel/math/compare.c

  3  *

  4  * (C) 1991 Linus Torvalds

  5  */

  6

  7 /*

  8  * temporary real comparison routines

  9  */

    /*

     * �ۼ�������ʱʵ���Ƚ��ӳ���

     */

 10

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

 12

    // ��λ״̬���е�C3��C2��C1��C0����λ��

 13 #define clear_Cx() (I387.swd &= ~0x4500)

 14

    // ����ʱʵ��a���й�񻯴���������ʾ��ָ������Ч����ʽ��

    // ���磺102.345 ��ʾ�� 1.02345 X 102�� 0.0001234 ��ʾ�� 1.234 X 10-4����Ȼ����������

    // �����Ʊ�ʾ��

 15 static void normalize(temp_real * a)

 16 {

 17         int i = a->exponent & 0x7fff;           // ȡָ��ֵ����ȥ����λ����

 18         int sign = a->exponent & 0x8000;        // ȡ����λ��

 19

    // �����ʱʵ��a��64λ��Ч����β����Ϊ0����ô˵��a����0��������a��ָ���������ء�

 20         if (!(a->a || a->b)) {

 21                 a->exponent = 0;

 22                 return;

 23         }

    // ���a��β���������0ֵ����λ����ô��β�����ƣ�ͬʱ����ָ��ֵ���ݼ�����ֱ��β��

    // ��b�ֶ������ЧλMSB��1λ�ã���ʱb����Ϊ��ֵ��������������Ϸ���λ��

 24         while (i && a->b >= 0) {

 25                 i--;

 26                 __asm__("addl %0,%0 ; adcl %1,%1"

 27                         :"=r" (a->a),"=r" (a->b)

 28                         :"" (a->a),"1" (a->b));

 29         }

 30         a->exponent = i | sign;

 31 }

 32

    // ���渡��ָ��FTST��

    // ��ջ���ۼ���ST(0)��0�Ƚϣ������ݱȽϽ����������λ����ST > 0.0����C3��C2��C0

    // �ֱ�Ϊ000����ST < 0.0��������λΪ001����ST == 0.0��������λ��100�������ɱȽϣ�

    // ������λΪ111��

 33 void ftst(const temp_real * a)

 34 {

 35         temp_real b;

 36

    // ������״̬����������־λ�����ԱȽ�ֵb��ST�����й�񻯴�������b�������㲢������

    // �˷���λ���Ǹ�����������������λC0��������������λC3��

 37         clear_Cx();

 38         b = *a;

 39         normalize(&b);

 40         if (b.a || b.b || b.exponent) {

 41                 if (b.exponent < 0)

 42                         set_C0();

 43         } else

 44                 set_C3();

 45 }

 46

    // ���渡��ָ��FCOM��

    // �Ƚ���������src1��src2�������ݱȽϽ����������λ����src1 > src2����C3��C2��C0

    // �ֱ�Ϊ000����src1 < src2��������λΪ001����������ȣ�������λ��100��

 47 void fcom(const temp_real * src1, const temp_real * src2)

 48 {

 49         temp_real a;

 50

 51         a = *src1;

 52         a.exponent ^= 0x8000;                   // ����λȡ����

 53         fadd(&a,src2,&a);                       // ������ӣ����������

 54         ftst(&a);                               // ���Խ������������λ��

 55 }

 56

    // ���渡��ָ��FUCOM���޴���Ƚϣ���

    // ���ڲ�����֮һ��NaN�ıȽϡ�

 57 void fucom(const temp_real * src1, const temp_real * src2)

 58 {

 59         fcom(src1,src2);

 60 }

 61