From 5b7c4cabbb65f5c469464da6c5f614cbd7f730f2 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 21 Feb 2023 18:24:12 -0800 Subject: Merge tag 'net-next-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next Pull networking updates from Jakub Kicinski: "Core: - Add dedicated kmem_cache for typical/small skb->head, avoid having to access struct page at kfree time, and improve memory use. - Introduce sysctl to set default RPS configuration for new netdevs. - Define Netlink protocol specification format which can be used to describe messages used by each family and auto-generate parsers. Add tools for generating kernel data structures and uAPI headers. - Expose all net/core sysctls inside netns. - Remove 4s sleep in netpoll if carrier is instantly detected on boot. - Add configurable limit of MDB entries per port, and port-vlan. - Continue populating drop reasons throughout the stack. - Retire a handful of legacy Qdiscs and classifiers. Protocols: - Support IPv4 big TCP (TSO frames larger than 64kB). - Add IP_LOCAL_PORT_RANGE socket option, to control local port range on socket by socket basis. - Track and report in procfs number of MPTCP sockets used. - Support mixing IPv4 and IPv6 flows in the in-kernel MPTCP path manager. - IPv6: don't check net.ipv6.route.max_size and rely on garbage collection to free memory (similarly to IPv4). - Support Penultimate Segment Pop (PSP) flavor in SRv6 (RFC8986). - ICMP: add per-rate limit counters. - Add support for user scanning requests in ieee802154. - Remove static WEP support. - Support minimal Wi-Fi 7 Extremely High Throughput (EHT) rate reporting. - WiFi 7 EHT channel puncturing support (client & AP). BPF: - Add a rbtree data structure following the "next-gen data structure" precedent set by recently added linked list, that is, by using kfunc + kptr instead of adding a new BPF map type. - Expose XDP hints via kfuncs with initial support for RX hash and timestamp metadata. - Add BPF_F_NO_TUNNEL_KEY extension to bpf_skb_set_tunnel_key to better support decap on GRE tunnel devices not operating in collect metadata. - Improve x86 JIT's codegen for PROBE_MEM runtime error checks. - Remove the need for trace_printk_lock for bpf_trace_printk and bpf_trace_vprintk helpers. - Extend libbpf's bpf_tracing.h support for tracing arguments of kprobes/uprobes and syscall as a special case. - Significantly reduce the search time for module symbols by livepatch and BPF. - Enable cpumasks to be used as kptrs, which is useful for tracing programs tracking which tasks end up running on which CPUs in different time intervals. - Add support for BPF trampoline on s390x and riscv64. - Add capability to export the XDP features supported by the NIC. - Add __bpf_kfunc tag for marking kernel functions as kfuncs. - Add cgroup.memory=nobpf kernel parameter option to disable BPF memory accounting for container environments. Netfilter: - Remove the CLUSTERIP target. It has been marked as obsolete for years, and we still have WARN splats wrt races of the out-of-band /proc interface installed by this target. - Add 'destroy' commands to nf_tables. They are identical to the existing 'delete' commands, but do not return an error if the referenced object (set, chain, rule...) did not exist. Driver API: - Improve cpumask_local_spread() locality to help NICs set the right IRQ affinity on AMD platforms. - Separate C22 and C45 MDIO bus transactions more clearly. - Introduce new DCB table to control DSCP rewrite on egress. - Support configuration of Physical Layer Collision Avoidance (PLCA) Reconciliation Sublayer (RS) (802.3cg-2019). Modern version of shared medium Ethernet. - Support for MAC Merge layer (IEEE 802.3-2018 clause 99). Allowing preemption of low priority frames by high priority frames. - Add support for controlling MACSec offload using netlink SET. - Rework devlink instance refcounts to allow registration and de-registration under the instance lock. Split the code into multiple files, drop some of the unnecessarily granular locks and factor out common parts of netlink operation handling. - Add TX frame aggregation parameters (for USB drivers). - Add a new attr TCA_EXT_WARN_MSG to report TC (offload) warning messages with notifications for debug. - Allow offloading of UDP NEW connections via act_ct. - Add support for per action HW stats in TC. - Support hardware miss to TC action (continue processing in SW from a specific point in the action chain). - Warn if old Wireless Extension user space interface is used with modern cfg80211/mac80211 drivers. Do not support Wireless Extensions for Wi-Fi 7 devices at all. Everyone should switch to using nl80211 interface instead. - Improve the CAN bit timing configuration. Use extack to return error messages directly to user space, update the SJW handling, including the definition of a new default value that will benefit CAN-FD controllers, by increasing their oscillator tolerance. New hardware / drivers: - Ethernet: - nVidia BlueField-3 support (control traffic driver) - Ethernet support for imx93 SoCs - Motorcomm yt8531 gigabit Ethernet PHY - onsemi NCN26000 10BASE-T1S PHY (with support for PLCA) - Microchip LAN8841 PHY (incl. cable diagnostics and PTP) - Amlogic gxl MDIO mux - WiFi: - RealTek RTL8188EU (rtl8xxxu) - Qualcomm Wi-Fi 7 devices (ath12k) - CAN: - Renesas R-Car V4H Drivers: - Bluetooth: - Set Per Platform Antenna Gain (PPAG) for Intel controllers. - Ethernet NICs: - Intel (1G, igc): - support TSN / Qbv / packet scheduling features of i226 model - Intel (100G, ice): - use GNSS subsystem instead of TTY - multi-buffer XDP support - extend support for GPIO pins to E823 devices - nVidia/Mellanox: - update the shared buffer configuration on PFC commands - implement PTP adjphase function for HW offset control - TC support for Geneve and GRE with VF tunnel offload - more efficient crypto key management method - multi-port eswitch support - Netronome/Corigine: - add DCB IEEE support - support IPsec offloading for NFP3800 - Freescale/NXP (enetc): - support XDP_REDIRECT for XDP non-linear buffers - improve reconfig, avoid link flap and waiting for idle - support MAC Merge layer - Other NICs: - sfc/ef100: add basic devlink support for ef100 - ionic: rx_push mode operation (writing descriptors via MMIO) - bnxt: use the auxiliary bus abstraction for RDMA - r8169: disable ASPM and reset bus in case of tx timeout - cpsw: support QSGMII mode for J721e CPSW9G - cpts: support pulse-per-second output - ngbe: add an mdio bus driver - usbnet: optimize usbnet_bh() by avoiding unnecessary queuing - r8152: handle devices with FW with NCM support - amd-xgbe: support 10Mbps, 2.5GbE speeds and rx-adaptation - virtio-net: support multi buffer XDP - virtio/vsock: replace virtio_vsock_pkt with sk_buff - tsnep: XDP support - Ethernet high-speed switches: - nVidia/Mellanox (mlxsw): - add support for latency TLV (in FW control messages) - Microchip (sparx5): - separate explicit and implicit traffic forwarding rules, make the implicit rules always active - add support for egress DSCP rewrite - IS0 VCAP support (Ingress Classification) - IS2 VCAP filters (protos, L3 addrs, L4 ports, flags, ToS etc.) - ES2 VCAP support (Egress Access Control) - support for Per-Stream Filtering and Policing (802.1Q, 8.6.5.1) - Ethernet embedded switches: - Marvell (mv88e6xxx): - add MAB (port auth) offload support - enable PTP receive for mv88e6390 - NXP (ocelot): - support MAC Merge layer - support for the the vsc7512 internal copper phys - Microchip: - lan9303: convert to PHYLINK - lan966x: support TC flower filter statistics - lan937x: PTP support for KSZ9563/KSZ8563 and LAN937x - lan937x: support Credit Based Shaper configuration - ksz9477: support Energy Efficient Ethernet - other: - qca8k: convert to regmap read/write API, use bulk operations - rswitch: Improve TX timestamp accuracy - Intel WiFi (iwlwifi): - EHT (Wi-Fi 7) rate reporting - STEP equalizer support: transfer some STEP (connection to radio on platforms with integrated wifi) related parameters from the BIOS to the firmware. - Qualcomm 802.11ax WiFi (ath11k): - IPQ5018 support - Fine Timing Measurement (FTM) responder role support - channel 177 support - MediaTek WiFi (mt76): - per-PHY LED support - mt7996: EHT (Wi-Fi 7) support - Wireless Ethernet Dispatch (WED) reset support - switch to using page pool allocator - RealTek WiFi (rtw89): - support new version of Bluetooth co-existance - Mobile: - rmnet: support TX aggregation" * tag 'net-next-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1872 commits) page_pool: add a comment explaining the fragment counter usage net: ethtool: fix __ethtool_dev_mm_supported() implementation ethtool: pse-pd: Fix double word in comments xsk: add linux/vmalloc.h to xsk.c sefltests: netdevsim: wait for devlink instance after netns removal selftest: fib_tests: Always cleanup before exit net/mlx5e: Align IPsec ASO result memory to be as required by hardware net/mlx5e: TC, Set CT miss to the specific ct action instance net/mlx5e: Rename CHAIN_TO_REG to MAPPED_OBJ_TO_REG net/mlx5: Refactor tc miss handling to a single function net/mlx5: Kconfig: Make tc offload depend on tc skb extension net/sched: flower: Support hardware miss to tc action net/sched: flower: Move filter handle initialization earlier net/sched: cls_api: Support hardware miss to tc action net/sched: Rename user cookie and act cookie sfc: fix builds without CONFIG_RTC_LIB sfc: clean up some inconsistent indentings net/mlx4_en: Introduce flexible array to silence overflow warning net: lan966x: Fix possible deadlock inside PTP net/ulp: Remove redundant ->clone() test in inet_clone_ulp(). ... --- arch/m68k/fpsp040/bugfix.S | 495 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 495 insertions(+) create mode 100644 arch/m68k/fpsp040/bugfix.S (limited to 'arch/m68k/fpsp040/bugfix.S') diff --git a/arch/m68k/fpsp040/bugfix.S b/arch/m68k/fpsp040/bugfix.S new file mode 100644 index 000000000..3bb9c84bb --- /dev/null +++ b/arch/m68k/fpsp040/bugfix.S @@ -0,0 +1,495 @@ +| +| bugfix.sa 3.2 1/31/91 +| +| +| This file contains workarounds for bugs in the 040 +| relating to the Floating-Point Software Package (FPSP) +| +| Fixes for bugs: 1238 +| +| Bug: 1238 +| +| +| /* The following dirty_bit clear should be left in +| * the handler permanently to improve throughput. +| * The dirty_bits are located at bits [23:16] in +| * longword $08 in the busy frame $4x60. Bit 16 +| * corresponds to FP0, bit 17 corresponds to FP1, +| * and so on. +| */ +| if (E3_exception_just_serviced) { +| dirty_bit[cmdreg3b[9:7]] = 0; +| } +| +| if (fsave_format_version != $40) {goto NOFIX} +| +| if !(E3_exception_just_serviced) {goto NOFIX} +| if (cupc == 0000000) {goto NOFIX} +| if ((cmdreg1b[15:13] != 000) && +| (cmdreg1b[15:10] != 010001)) {goto NOFIX} +| if (((cmdreg1b[15:13] != 000) || ((cmdreg1b[12:10] != cmdreg2b[9:7]) && +| (cmdreg1b[12:10] != cmdreg3b[9:7])) ) && +| ((cmdreg1b[ 9: 7] != cmdreg2b[9:7]) && +| (cmdreg1b[ 9: 7] != cmdreg3b[9:7])) ) {goto NOFIX} +| +| /* Note: for 6d43b or 8d43b, you may want to add the following code +| * to get better coverage. (If you do not insert this code, the part +| * won't lock up; it will simply get the wrong answer.) +| * Do NOT insert this code for 10d43b or later parts. +| * +| * if (fpiarcu == integer stack return address) { +| * cupc = 0000000; +| * goto NOFIX; +| * } +| */ +| +| if (cmdreg1b[15:13] != 000) {goto FIX_OPCLASS2} +| FIX_OPCLASS0: +| if (((cmdreg1b[12:10] == cmdreg2b[9:7]) || +| (cmdreg1b[ 9: 7] == cmdreg2b[9:7])) && +| (cmdreg1b[12:10] != cmdreg3b[9:7]) && +| (cmdreg1b[ 9: 7] != cmdreg3b[9:7])) { /* xu conflict only */ +| /* We execute the following code if there is an +| xu conflict and NOT an nu conflict */ +| +| /* first save some values on the fsave frame */ +| stag_temp = STAG[fsave_frame]; +| cmdreg1b_temp = CMDREG1B[fsave_frame]; +| dtag_temp = DTAG[fsave_frame]; +| ete15_temp = ETE15[fsave_frame]; +| +| CUPC[fsave_frame] = 0000000; +| FRESTORE +| FSAVE +| +| /* If the xu instruction is exceptional, we punt. +| * Otherwise, we would have to include OVFL/UNFL handler +| * code here to get the correct answer. +| */ +| if (fsave_frame_format == $4060) {goto KILL_PROCESS} +| +| fsave_frame = /* build a long frame of all zeros */ +| fsave_frame_format = $4060; /* label it as long frame */ +| +| /* load it with the temps we saved */ +| STAG[fsave_frame] = stag_temp; +| CMDREG1B[fsave_frame] = cmdreg1b_temp; +| DTAG[fsave_frame] = dtag_temp; +| ETE15[fsave_frame] = ete15_temp; +| +| /* Make sure that the cmdreg3b dest reg is not going to +| * be destroyed by a FMOVEM at the end of all this code. +| * If it is, you should move the current value of the reg +| * onto the stack so that the reg will loaded with that value. +| */ +| +| /* All done. Proceed with the code below */ +| } +| +| etemp = FP_reg_[cmdreg1b[12:10]]; +| ete15 = ~ete14; +| cmdreg1b[15:10] = 010010; +| clear(bug_flag_procIDxxxx); +| FRESTORE and return; +| +| +| FIX_OPCLASS2: +| if ((cmdreg1b[9:7] == cmdreg2b[9:7]) && +| (cmdreg1b[9:7] != cmdreg3b[9:7])) { /* xu conflict only */ +| /* We execute the following code if there is an +| xu conflict and NOT an nu conflict */ +| +| /* first save some values on the fsave frame */ +| stag_temp = STAG[fsave_frame]; +| cmdreg1b_temp = CMDREG1B[fsave_frame]; +| dtag_temp = DTAG[fsave_frame]; +| ete15_temp = ETE15[fsave_frame]; +| etemp_temp = ETEMP[fsave_frame]; +| +| CUPC[fsave_frame] = 0000000; +| FRESTORE +| FSAVE +| +| +| /* If the xu instruction is exceptional, we punt. +| * Otherwise, we would have to include OVFL/UNFL handler +| * code here to get the correct answer. +| */ +| if (fsave_frame_format == $4060) {goto KILL_PROCESS} +| +| fsave_frame = /* build a long frame of all zeros */ +| fsave_frame_format = $4060; /* label it as long frame */ +| +| /* load it with the temps we saved */ +| STAG[fsave_frame] = stag_temp; +| CMDREG1B[fsave_frame] = cmdreg1b_temp; +| DTAG[fsave_frame] = dtag_temp; +| ETE15[fsave_frame] = ete15_temp; +| ETEMP[fsave_frame] = etemp_temp; +| +| /* Make sure that the cmdreg3b dest reg is not going to +| * be destroyed by a FMOVEM at the end of all this code. +| * If it is, you should move the current value of the reg +| * onto the stack so that the reg will loaded with that value. +| */ +| +| /* All done. Proceed with the code below */ +| } +| +| if (etemp_exponent == min_sgl) etemp_exponent = min_dbl; +| if (etemp_exponent == max_sgl) etemp_exponent = max_dbl; +| cmdreg1b[15:10] = 010101; +| clear(bug_flag_procIDxxxx); +| FRESTORE and return; +| +| +| NOFIX: +| clear(bug_flag_procIDxxxx); +| FRESTORE and return; +| + + +| Copyright (C) Motorola, Inc. 1990 +| All Rights Reserved +| +| For details on the license for this file, please see the +| file, README, in this same directory. + +|BUGFIX idnt 2,1 | Motorola 040 Floating Point Software Package + + |section 8 + +#include "fpsp.h" + + |xref fpsp_fmt_error + + .global b1238_fix +b1238_fix: +| +| This code is entered only on completion of the handling of an +| nu-generated ovfl, unfl, or inex exception. If the version +| number of the fsave is not $40, this handler is not necessary. +| Simply branch to fix_done and exit normally. +| + cmpib #VER_40,4(%a7) + bne fix_done +| +| Test for cu_savepc equal to zero. If not, this is not a bug +| #1238 case. +| + moveb CU_SAVEPC(%a6),%d0 + andib #0xFE,%d0 + beq fix_done |if zero, this is not bug #1238 + +| +| Test the register conflict aspect. If opclass0, check for +| cu src equal to xu dest or equal to nu dest. If so, go to +| op0. Else, or if opclass2, check for cu dest equal to +| xu dest or equal to nu dest. If so, go to tst_opcl. Else, +| exit, it is not the bug case. +| +| Check for opclass 0. If not, go and check for opclass 2 and sgl. +| + movew CMDREG1B(%a6),%d0 + andiw #0xE000,%d0 |strip all but opclass + bne op2sgl |not opclass 0, check op2 +| +| Check for cu and nu register conflict. If one exists, this takes +| priority over a cu and xu conflict. +| + bfextu CMDREG1B(%a6){#3:#3},%d0 |get 1st src + bfextu CMDREG3B(%a6){#6:#3},%d1 |get 3rd dest + cmpb %d0,%d1 + beqs op0 |if equal, continue bugfix +| +| Check for cu dest equal to nu dest. If so, go and fix the +| bug condition. Otherwise, exit. +| + bfextu CMDREG1B(%a6){#6:#3},%d0 |get 1st dest + cmpb %d0,%d1 |cmp 1st dest with 3rd dest + beqs op0 |if equal, continue bugfix +| +| Check for cu and xu register conflict. +| + bfextu CMDREG2B(%a6){#6:#3},%d1 |get 2nd dest + cmpb %d0,%d1 |cmp 1st dest with 2nd dest + beqs op0_xu |if equal, continue bugfix + bfextu CMDREG1B(%a6){#3:#3},%d0 |get 1st src + cmpb %d0,%d1 |cmp 1st src with 2nd dest + beq op0_xu + bne fix_done |if the reg checks fail, exit +| +| We have the opclass 0 situation. +| +op0: + bfextu CMDREG1B(%a6){#3:#3},%d0 |get source register no + movel #7,%d1 + subl %d0,%d1 + clrl %d0 + bsetl %d1,%d0 + fmovemx %d0,ETEMP(%a6) |load source to ETEMP + + moveb #0x12,%d0 + bfins %d0,CMDREG1B(%a6){#0:#6} |opclass 2, extended +| +| Set ETEMP exponent bit 15 as the opposite of ete14 +| + btst #6,ETEMP_EX(%a6) |check etemp exponent bit 14 + beq setete15 + bclr #etemp15_bit,STAG(%a6) + bra finish +setete15: + bset #etemp15_bit,STAG(%a6) + bra finish + +| +| We have the case in which a conflict exists between the cu src or +| dest and the dest of the xu. We must clear the instruction in +| the cu and restore the state, allowing the instruction in the +| xu to complete. Remember, the instruction in the nu +| was exceptional, and was completed by the appropriate handler. +| If the result of the xu instruction is not exceptional, we can +| restore the instruction from the cu to the frame and continue +| processing the original exception. If the result is also +| exceptional, we choose to kill the process. +| +| Items saved from the stack: +| +| $3c stag - L_SCR1 +| $40 cmdreg1b - L_SCR2 +| $44 dtag - L_SCR3 +| +| The cu savepc is set to zero, and the frame is restored to the +| fpu. +| +op0_xu: + movel STAG(%a6),L_SCR1(%a6) + movel CMDREG1B(%a6),L_SCR2(%a6) + movel DTAG(%a6),L_SCR3(%a6) + andil #0xe0000000,L_SCR3(%a6) + moveb #0,CU_SAVEPC(%a6) + movel (%a7)+,%d1 |save return address from bsr + frestore (%a7)+ + fsave -(%a7) +| +| Check if the instruction which just completed was exceptional. +| + cmpw #0x4060,(%a7) + beq op0_xb +| +| It is necessary to isolate the result of the instruction in the +| xu if it is to fp0 - fp3 and write that value to the USER_FPn +| locations on the stack. The correct destination register is in +| cmdreg2b. +| + bfextu CMDREG2B(%a6){#6:#3},%d0 |get dest register no + cmpil #3,%d0 + bgts op0_xi + beqs op0_fp3 + cmpil #1,%d0 + blts op0_fp0 + beqs op0_fp1 +op0_fp2: + fmovemx %fp2-%fp2,USER_FP2(%a6) + bras op0_xi +op0_fp1: + fmovemx %fp1-%fp1,USER_FP1(%a6) + bras op0_xi +op0_fp0: + fmovemx %fp0-%fp0,USER_FP0(%a6) + bras op0_xi +op0_fp3: + fmovemx %fp3-%fp3,USER_FP3(%a6) +| +| The frame returned is idle. We must build a busy frame to hold +| the cu state information and setup etemp. +| +op0_xi: + movel #22,%d0 |clear 23 lwords + clrl (%a7) +op0_loop: + clrl -(%a7) + dbf %d0,op0_loop + movel #0x40600000,-(%a7) + movel L_SCR1(%a6),STAG(%a6) + movel L_SCR2(%a6),CMDREG1B(%a6) + movel L_SCR3(%a6),DTAG(%a6) + moveb #0x6,CU_SAVEPC(%a6) + movel %d1,-(%a7) |return bsr return address + bfextu CMDREG1B(%a6){#3:#3},%d0 |get source register no + movel #7,%d1 + subl %d0,%d1 + clrl %d0 + bsetl %d1,%d0 + fmovemx %d0,ETEMP(%a6) |load source to ETEMP + + moveb #0x12,%d0 + bfins %d0,CMDREG1B(%a6){#0:#6} |opclass 2, extended +| +| Set ETEMP exponent bit 15 as the opposite of ete14 +| + btst #6,ETEMP_EX(%a6) |check etemp exponent bit 14 + beq op0_sete15 + bclr #etemp15_bit,STAG(%a6) + bra finish +op0_sete15: + bset #etemp15_bit,STAG(%a6) + bra finish + +| +| The frame returned is busy. It is not possible to reconstruct +| the code sequence to allow completion. We will jump to +| fpsp_fmt_error and allow the kernel to kill the process. +| +op0_xb: + jmp fpsp_fmt_error + +| +| Check for opclass 2 and single size. If not both, exit. +| +op2sgl: + movew CMDREG1B(%a6),%d0 + andiw #0xFC00,%d0 |strip all but opclass and size + cmpiw #0x4400,%d0 |test for opclass 2 and size=sgl + bne fix_done |if not, it is not bug 1238 +| +| Check for cu dest equal to nu dest or equal to xu dest, with +| a cu and nu conflict taking priority an nu conflict. If either, +| go and fix the bug condition. Otherwise, exit. +| + bfextu CMDREG1B(%a6){#6:#3},%d0 |get 1st dest + bfextu CMDREG3B(%a6){#6:#3},%d1 |get 3rd dest + cmpb %d0,%d1 |cmp 1st dest with 3rd dest + beq op2_com |if equal, continue bugfix + bfextu CMDREG2B(%a6){#6:#3},%d1 |get 2nd dest + cmpb %d0,%d1 |cmp 1st dest with 2nd dest + bne fix_done |if the reg checks fail, exit +| +| We have the case in which a conflict exists between the cu src or +| dest and the dest of the xu. We must clear the instruction in +| the cu and restore the state, allowing the instruction in the +| xu to complete. Remember, the instruction in the nu +| was exceptional, and was completed by the appropriate handler. +| If the result of the xu instruction is not exceptional, we can +| restore the instruction from the cu to the frame and continue +| processing the original exception. If the result is also +| exceptional, we choose to kill the process. +| +| Items saved from the stack: +| +| $3c stag - L_SCR1 +| $40 cmdreg1b - L_SCR2 +| $44 dtag - L_SCR3 +| etemp - FP_SCR2 +| +| The cu savepc is set to zero, and the frame is restored to the +| fpu. +| +op2_xu: + movel STAG(%a6),L_SCR1(%a6) + movel CMDREG1B(%a6),L_SCR2(%a6) + movel DTAG(%a6),L_SCR3(%a6) + andil #0xe0000000,L_SCR3(%a6) + moveb #0,CU_SAVEPC(%a6) + movel ETEMP(%a6),FP_SCR2(%a6) + movel ETEMP_HI(%a6),FP_SCR2+4(%a6) + movel ETEMP_LO(%a6),FP_SCR2+8(%a6) + movel (%a7)+,%d1 |save return address from bsr + frestore (%a7)+ + fsave -(%a7) +| +| Check if the instruction which just completed was exceptional. +| + cmpw #0x4060,(%a7) + beq op2_xb +| +| It is necessary to isolate the result of the instruction in the +| xu if it is to fp0 - fp3 and write that value to the USER_FPn +| locations on the stack. The correct destination register is in +| cmdreg2b. +| + bfextu CMDREG2B(%a6){#6:#3},%d0 |get dest register no + cmpil #3,%d0 + bgts op2_xi + beqs op2_fp3 + cmpil #1,%d0 + blts op2_fp0 + beqs op2_fp1 +op2_fp2: + fmovemx %fp2-%fp2,USER_FP2(%a6) + bras op2_xi +op2_fp1: + fmovemx %fp1-%fp1,USER_FP1(%a6) + bras op2_xi +op2_fp0: + fmovemx %fp0-%fp0,USER_FP0(%a6) + bras op2_xi +op2_fp3: + fmovemx %fp3-%fp3,USER_FP3(%a6) +| +| The frame returned is idle. We must build a busy frame to hold +| the cu state information and fix up etemp. +| +op2_xi: + movel #22,%d0 |clear 23 lwords + clrl (%a7) +op2_loop: + clrl -(%a7) + dbf %d0,op2_loop + movel #0x40600000,-(%a7) + movel L_SCR1(%a6),STAG(%a6) + movel L_SCR2(%a6),CMDREG1B(%a6) + movel L_SCR3(%a6),DTAG(%a6) + moveb #0x6,CU_SAVEPC(%a6) + movel FP_SCR2(%a6),ETEMP(%a6) + movel FP_SCR2+4(%a6),ETEMP_HI(%a6) + movel FP_SCR2+8(%a6),ETEMP_LO(%a6) + movel %d1,-(%a7) + bra op2_com + +| +| We have the opclass 2 single source situation. +| +op2_com: + moveb #0x15,%d0 + bfins %d0,CMDREG1B(%a6){#0:#6} |opclass 2, double + + cmpw #0x407F,ETEMP_EX(%a6) |single +max + bnes case2 + movew #0x43FF,ETEMP_EX(%a6) |to double +max + bra finish +case2: + cmpw #0xC07F,ETEMP_EX(%a6) |single -max + bnes case3 + movew #0xC3FF,ETEMP_EX(%a6) |to double -max + bra finish +case3: + cmpw #0x3F80,ETEMP_EX(%a6) |single +min + bnes case4 + movew #0x3C00,ETEMP_EX(%a6) |to double +min + bra finish +case4: + cmpw #0xBF80,ETEMP_EX(%a6) |single -min + bne fix_done + movew #0xBC00,ETEMP_EX(%a6) |to double -min + bra finish +| +| The frame returned is busy. It is not possible to reconstruct +| the code sequence to allow completion. fpsp_fmt_error causes +| an fline illegal instruction to be executed. +| +| You should replace the jump to fpsp_fmt_error with a jump +| to the entry point used to kill a process. +| +op2_xb: + jmp fpsp_fmt_error + +| +| Enter here if the case is not of the situations affected by +| bug #1238, or if the fix is completed, and exit. +| +finish: +fix_done: + rts + + |end -- cgit v1.2.3