aboutsummaryrefslogtreecommitdiff
path: root/arch/m68k/fpsp040/get_op.S
diff options
context:
space:
mode:
authorLibravatar Linus Torvalds <torvalds@linux-foundation.org>2023-02-21 18:24:12 -0800
committerLibravatar Linus Torvalds <torvalds@linux-foundation.org>2023-02-21 18:24:12 -0800
commit5b7c4cabbb65f5c469464da6c5f614cbd7f730f2 (patch)
treecc5c2d0a898769fd59549594fedb3ee6f84e59a0 /arch/m68k/fpsp040/get_op.S
downloadlinux-5b7c4cabbb65f5c469464da6c5f614cbd7f730f2.tar.gz
linux-5b7c4cabbb65f5c469464da6c5f614cbd7f730f2.zip
Merge tag 'net-next-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-nextgrafted
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(). ...
Diffstat (limited to 'arch/m68k/fpsp040/get_op.S')
-rw-r--r--arch/m68k/fpsp040/get_op.S675
1 files changed, 675 insertions, 0 deletions
diff --git a/arch/m68k/fpsp040/get_op.S b/arch/m68k/fpsp040/get_op.S
new file mode 100644
index 000000000..64c36d79e
--- /dev/null
+++ b/arch/m68k/fpsp040/get_op.S
@@ -0,0 +1,675 @@
+|
+| get_op.sa 3.6 5/19/92
+|
+| get_op.sa 3.5 4/26/91
+|
+| Description: This routine is called by the unsupported format/data
+| type exception handler ('unsupp' - vector 55) and the unimplemented
+| instruction exception handler ('unimp' - vector 11). 'get_op'
+| determines the opclass (0, 2, or 3) and branches to the
+| opclass handler routine. See 68881/2 User's Manual table 4-11
+| for a description of the opclasses.
+|
+| For UNSUPPORTED data/format (exception vector 55) and for
+| UNIMPLEMENTED instructions (exception vector 11) the following
+| applies:
+|
+| - For unnormalized numbers (opclass 0, 2, or 3) the
+| number(s) is normalized and the operand type tag is updated.
+|
+| - For a packed number (opclass 2) the number is unpacked and the
+| operand type tag is updated.
+|
+| - For denormalized numbers (opclass 0 or 2) the number(s) is not
+| changed but passed to the next module. The next module for
+| unimp is do_func, the next module for unsupp is res_func.
+|
+| For UNSUPPORTED data/format (exception vector 55) only the
+| following applies:
+|
+| - If there is a move out with a packed number (opclass 3) the
+| number is packed and written to user memory. For the other
+| opclasses the number(s) are written back to the fsave stack
+| and the instruction is then restored back into the '040. The
+| '040 is then able to complete the instruction.
+|
+| For example:
+| fadd.x fpm,fpn where the fpm contains an unnormalized number.
+| The '040 takes an unsupported data trap and gets to this
+| routine. The number is normalized, put back on the stack and
+| then an frestore is done to restore the instruction back into
+| the '040. The '040 then re-executes the fadd.x fpm,fpn with
+| a normalized number in the source and the instruction is
+| successful.
+|
+| Next consider if in the process of normalizing the un-
+| normalized number it becomes a denormalized number. The
+| routine which converts the unnorm to a norm (called mk_norm)
+| detects this and tags the number as a denorm. The routine
+| res_func sees the denorm tag and converts the denorm to a
+| norm. The instruction is then restored back into the '040
+| which re_executes the instruction.
+|
+|
+| 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.
+
+GET_OP: |idnt 2,1 | Motorola 040 Floating Point Software Package
+
+ |section 8
+
+#include "fpsp.h"
+
+ .global PIRN,PIRZRM,PIRP
+ .global SMALRN,SMALRZRM,SMALRP
+ .global BIGRN,BIGRZRM,BIGRP
+
+PIRN:
+ .long 0x40000000,0xc90fdaa2,0x2168c235 |pi
+PIRZRM:
+ .long 0x40000000,0xc90fdaa2,0x2168c234 |pi
+PIRP:
+ .long 0x40000000,0xc90fdaa2,0x2168c235 |pi
+
+|round to nearest
+SMALRN:
+ .long 0x3ffd0000,0x9a209a84,0xfbcff798 |log10(2)
+ .long 0x40000000,0xadf85458,0xa2bb4a9a |e
+ .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc |log2(e)
+ .long 0x3ffd0000,0xde5bd8a9,0x37287195 |log10(e)
+ .long 0x00000000,0x00000000,0x00000000 |0.0
+| round to zero;round to negative infinity
+SMALRZRM:
+ .long 0x3ffd0000,0x9a209a84,0xfbcff798 |log10(2)
+ .long 0x40000000,0xadf85458,0xa2bb4a9a |e
+ .long 0x3fff0000,0xb8aa3b29,0x5c17f0bb |log2(e)
+ .long 0x3ffd0000,0xde5bd8a9,0x37287195 |log10(e)
+ .long 0x00000000,0x00000000,0x00000000 |0.0
+| round to positive infinity
+SMALRP:
+ .long 0x3ffd0000,0x9a209a84,0xfbcff799 |log10(2)
+ .long 0x40000000,0xadf85458,0xa2bb4a9b |e
+ .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc |log2(e)
+ .long 0x3ffd0000,0xde5bd8a9,0x37287195 |log10(e)
+ .long 0x00000000,0x00000000,0x00000000 |0.0
+
+|round to nearest
+BIGRN:
+ .long 0x3ffe0000,0xb17217f7,0xd1cf79ac |ln(2)
+ .long 0x40000000,0x935d8ddd,0xaaa8ac17 |ln(10)
+ .long 0x3fff0000,0x80000000,0x00000000 |10 ^ 0
+
+ .global PTENRN
+PTENRN:
+ .long 0x40020000,0xA0000000,0x00000000 |10 ^ 1
+ .long 0x40050000,0xC8000000,0x00000000 |10 ^ 2
+ .long 0x400C0000,0x9C400000,0x00000000 |10 ^ 4
+ .long 0x40190000,0xBEBC2000,0x00000000 |10 ^ 8
+ .long 0x40340000,0x8E1BC9BF,0x04000000 |10 ^ 16
+ .long 0x40690000,0x9DC5ADA8,0x2B70B59E |10 ^ 32
+ .long 0x40D30000,0xC2781F49,0xFFCFA6D5 |10 ^ 64
+ .long 0x41A80000,0x93BA47C9,0x80E98CE0 |10 ^ 128
+ .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E |10 ^ 256
+ .long 0x46A30000,0xE319A0AE,0xA60E91C7 |10 ^ 512
+ .long 0x4D480000,0xC9767586,0x81750C17 |10 ^ 1024
+ .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 |10 ^ 2048
+ .long 0x75250000,0xC4605202,0x8A20979B |10 ^ 4096
+|round to minus infinity
+BIGRZRM:
+ .long 0x3ffe0000,0xb17217f7,0xd1cf79ab |ln(2)
+ .long 0x40000000,0x935d8ddd,0xaaa8ac16 |ln(10)
+ .long 0x3fff0000,0x80000000,0x00000000 |10 ^ 0
+
+ .global PTENRM
+PTENRM:
+ .long 0x40020000,0xA0000000,0x00000000 |10 ^ 1
+ .long 0x40050000,0xC8000000,0x00000000 |10 ^ 2
+ .long 0x400C0000,0x9C400000,0x00000000 |10 ^ 4
+ .long 0x40190000,0xBEBC2000,0x00000000 |10 ^ 8
+ .long 0x40340000,0x8E1BC9BF,0x04000000 |10 ^ 16
+ .long 0x40690000,0x9DC5ADA8,0x2B70B59D |10 ^ 32
+ .long 0x40D30000,0xC2781F49,0xFFCFA6D5 |10 ^ 64
+ .long 0x41A80000,0x93BA47C9,0x80E98CDF |10 ^ 128
+ .long 0x43510000,0xAA7EEBFB,0x9DF9DE8D |10 ^ 256
+ .long 0x46A30000,0xE319A0AE,0xA60E91C6 |10 ^ 512
+ .long 0x4D480000,0xC9767586,0x81750C17 |10 ^ 1024
+ .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 |10 ^ 2048
+ .long 0x75250000,0xC4605202,0x8A20979A |10 ^ 4096
+|round to positive infinity
+BIGRP:
+ .long 0x3ffe0000,0xb17217f7,0xd1cf79ac |ln(2)
+ .long 0x40000000,0x935d8ddd,0xaaa8ac17 |ln(10)
+ .long 0x3fff0000,0x80000000,0x00000000 |10 ^ 0
+
+ .global PTENRP
+PTENRP:
+ .long 0x40020000,0xA0000000,0x00000000 |10 ^ 1
+ .long 0x40050000,0xC8000000,0x00000000 |10 ^ 2
+ .long 0x400C0000,0x9C400000,0x00000000 |10 ^ 4
+ .long 0x40190000,0xBEBC2000,0x00000000 |10 ^ 8
+ .long 0x40340000,0x8E1BC9BF,0x04000000 |10 ^ 16
+ .long 0x40690000,0x9DC5ADA8,0x2B70B59E |10 ^ 32
+ .long 0x40D30000,0xC2781F49,0xFFCFA6D6 |10 ^ 64
+ .long 0x41A80000,0x93BA47C9,0x80E98CE0 |10 ^ 128
+ .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E |10 ^ 256
+ .long 0x46A30000,0xE319A0AE,0xA60E91C7 |10 ^ 512
+ .long 0x4D480000,0xC9767586,0x81750C18 |10 ^ 1024
+ .long 0x5A920000,0x9E8B3B5D,0xC53D5DE6 |10 ^ 2048
+ .long 0x75250000,0xC4605202,0x8A20979B |10 ^ 4096
+
+ |xref nrm_zero
+ |xref decbin
+ |xref round
+
+ .global get_op
+ .global uns_getop
+ .global uni_getop
+get_op:
+ clrb DY_MO_FLG(%a6)
+ tstb UFLG_TMP(%a6) |test flag for unsupp/unimp state
+ beq uni_getop
+
+uns_getop:
+ btstb #direction_bit,CMDREG1B(%a6)
+ bne opclass3 |branch if a fmove out (any kind)
+ btstb #6,CMDREG1B(%a6)
+ beqs uns_notpacked
+
+ bfextu CMDREG1B(%a6){#3:#3},%d0
+ cmpb #3,%d0
+ beq pack_source |check for a packed src op, branch if so
+uns_notpacked:
+ bsr chk_dy_mo |set the dyadic/monadic flag
+ tstb DY_MO_FLG(%a6)
+ beqs src_op_ck |if monadic, go check src op
+| ;else, check dst op (fall through)
+
+ btstb #7,DTAG(%a6)
+ beqs src_op_ck |if dst op is norm, check src op
+ bras dst_ex_dnrm |else, handle destination unnorm/dnrm
+
+uni_getop:
+ bfextu CMDREG1B(%a6){#0:#6},%d0 |get opclass and src fields
+ cmpil #0x17,%d0 |if op class and size fields are $17,
+| ;it is FMOVECR; if not, continue
+|
+| If the instruction is fmovecr, exit get_op. It is handled
+| in do_func and smovecr.sa.
+|
+ bne not_fmovecr |handle fmovecr as an unimplemented inst
+ rts
+
+not_fmovecr:
+ btstb #E1,E_BYTE(%a6) |if set, there is a packed operand
+ bne pack_source |check for packed src op, branch if so
+
+| The following lines of are coded to optimize on normalized operands
+ moveb STAG(%a6),%d0
+ orb DTAG(%a6),%d0 |check if either of STAG/DTAG msb set
+ bmis dest_op_ck |if so, some op needs to be fixed
+ rts
+
+dest_op_ck:
+ btstb #7,DTAG(%a6) |check for unsupported data types in
+ beqs src_op_ck |the destination, if not, check src op
+ bsr chk_dy_mo |set dyadic/monadic flag
+ tstb DY_MO_FLG(%a6) |
+ beqs src_op_ck |if monadic, check src op
+|
+| At this point, destination has an extended denorm or unnorm.
+|
+dst_ex_dnrm:
+ movew FPTEMP_EX(%a6),%d0 |get destination exponent
+ andiw #0x7fff,%d0 |mask sign, check if exp = 0000
+ beqs src_op_ck |if denorm then check source op.
+| ;denorms are taken care of in res_func
+| ;(unsupp) or do_func (unimp)
+| ;else unnorm fall through
+ leal FPTEMP(%a6),%a0 |point a0 to dop - used in mk_norm
+ bsr mk_norm |go normalize - mk_norm returns:
+| ;L_SCR1{7:5} = operand tag
+| ; (000 = norm, 100 = denorm)
+| ;L_SCR1{4} = fpte15 or ete15
+| ; 0 = exp > $3fff
+| ; 1 = exp <= $3fff
+| ;and puts the normalized num back
+| ;on the fsave stack
+|
+ moveb L_SCR1(%a6),DTAG(%a6) |write the new tag & fpte15
+| ;to the fsave stack and fall
+| ;through to check source operand
+|
+src_op_ck:
+ btstb #7,STAG(%a6)
+ beq end_getop |check for unsupported data types on the
+| ;source operand
+ btstb #5,STAG(%a6)
+ bnes src_sd_dnrm |if bit 5 set, handle sgl/dbl denorms
+|
+| At this point only unnorms or extended denorms are possible.
+|
+src_ex_dnrm:
+ movew ETEMP_EX(%a6),%d0 |get source exponent
+ andiw #0x7fff,%d0 |mask sign, check if exp = 0000
+ beq end_getop |if denorm then exit, denorms are
+| ;handled in do_func
+ leal ETEMP(%a6),%a0 |point a0 to sop - used in mk_norm
+ bsr mk_norm |go normalize - mk_norm returns:
+| ;L_SCR1{7:5} = operand tag
+| ; (000 = norm, 100 = denorm)
+| ;L_SCR1{4} = fpte15 or ete15
+| ; 0 = exp > $3fff
+| ; 1 = exp <= $3fff
+| ;and puts the normalized num back
+| ;on the fsave stack
+|
+ moveb L_SCR1(%a6),STAG(%a6) |write the new tag & ete15
+ rts |end_getop
+
+|
+| At this point, only single or double denorms are possible.
+| If the inst is not fmove, normalize the source. If it is,
+| do nothing to the input.
+|
+src_sd_dnrm:
+ btstb #4,CMDREG1B(%a6) |differentiate between sgl/dbl denorm
+ bnes is_double
+is_single:
+ movew #0x3f81,%d1 |write bias for sgl denorm
+ bras common |goto the common code
+is_double:
+ movew #0x3c01,%d1 |write the bias for a dbl denorm
+common:
+ btstb #sign_bit,ETEMP_EX(%a6) |grab sign bit of mantissa
+ beqs pos
+ bset #15,%d1 |set sign bit because it is negative
+pos:
+ movew %d1,ETEMP_EX(%a6)
+| ;put exponent on stack
+
+ movew CMDREG1B(%a6),%d1
+ andw #0xe3ff,%d1 |clear out source specifier
+ orw #0x0800,%d1 |set source specifier to extended prec
+ movew %d1,CMDREG1B(%a6) |write back to the command word in stack
+| ;this is needed to fix unsupp data stack
+ leal ETEMP(%a6),%a0 |point a0 to sop
+
+ bsr mk_norm |convert sgl/dbl denorm to norm
+ moveb L_SCR1(%a6),STAG(%a6) |put tag into source tag reg - d0
+ rts |end_getop
+|
+| At this point, the source is definitely packed, whether
+| instruction is dyadic or monadic is still unknown
+|
+pack_source:
+ movel FPTEMP_LO(%a6),ETEMP(%a6) |write ms part of packed
+| ;number to etemp slot
+ bsr chk_dy_mo |set dyadic/monadic flag
+ bsr unpack
+
+ tstb DY_MO_FLG(%a6)
+ beqs end_getop |if monadic, exit
+| ;else, fix FPTEMP
+pack_dya:
+ bfextu CMDREG1B(%a6){#6:#3},%d0 |extract dest fp reg
+ movel #7,%d1
+ subl %d0,%d1
+ clrl %d0
+ bsetl %d1,%d0 |set up d0 as a dynamic register mask
+ fmovemx %d0,FPTEMP(%a6) |write to FPTEMP
+
+ btstb #7,DTAG(%a6) |check dest tag for unnorm or denorm
+ bne dst_ex_dnrm |else, handle the unnorm or ext denorm
+|
+| Dest is not denormalized. Check for norm, and set fpte15
+| accordingly.
+|
+ moveb DTAG(%a6),%d0
+ andib #0xf0,%d0 |strip to only dtag:fpte15
+ tstb %d0 |check for normalized value
+ bnes end_getop |if inf/nan/zero leave get_op
+ movew FPTEMP_EX(%a6),%d0
+ andiw #0x7fff,%d0
+ cmpiw #0x3fff,%d0 |check if fpte15 needs setting
+ bges end_getop |if >= $3fff, leave fpte15=0
+ orb #0x10,DTAG(%a6)
+ bras end_getop
+
+|
+| At this point, it is either an fmoveout packed, unnorm or denorm
+|
+opclass3:
+ clrb DY_MO_FLG(%a6) |set dyadic/monadic flag to monadic
+ bfextu CMDREG1B(%a6){#4:#2},%d0
+ cmpib #3,%d0
+ bne src_ex_dnrm |if not equal, must be unnorm or denorm
+| ;else it is a packed move out
+| ;exit
+end_getop:
+ rts
+
+|
+| Sets the DY_MO_FLG correctly. This is used only on if it is an
+| unsupported data type exception. Set if dyadic.
+|
+chk_dy_mo:
+ movew CMDREG1B(%a6),%d0
+ btstl #5,%d0 |testing extension command word
+ beqs set_mon |if bit 5 = 0 then monadic
+ btstl #4,%d0 |know that bit 5 = 1
+ beqs set_dya |if bit 4 = 0 then dyadic
+ andiw #0x007f,%d0 |get rid of all but extension bits {6:0}
+ cmpiw #0x0038,%d0 |if extension = $38 then fcmp (dyadic)
+ bnes set_mon
+set_dya:
+ st DY_MO_FLG(%a6) |set the inst flag type to dyadic
+ rts
+set_mon:
+ clrb DY_MO_FLG(%a6) |set the inst flag type to monadic
+ rts
+|
+| MK_NORM
+|
+| Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl
+| exception if denorm.
+|
+| CASE opclass 0x0 unsupp
+| mk_norm till msb set
+| set tag = norm
+|
+| CASE opclass 0x0 unimp
+| mk_norm till msb set or exp = 0
+| if integer bit = 0
+| tag = denorm
+| else
+| tag = norm
+|
+| CASE opclass 011 unsupp
+| mk_norm till msb set or exp = 0
+| if integer bit = 0
+| tag = denorm
+| set unfl_nmcexe = 1
+| else
+| tag = norm
+|
+| if exp <= $3fff
+| set ete15 or fpte15 = 1
+| else set ete15 or fpte15 = 0
+
+| input:
+| a0 = points to operand to be normalized
+| output:
+| L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm)
+| L_SCR1{4} = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff)
+| the normalized operand is placed back on the fsave stack
+mk_norm:
+ clrl L_SCR1(%a6)
+ bclrb #sign_bit,LOCAL_EX(%a0)
+ sne LOCAL_SGN(%a0) |transform into internal extended format
+
+ cmpib #0x2c,1+EXC_VEC(%a6) |check if unimp
+ bnes uns_data |branch if unsupp
+ bsr uni_inst |call if unimp (opclass 0x0)
+ bras reload
+uns_data:
+ btstb #direction_bit,CMDREG1B(%a6) |check transfer direction
+ bnes bit_set |branch if set (opclass 011)
+ bsr uns_opx |call if opclass 0x0
+ bras reload
+bit_set:
+ bsr uns_op3 |opclass 011
+reload:
+ cmpw #0x3fff,LOCAL_EX(%a0) |if exp > $3fff
+ bgts end_mk | fpte15/ete15 already set to 0
+ bsetb #4,L_SCR1(%a6) |else set fpte15/ete15 to 1
+| ;calling routine actually sets the
+| ;value on the stack (along with the
+| ;tag), since this routine doesn't
+| ;know if it should set ete15 or fpte15
+| ;ie, it doesn't know if this is the
+| ;src op or dest op.
+end_mk:
+ bfclr LOCAL_SGN(%a0){#0:#8}
+ beqs end_mk_pos
+ bsetb #sign_bit,LOCAL_EX(%a0) |convert back to IEEE format
+end_mk_pos:
+ rts
+|
+| CASE opclass 011 unsupp
+|
+uns_op3:
+ bsr nrm_zero |normalize till msb = 1 or exp = zero
+ btstb #7,LOCAL_HI(%a0) |if msb = 1
+ bnes no_unfl |then branch
+set_unfl:
+ orw #dnrm_tag,L_SCR1(%a6) |set denorm tag
+ bsetb #unfl_bit,FPSR_EXCEPT(%a6) |set unfl exception bit
+no_unfl:
+ rts
+|
+| CASE opclass 0x0 unsupp
+|
+uns_opx:
+ bsr nrm_zero |normalize the number
+ btstb #7,LOCAL_HI(%a0) |check if integer bit (j-bit) is set
+ beqs uns_den |if clear then now have a denorm
+uns_nrm:
+ orb #norm_tag,L_SCR1(%a6) |set tag to norm
+ rts
+uns_den:
+ orb #dnrm_tag,L_SCR1(%a6) |set tag to denorm
+ rts
+|
+| CASE opclass 0x0 unimp
+|
+uni_inst:
+ bsr nrm_zero
+ btstb #7,LOCAL_HI(%a0) |check if integer bit (j-bit) is set
+ beqs uni_den |if clear then now have a denorm
+uni_nrm:
+ orb #norm_tag,L_SCR1(%a6) |set tag to norm
+ rts
+uni_den:
+ orb #dnrm_tag,L_SCR1(%a6) |set tag to denorm
+ rts
+
+|
+| Decimal to binary conversion
+|
+| Special cases of inf and NaNs are completed outside of decbin.
+| If the input is an snan, the snan bit is not set.
+|
+| input:
+| ETEMP(a6) - points to packed decimal string in memory
+| output:
+| fp0 - contains packed string converted to extended precision
+| ETEMP - same as fp0
+unpack:
+ movew CMDREG1B(%a6),%d0 |examine command word, looking for fmove's
+ andw #0x3b,%d0
+ beq move_unpack |special handling for fmove: must set FPSR_CC
+
+ movew ETEMP(%a6),%d0 |get word with inf information
+ bfextu %d0{#20:#12},%d1 |get exponent into d1
+ cmpiw #0x0fff,%d1 |test for inf or NaN
+ bnes try_zero |if not equal, it is not special
+ bfextu %d0{#17:#3},%d1 |get SE and y bits into d1
+ cmpiw #7,%d1 |SE and y bits must be on for special
+ bnes try_zero |if not on, it is not special
+|input is of the special cases of inf and NaN
+ tstl ETEMP_HI(%a6) |check ms mantissa
+ bnes fix_nan |if non-zero, it is a NaN
+ tstl ETEMP_LO(%a6) |check ls mantissa
+ bnes fix_nan |if non-zero, it is a NaN
+ bra finish |special already on stack
+fix_nan:
+ btstb #signan_bit,ETEMP_HI(%a6) |test for snan
+ bne finish
+ orl #snaniop_mask,USER_FPSR(%a6) |always set snan if it is so
+ bra finish
+try_zero:
+ movew ETEMP_EX+2(%a6),%d0 |get word 4
+ andiw #0x000f,%d0 |clear all but last ni(y)bble
+ tstw %d0 |check for zero.
+ bne not_spec
+ tstl ETEMP_HI(%a6) |check words 3 and 2
+ bne not_spec
+ tstl ETEMP_LO(%a6) |check words 1 and 0
+ bne not_spec
+ tstl ETEMP(%a6) |test sign of the zero
+ bges pos_zero
+ movel #0x80000000,ETEMP(%a6) |write neg zero to etemp
+ clrl ETEMP_HI(%a6)
+ clrl ETEMP_LO(%a6)
+ bra finish
+pos_zero:
+ clrl ETEMP(%a6)
+ clrl ETEMP_HI(%a6)
+ clrl ETEMP_LO(%a6)
+ bra finish
+
+not_spec:
+ fmovemx %fp0-%fp1,-(%a7) |save fp0 - decbin returns in it
+ bsr decbin
+ fmovex %fp0,ETEMP(%a6) |put the unpacked sop in the fsave stack
+ fmovemx (%a7)+,%fp0-%fp1
+ fmovel #0,%FPSR |clr fpsr from decbin
+ bra finish
+
+|
+| Special handling for packed move in: Same results as all other
+| packed cases, but we must set the FPSR condition codes properly.
+|
+move_unpack:
+ movew ETEMP(%a6),%d0 |get word with inf information
+ bfextu %d0{#20:#12},%d1 |get exponent into d1
+ cmpiw #0x0fff,%d1 |test for inf or NaN
+ bnes mtry_zero |if not equal, it is not special
+ bfextu %d0{#17:#3},%d1 |get SE and y bits into d1
+ cmpiw #7,%d1 |SE and y bits must be on for special
+ bnes mtry_zero |if not on, it is not special
+|input is of the special cases of inf and NaN
+ tstl ETEMP_HI(%a6) |check ms mantissa
+ bnes mfix_nan |if non-zero, it is a NaN
+ tstl ETEMP_LO(%a6) |check ls mantissa
+ bnes mfix_nan |if non-zero, it is a NaN
+|input is inf
+ orl #inf_mask,USER_FPSR(%a6) |set I bit
+ tstl ETEMP(%a6) |check sign
+ bge finish
+ orl #neg_mask,USER_FPSR(%a6) |set N bit
+ bra finish |special already on stack
+mfix_nan:
+ orl #nan_mask,USER_FPSR(%a6) |set NaN bit
+ moveb #nan_tag,STAG(%a6) |set stag to NaN
+ btstb #signan_bit,ETEMP_HI(%a6) |test for snan
+ bnes mn_snan
+ orl #snaniop_mask,USER_FPSR(%a6) |set snan bit
+ btstb #snan_bit,FPCR_ENABLE(%a6) |test for snan enabled
+ bnes mn_snan
+ bsetb #signan_bit,ETEMP_HI(%a6) |force snans to qnans
+mn_snan:
+ tstl ETEMP(%a6) |check for sign
+ bge finish |if clr, go on
+ orl #neg_mask,USER_FPSR(%a6) |set N bit
+ bra finish
+
+mtry_zero:
+ movew ETEMP_EX+2(%a6),%d0 |get word 4
+ andiw #0x000f,%d0 |clear all but last ni(y)bble
+ tstw %d0 |check for zero.
+ bnes mnot_spec
+ tstl ETEMP_HI(%a6) |check words 3 and 2
+ bnes mnot_spec
+ tstl ETEMP_LO(%a6) |check words 1 and 0
+ bnes mnot_spec
+ tstl ETEMP(%a6) |test sign of the zero
+ bges mpos_zero
+ orl #neg_mask+z_mask,USER_FPSR(%a6) |set N and Z
+ movel #0x80000000,ETEMP(%a6) |write neg zero to etemp
+ clrl ETEMP_HI(%a6)
+ clrl ETEMP_LO(%a6)
+ bras finish
+mpos_zero:
+ orl #z_mask,USER_FPSR(%a6) |set Z
+ clrl ETEMP(%a6)
+ clrl ETEMP_HI(%a6)
+ clrl ETEMP_LO(%a6)
+ bras finish
+
+mnot_spec:
+ fmovemx %fp0-%fp1,-(%a7) |save fp0 ,fp1 - decbin returns in fp0
+ bsr decbin
+ fmovex %fp0,ETEMP(%a6)
+| ;put the unpacked sop in the fsave stack
+ fmovemx (%a7)+,%fp0-%fp1
+
+finish:
+ movew CMDREG1B(%a6),%d0 |get the command word
+ andw #0xfbff,%d0 |change the source specifier field to
+| ;extended (was packed).
+ movew %d0,CMDREG1B(%a6) |write command word back to fsave stack
+| ;we need to do this so the 040 will
+| ;re-execute the inst. without taking
+| ;another packed trap.
+
+fix_stag:
+|Converted result is now in etemp on fsave stack, now set the source
+|tag (stag)
+| if (ete =$7fff) then INF or NAN
+| if (etemp = $x.0----0) then
+| stag = INF
+| else
+| stag = NAN
+| else
+| if (ete = $0000) then
+| stag = ZERO
+| else
+| stag = NORM
+|
+| Note also that the etemp_15 bit (just right of the stag) must
+| be set accordingly.
+|
+ movew ETEMP_EX(%a6),%d1
+ andiw #0x7fff,%d1 |strip sign
+ cmpw #0x7fff,%d1
+ bnes z_or_nrm
+ movel ETEMP_HI(%a6),%d1
+ bnes is_nan
+ movel ETEMP_LO(%a6),%d1
+ bnes is_nan
+is_inf:
+ moveb #0x40,STAG(%a6)
+ movel #0x40,%d0
+ rts
+is_nan:
+ moveb #0x60,STAG(%a6)
+ movel #0x60,%d0
+ rts
+z_or_nrm:
+ tstw %d1
+ bnes is_nrm
+is_zro:
+| For a zero, set etemp_15
+ moveb #0x30,STAG(%a6)
+ movel #0x20,%d0
+ rts
+is_nrm:
+| For a norm, check if the exp <= $3fff; if so, set etemp_15
+ cmpiw #0x3fff,%d1
+ bles set_bit15
+ moveb #0,STAG(%a6)
+ bras end_is_nrm
+set_bit15:
+ moveb #0x10,STAG(%a6)
+end_is_nrm:
+ movel #0,%d0
+end_fix:
+ rts
+
+end_get:
+ rts
+ |end