This source file includes following definitions.
- reg_add
- reg_sub
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include "exception.h"
18 #include "reg_constant.h"
19 #include "fpu_emu.h"
20
21
22
23 void reg_add(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
24 {
25 int diff;
26
27 if ( !(a->tag | b->tag) )
28 {
29
30 if (!(a->sign ^ b->sign))
31 {
32
33 reg_u_add(a, b, dest);
34 dest->sign = a->sign;
35 return;
36 }
37
38
39 diff = a->exp - b->exp;
40 if (!diff)
41 {
42 diff = a->sigh - b->sigh;
43 if (!diff)
44 diff = a->sigl > b->sigl;
45 }
46
47 if (diff > 0)
48 {
49 reg_u_sub(a, b, dest);
50 dest->sign = a->sign;
51 return;
52 }
53 else
54 {
55 reg_u_sub(b, a, dest);
56 dest->sign = b->sign;
57 return;
58 }
59 }
60 else
61 {
62 if ( (a->tag == TW_NaN) || (b->tag == TW_NaN) )
63 { real_2op_NaN(a, b, dest); return; }
64 else if (a->tag == TW_Zero)
65 { reg_move(b, dest); return; }
66 else if (b->tag == TW_Zero)
67 { reg_move(a, dest); return; }
68 else if (a->tag == TW_Infinity)
69 {
70 if (b->tag != TW_Infinity)
71 { reg_move(a, dest); return; }
72
73 if (a->sign == b->sign)
74 { reg_move(a, dest); return; }
75 reg_move(&CONST_QNaN, dest);
76 return;
77 }
78 else if (b->tag == TW_Infinity)
79 { reg_move(b, dest); return; }
80 }
81 #ifdef PARANOID
82 EXCEPTION(EX_INTERNAL|0x101);
83 #endif
84 }
85
86
87
88 void reg_sub(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
89 {
90 int diff;
91
92 if ( !(a->tag | b->tag) )
93 {
94
95 diff = a->exp - b->exp;
96 if (!diff)
97 {
98 diff = a->sigh - b->sigh;
99 if (!diff)
100 diff = a->sigl > b->sigl;
101 }
102
103 switch (a->sign*2 + b->sign)
104 {
105 case 0:
106 case 3:
107 if (diff > 0)
108 {
109 reg_u_sub(a, b, dest);
110 dest->sign = a->sign;
111 }
112 else
113 {
114 reg_u_sub(b, a, dest);
115 dest->sign = a->sign ^ SIGN_POS^SIGN_NEG;
116 }
117 return;
118 case 1:
119 reg_u_add(a, b, dest);
120 dest->sign = SIGN_POS;
121 return;
122 case 2:
123 reg_u_add(a, b, dest);
124 dest->sign = SIGN_NEG;
125 return;
126 }
127 }
128 else
129 {
130 if ( (a->tag == TW_NaN) || (b->tag == TW_NaN) )
131 { real_2op_NaN(a, b, dest); return; }
132 else if (b->tag == TW_Zero)
133 { reg_move(a, dest); return; }
134 else if (a->tag == TW_Zero)
135 {
136 reg_move(b, dest);
137 dest->sign ^= SIGN_POS^SIGN_NEG;
138 return;
139 }
140 else if (a->tag == TW_Infinity)
141 {
142 if (b->tag != TW_Infinity)
143 { reg_move(a, dest); return; }
144 if (a->sign == b->sign)
145 { reg_move(&CONST_QNaN, dest); return; }
146 reg_move(a, dest);
147 return;
148 }
149 else if (b->tag == TW_Infinity)
150 {
151 reg_move(b, dest);
152 dest->sign ^= SIGN_POS^SIGN_NEG;
153 return;
154 }
155 }
156 #ifdef PARANOID
157 EXCEPTION(EX_INTERNAL|0x110);
158 #endif
159 }
160