Print this page
de-linting of .s files
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/sparc/v9/ml/float.s
+++ new/usr/src/uts/sparc/v9/ml/float.s
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
25 25
26 26 #ident "%Z%%M% %I% %E% SMI"
27 27
28 28 #include <sys/asm_linkage.h>
29 29 #include <sys/trap.h>
30 30 #include <sys/machpcb.h>
31 31 #include <sys/machtrap.h>
32 32 #include <sys/machsig.h>
33 33 #include <sys/machthread.h>
34 34
35 -#if !defined(lint) && !defined(__lint)
36 35 #include "assym.h"
37 -#endif /* lint */
38 36
39 37 /*
40 38 * Floating point trap handling.
41 39 *
42 40 * The FPU is always in a V9 current configuration.
43 41 *
44 42 * When a user process is first started via exec,
45 43 * floating point operations will be disabled by default.
46 44 * Upon execution of the first floating point instruction,
47 45 * a fp_disabled trap will be generated; then a word in
48 46 * the uarea is written signifying use of the floating point
49 47 * registers so that subsequent context switches will save
50 48 * and restore the floating point them. The trapped instruction
51 49 * will be restarted and processing will continue as normal.
52 50 *
53 51 * When a operation occurs that the hardware cannot properly
54 52 * handle, an unfinshed fp_op exception will be generated.
55 53 * Software routines in the kernel will be executed to
56 54 * simulate proper handling of such conditions.
57 55 *
58 56 * Exception handling will emulate all instructions
59 57 * in the floating point address queue. Note that there
60 58 * is no %fq in sun4u, because it has precise FP traps.
61 59 *
62 60 * Floating point queues are now machine dependent, and std %fq
63 61 * is an illegal V9 instruction. The fp_exception code has been
64 62 * moved to sun4u/ml/machfloat.s.
65 63 *
66 64 * NOTE: This code DOES NOT SUPPORT KERNEL (DEVICE DRIVER)
67 65 * USE OF THE FPU
68 66 *
69 67 * Instructions for running without the hardware fpu:
70 68 * 1. Setting fpu_exists to 0 now only works on a DEBUG kernel.
71 69 * 2. adb -w unix and set fpu_exists, use_hw_bcopy, use_hw_copyio, and
72 70 * use_hw_bzero to 0 and rename libc_psr.so.1 in
73 71 * /usr/platform/sun4u/lib so that it will not get used by
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
74 72 * the libc bcopy routines. Then reboot the system and you
75 73 * should see the bootup message "FPU not in use".
76 74 * 3. To run kaos, you must comment out the code which sets the
77 75 * version number of the fsr to 7, in fldst: stfsr/stxfsr
78 76 * (unless you are running against a comparison system that
79 77 * has the same fsr version number).
80 78 * 4. The stqf{a}/ldqf{a} instructions cause kaos errors, for reasons
81 79 * that appear to be a kaos bug, so don't use them!
82 80 */
83 81
84 -#if defined(lint) || defined(__lint)
85 -
86 -#ifdef FP_DISABLED
87 -int fpu_exists = 0;
88 -#else
89 -int fpu_exists = 1;
90 -#endif
91 -
92 -#else /* lint */
93 -
94 82 .section ".data"
95 83 .align 8
96 84 fsrholder:
97 85 .word 0 ! dummy place to write fsr
98 86 .word 0
99 87
100 88 DGDEF(fpu_exists) ! always exists for V9
101 89 #ifdef FP_DISABLED
102 90 .word 0
103 91 #else
104 92 .word 1 ! sundiag (gack) uses this variable
105 93 #endif
106 94
107 95 DGDEF(fpu_version)
108 96 .word -1
109 97
110 -#endif /* lint */
111 -
112 98 /*
113 99 * FPU probe - read the %fsr and get fpu_version.
114 100 * Called from autoconf. If a %fq is created for
115 101 * future cpu versions, a fq_exists variable
116 102 * could be created by this function.
117 103 */
118 104
119 -#if defined(lint) || defined(__lint)
120 -
121 -/*ARGSUSED*/
122 -void
123 -fpu_probe(void)
124 -{}
125 -
126 -#else /* lint */
127 -
128 105 ENTRY_NP(fpu_probe)
129 106 wr %g0, FPRS_FEF, %fprs ! enable fpu in fprs
130 107 rdpr %pstate, %g2 ! read pstate, save value in %g2
131 108 or %g2, PSTATE_PEF, %g1 ! new pstate with fpu enabled
132 109 wrpr %g1, %g0, %pstate ! write pstate
133 110
134 111 sethi %hi(fsrholder), %g2
135 112 stx %fsr, [%g2 + %lo(fsrholder)]
136 113 ldx [%g2 + %lo(fsrholder)], %g2 ! snarf the FSR
137 114 set FSR_VER, %g1
138 115 and %g2, %g1, %g2 ! get version
139 116 srl %g2, FSR_VER_SHIFT, %g2 ! and shift it down
140 117 sethi %hi(fpu_version), %g3 ! save the FPU version
141 118 st %g2, [%g3 + %lo(fpu_version)]
142 119
143 120 ba fp_kstat_init ! initialize the fpu_kstat
144 121 wr %g0, %g0, %fprs ! disable fpu and clear fprs
145 122 SET_SIZE(fpu_probe)
146 123
147 -#endif /* lint */
148 -
149 124 /*
150 125 * fp_clearregs(fp)
151 126 * struct v9_fpu *fp;
152 127 *
153 128 * Initialization for the hardware fpu.
154 129 * Clear the fsr and initialize registers to NaN (-1)
155 130 * The caller (fp_disabled) is supposed to update the fprs
156 131 * so when the return to userland is made, the fpu is enabled.
157 132 */
158 133
159 -#if defined(lint) || defined(__lint)
160 -
161 -/*ARGSUSED*/
162 -void
163 -fp_clearregs(kfpu_t *fp)
164 -{}
165 -
166 -#else /* lint */
167 -
168 134 ENTRY_NP(fp_clearregs)
169 135 ldx [%o0 + FPU_FSR], %fsr ! load fsr
170 136
171 137 mov -1, %g2 ! -1 is NaN
172 138 stx %g2, [%o0] ! initialize %f0
173 139 ldd [%o0], %d0
174 140 ldd [%o0], %d2
175 141 ldd [%o0], %d4
176 142 ldd [%o0], %d6
177 143 ldd [%o0], %d8
178 144 ldd [%o0], %d10
179 145 ldd [%o0], %d12
180 146 ldd [%o0], %d14
181 147 ldd [%o0], %d16
182 148 ldd [%o0], %d18
183 149 ldd [%o0], %d20
184 150 ldd [%o0], %d22
185 151 ldd [%o0], %d24
186 152 ldd [%o0], %d26
187 153 ldd [%o0], %d28
188 154 ldd [%o0], %d30
189 155 ldd [%o0], %d32
190 156 ldd [%o0], %d34
191 157 ldd [%o0], %d36
192 158 ldd [%o0], %d38
193 159 ldd [%o0], %d40
194 160 ldd [%o0], %d42
195 161 ldd [%o0], %d44
196 162 ldd [%o0], %d46
197 163 ldd [%o0], %d48
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
198 164 ldd [%o0], %d50
199 165 ldd [%o0], %d52
200 166 ldd [%o0], %d54
201 167 ldd [%o0], %d56
202 168 ldd [%o0], %d58
203 169 ldd [%o0], %d60
204 170 retl
205 171 ldd [%o0], %d62
206 172 SET_SIZE(fp_clearregs)
207 173
208 -#endif /* lint */
209 -
210 174 /*
211 175 * void _fp_read_pfreg(pf, n)
212 176 * uint32_t *pf; Old freg value.
213 177 * unsigned n; Want to read register n
214 178 *
215 179 * {
216 180 * *pf = %f[n];
217 181 * }
218 182 *
219 183 * void
220 184 * _fp_write_pfreg(pf, n)
221 185 * uint32_t *pf; New freg value.
222 186 * unsigned n; Want to write register n.
223 187 *
224 188 * {
225 189 * %f[n] = *pf;
226 190 * }
227 191 */
228 192
229 -#if defined(lint) || defined(__lint)
230 -
231 -/*ARGSUSED*/
232 -void
233 -_fp_read_pfreg(uint32_t *pf, u_int n)
234 -{}
235 -
236 -/*ARGSUSED*/
237 -void
238 -_fp_write_pfreg(uint32_t *pf, u_int n)
239 -{}
240 -
241 -#else /* lint */
242 -
243 193 ENTRY_NP(_fp_read_pfreg)
244 194 sll %o1, 3, %o1 ! Table entries are 8 bytes each.
245 195 set .stable, %g1 ! g1 gets base of table.
246 196 jmp %g1 + %o1 ! Jump into table
247 197 nop ! Can't follow CTI by CTI.
248 198
249 199 ENTRY_NP(_fp_write_pfreg)
250 200 sll %o1, 3, %o1 ! Table entries are 8 bytes each.
251 201 set .ltable, %g1 ! g1 gets base of table.
252 202 jmp %g1 + %o1 ! Jump into table
253 203 nop ! Can't follow CTI by CTI.
254 204
255 205 #define STOREFP(n) jmp %o7+8 ; st %f/**/n, [%o0]
256 206
257 207 .stable:
258 208 STOREFP(0)
259 209 STOREFP(1)
260 210 STOREFP(2)
261 211 STOREFP(3)
262 212 STOREFP(4)
263 213 STOREFP(5)
264 214 STOREFP(6)
265 215 STOREFP(7)
266 216 STOREFP(8)
267 217 STOREFP(9)
268 218 STOREFP(10)
269 219 STOREFP(11)
270 220 STOREFP(12)
271 221 STOREFP(13)
272 222 STOREFP(14)
273 223 STOREFP(15)
274 224 STOREFP(16)
275 225 STOREFP(17)
276 226 STOREFP(18)
277 227 STOREFP(19)
278 228 STOREFP(20)
279 229 STOREFP(21)
280 230 STOREFP(22)
281 231 STOREFP(23)
282 232 STOREFP(24)
283 233 STOREFP(25)
284 234 STOREFP(26)
285 235 STOREFP(27)
286 236 STOREFP(28)
287 237 STOREFP(29)
288 238 STOREFP(30)
289 239 STOREFP(31)
290 240
291 241 #define LOADFP(n) jmp %o7+8 ; ld [%o0],%f/**/n
292 242
293 243 .ltable:
294 244 LOADFP(0)
295 245 LOADFP(1)
296 246 LOADFP(2)
297 247 LOADFP(3)
298 248 LOADFP(4)
299 249 LOADFP(5)
300 250 LOADFP(6)
301 251 LOADFP(7)
302 252 LOADFP(8)
303 253 LOADFP(9)
304 254 LOADFP(10)
305 255 LOADFP(11)
306 256 LOADFP(12)
307 257 LOADFP(13)
308 258 LOADFP(14)
309 259 LOADFP(15)
310 260 LOADFP(16)
311 261 LOADFP(17)
312 262 LOADFP(18)
313 263 LOADFP(19)
314 264 LOADFP(20)
315 265 LOADFP(21)
316 266 LOADFP(22)
317 267 LOADFP(23)
318 268 LOADFP(24)
↓ open down ↓ |
66 lines elided |
↑ open up ↑ |
319 269 LOADFP(25)
320 270 LOADFP(26)
321 271 LOADFP(27)
322 272 LOADFP(28)
323 273 LOADFP(29)
324 274 LOADFP(30)
325 275 LOADFP(31)
326 276 SET_SIZE(_fp_read_pfreg)
327 277 SET_SIZE(_fp_write_pfreg)
328 278
329 -#endif /* lint */
330 -
331 279 /*
332 280 * void _fp_read_pdreg(
333 281 * uint64_t *pd, Old dreg value.
334 282 * u_int n) Want to read register n
335 283 *
336 284 * {
337 285 * *pd = %d[n];
338 286 * }
339 287 *
340 288 * void
341 289 * _fp_write_pdreg(
342 290 * uint64_t *pd, New dreg value.
343 291 * u_int n) Want to write register n.
344 292 *
345 293 * {
346 294 * %d[n] = *pd;
347 295 * }
348 296 */
349 297
350 -#if defined(lint) || defined(__lint)
351 -
352 -/*ARGSUSED*/
353 -void
354 -_fp_read_pdreg(uint64_t *pd, u_int n)
355 -{}
356 -
357 -/*ARGSUSED*/
358 -void
359 -_fp_write_pdreg(uint64_t *pd, u_int n)
360 -{}
361 -
362 -#else /* lint */
363 -
364 298 ENTRY_NP(_fp_read_pdreg)
365 299 sll %o1, 3, %o1 ! Table entries are 8 bytes each.
366 300 set .dstable, %g1 ! g1 gets base of table.
367 301 jmp %g1 + %o1 ! Jump into table
368 302 nop ! Can't follow CTI by CTI.
369 303
370 304 ENTRY_NP(_fp_write_pdreg)
371 305 sll %o1, 3, %o1 ! Table entries are 8 bytes each.
372 306 set .dltable, %g1 ! g1 gets base of table.
373 307 jmp %g1 + %o1 ! Jump into table
374 308 nop ! Can't follow CTI by CTI.
375 309
376 310 #define STOREDP(n) jmp %o7+8 ; std %d/**/n, [%o0]
377 311
378 312 .dstable:
379 313 STOREDP(0)
380 314 STOREDP(2)
381 315 STOREDP(4)
382 316 STOREDP(6)
383 317 STOREDP(8)
384 318 STOREDP(10)
385 319 STOREDP(12)
386 320 STOREDP(14)
387 321 STOREDP(16)
388 322 STOREDP(18)
389 323 STOREDP(20)
390 324 STOREDP(22)
391 325 STOREDP(24)
392 326 STOREDP(26)
393 327 STOREDP(28)
394 328 STOREDP(30)
395 329 STOREDP(32)
396 330 STOREDP(34)
397 331 STOREDP(36)
398 332 STOREDP(38)
399 333 STOREDP(40)
400 334 STOREDP(42)
401 335 STOREDP(44)
402 336 STOREDP(46)
403 337 STOREDP(48)
404 338 STOREDP(50)
405 339 STOREDP(52)
406 340 STOREDP(54)
407 341 STOREDP(56)
408 342 STOREDP(58)
409 343 STOREDP(60)
410 344 STOREDP(62)
411 345
412 346 #define LOADDP(n) jmp %o7+8 ; ldd [%o0],%d/**/n
413 347
414 348 .dltable:
415 349 LOADDP(0)
416 350 LOADDP(2)
417 351 LOADDP(4)
418 352 LOADDP(6)
419 353 LOADDP(8)
420 354 LOADDP(10)
421 355 LOADDP(12)
422 356 LOADDP(14)
423 357 LOADDP(16)
424 358 LOADDP(18)
425 359 LOADDP(20)
426 360 LOADDP(22)
427 361 LOADDP(24)
428 362 LOADDP(26)
429 363 LOADDP(28)
430 364 LOADDP(30)
431 365 LOADDP(32)
432 366 LOADDP(34)
433 367 LOADDP(36)
434 368 LOADDP(38)
435 369 LOADDP(40)
436 370 LOADDP(42)
437 371 LOADDP(44)
438 372 LOADDP(46)
439 373 LOADDP(48)
↓ open down ↓ |
66 lines elided |
↑ open up ↑ |
440 374 LOADDP(50)
441 375 LOADDP(52)
442 376 LOADDP(54)
443 377 LOADDP(56)
444 378 LOADDP(58)
445 379 LOADDP(60)
446 380 LOADDP(62)
447 381 SET_SIZE(_fp_read_pdreg)
448 382 SET_SIZE(_fp_write_pdreg)
449 383
450 -#endif /* lint */
451 -
452 -#if defined(lint) || defined(__lint)
453 -
454 -/*ARGSUSED*/
455 -void
456 -_fp_write_pfsr(uint64_t *fsr)
457 -{}
458 -
459 -#else /* lint */
460 -
461 384 ENTRY_NP(_fp_write_pfsr)
462 385 retl
463 386 ldx [%o0], %fsr
464 387 SET_SIZE(_fp_write_pfsr)
465 388
466 -#endif /* lint */
467 -
468 -#if defined(lint) || defined(__lint)
469 -
470 -/*ARGSUSED*/
471 -void
472 -_fp_read_pfsr(uint64_t *fsr)
473 -{}
474 -
475 -#else /* lint */
476 -
477 389 ENTRY_NP(_fp_read_pfsr)
478 390 retl
479 391 stx %fsr, [%o0]
480 392 SET_SIZE(_fp_read_pfsr)
481 393
482 -#endif /* lint */
483 -
484 -#if defined(lint) || defined(__lint)
485 -
486 -/*ARGSUSED*/
487 -void
488 -_fp_write_fprs(u_int fprs_val)
489 -{}
490 -
491 -#else /* lint */
492 -
493 394 ENTRY_NP(_fp_write_fprs)
494 395 retl
495 396 wr %o0, %g0, %fprs ! write fprs
496 397 SET_SIZE(_fp_write_fprs)
497 398
498 -#endif /* lint */
499 -
500 -#if defined(lint) || defined(__lint)
501 -
502 -unsigned
503 -_fp_read_fprs(void)
504 -{return 0;}
505 -
506 -#else /* lint */
507 -
508 399 ENTRY_NP(_fp_read_fprs)
509 400 retl
510 401 rd %fprs, %o0 ! save fprs
511 402 SET_SIZE(_fp_read_fprs)
512 403
513 -#endif /* lint */
514 -
515 -#if defined(lint) || defined(__lint)
516 -
517 -unsigned
518 -_fp_subcc_ccr(void)
519 -{return 0;}
520 -
521 -#else /* lint */
522 -
523 404 ENTRY_NP(_fp_subcc_ccr)
524 405 subcc %o0, %o1, %g0
525 406 retl
526 407 rd %ccr, %o0 ! save ccr
527 408 SET_SIZE(_fp_subcc_ccr)
528 409
529 -#endif /* lint */
530 -
531 410 /*
532 411 * Floating Point Exceptions handled according to type:
533 412 * 2) unfinished_fpop
534 413 * re-execute the faulty instruction(s) using
535 414 * software emulation (must do every instruction in FQ)
536 415 * 3) unimplemented_fpop
537 416 * an unimplemented instruction, if it is legal,
538 417 * will cause emulation of the instruction (and all
539 418 * other instuctions in the FQ)
540 419 * 4) sequence_error
541 420 * panic, this should not happen, and if it does it
542 421 * it is the result of a kernel bug
543 422 *
544 423 * This code assumes the trap preamble has set up the window environment
545 424 * for execution of kernel code.
546 425 * Note: this code could be changed to be part of the cpu-specific
547 426 * (ie, Spitfire-specific) module code before final release.
548 427 */
549 428
550 -#if defined(lint)
551 -
552 -/* ARGSUSED */
553 -void
554 -_fp_exception(struct regs *rp, uint64_t fsr)
555 -{}
556 -
557 -#else /* lint */
558 -
559 429 ENTRY_NP(_fp_exception)
560 430 mov %o7, %l0 ! saved return address
561 431 mov %o0, %l1 ! saved *rp
562 432 set FSR_FTT, %o4 ! put FSR_FTT in %o4
563 433 xor %o4, 0xffffffffffffffff, %o3 ! xor FSR_FTT to get
564 434 and %o1, %o3, %o2 ! an fsr with a zero'd ftt
565 435 ldn [THREAD_REG + T_LWP], %o3 ! get lwp
566 436 ldn [%o3 + LWP_FPU], %l3 ! get lwp_fpu
567 437 stx %o2, [%l3 + FPU_FSR] ! save floating point status
568 438 and %o1, %o4, %g2 ! get the ftt trap type
569 439 #ifdef DEBUG
570 440 brnz,a,pt %g2, fttok
571 441 nop
572 442 set .badfpfttmsg, %o0 ! panic message
573 443 call panic ! %o1 has the fsr w/ftt value
574 444 nop
575 445 fttok:
576 446 #endif /* DEBUG */
577 447 srl %g2, FSR_FTT_SHIFT, %o4 ! check ftt
578 448 cmp %o4, FTT_SEQ ! sanity check for bogus exceptions
579 449 !
580 450 ! traps are already enabled to allow other
581 451 ! interrupts while emulating floating point instructions
582 452 !
583 453 blt,a,pt %xcc, fpeok
584 454 nop
585 455 !
586 456 ! Sequence error or unknown ftt exception.
587 457 !
588 458 seq_error:
589 459 set .badfpexcpmsg, %o0 ! panic if bad ftt
590 460 call panic
591 461 sra %o4, 0, %o1 ! mov ftt to o1 for panic message
592 462
593 463 fpeok:
594 464 call fp_kstat_update ! fp_kstat_update(ftt)
595 465 mov %o4, %o0 ! ftt
596 466 !
597 467 ! Get the floating point instruction, and run the floating
598 468 ! point simulator. There is no floating point queue, so we fake one.
599 469 !
600 470 call fp_precise ! fp_precise(®s)
601 471 mov %l1, %o0 ! saved *rp
602 472
603 473 fp_ret:
604 474 rd %fprs, %g1 ! read fprs, save value in %g1
605 475 st %g1, [%l3 + FPU_FPRS] ! save fprs
606 476 jmp %l0 + 8 ! jump to saved return address
607 477 stx %fsr, [%l3 + FPU_FSR] ! save fsr
↓ open down ↓ |
39 lines elided |
↑ open up ↑ |
608 478 SET_SIZE(_fp_exception)
609 479
610 480 .badfpexcpmsg:
611 481 .asciz "unexpected floating point exception %x"
612 482
613 483 #ifdef DEBUG
614 484 .badfpfttmsg:
615 485 .asciz "No floating point ftt, fsr %llx"
616 486 #endif /* DEBUG */
617 487
618 -#endif /* lint */
619 -
620 488 /*
621 489 * Floating Point Exceptions.
622 490 * handled according to type:
623 491 * 1) IEEE_exception
624 492 * re-execute the faulty instruction(s) using
625 493 * software emulation (must do every instruction in FQ)
626 494 *
627 495 * This code assumes the trap preamble has set up the window environment
628 496 * for execution of kernel code.
629 497 */
630 498
631 -#if defined(lint)
632 -
633 -/* ARGSUSED */
634 -void
635 -_fp_ieee_exception(struct regs *rp, uint64_t fsr)
636 -{}
637 -
638 -#else /* lint */
639 -
640 499 ENTRY_NP(_fp_ieee_exception)
641 500 mov %o7, %l0 ! saved return address
642 501 mov %o0, %l1 ! saved *rp
643 502 mov %o1, %l2 ! saved fsr
644 503 set FSR_FTT, %o4 ! put FSR_FTT in %o4
645 504 xor %o4, 0xffffffffffffffff, %o3 ! ! xor FSR_FTT to get
646 505 and %o1, %o3, %o2 ! an fsr with a zero'd ftt
647 506 ldn [THREAD_REG + T_LWP], %o3 ! get lwp
648 507 ldn [%o3 + LWP_FPU], %l3 ! get lwp_fpu
649 508 stx %o2, [%l3 + FPU_FSR] ! save floating point status
650 509 stub %g0, [%l3 + FPU_QCNT] ! clear fpu_qcnt
651 510 and %o1, %o4, %g2 ! mask out trap type
652 511 #ifdef DEBUG
653 512 brnz,a,pt %g2, fttgd
654 513 nop
655 514 set .badfpfttmsg, %o0 ! panic message
656 515 call panic ! %o1 has the fsr w/ftt value
657 516 nop
658 517 fttgd:
659 518 #endif /* DEBUG */
660 519 srl %g2, FSR_FTT_SHIFT, %o4 ! check ftt
661 520 cmp %o4, FTT_SEQ ! sanity check for bogus exceptions
662 521 !
663 522 ! traps are already enabled to allow other
664 523 ! interrupts while emulating floating point instructions
665 524 !
666 525 blt,a,pt %xcc, fpegd
667 526 nop
668 527 !
669 528 ! Sequence error or unknown ftt exception.
670 529 !
671 530 seq_err:
672 531 set .badfpexcpmsg, %o0 ! panic if bad ftt
673 532 call panic
674 533 sra %o4, 0, %o1 ! mov ftt to o1 for panic message
675 534
676 535 fpegd:
677 536 call fp_kstat_update ! fp_kstat_update(ftt)
678 537 mov %o4, %o0 ! ftt
679 538 !
680 539 ! Call fpu_trap directly, don't bother to run the fp simulator.
681 540 ! The *rp is already in %o0. Clear fpu_qcnt.
682 541 !
683 542 set (T_FP_EXCEPTION_IEEE), %o2 ! trap type
684 543
685 544 set FSR_CEXC, %o3
686 545 and %l2, %o3, %g2 ! mask out cexc
687 546
688 547 andcc %g2, FSR_CEXC_NX, %g0 ! check for inexact
689 548 bnz,a,pt %xcc, fpok
690 549 or %g0, FPE_FLTRES, %o3 ! fp inexact code
691 550
692 551 andcc %g2, FSR_CEXC_DZ, %g0 ! check for divide-by-zero
693 552 bnz,a,pt %xcc, fpok
694 553 or %g0, FPE_FLTDIV, %o3 ! fp divide by zero code
695 554
696 555 andcc %g2, FSR_CEXC_UF, %g0 ! check for underflow
697 556 bnz,a,pt %xcc, fpok
698 557 or %g0, FPE_FLTUND, %o3 ! fp underflow code
699 558
700 559 andcc %g2, FSR_CEXC_OF, %g0 ! check for overflow
701 560 bnz,a,pt %xcc, fpok
702 561 or %g0, FPE_FLTOVF, %o3 ! fp overflow code
703 562
704 563 andcc %g2, FSR_CEXC_NV, %g0 ! check for invalid
705 564 bnz,a,pn %xcc, fpok
706 565 or %g0, FPE_FLTINV, %o3 ! fp invalid code
707 566
708 567 cexec_err:
709 568 set .badfpcexcmsg, %o0 ! panic message
710 569 call panic ! panic if no cexc bit set
711 570 mov %g1, %o1
712 571 fpok:
713 572 mov %l1, %o0 ! saved *rp
714 573 call fpu_trap ! fpu_trap(®s, addr, type, code)
715 574 ldn [%o0 + PC_OFF], %o1 ! address of trapping instruction
↓ open down ↓ |
66 lines elided |
↑ open up ↑ |
716 575
717 576 rd %fprs, %g1 ! read fprs, save value in %g1
718 577 st %g1, [%l3 + FPU_FPRS] ! save fprs
719 578 jmp %l0 + 8 ! jump to saved return address
720 579 stx %fsr, [%l3 + FPU_FSR] ! save fsr
721 580 SET_SIZE(_fp_ieee_exception)
722 581
723 582 .badfpcexcmsg:
724 583 .asciz "No floating point exception, fsr %llx"
725 584
726 -#endif /* lint */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX