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