����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