* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / as / asm / fadd.asm
blobd18f002c2aa96d12416109eb5739c421d54d112a
1 _fadd:
2 PUSH BP
3 MOV BP,SP
4 MOV EAX,DWORD PTR [BP+4]
5 MOV EDX,DWORD PTR [BP+8]
6 MOV EBX,DWORD PTR [BP+12]
7 MOV ECX,DWORD PTR [BP+16]
8 CALL faddfxfy
9 MOV DWORD PTR _facc,EAX
10 MOV DWORD PTR _facc+4,EDX
11 POP BP
12 RET
14 fsubfxfy:
15 XOR ECX,#$80000000 ; complement sign bit, fall into add routine
16 faddfxfy:
17 PUSH EBP
18 PUSH EDI
19 PUSH ESI
20 MOV EDI,ECX ; free CL for shifts
21 MOV ESI,EDX ; this mainly for consistent naming
22 AND ESI,#$7FFFFFFF ; discard sign so comparison is simple
23 AND EDI,#$7FFFFFFF
25 CMP ESI,EDI
26 JA XBIG
27 JB SWAP
28 CMP EAX,EBX
29 JAE XBIG
30 SWAP:
31 XCHG EDX,ECX
32 XCHG ESI,EDI
33 XCHG EAX,EBX
34 XBIG:
35 AND ESI,#$000FFFFF ; discard exponent
36 AND EDI,#$000FFFFF
37 OR ESI,#$00100000 ; normalize
38 OR EDI,#$00100000
40 SHR ECX,32-(1+11)
41 SHR EDX,32-(1+11)
42 MOV EBP,ECX ; prepare to compare signs (want high bits 0)
43 SUB CX,DX ; get difference of signs in CX
44 NEG CX ; D holds sign and exponent of both throughout
45 CMP CX,#(64-11)+2
46 JAE TO_DONE1 ; x dominates y
47 XOR BP,DX
48 AND BP,#$0800 ; see if signs are same
49 JNZ TO_SUBTRACT ; else roundoff reg EBP is 0
51 CMP CL,#32
52 JAE TO_ADD_BIGSHIFT
53 SHRD EBP,EBX,CL
54 SHRD EBX,EDI,CL
55 SHR EDI,CL
56 ADD EAX,EBX
57 ADC ESI,EDI
58 SUB EBX,EBX
60 ; result DX(1+11):SI:AX:BP:BX but needs normalization
62 NORMALIZE:
63 MOV CX,DX
64 AND CX,#$07FF
65 TEST ESI,#$00200000
66 JZ NORMALIZE2
67 BR LOVERFLOW
69 TO_DONE1:
70 JMP DONE1
72 TO_SUBTRACT:
73 BR SUBTRACT
75 TO_ADD_BIGSHIFT:
76 BR ADD_BIGSHIFT
78 TO_NORMLITTLE:
79 BR NORMLITTLE
81 ; result DX(1):CX(11):SI:AX:BP:BX
83 NORMALIZE2:
84 SHRD EDI,ESI,32-11
85 ; top 11 bits of ESI known 0 and BSR is slooow
86 BSR EDI,EDI ; index of leading 1 bit in EDI is 11..31 in DI
87 JZ TO_NORMLITTLE ; ESI is zero (flag wrong in Intel Manual)
88 SUB DI,#31
89 NEG DI
90 PUSH CX ; gr
91 MOV CX,DI ; rr
92 SHLD ESI,EAX,CL
93 SHLD EAX,EBP,CL
94 SHLD EBP,EBX,CL
95 SHL EBX,CL
96 POP CX ; rr
97 SUB CX,DI
98 JC UNDERFLOW
100 ROUND:
101 CMP EBP,#$80000000 ; test roundoff register
102 JA ROUNDUP
103 JB DONE ; no rounding
104 TEST EBX,EBX
105 JNZ ROUNDUP
106 TEST AL,#1 ; ambiguous case, round to even
107 JZ DONE ; even, no rounding
108 ROUNDUP:
109 ADD EAX,#1
110 ADC ESI,#0
111 SUB EBP,EBP
112 SUB EBX,EBX
113 TEST ESI,#$00200000
114 JNZ LOVERFLOW ; rounding may cause overflow!
116 DONE:
117 AND DX,#$0800 ; extract sign of largest and result
118 OR DX,CX ; include exponent with sign
119 DONE1:
120 SHL EDX,32-(1+11)
121 AND ESI,#$000FFFFF ; discard normalization bit
122 OR EDX,ESI
123 POP ESI
124 POP EDI
125 POP EBP
128 UNDERFLOW: ; should have error message here
129 ANSWER0:
130 SUB EDX,EDX
131 MOV EAX,EDX
132 POP ESI
133 POP EDI
134 POP EBP
137 LOVERFLOW: ; carry bit must be right-shifted back in
138 SHR ESI,1
139 RCR EAX,1
140 RCR EBP,1
141 RCR EBX,1
142 INC CX
143 CMP CX,#$0800
144 JNZ ROUND
146 OVERFLOW: ; should have error message here
147 MOV EDX,#$FFE00000 ; + infinity
148 SUB EAX,EAX
149 POP ESI
150 POP EDI
151 POP EBP
154 ADD_BIGSHIFT:
155 SUB CL,#32
156 SHRD EBP,EBX,CL
157 SHRD EBX,EDI,CL
158 SHR EDI,CL
159 ADD EAX,EDI
160 ADC ESI,#0
161 XCHG EBP,EBX
162 BR NORMALIZE
164 NORMLITTLE:
165 SHLD ESI,EAX,32-(1+11)
166 SHLD EAX,EBP,32-(1+11)
167 SHLD EBP,EBX,32-(1+11)
168 SHL EBX,20
169 SUB CL,#32-(1+11)
170 JC UNDERFLOW
171 BR NORMALIZE2
173 SUBTRACT:
174 SUB EBP,EBP ; set up roundoff register
175 CMP CL,#32
176 JAE SUBTRACT_BIGSHIFT
177 SHRD EBP,EBX,CL
178 SHRD EBX,EDI,CL
179 SHR EDI,CL
180 NEG EBP
181 SBB EAX,EBX
182 SBB ESI,EDI
183 SUB EBX,EBX
184 MOV CX,DX
185 AND CX,#$07FF
186 BR NORMALIZE2
188 SUBTRACT_BIGSHIFT:
189 SUB CL,#32
190 SHRD EBP,EBX,CL
191 SHRD EBX,EDI,CL
192 SHR EDI,CL
193 NEG EBX
194 NEG EBP
195 SBB EBX,#0
196 SBB EAX,EDI
197 SBB ESI,#0
198 XCHG EBP,EBX
199 MOV CX,DX
200 AND CX,#$07FF
201 BR NORMALIZE2
203 TO_ANSWER0:
204 BR ANSWER0
206 TO_OVERFLOW:
207 JMP TO_OVERFLOW
209 TO_UNDERFLOW:
210 BR UNDERFLOW
212 fmulfxfy:
213 PUSH EBP
214 PUSH EDI
215 PUSH ESI
216 MOV ESI,EDX ; free DX for multiplications
217 MOV EDI,ECX ; this mainly for consistent naming
218 SHR EDX,32-(1+11)
219 SHR ECX,32-(1+11)
220 MOV BP,DX
221 XOR BP,CX
222 AND BP,#$0800 ; extract sign
223 AND DX,#$07FF ; exp(x)
224 JZ TO_ANSWER0
225 AND CX,#$07FF ; exp(y)
226 JZ TO_ANSWER0
227 ADD CX,DX
228 SUB CX,#$0400
229 JB TO_UNDERFLOW
230 CMP CX,#$07FF
231 JA TO_OVERFLOW ; probably not quite right
233 AND ESI,#$000FFFFF ; discard sign and exponent
234 AND EDI,#$000FFFFF
235 OR ESI,#$00100000 ; normalize
236 OR EDI,#$00100000
238 ; exponent is in CX, sign in BP, operands in ESI:EAX and EDI:EBX, DX is free
239 ; product to go in ESI:EAX:EBP:EBX
240 ; terminology: x * y = (x32:x0) * (y32:y0) = x32y32 + x32y0 + x0y32 +x0y0
242 PUSH CX
243 PUSH BP
244 MOV ECX,EAX
245 MUL EBX ; x0y0
246 MOV EBP,EDX ; x0y0.high in EBP
247 XCHG EBX,EAX ; x0y0.low in EBX (final), y0 in EAX
248 MUL ESI ; x32y0
249 PUSH EAX ; x32y0.low on stack
250 PUSH EDX ; x32y0.high on stack
251 MOV EAX,ESI
252 MUL EDI ; x32y32
253 MOV ESI,EDX ; x32y32.high in ESI (final except carries)
254 XCHG ECX,EAX ; x32y32.low in ECX, x0 in EAX
255 MUL EDI ; x0y32
257 ADD EBP,EAX ; x0y0.high + x0y32.low
258 POP EAX ; x32y0.high
259 ADC EAX,EDX ; x32y0.high + x0y32.high
260 ADC ESI,#0
261 POP EDX ; x32y0.low
262 ADD EBP,EDX ; (x0y0.high + x0y32.low) + x32y0.low
263 ADC EAX,ECX ; (x32y0.high + x0y32.high) + x32y32.low
264 ADC ESI,#0
265 POP DX ; sign
266 POP CX ; exponent
267 ADD CX,#13 ; temp fixup
268 BR NORMALIZE2
270 _facc:
271 .word 0,0