Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | | |
2 | | util.sa 3.7 7/29/91 | |
3 | | | |
4 | | This file contains routines used by other programs. | |
5 | | | |
6 | | ovf_res: used by overflow to force the correct | |
7 | | result. ovf_r_k, ovf_r_x2, ovf_r_x3 are | |
8 | | derivatives of this routine. | |
9 | | get_fline: get user's opcode word | |
10 | | g_dfmtou: returns the destination format. | |
11 | | g_opcls: returns the opclass of the float instruction. | |
12 | | g_rndpr: returns the rounding precision. | |
13 | | reg_dest: write byte, word, or long data to Dn | |
14 | | | |
15 | | | |
16 | | Copyright (C) Motorola, Inc. 1990 | |
17 | | All Rights Reserved | |
18 | | | |
e00d82d0 MW |
19 | | For details on the license for this file, please see the |
20 | | file, README, in this same directory. | |
1da177e4 LT |
21 | |
22 | |UTIL idnt 2,1 | Motorola 040 Floating Point Software Package | |
23 | ||
24 | |section 8 | |
25 | ||
26 | #include "fpsp.h" | |
27 | ||
28 | |xref mem_read | |
29 | ||
30 | .global g_dfmtou | |
31 | .global g_opcls | |
32 | .global g_rndpr | |
33 | .global get_fline | |
34 | .global reg_dest | |
35 | ||
36 | | | |
37 | | Final result table for ovf_res. Note that the negative counterparts | |
38 | | are unnecessary as ovf_res always returns the sign separately from | |
39 | | the exponent. | |
40 | | ;+inf | |
41 | EXT_PINF: .long 0x7fff0000,0x00000000,0x00000000,0x00000000 | |
42 | | ;largest +ext | |
43 | EXT_PLRG: .long 0x7ffe0000,0xffffffff,0xffffffff,0x00000000 | |
44 | | ;largest magnitude +sgl in ext | |
45 | SGL_PLRG: .long 0x407e0000,0xffffff00,0x00000000,0x00000000 | |
46 | | ;largest magnitude +dbl in ext | |
47 | DBL_PLRG: .long 0x43fe0000,0xffffffff,0xfffff800,0x00000000 | |
48 | | ;largest -ext | |
49 | ||
50 | tblovfl: | |
51 | .long EXT_RN | |
52 | .long EXT_RZ | |
53 | .long EXT_RM | |
54 | .long EXT_RP | |
55 | .long SGL_RN | |
56 | .long SGL_RZ | |
57 | .long SGL_RM | |
58 | .long SGL_RP | |
59 | .long DBL_RN | |
60 | .long DBL_RZ | |
61 | .long DBL_RM | |
62 | .long DBL_RP | |
63 | .long error | |
64 | .long error | |
65 | .long error | |
66 | .long error | |
67 | ||
68 | ||
69 | | | |
70 | | ovf_r_k --- overflow result calculation | |
71 | | | |
72 | | This entry point is used by kernel_ex. | |
73 | | | |
74 | | This forces the destination precision to be extended | |
75 | | | |
76 | | Input: operand in ETEMP | |
77 | | Output: a result is in ETEMP (internal extended format) | |
78 | | | |
79 | .global ovf_r_k | |
80 | ovf_r_k: | |
81 | lea ETEMP(%a6),%a0 |a0 points to source operand | |
82 | bclrb #sign_bit,ETEMP_EX(%a6) | |
83 | sne ETEMP_SGN(%a6) |convert to internal IEEE format | |
84 | ||
85 | | | |
86 | | ovf_r_x2 --- overflow result calculation | |
87 | | | |
88 | | This entry point used by x_ovfl. (opclass 0 and 2) | |
89 | | | |
90 | | Input a0 points to an operand in the internal extended format | |
91 | | Output a0 points to the result in the internal extended format | |
92 | | | |
93 | | This sets the round precision according to the user's FPCR unless the | |
94 | | instruction is fsgldiv or fsglmul or fsadd, fdadd, fsub, fdsub, fsmul, | |
95 | | fdmul, fsdiv, fddiv, fssqrt, fsmove, fdmove, fsabs, fdabs, fsneg, fdneg. | |
96 | | If the instruction is fsgldiv of fsglmul, the rounding precision must be | |
97 | | extended. If the instruction is not fsgldiv or fsglmul but a force- | |
98 | | precision instruction, the rounding precision is then set to the force | |
99 | | precision. | |
100 | ||
101 | .global ovf_r_x2 | |
102 | ovf_r_x2: | |
103 | btstb #E3,E_BYTE(%a6) |check for nu exception | |
104 | beql ovf_e1_exc |it is cu exception | |
105 | ovf_e3_exc: | |
106 | movew CMDREG3B(%a6),%d0 |get the command word | |
107 | andiw #0x00000060,%d0 |clear all bits except 6 and 5 | |
108 | cmpil #0x00000040,%d0 | |
109 | beql ovff_sgl |force precision is single | |
110 | cmpil #0x00000060,%d0 | |
111 | beql ovff_dbl |force precision is double | |
112 | movew CMDREG3B(%a6),%d0 |get the command word again | |
113 | andil #0x7f,%d0 |clear all except operation | |
114 | cmpil #0x33,%d0 | |
115 | beql ovf_fsgl |fsglmul or fsgldiv | |
116 | cmpil #0x30,%d0 | |
117 | beql ovf_fsgl | |
118 | bra ovf_fpcr |instruction is none of the above | |
119 | | ;use FPCR | |
120 | ovf_e1_exc: | |
121 | movew CMDREG1B(%a6),%d0 |get command word | |
122 | andil #0x00000044,%d0 |clear all bits except 6 and 2 | |
123 | cmpil #0x00000040,%d0 | |
124 | beql ovff_sgl |the instruction is force single | |
125 | cmpil #0x00000044,%d0 | |
126 | beql ovff_dbl |the instruction is force double | |
127 | movew CMDREG1B(%a6),%d0 |again get the command word | |
128 | andil #0x0000007f,%d0 |clear all except the op code | |
129 | cmpil #0x00000027,%d0 | |
130 | beql ovf_fsgl |fsglmul | |
131 | cmpil #0x00000024,%d0 | |
132 | beql ovf_fsgl |fsgldiv | |
133 | bra ovf_fpcr |none of the above, use FPCR | |
134 | | | |
135 | | | |
136 | | Inst is either fsgldiv or fsglmul. Force extended precision. | |
137 | | | |
138 | ovf_fsgl: | |
139 | clrl %d0 | |
140 | bra ovf_res | |
141 | ||
142 | ovff_sgl: | |
143 | movel #0x00000001,%d0 |set single | |
144 | bra ovf_res | |
145 | ovff_dbl: | |
146 | movel #0x00000002,%d0 |set double | |
147 | bra ovf_res | |
148 | | | |
149 | | The precision is in the fpcr. | |
150 | | | |
151 | ovf_fpcr: | |
152 | bfextu FPCR_MODE(%a6){#0:#2},%d0 |set round precision | |
153 | bra ovf_res | |
154 | ||
155 | | | |
156 | | | |
157 | | ovf_r_x3 --- overflow result calculation | |
158 | | | |
159 | | This entry point used by x_ovfl. (opclass 3 only) | |
160 | | | |
161 | | Input a0 points to an operand in the internal extended format | |
162 | | Output a0 points to the result in the internal extended format | |
163 | | | |
164 | | This sets the round precision according to the destination size. | |
165 | | | |
166 | .global ovf_r_x3 | |
167 | ovf_r_x3: | |
168 | bsr g_dfmtou |get dest fmt in d0{1:0} | |
169 | | ;for fmovout, the destination format | |
170 | | ;is the rounding precision | |
171 | ||
172 | | | |
173 | | ovf_res --- overflow result calculation | |
174 | | | |
175 | | Input: | |
176 | | a0 points to operand in internal extended format | |
177 | | Output: | |
178 | | a0 points to result in internal extended format | |
179 | | | |
180 | .global ovf_res | |
181 | ovf_res: | |
182 | lsll #2,%d0 |move round precision to d0{3:2} | |
183 | bfextu FPCR_MODE(%a6){#2:#2},%d1 |set round mode | |
184 | orl %d1,%d0 |index is fmt:mode in d0{3:0} | |
185 | leal tblovfl,%a1 |load a1 with table address | |
186 | movel %a1@(%d0:l:4),%a1 |use d0 as index to the table | |
187 | jmp (%a1) |go to the correct routine | |
188 | | | |
189 | |case DEST_FMT = EXT | |
190 | | | |
191 | EXT_RN: | |
192 | leal EXT_PINF,%a1 |answer is +/- infinity | |
193 | bsetb #inf_bit,FPSR_CC(%a6) | |
194 | bra set_sign |now go set the sign | |
195 | EXT_RZ: | |
196 | leal EXT_PLRG,%a1 |answer is +/- large number | |
197 | bra set_sign |now go set the sign | |
198 | EXT_RM: | |
199 | tstb LOCAL_SGN(%a0) |if negative overflow | |
200 | beqs e_rm_pos | |
201 | e_rm_neg: | |
202 | leal EXT_PINF,%a1 |answer is negative infinity | |
203 | orl #neginf_mask,USER_FPSR(%a6) | |
204 | bra end_ovfr | |
205 | e_rm_pos: | |
206 | leal EXT_PLRG,%a1 |answer is large positive number | |
207 | bra end_ovfr | |
208 | EXT_RP: | |
209 | tstb LOCAL_SGN(%a0) |if negative overflow | |
210 | beqs e_rp_pos | |
211 | e_rp_neg: | |
212 | leal EXT_PLRG,%a1 |answer is large negative number | |
213 | bsetb #neg_bit,FPSR_CC(%a6) | |
214 | bra end_ovfr | |
215 | e_rp_pos: | |
216 | leal EXT_PINF,%a1 |answer is positive infinity | |
217 | bsetb #inf_bit,FPSR_CC(%a6) | |
218 | bra end_ovfr | |
219 | | | |
220 | |case DEST_FMT = DBL | |
221 | | | |
222 | DBL_RN: | |
223 | leal EXT_PINF,%a1 |answer is +/- infinity | |
224 | bsetb #inf_bit,FPSR_CC(%a6) | |
225 | bra set_sign | |
226 | DBL_RZ: | |
227 | leal DBL_PLRG,%a1 |answer is +/- large number | |
228 | bra set_sign |now go set the sign | |
229 | DBL_RM: | |
230 | tstb LOCAL_SGN(%a0) |if negative overflow | |
231 | beqs d_rm_pos | |
232 | d_rm_neg: | |
233 | leal EXT_PINF,%a1 |answer is negative infinity | |
234 | orl #neginf_mask,USER_FPSR(%a6) | |
235 | bra end_ovfr |inf is same for all precisions (ext,dbl,sgl) | |
236 | d_rm_pos: | |
237 | leal DBL_PLRG,%a1 |answer is large positive number | |
238 | bra end_ovfr | |
239 | DBL_RP: | |
240 | tstb LOCAL_SGN(%a0) |if negative overflow | |
241 | beqs d_rp_pos | |
242 | d_rp_neg: | |
243 | leal DBL_PLRG,%a1 |answer is large negative number | |
244 | bsetb #neg_bit,FPSR_CC(%a6) | |
245 | bra end_ovfr | |
246 | d_rp_pos: | |
247 | leal EXT_PINF,%a1 |answer is positive infinity | |
248 | bsetb #inf_bit,FPSR_CC(%a6) | |
249 | bra end_ovfr | |
250 | | | |
251 | |case DEST_FMT = SGL | |
252 | | | |
253 | SGL_RN: | |
254 | leal EXT_PINF,%a1 |answer is +/- infinity | |
255 | bsetb #inf_bit,FPSR_CC(%a6) | |
256 | bras set_sign | |
257 | SGL_RZ: | |
258 | leal SGL_PLRG,%a1 |answer is +/- large number | |
259 | bras set_sign | |
260 | SGL_RM: | |
261 | tstb LOCAL_SGN(%a0) |if negative overflow | |
262 | beqs s_rm_pos | |
263 | s_rm_neg: | |
264 | leal EXT_PINF,%a1 |answer is negative infinity | |
265 | orl #neginf_mask,USER_FPSR(%a6) | |
266 | bras end_ovfr | |
267 | s_rm_pos: | |
268 | leal SGL_PLRG,%a1 |answer is large positive number | |
269 | bras end_ovfr | |
270 | SGL_RP: | |
271 | tstb LOCAL_SGN(%a0) |if negative overflow | |
272 | beqs s_rp_pos | |
273 | s_rp_neg: | |
274 | leal SGL_PLRG,%a1 |answer is large negative number | |
275 | bsetb #neg_bit,FPSR_CC(%a6) | |
276 | bras end_ovfr | |
277 | s_rp_pos: | |
278 | leal EXT_PINF,%a1 |answer is positive infinity | |
279 | bsetb #inf_bit,FPSR_CC(%a6) | |
280 | bras end_ovfr | |
281 | ||
282 | set_sign: | |
283 | tstb LOCAL_SGN(%a0) |if negative overflow | |
284 | beqs end_ovfr | |
285 | neg_sign: | |
286 | bsetb #neg_bit,FPSR_CC(%a6) | |
287 | ||
288 | end_ovfr: | |
289 | movew LOCAL_EX(%a1),LOCAL_EX(%a0) |do not overwrite sign | |
290 | movel LOCAL_HI(%a1),LOCAL_HI(%a0) | |
291 | movel LOCAL_LO(%a1),LOCAL_LO(%a0) | |
292 | rts | |
293 | ||
294 | ||
295 | | | |
296 | | ERROR | |
297 | | | |
298 | error: | |
299 | rts | |
300 | | | |
301 | | get_fline --- get f-line opcode of interrupted instruction | |
302 | | | |
303 | | Returns opcode in the low word of d0. | |
304 | | | |
305 | get_fline: | |
306 | movel USER_FPIAR(%a6),%a0 |opcode address | |
307 | movel #0,-(%a7) |reserve a word on the stack | |
308 | leal 2(%a7),%a1 |point to low word of temporary | |
309 | movel #2,%d0 |count | |
310 | bsrl mem_read | |
311 | movel (%a7)+,%d0 | |
312 | rts | |
313 | | | |
314 | | g_rndpr --- put rounding precision in d0{1:0} | |
315 | | | |
316 | | valid return codes are: | |
317 | | 00 - extended | |
318 | | 01 - single | |
319 | | 10 - double | |
320 | | | |
321 | | begin | |
322 | | get rounding precision (cmdreg3b{6:5}) | |
323 | | begin | |
324 | | case opclass = 011 (move out) | |
325 | | get destination format - this is the also the rounding precision | |
326 | | | |
327 | | case opclass = 0x0 | |
328 | | if E3 | |
329 | | *case RndPr(from cmdreg3b{6:5} = 11 then RND_PREC = DBL | |
330 | | *case RndPr(from cmdreg3b{6:5} = 10 then RND_PREC = SGL | |
331 | | case RndPr(from cmdreg3b{6:5} = 00 | 01 | |
332 | | use precision from FPCR{7:6} | |
333 | | case 00 then RND_PREC = EXT | |
334 | | case 01 then RND_PREC = SGL | |
335 | | case 10 then RND_PREC = DBL | |
336 | | else E1 | |
337 | | use precision in FPCR{7:6} | |
338 | | case 00 then RND_PREC = EXT | |
339 | | case 01 then RND_PREC = SGL | |
340 | | case 10 then RND_PREC = DBL | |
341 | | end | |
342 | | | |
343 | g_rndpr: | |
344 | bsr g_opcls |get opclass in d0{2:0} | |
345 | cmpw #0x0003,%d0 |check for opclass 011 | |
346 | bnes op_0x0 | |
347 | ||
348 | | | |
349 | | For move out instructions (opclass 011) the destination format | |
350 | | is the same as the rounding precision. Pass results from g_dfmtou. | |
351 | | | |
352 | bsr g_dfmtou | |
353 | rts | |
354 | op_0x0: | |
355 | btstb #E3,E_BYTE(%a6) | |
356 | beql unf_e1_exc |branch to e1 underflow | |
357 | unf_e3_exc: | |
358 | movel CMDREG3B(%a6),%d0 |rounding precision in d0{10:9} | |
359 | bfextu %d0{#9:#2},%d0 |move the rounding prec bits to d0{1:0} | |
360 | cmpil #0x2,%d0 | |
361 | beql unff_sgl |force precision is single | |
362 | cmpil #0x3,%d0 |force precision is double | |
363 | beql unff_dbl | |
364 | movew CMDREG3B(%a6),%d0 |get the command word again | |
365 | andil #0x7f,%d0 |clear all except operation | |
366 | cmpil #0x33,%d0 | |
367 | beql unf_fsgl |fsglmul or fsgldiv | |
368 | cmpil #0x30,%d0 | |
369 | beql unf_fsgl |fsgldiv or fsglmul | |
370 | bra unf_fpcr | |
371 | unf_e1_exc: | |
372 | movel CMDREG1B(%a6),%d0 |get 32 bits off the stack, 1st 16 bits | |
373 | | ;are the command word | |
374 | andil #0x00440000,%d0 |clear all bits except bits 6 and 2 | |
375 | cmpil #0x00400000,%d0 | |
376 | beql unff_sgl |force single | |
377 | cmpil #0x00440000,%d0 |force double | |
378 | beql unff_dbl | |
379 | movel CMDREG1B(%a6),%d0 |get the command word again | |
380 | andil #0x007f0000,%d0 |clear all bits except the operation | |
381 | cmpil #0x00270000,%d0 | |
382 | beql unf_fsgl |fsglmul | |
383 | cmpil #0x00240000,%d0 | |
384 | beql unf_fsgl |fsgldiv | |
385 | bra unf_fpcr | |
386 | ||
387 | | | |
388 | | Convert to return format. The values from cmdreg3b and the return | |
389 | | values are: | |
390 | | cmdreg3b return precision | |
391 | | -------- ------ --------- | |
392 | | 00,01 0 ext | |
393 | | 10 1 sgl | |
394 | | 11 2 dbl | |
395 | | Force single | |
396 | | | |
397 | unff_sgl: | |
398 | movel #1,%d0 |return 1 | |
399 | rts | |
400 | | | |
401 | | Force double | |
402 | | | |
403 | unff_dbl: | |
404 | movel #2,%d0 |return 2 | |
405 | rts | |
406 | | | |
407 | | Force extended | |
408 | | | |
409 | unf_fsgl: | |
410 | movel #0,%d0 | |
411 | rts | |
412 | | | |
413 | | Get rounding precision set in FPCR{7:6}. | |
414 | | | |
415 | unf_fpcr: | |
416 | movel USER_FPCR(%a6),%d0 |rounding precision bits in d0{7:6} | |
417 | bfextu %d0{#24:#2},%d0 |move the rounding prec bits to d0{1:0} | |
418 | rts | |
419 | | | |
420 | | g_opcls --- put opclass in d0{2:0} | |
421 | | | |
422 | g_opcls: | |
423 | btstb #E3,E_BYTE(%a6) | |
424 | beqs opc_1b |if set, go to cmdreg1b | |
425 | opc_3b: | |
426 | clrl %d0 |if E3, only opclass 0x0 is possible | |
427 | rts | |
428 | opc_1b: | |
429 | movel CMDREG1B(%a6),%d0 | |
430 | bfextu %d0{#0:#3},%d0 |shift opclass bits d0{31:29} to d0{2:0} | |
431 | rts | |
432 | | | |
433 | | g_dfmtou --- put destination format in d0{1:0} | |
434 | | | |
435 | | If E1, the format is from cmdreg1b{12:10} | |
436 | | If E3, the format is extended. | |
437 | | | |
438 | | Dest. Fmt. | |
439 | | extended 010 -> 00 | |
440 | | single 001 -> 01 | |
441 | | double 101 -> 10 | |
442 | | | |
443 | g_dfmtou: | |
444 | btstb #E3,E_BYTE(%a6) | |
445 | beqs op011 | |
446 | clrl %d0 |if E1, size is always ext | |
447 | rts | |
448 | op011: | |
449 | movel CMDREG1B(%a6),%d0 | |
450 | bfextu %d0{#3:#3},%d0 |dest fmt from cmdreg1b{12:10} | |
451 | cmpb #1,%d0 |check for single | |
452 | bnes not_sgl | |
453 | movel #1,%d0 | |
454 | rts | |
455 | not_sgl: | |
456 | cmpb #5,%d0 |check for double | |
457 | bnes not_dbl | |
458 | movel #2,%d0 | |
459 | rts | |
460 | not_dbl: | |
461 | clrl %d0 |must be extended | |
462 | rts | |
463 | ||
464 | | | |
465 | | | |
466 | | Final result table for unf_sub. Note that the negative counterparts | |
467 | | are unnecessary as unf_sub always returns the sign separately from | |
468 | | the exponent. | |
469 | | ;+zero | |
470 | EXT_PZRO: .long 0x00000000,0x00000000,0x00000000,0x00000000 | |
471 | | ;+zero | |
472 | SGL_PZRO: .long 0x3f810000,0x00000000,0x00000000,0x00000000 | |
473 | | ;+zero | |
474 | DBL_PZRO: .long 0x3c010000,0x00000000,0x00000000,0x00000000 | |
475 | | ;smallest +ext denorm | |
476 | EXT_PSML: .long 0x00000000,0x00000000,0x00000001,0x00000000 | |
477 | | ;smallest +sgl denorm | |
478 | SGL_PSML: .long 0x3f810000,0x00000100,0x00000000,0x00000000 | |
479 | | ;smallest +dbl denorm | |
480 | DBL_PSML: .long 0x3c010000,0x00000000,0x00000800,0x00000000 | |
481 | | | |
482 | | UNF_SUB --- underflow result calculation | |
483 | | | |
484 | | Input: | |
485 | | d0 contains round precision | |
486 | | a0 points to input operand in the internal extended format | |
487 | | | |
488 | | Output: | |
489 | | a0 points to correct internal extended precision result. | |
490 | | | |
491 | ||
492 | tblunf: | |
493 | .long uEXT_RN | |
494 | .long uEXT_RZ | |
495 | .long uEXT_RM | |
496 | .long uEXT_RP | |
497 | .long uSGL_RN | |
498 | .long uSGL_RZ | |
499 | .long uSGL_RM | |
500 | .long uSGL_RP | |
501 | .long uDBL_RN | |
502 | .long uDBL_RZ | |
503 | .long uDBL_RM | |
504 | .long uDBL_RP | |
505 | .long uDBL_RN | |
506 | .long uDBL_RZ | |
507 | .long uDBL_RM | |
508 | .long uDBL_RP | |
509 | ||
510 | .global unf_sub | |
511 | unf_sub: | |
512 | lsll #2,%d0 |move round precision to d0{3:2} | |
513 | bfextu FPCR_MODE(%a6){#2:#2},%d1 |set round mode | |
514 | orl %d1,%d0 |index is fmt:mode in d0{3:0} | |
515 | leal tblunf,%a1 |load a1 with table address | |
516 | movel %a1@(%d0:l:4),%a1 |use d0 as index to the table | |
517 | jmp (%a1) |go to the correct routine | |
518 | | | |
519 | |case DEST_FMT = EXT | |
520 | | | |
521 | uEXT_RN: | |
522 | leal EXT_PZRO,%a1 |answer is +/- zero | |
523 | bsetb #z_bit,FPSR_CC(%a6) | |
524 | bra uset_sign |now go set the sign | |
525 | uEXT_RZ: | |
526 | leal EXT_PZRO,%a1 |answer is +/- zero | |
527 | bsetb #z_bit,FPSR_CC(%a6) | |
528 | bra uset_sign |now go set the sign | |
529 | uEXT_RM: | |
530 | tstb LOCAL_SGN(%a0) |if negative underflow | |
531 | beqs ue_rm_pos | |
532 | ue_rm_neg: | |
533 | leal EXT_PSML,%a1 |answer is negative smallest denorm | |
534 | bsetb #neg_bit,FPSR_CC(%a6) | |
535 | bra end_unfr | |
536 | ue_rm_pos: | |
537 | leal EXT_PZRO,%a1 |answer is positive zero | |
538 | bsetb #z_bit,FPSR_CC(%a6) | |
539 | bra end_unfr | |
540 | uEXT_RP: | |
541 | tstb LOCAL_SGN(%a0) |if negative underflow | |
542 | beqs ue_rp_pos | |
543 | ue_rp_neg: | |
544 | leal EXT_PZRO,%a1 |answer is negative zero | |
545 | oril #negz_mask,USER_FPSR(%a6) | |
546 | bra end_unfr | |
547 | ue_rp_pos: | |
548 | leal EXT_PSML,%a1 |answer is positive smallest denorm | |
549 | bra end_unfr | |
550 | | | |
551 | |case DEST_FMT = DBL | |
552 | | | |
553 | uDBL_RN: | |
554 | leal DBL_PZRO,%a1 |answer is +/- zero | |
555 | bsetb #z_bit,FPSR_CC(%a6) | |
556 | bra uset_sign | |
557 | uDBL_RZ: | |
558 | leal DBL_PZRO,%a1 |answer is +/- zero | |
559 | bsetb #z_bit,FPSR_CC(%a6) | |
560 | bra uset_sign |now go set the sign | |
561 | uDBL_RM: | |
562 | tstb LOCAL_SGN(%a0) |if negative overflow | |
563 | beqs ud_rm_pos | |
564 | ud_rm_neg: | |
565 | leal DBL_PSML,%a1 |answer is smallest denormalized negative | |
566 | bsetb #neg_bit,FPSR_CC(%a6) | |
567 | bra end_unfr | |
568 | ud_rm_pos: | |
569 | leal DBL_PZRO,%a1 |answer is positive zero | |
570 | bsetb #z_bit,FPSR_CC(%a6) | |
571 | bra end_unfr | |
572 | uDBL_RP: | |
573 | tstb LOCAL_SGN(%a0) |if negative overflow | |
574 | beqs ud_rp_pos | |
575 | ud_rp_neg: | |
576 | leal DBL_PZRO,%a1 |answer is negative zero | |
577 | oril #negz_mask,USER_FPSR(%a6) | |
578 | bra end_unfr | |
579 | ud_rp_pos: | |
580 | leal DBL_PSML,%a1 |answer is smallest denormalized negative | |
581 | bra end_unfr | |
582 | | | |
583 | |case DEST_FMT = SGL | |
584 | | | |
585 | uSGL_RN: | |
586 | leal SGL_PZRO,%a1 |answer is +/- zero | |
587 | bsetb #z_bit,FPSR_CC(%a6) | |
588 | bras uset_sign | |
589 | uSGL_RZ: | |
590 | leal SGL_PZRO,%a1 |answer is +/- zero | |
591 | bsetb #z_bit,FPSR_CC(%a6) | |
592 | bras uset_sign | |
593 | uSGL_RM: | |
594 | tstb LOCAL_SGN(%a0) |if negative overflow | |
595 | beqs us_rm_pos | |
596 | us_rm_neg: | |
597 | leal SGL_PSML,%a1 |answer is smallest denormalized negative | |
598 | bsetb #neg_bit,FPSR_CC(%a6) | |
599 | bras end_unfr | |
600 | us_rm_pos: | |
601 | leal SGL_PZRO,%a1 |answer is positive zero | |
602 | bsetb #z_bit,FPSR_CC(%a6) | |
603 | bras end_unfr | |
604 | uSGL_RP: | |
605 | tstb LOCAL_SGN(%a0) |if negative overflow | |
606 | beqs us_rp_pos | |
607 | us_rp_neg: | |
608 | leal SGL_PZRO,%a1 |answer is negative zero | |
609 | oril #negz_mask,USER_FPSR(%a6) | |
610 | bras end_unfr | |
611 | us_rp_pos: | |
612 | leal SGL_PSML,%a1 |answer is smallest denormalized positive | |
613 | bras end_unfr | |
614 | ||
615 | uset_sign: | |
616 | tstb LOCAL_SGN(%a0) |if negative overflow | |
617 | beqs end_unfr | |
618 | uneg_sign: | |
619 | bsetb #neg_bit,FPSR_CC(%a6) | |
620 | ||
621 | end_unfr: | |
622 | movew LOCAL_EX(%a1),LOCAL_EX(%a0) |be careful not to overwrite sign | |
623 | movel LOCAL_HI(%a1),LOCAL_HI(%a0) | |
624 | movel LOCAL_LO(%a1),LOCAL_LO(%a0) | |
625 | rts | |
626 | | | |
627 | | reg_dest --- write byte, word, or long data to Dn | |
628 | | | |
629 | | | |
630 | | Input: | |
631 | | L_SCR1: Data | |
632 | | d1: data size and dest register number formatted as: | |
633 | | | |
634 | | 32 5 4 3 2 1 0 | |
635 | | ----------------------------------------------- | |
636 | | | 0 | Size | Dest Reg # | | |
637 | | ----------------------------------------------- | |
638 | | | |
639 | | Size is: | |
640 | | 0 - Byte | |
641 | | 1 - Word | |
642 | | 2 - Long/Single | |
643 | | | |
644 | pregdst: | |
645 | .long byte_d0 | |
646 | .long byte_d1 | |
647 | .long byte_d2 | |
648 | .long byte_d3 | |
649 | .long byte_d4 | |
650 | .long byte_d5 | |
651 | .long byte_d6 | |
652 | .long byte_d7 | |
653 | .long word_d0 | |
654 | .long word_d1 | |
655 | .long word_d2 | |
656 | .long word_d3 | |
657 | .long word_d4 | |
658 | .long word_d5 | |
659 | .long word_d6 | |
660 | .long word_d7 | |
661 | .long long_d0 | |
662 | .long long_d1 | |
663 | .long long_d2 | |
664 | .long long_d3 | |
665 | .long long_d4 | |
666 | .long long_d5 | |
667 | .long long_d6 | |
668 | .long long_d7 | |
669 | ||
670 | reg_dest: | |
671 | leal pregdst,%a0 | |
672 | movel %a0@(%d1:l:4),%a0 | |
673 | jmp (%a0) | |
674 | ||
675 | byte_d0: | |
676 | moveb L_SCR1(%a6),USER_D0+3(%a6) | |
677 | rts | |
678 | byte_d1: | |
679 | moveb L_SCR1(%a6),USER_D1+3(%a6) | |
680 | rts | |
681 | byte_d2: | |
682 | moveb L_SCR1(%a6),%d2 | |
683 | rts | |
684 | byte_d3: | |
685 | moveb L_SCR1(%a6),%d3 | |
686 | rts | |
687 | byte_d4: | |
688 | moveb L_SCR1(%a6),%d4 | |
689 | rts | |
690 | byte_d5: | |
691 | moveb L_SCR1(%a6),%d5 | |
692 | rts | |
693 | byte_d6: | |
694 | moveb L_SCR1(%a6),%d6 | |
695 | rts | |
696 | byte_d7: | |
697 | moveb L_SCR1(%a6),%d7 | |
698 | rts | |
699 | word_d0: | |
700 | movew L_SCR1(%a6),USER_D0+2(%a6) | |
701 | rts | |
702 | word_d1: | |
703 | movew L_SCR1(%a6),USER_D1+2(%a6) | |
704 | rts | |
705 | word_d2: | |
706 | movew L_SCR1(%a6),%d2 | |
707 | rts | |
708 | word_d3: | |
709 | movew L_SCR1(%a6),%d3 | |
710 | rts | |
711 | word_d4: | |
712 | movew L_SCR1(%a6),%d4 | |
713 | rts | |
714 | word_d5: | |
715 | movew L_SCR1(%a6),%d5 | |
716 | rts | |
717 | word_d6: | |
718 | movew L_SCR1(%a6),%d6 | |
719 | rts | |
720 | word_d7: | |
721 | movew L_SCR1(%a6),%d7 | |
722 | rts | |
723 | long_d0: | |
724 | movel L_SCR1(%a6),USER_D0(%a6) | |
725 | rts | |
726 | long_d1: | |
727 | movel L_SCR1(%a6),USER_D1(%a6) | |
728 | rts | |
729 | long_d2: | |
730 | movel L_SCR1(%a6),%d2 | |
731 | rts | |
732 | long_d3: | |
733 | movel L_SCR1(%a6),%d3 | |
734 | rts | |
735 | long_d4: | |
736 | movel L_SCR1(%a6),%d4 | |
737 | rts | |
738 | long_d5: | |
739 | movel L_SCR1(%a6),%d5 | |
740 | rts | |
741 | long_d6: | |
742 | movel L_SCR1(%a6),%d6 | |
743 | rts | |
744 | long_d7: | |
745 | movel L_SCR1(%a6),%d7 | |
746 | rts | |
747 | |end |