| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: fp_complete.c,v 1.23 2019/03/25 19:24:30 maxv Exp $ */ | | 1 | /* $NetBSD: fp_complete.c,v 1.23.4.1 2020/09/02 12:38:07 martin Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2001 Ross Harvey | | 4 | * Copyright (c) 2001 Ross Harvey |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -25,27 +25,27 @@ | | | @@ -25,27 +25,27 @@ |
25 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 25 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
26 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 26 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
27 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 27 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
28 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 28 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
32 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 32 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
33 | * POSSIBILITY OF SUCH DAMAGE. | | 33 | * POSSIBILITY OF SUCH DAMAGE. |
34 | */ | | 34 | */ |
35 | | | 35 | |
36 | #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ | | 36 | #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ |
37 | | | 37 | |
38 | __KERNEL_RCSID(0, "$NetBSD: fp_complete.c,v 1.23 2019/03/25 19:24:30 maxv Exp $"); | | 38 | __KERNEL_RCSID(0, "$NetBSD: fp_complete.c,v 1.23.4.1 2020/09/02 12:38:07 martin Exp $"); |
39 | | | 39 | |
40 | #include <sys/param.h> | | 40 | #include <sys/param.h> |
41 | #include <sys/systm.h> | | 41 | #include <sys/systm.h> |
42 | #include <sys/proc.h> | | 42 | #include <sys/proc.h> |
43 | #include <sys/atomic.h> | | 43 | #include <sys/atomic.h> |
44 | #include <sys/evcnt.h> | | 44 | #include <sys/evcnt.h> |
45 | | | 45 | |
46 | #include <machine/cpu.h> | | 46 | #include <machine/cpu.h> |
47 | #include <machine/fpu.h> | | 47 | #include <machine/fpu.h> |
48 | #include <machine/reg.h> | | 48 | #include <machine/reg.h> |
49 | #include <machine/alpha.h> | | 49 | #include <machine/alpha.h> |
50 | #include <alpha/alpha/db_instruction.h> | | 50 | #include <alpha/alpha/db_instruction.h> |
51 | | | 51 | |
| @@ -189,33 +189,33 @@ lds(unsigned int rn, s_float *v, struct | | | @@ -189,33 +189,33 @@ lds(unsigned int rn, s_float *v, struct |
189 | alpha_lds(rn, v); | | 189 | alpha_lds(rn, v); |
190 | } | | 190 | } |
191 | | | 191 | |
192 | static inline void | | 192 | static inline void |
193 | ldt(unsigned int rn, t_float *v, struct lwp *l) | | 193 | ldt(unsigned int rn, t_float *v, struct lwp *l) |
194 | { | | 194 | { |
195 | POSTFILTER_SUBNORMAL(l, v); | | 195 | POSTFILTER_SUBNORMAL(l, v); |
196 | alpha_ldt(rn, v); | | 196 | alpha_ldt(rn, v); |
197 | } | | 197 | } |
198 | | | 198 | |
199 | static float64 | | 199 | static float64 |
200 | compare_lt(float64 a, float64 b) | | 200 | compare_lt(float64 a, float64 b) |
201 | { | | 201 | { |
202 | return CMP_RESULT(float64_lt(a, b)); | | 202 | return CMP_RESULT(float64_lt_quiet(a, b)); |
203 | } | | 203 | } |
204 | | | 204 | |
205 | static float64 | | 205 | static float64 |
206 | compare_le(float64 a, float64 b) | | 206 | compare_le(float64 a, float64 b) |
207 | { | | 207 | { |
208 | return CMP_RESULT(float64_le(a, b)); | | 208 | return CMP_RESULT(float64_le_quiet(a, b)); |
209 | } | | 209 | } |
210 | | | 210 | |
211 | static float64 | | 211 | static float64 |
212 | compare_un(float64 a, float64 b) | | 212 | compare_un(float64 a, float64 b) |
213 | { | | 213 | { |
214 | if (float64_is_nan(a) | float64_is_nan(b)) { | | 214 | if (float64_is_nan(a) | float64_is_nan(b)) { |
215 | if (float64_is_signaling_nan(a) | float64_is_signaling_nan(b)) | | 215 | if (float64_is_signaling_nan(a) | float64_is_signaling_nan(b)) |
216 | float_set_invalid(); | | 216 | float_set_invalid(); |
217 | return CMP_RESULT(1); | | 217 | return CMP_RESULT(1); |
218 | } | | 218 | } |
219 | return CMP_RESULT(0); | | 219 | return CMP_RESULT(0); |
220 | } | | 220 | } |
221 | | | 221 | |
| @@ -492,27 +492,27 @@ float64_unk(float64 a, float64 b) | | | @@ -492,27 +492,27 @@ float64_unk(float64 a, float64 b) |
492 | * 1 1 1 0 . . . cvtXt/g (cvtqt, cvt[dq]g only) | | 492 | * 1 1 1 0 . . . cvtXt/g (cvtqt, cvt[dq]g only) |
493 | * 1 1 1 1 . . . cvtXq/q (cvttq, cvtgq) | | 493 | * 1 1 1 1 . . . cvtXq/q (cvttq, cvtgq) |
494 | * | | | | 494 | * | | |
495 | * 15 14 13|12 11 10 09|08 07 06 05 the twilight zone | | 495 | * 15 14 13|12 11 10 09|08 07 06 05 the twilight zone |
496 | * --------======------============ | | 496 | * --------======------============ |
497 | * TRAP : RND : SRC : FUNCTION : | | 497 | * TRAP : RND : SRC : FUNCTION : |
498 | * /s /i /u x x 1 0 1 1 0 0 . . . cvtts, /siu only 0, 1, 5, 7 | | 498 | * /s /i /u x x 1 0 1 1 0 0 . . . cvtts, /siu only 0, 1, 5, 7 |
499 | * 0 1 0 1 0 1 0 1 1 0 0 . . . cvtst (src == T (!)) 2ac NOT /S | | 499 | * 0 1 0 1 0 1 0 1 1 0 0 . . . cvtst (src == T (!)) 2ac NOT /S |
500 | * 1 1 0 1 0 1 0 1 1 0 0 . . . cvtst/s (src == T (!)) 6ac | | 500 | * 1 1 0 1 0 1 0 1 1 0 0 . . . cvtst/s (src == T (!)) 6ac |
501 | * x 0 x x x x 0 1 1 1 1 . . . cvttq/_ (src == T) | | 501 | * x 0 x x x x 0 1 1 1 1 . . . cvttq/_ (src == T) |
502 | */ | | 502 | */ |
503 | | | 503 | |
504 | static void | | 504 | static void |
505 | alpha_fp_interpret(alpha_instruction *pc, struct lwp *l, uint64_t bits) | | 505 | alpha_fp_interpret(alpha_instruction *pc, struct lwp *l, uint32_t bits) |
506 | { | | 506 | { |
507 | s_float sfa, sfb, sfc; | | 507 | s_float sfa, sfb, sfc; |
508 | t_float tfa, tfb, tfc; | | 508 | t_float tfa, tfb, tfc; |
509 | alpha_instruction inst; | | 509 | alpha_instruction inst; |
510 | | | 510 | |
511 | inst.bits = bits; | | 511 | inst.bits = bits; |
512 | switch(inst.generic_format.opcode) { | | 512 | switch(inst.generic_format.opcode) { |
513 | default: | | 513 | default: |
514 | /* this "cannot happen" */ | | 514 | /* this "cannot happen" */ |
515 | this_cannot_happen(2, inst.bits); | | 515 | this_cannot_happen(2, inst.bits); |
516 | return; | | 516 | return; |
517 | case op_any_float: | | 517 | case op_any_float: |
518 | if (inst.float_format.function == op_cvtql_sv || | | 518 | if (inst.float_format.function == op_cvtql_sv || |
| @@ -624,33 +624,35 @@ alpha_fp_complete(u_long a0, u_long a1, | | | @@ -624,33 +624,35 @@ alpha_fp_complete(u_long a0, u_long a1, |
624 | { | | 624 | { |
625 | int t; | | 625 | int t; |
626 | int sig; | | 626 | int sig; |
627 | uint64_t op_class; | | 627 | uint64_t op_class; |
628 | alpha_instruction inst; | | 628 | alpha_instruction inst; |
629 | /* "trigger_pc" is Compaq's term for the earliest faulting op */ | | 629 | /* "trigger_pc" is Compaq's term for the earliest faulting op */ |
630 | alpha_instruction *trigger_pc, *usertrap_pc; | | 630 | alpha_instruction *trigger_pc, *usertrap_pc; |
631 | alpha_instruction *pc, *win_begin, tsw[TSWINSIZE]; | | 631 | alpha_instruction *pc, *win_begin, tsw[TSWINSIZE]; |
632 | | | 632 | |
633 | sig = SIGFPE; | | 633 | sig = SIGFPE; |
634 | pc = (alpha_instruction *)l->l_md.md_tf->tf_regs[FRAME_PC]; | | 634 | pc = (alpha_instruction *)l->l_md.md_tf->tf_regs[FRAME_PC]; |
635 | trigger_pc = pc - 1; /* for ALPHA_AMASK_PAT case */ | | 635 | trigger_pc = pc - 1; /* for ALPHA_AMASK_PAT case */ |
636 | if (cpu_amask & ALPHA_AMASK_PAT) { | | 636 | if (cpu_amask & ALPHA_AMASK_PAT) { |
637 | if (a0 & 1 || alpha_fp_sync_complete) { | | 637 | /* SWC | INV */ |
| | | 638 | if (a0 & 3 || alpha_fp_sync_complete) { |
638 | sig = alpha_fp_complete_at(trigger_pc, l, ucode); | | 639 | sig = alpha_fp_complete_at(trigger_pc, l, ucode); |
639 | goto done; | | 640 | goto done; |
640 | } | | 641 | } |
641 | } | | 642 | } |
642 | *ucode = a0; | | 643 | *ucode = a0; |
643 | if (!(a0 & 1)) | | 644 | /* SWC | INV */ |
| | | 645 | if (!(a0 & 3)) |
644 | return sig; | | 646 | return sig; |
645 | /* | | 647 | /* |
646 | * At this point we are somewhere in the trap shadow of one or more instruc- | | 648 | * At this point we are somewhere in the trap shadow of one or more instruc- |
647 | * tions that have trapped with software completion specified. We have a mask | | 649 | * tions that have trapped with software completion specified. We have a mask |
648 | * of the registers written by trapping instructions. | | 650 | * of the registers written by trapping instructions. |
649 | * | | 651 | * |
650 | * Now step backwards through the trap shadow, clearing bits in the | | 652 | * Now step backwards through the trap shadow, clearing bits in the |
651 | * destination write mask until the trigger instruction is found, and | | 653 | * destination write mask until the trigger instruction is found, and |
652 | * interpret this one instruction in SW. If a SIGFPE is not required, back up | | 654 | * interpret this one instruction in SW. If a SIGFPE is not required, back up |
653 | * the PC until just after this instruction and restart. This will execute all | | 655 | * the PC until just after this instruction and restart. This will execute all |
654 | * trap shadow instructions between the trigger pc and the trap pc twice. | | 656 | * trap shadow instructions between the trigger pc and the trap pc twice. |
655 | */ | | 657 | */ |
656 | trigger_pc = 0; | | 658 | trigger_pc = 0; |