aboutsummaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsvn2git <svn2git@FreeBSD.org>1994-07-01 00:00:00 -0800
committersvn2git <svn2git@FreeBSD.org>1994-07-01 00:00:00 -0800
commit5e0e9b99dc3fc0ecd49d929db0d57c784b66f481 (patch)
treee779b5a6edddbb949b7990751b12d6f25304ba86 /sys
parenta16f65c7d117419bd266c28a1901ef129a337569 (diff)
downloadsrc-releng/1.tar.gz
src-releng/1.zip
Release FreeBSD 1.1.5.1release/1.1.5.1_cvsreleng/1
This commit was manufactured to restore the state of the 1.1.5.1-RELEASE image. Releases prior to 5.3-RELEASE are omitting the secure/ and crypto/ subdirs.
Diffstat (limited to 'sys')
-rw-r--r--sys/conf/files5
-rw-r--r--sys/conf/newvers.sh12
-rw-r--r--sys/conf/param.c2
-rw-r--r--sys/doc/Changes (renamed from sys/i386/doc/Changes)96
-rw-r--r--sys/doc/Makefile (renamed from sys/i386/doc/Makefile)2
-rw-r--r--sys/doc/ata/ata-1 (renamed from sys/i386/doc/ata/ata-1)0
-rw-r--r--sys/doc/ata/ata-10 (renamed from sys/i386/doc/ata/ata-10)0
-rw-r--r--sys/doc/ata/ata-11 (renamed from sys/i386/doc/ata/ata-11)0
-rw-r--r--sys/doc/ata/ata-2 (renamed from sys/i386/doc/ata/ata-2)0
-rw-r--r--sys/doc/ata/ata-3 (renamed from sys/i386/doc/ata/ata-3)0
-rw-r--r--sys/doc/ata/ata-4 (renamed from sys/i386/doc/ata/ata-4)0
-rw-r--r--sys/doc/ata/ata-5 (renamed from sys/i386/doc/ata/ata-5)0
-rw-r--r--sys/doc/ata/ata-6 (renamed from sys/i386/doc/ata/ata-6)0
-rw-r--r--sys/doc/ata/ata-7 (renamed from sys/i386/doc/ata/ata-7)0
-rw-r--r--sys/doc/ata/ata-8 (renamed from sys/i386/doc/ata/ata-8)0
-rw-r--r--sys/doc/ata/ata-9 (renamed from sys/i386/doc/ata/ata-9)0
-rw-r--r--sys/doc/ata/ata-apx (renamed from sys/i386/doc/ata/ata-apx)0
-rw-r--r--sys/doc/ata/ata-prt (renamed from sys/i386/doc/ata/ata-prt)0
-rw-r--r--sys/doc/ata/ata-toc (renamed from sys/i386/doc/ata/ata-toc)0
-rw-r--r--sys/doc/ed.relnotes (renamed from sys/i386/doc/ed.relnotes)2
-rw-r--r--sys/doc/memory-test.doc40
-rw-r--r--sys/doc/options.doc682
-rw-r--r--sys/doc/options.texi (renamed from sys/i386/doc/options.texi)256
-rw-r--r--sys/doc/seagate.doc125
-rw-r--r--sys/doc/sound.doc80
-rw-r--r--sys/doc/vm_layout.doc (renamed from sys/i386/doc/vm_layout.doc)2
-rw-r--r--sys/doc/wt.doc (renamed from sys/i386/doc/wt.doc)0
-rw-r--r--sys/gnu/fpemul/Changelog36
-rw-r--r--sys/gnu/fpemul/README277
-rw-r--r--sys/gnu/fpemul/control_w.h95
-rw-r--r--sys/gnu/fpemul/div_small.s101
-rw-r--r--sys/gnu/fpemul/errors.c612
-rw-r--r--sys/gnu/fpemul/exception.h102
-rw-r--r--sys/gnu/fpemul/fpu_arith.c235
-rw-r--r--sys/gnu/fpemul/fpu_asm.h82
-rw-r--r--sys/gnu/fpemul/fpu_aux.c233
-rw-r--r--sys/gnu/fpemul/fpu_emu.h188
-rw-r--r--sys/gnu/fpemul/fpu_entry.c483
-rw-r--r--sys/gnu/fpemul/fpu_etc.c175
-rw-r--r--sys/gnu/fpemul/fpu_proto.h115
-rw-r--r--sys/gnu/fpemul/fpu_system.h97
-rw-r--r--sys/gnu/fpemul/fpu_trig.c1367
-rw-r--r--sys/gnu/fpemul/get_address.c203
-rw-r--r--sys/gnu/fpemul/load_store.c269
-rw-r--r--sys/gnu/fpemul/math_emu.h47
-rw-r--r--sys/gnu/fpemul/poly_2xm1.c141
-rw-r--r--sys/gnu/fpemul/poly_atan.c252
-rw-r--r--sys/gnu/fpemul/poly_div.s144
-rw-r--r--sys/gnu/fpemul/poly_l2.c318
-rw-r--r--sys/gnu/fpemul/poly_mul64.s124
-rw-r--r--sys/gnu/fpemul/poly_sin.c192
-rw-r--r--sys/gnu/fpemul/poly_tan.c229
-rw-r--r--sys/gnu/fpemul/polynomial.s192
-rw-r--r--sys/gnu/fpemul/reg_add_sub.c303
-rw-r--r--sys/gnu/fpemul/reg_compare.c384
-rw-r--r--sys/gnu/fpemul/reg_constant.c175
-rw-r--r--sys/gnu/fpemul/reg_constant.h82
-rw-r--r--sys/gnu/fpemul/reg_div.s295
-rw-r--r--sys/gnu/fpemul/reg_ld_str.c1387
-rw-r--r--sys/gnu/fpemul/reg_mul.c162
-rw-r--r--sys/gnu/fpemul/reg_norm.s182
-rw-r--r--sys/gnu/fpemul/reg_round.s653
-rw-r--r--sys/gnu/fpemul/reg_u_add.s244
-rw-r--r--sys/gnu/fpemul/reg_u_div.s506
-rw-r--r--sys/gnu/fpemul/reg_u_mul.s199
-rw-r--r--sys/gnu/fpemul/reg_u_sub.s361
-rw-r--r--sys/gnu/fpemul/status_w.h106
-rw-r--r--sys/gnu/fpemul/version.h61
-rw-r--r--sys/gnu/fpemul/wm_shrx.s261
-rw-r--r--sys/gnu/fpemul/wm_sqrt.s496
-rw-r--r--sys/i386/boot/Makefile45
-rw-r--r--sys/i386/boot/biosbootbin0 -> 512 bytes
-rw-r--r--sys/i386/boot/bootbin0 -> 7632 bytes
-rw-r--r--sys/i386/boot/boot.c12
-rwxr-xr-xsys/i386/boot/boot.symbin0 -> 10379 bytes
-rw-r--r--sys/i386/boot/boot2.S12
-rw-r--r--sys/i386/boot/bootbiosbin0 -> 7120 bytes
-rw-r--r--sys/i386/boot/disk.c45
-rw-r--r--sys/i386/boot/io.c20
-rw-r--r--sys/i386/boot/start.S3
-rw-r--r--sys/i386/conf/ECLIPSE66
-rw-r--r--sys/i386/conf/GENERICAH13
-rw-r--r--sys/i386/conf/GENERICBT12
-rw-r--r--sys/i386/conf/HAMSTER67
-rw-r--r--sys/i386/conf/LAPTOP68
-rw-r--r--sys/i386/conf/LINT79
-rw-r--r--sys/i386/conf/Makefile.i38618
-rw-r--r--sys/i386/conf/SYSCONS86
-rw-r--r--sys/i386/conf/TIME64
-rw-r--r--sys/i386/conf/WCARCH67
-rw-r--r--sys/i386/conf/WCARCHIVE73
-rw-r--r--sys/i386/conf/devices.i3863
-rw-r--r--sys/i386/conf/files.i38694
-rw-r--r--sys/i386/doc/sound.doc38
-rw-r--r--sys/i386/i386/autoconf.c7
-rw-r--r--sys/i386/i386/conf.c65
-rw-r--r--sys/i386/i386/db_interface.c21
-rw-r--r--sys/i386/i386/exception.s138
-rw-r--r--sys/i386/i386/in_cksum.c94
-rw-r--r--sys/i386/i386/locore.s117
-rw-r--r--sys/i386/i386/machdep.c133
-rw-r--r--sys/i386/i386/math_emulate.c144
-rw-r--r--sys/i386/i386/microtime.s87
-rw-r--r--sys/i386/i386/pmap.c879
-rw-r--r--sys/i386/i386/random.s60
-rw-r--r--sys/i386/i386/support.s323
-rw-r--r--sys/i386/i386/swtch.s43
-rw-r--r--sys/i386/i386/trap.c814
-rw-r--r--sys/i386/i386/vm_machdep.c889
-rw-r--r--sys/i386/include/ansi.h21
-rw-r--r--sys/i386/include/asmacros.h6
-rw-r--r--sys/i386/include/console.h31
-rw-r--r--sys/i386/include/cpu.h13
-rw-r--r--sys/i386/include/cpufunc.h13
-rw-r--r--sys/i386/include/ioctl_fd.h31
-rw-r--r--sys/i386/include/limits.h6
-rw-r--r--sys/i386/include/lpt.h24
-rw-r--r--sys/i386/include/mouse.h44
-rw-r--r--sys/i386/include/npx.h10
-rw-r--r--sys/i386/include/param.h6
-rw-r--r--sys/i386/include/pcaudioio.h75
-rw-r--r--sys/i386/include/pmap.h55
-rw-r--r--sys/i386/include/psl.h6
-rw-r--r--sys/i386/include/pte.h4
-rw-r--r--sys/i386/include/soundcard.h50
-rw-r--r--sys/i386/include/spl.h104
-rw-r--r--sys/i386/include/ultrasound.h9
-rw-r--r--sys/i386/include/vmparam.h2
-rw-r--r--sys/i386/isa/aha1542.c13
-rw-r--r--sys/i386/isa/bt742a.c111
-rw-r--r--sys/i386/isa/bt742a_32.c1694
-rw-r--r--sys/i386/isa/clock.c279
-rw-r--r--sys/i386/isa/com.c101
-rw-r--r--sys/i386/isa/debug.h85
-rw-r--r--sys/i386/isa/elink.c77
-rw-r--r--sys/i386/isa/elink.h39
-rw-r--r--sys/i386/isa/fd.c778
-rw-r--r--sys/i386/isa/fdc.h12
-rw-r--r--sys/i386/isa/fdreg.h20
-rw-r--r--sys/i386/isa/ft.c1188
-rw-r--r--sys/i386/isa/ftreg.h11
-rw-r--r--sys/i386/isa/ic/i82365.h190
-rw-r--r--sys/i386/isa/ic/nec765.h73
-rw-r--r--sys/i386/isa/icu.h12
-rw-r--r--sys/i386/isa/icu.s492
-rw-r--r--sys/i386/isa/if_ed.c1451
-rw-r--r--sys/i386/isa/if_edreg.h2
-rw-r--r--sys/i386/isa/if_el.c800
-rw-r--r--sys/i386/isa/if_elreg.h76
-rw-r--r--sys/i386/isa/if_ep.c164
-rw-r--r--sys/i386/isa/if_ie507.h19
-rw-r--r--sys/i386/isa/if_is.c10
-rw-r--r--sys/i386/isa/if_ze.c1951
-rw-r--r--sys/i386/isa/if_zereg.h859
-rw-r--r--sys/i386/isa/ipl.h7
-rw-r--r--sys/i386/isa/isa.c227
-rw-r--r--sys/i386/isa/isa.h9
-rw-r--r--sys/i386/isa/isa_device.h4
-rw-r--r--sys/i386/isa/kbdtables.h40
-rw-r--r--sys/i386/isa/lpa.c14
-rw-r--r--sys/i386/isa/lpt.c150
-rw-r--r--sys/i386/isa/mcd.c5
-rw-r--r--sys/i386/isa/npx.c22
-rw-r--r--sys/i386/isa/pcaudio.c430
-rw-r--r--sys/i386/isa/pccons.c101
-rw-r--r--sys/i386/isa/psm.c464
-rw-r--r--sys/i386/isa/seagate.c2036
-rw-r--r--sys/i386/isa/sio.c1242
-rw-r--r--sys/i386/isa/sound/CHANGELOG75
-rw-r--r--sys/i386/isa/sound/RELNOTES.Linux256
-rw-r--r--sys/i386/isa/sound/adlib_card.c13
-rw-r--r--sys/i386/isa/sound/audio.c106
-rw-r--r--sys/i386/isa/sound/debug.h29
-rw-r--r--sys/i386/isa/sound/dev_table.c148
-rw-r--r--sys/i386/isa/sound/dev_table.h46
-rw-r--r--sys/i386/isa/sound/dmabuf.c360
-rw-r--r--sys/i386/isa/sound/dsp.c270
-rw-r--r--sys/i386/isa/sound/gus_card.c87
-rw-r--r--sys/i386/isa/sound/gus_hw.h15
-rw-r--r--sys/i386/isa/sound/gus_linearvol.h18
-rw-r--r--sys/i386/isa/sound/gus_midi.c14
-rw-r--r--sys/i386/isa/sound/gus_vol.c70
-rw-r--r--sys/i386/isa/sound/gus_wave.c1834
-rw-r--r--sys/i386/isa/sound/ics2101.c265
-rw-r--r--sys/i386/isa/sound/local.h13
-rw-r--r--sys/i386/isa/sound/midi.c220
-rw-r--r--sys/i386/isa/sound/midibuf.c14
-rw-r--r--sys/i386/isa/sound/mpu401.c129
-rw-r--r--sys/i386/isa/sound/opl3.c68
-rw-r--r--sys/i386/isa/sound/os.h94
-rw-r--r--sys/i386/isa/sound/pas.h12
-rw-r--r--sys/i386/isa/sound/pas2_card.c135
-rw-r--r--sys/i386/isa/sound/pas2_midi.c16
-rw-r--r--sys/i386/isa/sound/pas2_mixer.c40
-rw-r--r--sys/i386/isa/sound/pas2_pcm.c91
-rw-r--r--sys/i386/isa/sound/patmgr.c41
-rw-r--r--sys/i386/isa/sound/pro_midi.c140
-rw-r--r--sys/i386/isa/sound/sb.h28
-rw-r--r--sys/i386/isa/sound/sb16_dsp.c627
-rw-r--r--sys/i386/isa/sound/sb16_midi.c287
-rw-r--r--sys/i386/isa/sound/sb_card.c13
-rw-r--r--sys/i386/isa/sound/sb_dsp.c1140
-rw-r--r--sys/i386/isa/sound/sb_midi.c224
-rw-r--r--sys/i386/isa/sound/sb_mixer.c422
-rw-r--r--sys/i386/isa/sound/sb_mixer.h212
-rw-r--r--sys/i386/isa/sound/sequencer.c311
-rw-r--r--sys/i386/isa/sound/sound_calls.h59
-rw-r--r--sys/i386/isa/sound/sound_config.h43
-rw-r--r--sys/i386/isa/sound/sound_switch.c445
-rw-r--r--sys/i386/isa/sound/soundcard.c307
-rw-r--r--sys/i386/isa/spkr.c23
-rw-r--r--sys/i386/isa/syscons.c623
-rw-r--r--sys/i386/isa/tw.c997
-rw-r--r--sys/i386/isa/ultra14f.c6
-rw-r--r--sys/i386/isa/vector.s196
-rw-r--r--sys/i386/isa/wd.c204
-rw-r--r--sys/i386/isa/wt.c3
-rw-r--r--sys/i386/isa/wt.c.orig902
-rw-r--r--sys/i386/netboot/Makefile9
-rw-r--r--sys/i386/netboot/bootmenu.c2
-rw-r--r--sys/i386/netboot/ether.c479
-rw-r--r--sys/i386/netboot/ether.h178
-rw-r--r--sys/i386/netboot/wd80x3.c240
-rw-r--r--sys/i386/pci/ncr.c5507
-rw-r--r--sys/i386/pci/ncr_reg.h489
-rw-r--r--sys/i386/pci/pci.c494
-rw-r--r--sys/i386/pci/pci.h58
-rw-r--r--sys/i386/pci/pci_config.c45
-rw-r--r--sys/i386/pci/pci_device.h88
-rw-r--r--sys/i386/pci/pcibios.c261
-rw-r--r--sys/i386/pci/pcibios.h53
-rw-r--r--sys/isofs/isofs_rrip.c7
-rw-r--r--sys/isofs/isofs_vfsops.c6
-rw-r--r--sys/isofs/isofs_vnops.c15
-rw-r--r--sys/kern/imgact_aout.c6
-rw-r--r--sys/kern/init_main.c34
-rw-r--r--sys/kern/init_sysent.c8
-rw-r--r--sys/kern/kern_acct.c2
-rw-r--r--sys/kern/kern_clock.c608
-rw-r--r--sys/kern/kern_descrip.c4
-rw-r--r--sys/kern/kern_execve.c45
-rw-r--r--sys/kern/kern_exit.c5
-rw-r--r--sys/kern/kern_fork.c10
-rw-r--r--sys/kern/kern_malloc.c74
-rw-r--r--sys/kern/kern_ntptime.c267
-rw-r--r--sys/kern/kern_physio.c105
-rw-r--r--sys/kern/kern_prot.c2
-rw-r--r--sys/kern/kern_resource.c2
-rw-r--r--sys/kern/kern_sig.c12
-rw-r--r--sys/kern/kern_subr.c2
-rw-r--r--sys/kern/kern_synch.c4
-rw-r--r--sys/kern/kern_time.c6
-rw-r--r--sys/kern/makesyscalls.sh4
-rw-r--r--sys/kern/spec_vnops.c4
-rw-r--r--sys/kern/subr_prf.c11
-rw-r--r--sys/kern/subr_rand.c100
-rw-r--r--sys/kern/sys_process.c2
-rw-r--r--sys/kern/syscalls.c6
-rw-r--r--sys/kern/syscalls.master6
-rw-r--r--sys/kern/sysv_msg.c6
-rw-r--r--sys/kern/sysv_sem.c12
-rw-r--r--sys/kern/sysv_shm.c14
-rw-r--r--sys/kern/tty.c545
-rw-r--r--sys/kern/tty_conf.c6
-rw-r--r--sys/kern/tty_pty.c155
-rw-r--r--sys/kern/uipc_mbuf.c17
-rw-r--r--sys/kern/vfs__bio.c95
-rw-r--r--sys/kern/vfs_lookup.c15
-rw-r--r--sys/kern/vfs_subr.c25
-rw-r--r--sys/kern/vfs_syscalls.c7
-rw-r--r--sys/kern/vfs_vnops.c3
-rw-r--r--sys/net/if.c7
-rw-r--r--sys/net/if.h12
-rw-r--r--sys/net/if_ethersubr.c226
-rw-r--r--sys/net/if_loop.c30
-rw-r--r--sys/net/if_ppp.c108
-rw-r--r--sys/net/if_sl.c54
-rw-r--r--sys/net/netisr.h15
-rw-r--r--sys/net/pppdefs.h (renamed from sys/net/ppp.h)8
-rw-r--r--sys/net/raw_cb.h3
-rw-r--r--sys/net/route.c2
-rw-r--r--sys/netinet/if_ether.c8
-rw-r--r--sys/netinet/if_ether.h100
-rw-r--r--sys/netinet/igmp.c321
-rw-r--r--sys/netinet/igmp.h60
-rw-r--r--sys/netinet/igmp_var.h80
-rw-r--r--sys/netinet/in.c132
-rw-r--r--sys/netinet/in.h37
-rw-r--r--sys/netinet/in_pcb.c93
-rw-r--r--sys/netinet/in_pcb.h7
-rw-r--r--sys/netinet/in_pcb.old.c503
-rw-r--r--sys/netinet/in_pcb.orig.c498
-rw-r--r--sys/netinet/in_proto.c12
-rw-r--r--sys/netinet/in_var.h117
-rw-r--r--sys/netinet/ip_icmp.c7
-rw-r--r--sys/netinet/ip_input.c53
-rw-r--r--sys/netinet/ip_mroute.c1056
-rw-r--r--sys/netinet/ip_mroute.h174
-rw-r--r--sys/netinet/ip_output.c494
-rw-r--r--sys/netinet/ip_var.h17
-rw-r--r--sys/netinet/raw_ip.c54
-rw-r--r--sys/netinet/tcp_usrreq.c7
-rw-r--r--sys/netinet/udp_usrreq.c104
-rw-r--r--sys/nfs/nfs_bio.c8
-rw-r--r--sys/nfs/nfs_serv.c16
-rw-r--r--sys/nfs/nfs_socket.c2
-rw-r--r--sys/nfs/nfs_subs.c60
-rw-r--r--sys/nfs/nfs_vnops.c16
-rw-r--r--sys/pcfs/pcfs_conv.c6
-rw-r--r--sys/pcfs/pcfs_fat.c18
-rw-r--r--sys/pcfs/pcfs_vfsops.c5
-rw-r--r--sys/pcfs/pcfs_vnops.c41
-rw-r--r--sys/procfs/procfs_subr.c174
-rw-r--r--sys/procfs/procfs_vnops.c10
-rw-r--r--sys/scsi/cd.c13
-rw-r--r--sys/scsi/scsi_base.c16
-rw-r--r--sys/scsi/scsi_ioctl.c2
-rw-r--r--sys/scsi/scsiconf.h3
-rw-r--r--sys/scsi/sd.c20
-rw-r--r--sys/scsi/st.c22
-rw-r--r--sys/sys/acct.h2
-rw-r--r--sys/sys/buf.h8
-rw-r--r--sys/sys/callout.h2
-rw-r--r--sys/sys/conf.h4
-rw-r--r--sys/sys/disklabel.h3
-rw-r--r--sys/sys/dkstat.h2
-rw-r--r--sys/sys/errno.h2
-rw-r--r--sys/sys/exec.h4
-rw-r--r--sys/sys/fcntl.h2
-rw-r--r--sys/sys/ftape.h5
-rw-r--r--sys/sys/ioctl.h9
-rw-r--r--sys/sys/ioctl_compat.h2
-rw-r--r--sys/sys/ipc.h2
-rw-r--r--sys/sys/kernel.h11
-rw-r--r--sys/sys/malloc.h17
-rw-r--r--sys/sys/map.h2
-rw-r--r--sys/sys/mbuf.h54
-rw-r--r--sys/sys/mount.h5
-rw-r--r--sys/sys/namei.h2
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/proc.h2
-rw-r--r--sys/sys/procfs.h24
-rw-r--r--sys/sys/signal.h2
-rw-r--r--sys/sys/specdev.h4
-rw-r--r--sys/sys/stat.h2
-rw-r--r--sys/sys/syscall.h6
-rw-r--r--sys/sys/systm.h42
-rw-r--r--sys/sys/termios.h8
-rw-r--r--sys/sys/timeb.h2
-rw-r--r--sys/sys/times.h2
-rw-r--r--sys/sys/timex.h290
-rw-r--r--sys/sys/tty.h55
-rw-r--r--sys/sys/ttydefaults.h8
-rw-r--r--sys/sys/types.h2
-rw-r--r--sys/sys/unistd.h12
-rw-r--r--sys/ufs/dir.h2
-rw-r--r--sys/ufs/ufs_disksubr.c7
-rw-r--r--sys/ufs/ufs_lookup.c2
-rw-r--r--sys/ufs/ufs_vfsops.c2
-rw-r--r--sys/ufs/ufs_vnops.c7
-rw-r--r--sys/vm/device_pager.c1
-rw-r--r--sys/vm/queue.h26
-rw-r--r--sys/vm/swap_pager.c1012
-rw-r--r--sys/vm/swap_pager.h9
-rw-r--r--sys/vm/vm_fault.c28
-rw-r--r--sys/vm/vm_glue.c52
-rw-r--r--sys/vm/vm_mmap.c101
-rw-r--r--sys/vm/vm_object.c24
-rw-r--r--sys/vm/vm_object.h5
-rw-r--r--sys/vm/vm_page.c93
-rw-r--r--sys/vm/vm_page.h40
-rw-r--r--sys/vm/vm_pageout.c763
-rw-r--r--sys/vm/vm_pageout.h3
-rw-r--r--sys/vm/vm_pager.c22
-rw-r--r--sys/vm/vm_pager.h4
-rw-r--r--sys/vm/vm_swap.c4
-rw-r--r--sys/vm/vm_unix.c9
-rw-r--r--sys/vm/vnode_pager.c1408
378 files changed, 54616 insertions, 10228 deletions
diff --git a/sys/conf/files b/sys/conf/files
index 3fdbb5a24850..82cf5c8fd714 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $Id: files,v 1.20 1994/01/25 11:16:01 rgrimes Exp $
+# $Id: files,v 1.22 1994/05/17 22:30:25 jkh Exp $
#
ddb/db_access.c optional ddb
ddb/db_aout.c optional ddb
@@ -39,6 +39,7 @@ kern/kern_fork.c standard
kern/kern_kinfo.c standard
kern/kern_ktrace.c standard
kern/kern_malloc.c standard
+kern/kern_ntptime.c standard
kern/kern_proc.c standard
kern/kern_prot.c standard
kern/kern_resource.c standard
@@ -132,6 +133,8 @@ netinet/tcp_subr.c optional inet
netinet/tcp_timer.c optional inet
netinet/tcp_usrreq.c optional inet
netinet/udp_usrreq.c optional inet
+netinet/igmp.c optional multicast
+netinet/ip_mroute.c optional inet multicast mrouting
netiso/clnp_debug.c optional iso
netiso/clnp_er.c optional iso
netiso/clnp_frag.c optional iso
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index ab111aa33136..949e4cf49f08 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -32,7 +32,7 @@
# SUCH DAMAGE.
#
# from: @(#)newvers.sh 7.4 (Berkeley) 12/7/90
-# $Id: newvers.sh,v 1.7.2.3 1994/05/01 19:19:34 rgrimes Exp $
+# $Id: newvers.sh,v 1.10 1994/06/28 10:39:08 jkh Exp $
#
if [ ! -r version ]
@@ -44,12 +44,18 @@ fi
touch version
-kernvers="FreeBSD 1.1(Release)"
+ostype="FreeBSD"
+osrelease="1.1.5.1(RELEASE)"
+kernvers="${ostype} ${osrelease}"
v=`cat version` t=`date "+ %m/%d/%y %H:%M"`
t=`date`
user=${USER-root}
host=`hostname`
dir=`pwd`
(
- echo "char version[] = \"${kernvers} ($1) #${v}: ${t}\\n ${user}@${host}:${dir}\\n\";"
+ echo "const char version[] = \"${kernvers} ($1) #${v}: ${t}\\n ${user}@${host}:${dir}\\n\";"
+ echo "const char ostype[] = \"${ostype}\";"
+ echo "const char osrelease[] = \"${osrelease}\";"
+ echo "const int osbuild = ${v};"
+ echo "const char osconfig[] = \"$1\";"
) > vers.c
diff --git a/sys/conf/param.c b/sys/conf/param.c
index 115a3239c44e..1c4fcb161b33 100644
--- a/sys/conf/param.c
+++ b/sys/conf/param.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)param.c 7.20 (Berkeley) 6/27/91
- * $Id: param.c,v 1.9.2.1 1994/05/04 07:44:02 rgrimes Exp $
+ * $Id: param.c,v 1.10 1994/05/04 08:22:05 rgrimes Exp $
*/
#include "sys/param.h"
diff --git a/sys/i386/doc/Changes b/sys/doc/Changes
index 590f087f85bf..685f1f3173b5 100644
--- a/sys/i386/doc/Changes
+++ b/sys/doc/Changes
@@ -1,15 +1,90 @@
Hello, Emacs, this is an -*- Indented-Text -*- file!
-$Id: Changes,v 1.15 1994/02/21 23:03:09 rgrimes Exp $
+$Id: Changes,v 1.5 1994/04/20 19:22:38 wollman Exp $
This file is intended to keep track of important kernel and user
changes in FreeBSD between releases. Entries are in reverse
chronological order; userids can be decoded with the chart at the end
of this file.
+---------------
Since 1.1 BETA:
-
+---------------
+
+- I/O clustering is implemented for all block devices. This should
+ substantially improve the performance of disk drives which don't
+ have write-behind caches, especially on IDE drives. (dyson/davidg)
+
+- Allow mbufs to point to other ``external'' objects than just
+ clusters, and add in performance enhancements for NFS from Yuval
+ Yarom. (davidg)
+
+- Yet more VM system improvements. (dyson/davidg)
+ o 4-MB systems should now spend substantially less time in the VM
+ system.
+ o General cleanup and some portability fixes.
+ o A new system process is now responsible for keeping page
+ statistics, rather than making the pagedaemon do it, which was
+ getting impractical. Performance is improved on small-memory
+ machines.
+ o Process resource usage counters are now properly updated for
+ faults and swaps.
+
+- Fixed bugs in truncating mapped files. (dyson/davidg)
+
+- A new version of the interrupt-handler glue code has been added, which
+ is faster and architecturally cleaner than the previous version. The
+ beginnings of better profiling support have also been added. (bde/davidg)
+
+- This file moved from /sys/i386/doc to /sys/doc. (wollman)
+
+- Bounce buffers have been implemented for ISA devices which use
+ DMA (although not all devices can make use of it yet). (davidg/dyson)
+
+- The set*id() functions have been changed (wollman):
+ o A significant security hole involving the POSIX saved uid and gid
+ has been plugged.
+ o The setreuid() and setregid() functions now never change the real
+ ID, but rather only ensure that you will be able to change the
+ EFFECTIVE ID back to what you specified as a real ID. This change
+ breaks the setruid() and setrgid() functions, which were a bad
+ idea in a POSIX environment anyway. Logic taken from 4.4BSD.
+ o The SUGID process flag bit has been implemented as in 4.4, and the
+ `ps' program modified to print it out.
+
+- The scheduling algorithm has been changed to penalize
+ processes that fork a lot, like `make', which should enhance
+ interactive performance during such operations significantly.
+ (davidg/dyson)
+
+- MCLBYTES is now 4096, so each mbuf cluster is given a whole page, in
+ preparation for page flipping. (davidg/dyson)
+
+- More VM system improvements (dyson/davidg):
+ o Pre-faulting of initial pages on process startup and mmap (faster
+ than starting and immediately taking a fault).
+ o Even more efficient physical map (pmap) code.
+ o Pageouts are now clustered, similar to pagein clustering in 1.1.
+ o The pageout code is more efficient and keeps better statistics.
+ o The procfs can now provide more information from the VM system.
+ o Some pager bugs have been fixed.
+
+- Improved IP checksum and bzero routines. (bde/dyson)
+
+- The Mitsumi CD-ROM driver is more careful about recognizing Ethernet
+ cards as CD-ROMs. (jkh)
+
+- `struct tty's now allocated dynamically, and ring buffers can be
+ deallocated. (guido)
+
+
+---------------------------
Between 1.1 BETA and 1.0.2:
+---------------------------
+
+- QIC-40 and QIC-80 tapes are now supported, using the `ft' driver
+ from Jim Babb. (alm/nate)
+
- Improved lpt driver, should no longer lock up when lprm is done on
an active job. Fixed up the probe routine so that it works on most
if not all printers now. (csgr/rgrimes)
@@ -103,12 +178,12 @@ Between 1.1 BETA and 1.0.2:
the lower 640k is reclaimed for system use. This removes
the 640K kernel size limit.
o VM object cache size is now dynamic and a function of the
- kernel 'maxusers' parameter.
+ kernel `maxusers' parameter.
o Memory in the I/O hole is explicitly marked non-cacheable.
- Added 3C509 driver written by Herb Peyerl. (ats/nate)
-- Added a new 'wd' driver which does a much better job of probing, handles
+- Added a new `wd' driver which does a much better job of probing, handles
stray interrupts better, and supports multiple controllers. In addition
this driver supports DOS partitions much better and conforms to ATA specs
much better. NB: configuration lines for this driver are different
@@ -117,7 +192,7 @@ Between 1.1 BETA and 1.0.2:
- Added support in the if_ed driver for the Toshiba ethernet cards.The
support must be enabled with an "options TOSH_ETHER" in the config
- file. Done it this way, because i don't know how widespread the cards
+ file. Done it this way, because I don't know how widespread the cards
are. (ats)
- Added support in the if_ed driver for the SMC Ultra via patches from
@@ -174,17 +249,10 @@ Between 1.1 BETA and 1.0.2:
- Make it possible to mmap(2) /dev/mem. (julian)
-Between 1.0.2 and 1.0:
-
-Between 1.0 EPSILON and 1.0 GAMMA:
-
-Between 1.0 GAMMA and 1.0 BETA:
-
-Between 1.0 BETA and 1.0 ALPHA:
-
-Between 1.0 ALPHA and Patchkit 0.2.4:
+-----------------------
Userids map as follows:
+-----------------------
ache Andrew Chernov
alm Andrew Moore
ats Andreas Schulz
diff --git a/sys/i386/doc/Makefile b/sys/doc/Makefile
index 67fb36b0ceac..78e3021c3831 100644
--- a/sys/i386/doc/Makefile
+++ b/sys/doc/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.1 1993/11/06 00:07:42 wollman Exp $
+# $Id: Makefile,v 1.1 1994/03/30 20:36:32 wollman Exp $
#
# Makefile for /sys/i386/doc
# This creates options.info and options.doc from options.texi, if the
diff --git a/sys/i386/doc/ata/ata-1 b/sys/doc/ata/ata-1
index 5486217b026b..5486217b026b 100644
--- a/sys/i386/doc/ata/ata-1
+++ b/sys/doc/ata/ata-1
diff --git a/sys/i386/doc/ata/ata-10 b/sys/doc/ata/ata-10
index f4c0336944d4..f4c0336944d4 100644
--- a/sys/i386/doc/ata/ata-10
+++ b/sys/doc/ata/ata-10
diff --git a/sys/i386/doc/ata/ata-11 b/sys/doc/ata/ata-11
index bba6a1073cc8..bba6a1073cc8 100644
--- a/sys/i386/doc/ata/ata-11
+++ b/sys/doc/ata/ata-11
diff --git a/sys/i386/doc/ata/ata-2 b/sys/doc/ata/ata-2
index bad2d9eea869..bad2d9eea869 100644
--- a/sys/i386/doc/ata/ata-2
+++ b/sys/doc/ata/ata-2
diff --git a/sys/i386/doc/ata/ata-3 b/sys/doc/ata/ata-3
index 54645e040b7f..54645e040b7f 100644
--- a/sys/i386/doc/ata/ata-3
+++ b/sys/doc/ata/ata-3
diff --git a/sys/i386/doc/ata/ata-4 b/sys/doc/ata/ata-4
index 0c2fb638ce8d..0c2fb638ce8d 100644
--- a/sys/i386/doc/ata/ata-4
+++ b/sys/doc/ata/ata-4
diff --git a/sys/i386/doc/ata/ata-5 b/sys/doc/ata/ata-5
index c120a39b3736..c120a39b3736 100644
--- a/sys/i386/doc/ata/ata-5
+++ b/sys/doc/ata/ata-5
diff --git a/sys/i386/doc/ata/ata-6 b/sys/doc/ata/ata-6
index 1bce4866f5b5..1bce4866f5b5 100644
--- a/sys/i386/doc/ata/ata-6
+++ b/sys/doc/ata/ata-6
diff --git a/sys/i386/doc/ata/ata-7 b/sys/doc/ata/ata-7
index 240706912a85..240706912a85 100644
--- a/sys/i386/doc/ata/ata-7
+++ b/sys/doc/ata/ata-7
diff --git a/sys/i386/doc/ata/ata-8 b/sys/doc/ata/ata-8
index f651b6b49326..f651b6b49326 100644
--- a/sys/i386/doc/ata/ata-8
+++ b/sys/doc/ata/ata-8
diff --git a/sys/i386/doc/ata/ata-9 b/sys/doc/ata/ata-9
index 4cd3f6684989..4cd3f6684989 100644
--- a/sys/i386/doc/ata/ata-9
+++ b/sys/doc/ata/ata-9
diff --git a/sys/i386/doc/ata/ata-apx b/sys/doc/ata/ata-apx
index cd8981c58eab..cd8981c58eab 100644
--- a/sys/i386/doc/ata/ata-apx
+++ b/sys/doc/ata/ata-apx
diff --git a/sys/i386/doc/ata/ata-prt b/sys/doc/ata/ata-prt
index 546510bcf6a0..546510bcf6a0 100644
--- a/sys/i386/doc/ata/ata-prt
+++ b/sys/doc/ata/ata-prt
diff --git a/sys/i386/doc/ata/ata-toc b/sys/doc/ata/ata-toc
index 1866f7677596..1866f7677596 100644
--- a/sys/i386/doc/ata/ata-toc
+++ b/sys/doc/ata/ata-toc
diff --git a/sys/i386/doc/ed.relnotes b/sys/doc/ed.relnotes
index d01e21d4c427..c46c26124f8f 100644
--- a/sys/i386/doc/ed.relnotes
+++ b/sys/doc/ed.relnotes
@@ -171,4 +171,4 @@ KNOWN PROBLEMS
on the 16bit boards. This can lead to ring-buffer overruns resulting in
additional lost data during heavy network traffic.
-$Id: ed.relnotes,v 1.4 1993/11/22 11:15:16 davidg Exp $
+$Id: ed.relnotes,v 1.1 1994/03/30 20:36:33 wollman Exp $
diff --git a/sys/doc/memory-test.doc b/sys/doc/memory-test.doc
new file mode 100644
index 000000000000..cda44f7f1a48
--- /dev/null
+++ b/sys/doc/memory-test.doc
@@ -0,0 +1,40 @@
+Message-Id: <199403270118.RAA00584@corbin.Root.COM>
+From: David Greenman <davidg@root.com>
+To: "Jordan K. Hubbard" <jkh@whisker.hubbard.ie>
+Cc: csgr@alpha.ru.ac.za, freebsd-hackers@freefall.cdrom.com
+Subject: Re: Boune Buffers : Crash and Burn ^&%$&&^%
+Date: Sat, 26 Mar 1994 17:18:04 -0800
+
+>Ummm. I suppose it would be stupid to wonder whether or not this is good
+>memory you just stuck in there? :-) It does raise the point: David - what
+>does your memory test do when it finds memory errors?
+
+ The order of events is like this:
+
+1) Determine amount of memory by looking at CMOS.
+2) Do memory test of this memory, starting at the highest address and going
+backwards.
+3) If a bad page is found, TRUNCATE the physical memory to end just before
+this page. Continue until all memory is tested.
+
+ So all memory past the lowest bad page is ignored. The number of pages that
+were chopped are then reported as # of "bad pages" when the memory information
+is printed. If there aren't any, then nothing is printed.
+ The rationale for not constructing a bit mask and weeding out just the
+pages that test bad is a flimsy one - doing so would have required moving the
+memory test into the machine independant portion of the VM system, and would
+have required much trickier coding. Since the main purpose of this was to
+verify that what the CMOS was telling us was correct, and also to identify
+when there is bad memory, trying to make the best of it when there really is
+some bad memory didn't seem important to me. ..but hey, if somebody wants to
+recode it, I won't complain. :-)
+ The problem that Terry eluded to, but didn't state, is where you test memory
+for the purpose of determining how much you have. This is problematic because
+many memory controllers will generate a fatal NMI when you 'test' non-existant
+memory (i.e. the parity check fails, and the condition is handled less than
+gracefully), and can also happen with some memory controllers that do strange
+address wrapping in the non-existant memory area. Compaq machines are alledged
+to be suseptable to one of these two problems.
+
+-DG
+
diff --git a/sys/doc/options.doc b/sys/doc/options.doc
new file mode 100644
index 000000000000..178eaf0b3c59
--- /dev/null
+++ b/sys/doc/options.doc
@@ -0,0 +1,682 @@
+$Id: options.doc,v 1.10 1994/06/28 14:00:21 jkh Exp $
+
+ This file documents the configuration options available in the
+FreeBSD operating system.
+
+ Copyright (C) 1993, 1994, Garrett A. Wollman. All rights reserved.
+
+ Redistribution and use in source and printed forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice and this list of conditions.
+ 2. Redistributions in printed form must reproduce the above copyright
+ notice, this list of conditions and the following notice of
+ authorship.
+
+ Trademarks are property of their respective owners.
+
+FreeBSD Configuration Options
+*****************************
+
+ This document describes kernel configuration options relevant to the
+FreeBSD operating system between versions 1.1 and 1.2. It is intended
+for readers who already have a general understanding of the process of
+configuring a BSD kernel and wish to get a general overview of the
+meaning of various configuration options. This document covers
+configurable options and pseudo-devices; it is intended that devices may
+be added at a later date.
+
+Options for Subsystems
+**********************
+
+ This chapter discusses options controlling the inclusion of various
+subsystems in FreeBSD. These include things like filesystems,
+networking modules, and whatnot. Remember that options containing
+underscores must be quoted.
+
+`pseudo-device bpfilter NUMBER'
+ The `bpfilter' pseudo-device is the Berkeley Packet Filter,
+ developed by Lawrence Berkeley Labs and based on an earlier packet
+ filter from Stanford. See the `bpf' manual page for more details.
+ The NUMBER given is the maximum number of simultaneous users
+ permitted. (NB: in previous version of BPF, the NUMBER had to be
+ greater than the number of interfaces; this space is now
+ dynamically allocated so this requirement is no longer present.)
+
+`options CCITT'
+ The `CCITT' option enables support for the ITU-T X.25(1980)
+ network-layer protocol. Nobody we know has a direct X.25
+ connection to anything, so this code has never been tested.
+
+ This option will likely be removed in a future release of FreeBSD.
+
+`options "COMPAT_42"'
+ This option is used to disable UDP checksumming. Under ordinary
+ circumstances it should never ever ever be defined; however, if
+ you are stuck trying to communicate with an old 4.2BSD machine, or
+ one running something derived from 4.2 like SunOS 3.5 or Ultrix
+ 2.0, this may be necessary in order to successfully receive UDP
+ packets.
+
+ This option will be replaced by run-time configuration in a future
+ release of FreeBSD.
+
+`options "COMPAT_43"'
+ This option controls a whole host of features, mostly relating to
+ system-call compatibilty with 4.3BSD. At the present time, it
+ should not be turned off, as many utilities and library routines
+ still depend on these obsolescent system calls being present. At
+ some future date, this will probably be split up into two separate
+ options, one for binary compatibility and one for the old but
+ useful system calls.
+
+`options "COMPAT_102"'
+ This option, which is not yet implemented, will control whether
+ certain entry points which were system calls in FreeBSD 1.0.2 but
+ have been replaced with library routines, are supported in the
+ kernel for backwards compatiblity.
+
+`options "DIRECTED_BROADCAST"'
+ If this option is enabled, the kernel will support sending IP
+ broadcast packets to subnets other than the one that the machine
+ is on, and when forwarding will accept such packets. That is to
+ say, if your host lives on subnets `132.198.3' and `132.198.4',
+ and the `132.198.3' side receives a packet addressed to
+ `132.198.4.255', it will forward the packet as a broadcast on that
+ subnet.
+
+ This option will likely be replaced by run-time configuration in a
+ future release of FreeBSD.
+
+`options "DISKLABEL_UNPROTECTED"'
+ This options disables the checks which normally protects the
+ disklabel from being overwritten. This allows dd of=/dev/rwd0d
+ if=file bs=8k to restore an diskimage.
+
+`pseudo-device ether'
+ This pseudo-device provides link-layer support for Ethernet device
+ drivers. It is mandatory for all systems which include Ethernet or
+ Ethernet-like devices, such as `ed', `ie', and `is'. This code is
+ due for a redesign.
+
+`options EON'
+`pseudo-device eon'
+ The `eon' network interface supports the ISO 8473
+ Connectionless-Mode Network Protocol, tunnelled through IP version
+ 4. `eon' interfaces are created automatically once initially
+ configured by adding ISO routes with IP destinations. At present,
+ both the pseudo-device and option declaration are necessary.
+
+ This option will likely be removed in a future release of FreeBSD.
+
+`options FIFO'
+ This option enables support for System V- and POSIX-style named
+ pipes or fifos.
+
+`options GATEWAY'
+`options IPFORWARDING=VALUE'
+`options IPSENDREDIRECTS=VALUE'
+ These three options control whether FreeBSD's IP forwarding
+ functions are enabled. Technically speaking, because FreeBSD does
+ not meet the standards set out in the "Router Requirements"
+ document (RFC 1009), these should not be enabled, but sometimes it
+ is necessary to enable this function. The `GATEWAY' option turns
+ on `IPFORWARDING', and also controls the sizing of certain system
+ tables. The `IPFORWARDING' option controls the initial value of
+ the `ipforwarding' kernel variable (default 1 if `GATEWAY'
+ defined, 0 otherwise), which controls whether packets are acutally
+ forwarded or not; VALUE should be either `0' or `1'.
+ `IPSENDREDIRECTS' controls the initial value of the
+ `ipsendredirects' variable (default is one, but should be changed
+ to zero); its VALUE should also be either `0' or `1'.
+
+ This option will be replaced by run-time configuration in a future
+ release of FreeBSD.
+
+`options INET'
+ This option controls the inclusion of the Internet protocol suite,
+ including IP version 4, TCP, UDP, and ICMP. Support for IP
+ multicast, IP next generation, and IGMP will be provided at a
+ future date. It is not recommended to even attempt to generate a
+ system with this option turned off, as many parts of the system
+ depend on Internet networking in important and subtle ways.
+
+`options ISO'
+`options TPIP'
+ These options control the inclusion of ISO OSI networking
+ protocols. The TPIP option includes just enough support to run
+ ISO Transport Protocol class 4 over IP, supporing the
+ `SOCK_SEQPACKET' abstraction. The ISO option includes support for
+ CLNP, TP class 0, ISO 9542 ESIS, and IEEE 802.2 logical link
+ control class 0 (for CLNP only).
+
+ This option will likely be removed in a future release of FreeBSD.
+
+`options ISOFS'
+ The `ISOFS' option enables kernel support for the ISO 9660 CD-ROM
+ filesystem, including RockRidge extensions.
+
+`options "ISO_X25ESIS"'
+ This option controls whether ISO 9542 ESIS is run over ITU-T X.25
+ link layers. This requires the `CCITT' option to be enabled as
+ well.
+
+ This option will likely be removed in a future release of FreeBSD.
+
+`options KTRACE'
+ This option enables the tracing of several classes of internal
+ kernel events. See the `ktrace' command for more details.
+ Recommended.
+
+`pseudo-device log'
+ The `log' pseudo-device provides kernel support to send kernel
+ messages to `syslog'. It is mandatory.
+
+`pseudo-device loop'
+ The `loop' pseudo-device provides the trivial network interface.
+ It is required when any networking options are enabled.
+
+`options MACHVMCOMPAT'
+ This option enables a Mach-compatible interface to the virtual
+ memory subsystem, supporting system calls `vm_allocate',
+ `vm_deallocate', `vm_inherit', and `vm_protect'. (Given the
+ nature of the VM system, it is impossible to support a Mach-style
+ `vm_region' call, and in every case the `map' argument is ignored
+ and replaced with the calling process's own map.)
+
+`options MFS'
+ This option enables support for the memory filesystem, an in-core
+ filesystem which lives in the swap area. Using MFS as a `/tmp'
+ filesystem can dramatically increase the speed of
+ temporary-space-intensive operations such as compilations. See the
+ `mount_mfs' manual page for more details.
+
+`options MULTICAST'
+ Enable multicast support for things like vat, nv, etc.
+
+`options MROUTING'
+ Enable multicast routing support (generally goes hand-in-hand with
+ the above). See also mrouted(1).
+
+`options NFS'
+ The `NFS' option enables support for Sun's Network File System.
+ (Also called "Nightmare" or "Not a"....) This presently includes
+ both client- and server-side kernelized NFS support; it may in the
+ future be broken into separate options. This NFS implmentation
+ comes to BSD courtesy of Rick Macklem of the University of Guelph,
+ and is not derived from Sun licensed source code. As a result,
+ there are sometimes interoperability problems where the published
+ specification is vague, and this option supports several new and
+ useful features compared to Sun's. See the `mount' manual page
+ for more details.
+
+`options NS'
+`options NSIP'
+ `NS' controls the inclusion of support for the Xerox Network
+ Service protocol family. At the present time, it is not known
+ whether this code even works; testers are welcome. The `NSIP'
+ option enables encapsulation of XNS IDP over IP.
+
+ These options will likely be removed in a future release of
+ FreeBSD.
+
+`options "PANIC_REBOOT_WAIT_TIME=TIME"'
+ This option controls how long the system waits after a panic
+ before it reboots. If a TIME of zero is specified, it reboots
+ immediately; otherwise, TIME is the number of seconds to wait
+ before rebooting. If, during the waiting period, a key is hit on
+ the console, the countdown stops and the system will wait for the
+ user to copy down the panic message and hit another key before
+ rebooting.
+
+`options PCFS'
+ This option controls support for mounting MS-DOS disks and disk
+ partitions under FreeBSD. The `pcfs' manual page is presently very
+ bogus.
+
+`pseudo-device ppp NUMBER'
+ The `ppp' pseudo-device provides support for the Internet
+ Point-to-Point protocol (RFC 1351 et seq), implemented as a line
+ discipline over standard serial links. NUMBER should be the
+ number of simultaneous PPP interfaces which will be configured.
+
+`pseudo-device pty NUMBER'
+ This pseudo-device provides support for pseudo-ttys, which are
+ required for `rlogin', `telnet', and `xterm' to operate correctly;
+ NUMBER should be set to the total number of these programs you
+ expect to have running at any given time. Because pty's are not
+ as yet dynamically allocated, and the underlying structures are
+ large, it is best to keep this value as small as feasible, until
+ this deficiency is remedied.
+
+`options QUOTA'
+ The `QUOTA' option enables support for disk quotas. Note that NFS
+ quota support is not available.
+
+`pseudo-device sl NUMBER'
+ This pseudo-device provides support for the Serial Line Internet
+ Protocol (RFC 1055), implemented as a line discipline over standard
+ serial links. It includes support for Van Jacobson header
+ compression. NUMBER should be the number of simultaneous SLIP
+ interfaces which will be configured. See also the `slattach'
+ manual page.
+
+`options SYSVSHM'
+`options SYSVSEM'
+`options SYSVMSG'
+`options SHMMAXPGS=VALUE'
+ The `SYSVSHM' option enables kernel-side emulation of System
+ V-compatible shared memory. The `SHMMAXPGS' option (default 64
+ pages or 256K) determines the maximum amount of shared memory
+ available under this mechanism. The `SYSVSEM' option provides
+ emulation of System V-compatible semaphores, and likewise
+ `SYSVMSG' for message queues.
+
+`options "TCP_COMPAT_42"'
+ This option controls the perpetuation of several bugs inherited
+ from the 4.2BSD implementation of TCP. It should only be defined
+ in the circumstances outlined for `COMPAT_42', above.
+
+ This option will likely be replaced by run-time configuration in a
+ future release of FreeBSD.
+
+`pseudo-device tun'
+ The `tun' driver provides a network interface which is attached to
+ a character device. In this way, a user-mode program can grab
+ packets out of the networking system, fiddle with them or move
+ them around, and pass stuff packets back up into the kernel. It
+ is not known if this device either compiles or operates correctly,
+ although it was believed to do both at some time in the past.
+
+`options UCONSOLE'
+ This option allows any old user to grab kernel output away from the
+ console and send it to the tty of their choice. It presents an
+ incredile security hole for some systems, but is necessary in
+ order to allow programs like `xconsole' to operate.
+
+`options XSERVER'
+ This obsolescent option enables support in the `pc' console driver
+ for certain operations required by the XFree86 server.
+
+Performace and Debugging Options
+********************************
+
+ The following options are provided for system performace
+optimization. Note that kernel profiling is supported via the `-p'
+option to the `config' command; for more information see the `config'
+manual page.
+
+`psuedo-device ddb'
+ This option enables the `ddb' debugger, taken from Mach. See the
+ `ddb' and `dbsym' manual pages for more information on the use of
+ this debugger.
+
+`options DIAGNOSTIC'
+`options NAMEI_DIAGNOSTIC'
+`options PARANOID'
+ These debugging options reduce performace. They are intended to
+ enable certain internal consistency checks which are not supposed
+ to fail during correct operation, and so are normally disabled for
+ performace reasons.
+
+`options FASTLINKS'
+ The `FASTLINKS' option enables the creation of symbolic links whose
+ target names reside entirely within the i-node of the link, when
+ possible. This results in faster access for those links which are
+ short enough (in practice, most of them). All kernels can read
+ such links, but only `FASTLINKS' kernels will create them, for
+ compatibility with older kernels lacking such support.
+
+`options ICMPPRINTFS'
+ This option is defined to allow debugging of ICMP ("Internet
+ Control Message Protocol") packets in the kernel. When defined
+ and the `icmpprintfs' kernel variable (default false) is set to
+ true, ICMP packets will be printed out to the console when
+ received. Note that it is probably better to use `tcpdump' for
+ this kind of debugging.
+
+`options KGDB'
+ The `KGDB' option enables certain bits of kernel code which will
+ eventually be able to talk to a remote copy of the `gdb' debugger
+ over a serial connection. The present code does not work, but
+ users are invited to hack on it and contribute the changes back to
+ the FreeBSD team.
+
+`options MAXMEM=SIZE'
+ The `MAXMEM' option controls how much memory the kernel will
+ recognize on bootup, specified in kilobytes. This may be useful
+ for dealing with certain broken attachment busses (or the adapters
+ thereon) which are unable to deal with memory beyond a certain
+ address.
+
+`options SUBNETSARELOCAL'
+ This option controls whether the TCP system believes that machines
+ on other subnets of your network are considered to be "local" to
+ your host. For most systems, this option should be on (the
+ default); if you are directly connected to a class A network,
+ however, then it may need to be turned off. (This is true of
+ networks like the MILNET.)
+
+`options "SYMTAB_SPACE=VALUE"'
+ This obsolescent option controls the amount of space that will be
+ statically allocated in the debugger source code to hold the kernel
+ symbol table that `dbsym' sticks there. Eventually this will be
+ dynamically allocated at load time. The default VALUE is 63000
+ bytes.
+
+`options "UPDATE_INTERVAL=VALUE"'
+ This option controls the wait time between successive `sync'
+ operations run by the `update' system process (pid 3). This option
+ will be replaced by run-time configuration in a future release of
+ FreeBSD.
+
+`options DUMMY_NOPS'
+ This option controls the use of real Nops for bus operations.
+ This might break on older systems so should be used with care.
+
+Device Options
+**************
+
+ There are different device selections available depending on the
+type of bus present in your computer. We will cover generic FreeBSD
+devices, ISA-bus devices, and EISA-bus devices. A separate section
+describes the devices available in the SCSI subsystem.
+
+Generic Devices and Options
+===========================
+
+ The following devices and options are available in all FreeBSD
+configurations. In addition to these devices, a selection of ISA
+devices (*note ISA::.) is required in order to generate a workable
+system.
+
+`machine "i386"'
+ This mandatory declaration informs the `config' program that you
+ are using an i386 or compatible CPU, and enables the selection of
+ all the other devices listed here.
+
+`cpu "I386_CPU"'
+`cpu "I486_CPU"'
+ These two options control which specific CPUs will be supported by
+ the generated kernel. If the kernel detects that it is not
+ running on a CPU for which support was enabled, it will panic
+ quickly upon startup. If you do not expect to need to run your
+ kernel on an i386 or similar CPU, leaving out that support can
+ increase virtual memory system performance.
+
+`options "MATH_EMULATE"'
+ When this option is defined, the math coprocessor emulator is
+ compiled into the kernel. When it is not defined and the
+ coprocessor is absent, programs which use floating-point
+ operations are automatically killed.
+
+`device npx0 at isa? port "IO_NPX" irq 13 vector npxintr'
+ The `npx' device provides support for the i387 numeric coprocessor
+ and the floating-point portions of the i486 CPU. This will
+ eventually be fixed to not require ISA to be configured.
+
+`pseudo-device speaker'
+ The `speaker' pseudo-device provides support for rudimentary access
+ to the PC's speaker via `/dev/spkr'. It provides a
+ character-device interface which interprets `PLAY' strings similar
+ to IBM PC Advanced BASIC, as well as an `ioctl' interface with more
+ fine-grained control. See the `spkr' manual page for more
+ information.
+
+ISA-bus Devices and Options
+===========================
+
+ The following options are specific to ISA-bus devices and systems.
+Since the EISA bus is backwards-compatible with the ISA bus, all these
+options also apply to EISA systems. The same goes for VESA Local Bus
+(VL-Bus) systems.
+
+`controller isa0'
+ This *mandatory* declaration must precede any other devices listed
+ in this section. It provides the basic support for the ISA-bus
+ glue logic, including DMA and autoconfiguration.
+
+`controller aha0 at isa? port "IO_AHA0" bio irq 11 drq 5 vector ahaintr'
+`options "TUNE_1542"'
+ The `aha' device supports the Adaptec 154x series of SCSI
+ controllers, and attempts to support other vendors' controllers
+ which claim compatibility with the Adaptec 1542, such as the
+ BusLogic 545. This device is included in the `GENERICAH'
+ distribution kernel. The `scbus' device (*note SCSI::.) is a
+ prerequisite for this device.
+
+ Some older versions of this code would attempt to set the
+ controller's bus access speed to the fastest possible without
+ losing data; we have found that this makes the driver unusable for
+ some users. If you wish to enable this optimization, or if you
+ suspect that your SCSI transfers are running slower than they
+ should, then you can use the `TUNE_1542' option to enable
+ bus-timing detection.
+
+`controller bt0 at isa? port "IO_BT0" bio irq 12 vector btintr'
+ This device supports the Bustek 742 SCSI controller. It is
+ included in the `GENERICBT' distribution kernel; the `scbus' device
+ (*note SCSI::.) is a prerequisite.
+
+`options ALLOW_CONFLICT_IOADDR'
+ Allow devices on the ISA bus to share conflicting IO address
+ spaces. This is generally an error, though things like PS/2 mouse
+ drivers which are implemented seperately from the keyboard driver
+ will require this option to be set. Note that this is almost
+ always sub-optimal, and the current PS/2 mouse driver will, in
+ fact, frequently fight with the keyboard if you try to use them
+ concurrently. Needing this option enabled is a sure sign that you
+ need to consider a different design for your driver.
+
+`options ALLOW_CONFLICT_IRQ'
+ Allow devices on the ISA bus to share conflicting IRQ's. This is
+ often necessary for multiport serial cards which have several
+ devices at the same IRQ. Enable this only with caution!
+
+`options COM_MULTIPORT'
+ This option enables support in the `sio' serial driver for certain
+ multi-port serial boards.
+
+`device ed0 at isa? port 0x280 net irq 5 iomem 0xd8000 vector edintr'
+`device ed1 at isa? port 0x300 net irq 5 iomem 0xd8000 vector edintr'
+ The `ed' network interface driver provides support for the Western
+ Digital/SMC 80x3 series, the 3Com 3c503, and Novell NE1000 and
+ NE2000 series of Ethernet controllers. It automatically detects
+ differences among the various versions of these controllers and
+ adapts appropriately. The `ed1' line shown is for the Novell
+ boards; the `ed0' line is appropriate for all other supported
+ controllers. (The Novell controllers cannot be configured to use
+ port 0x280.)
+
+`controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr'
+`disk fd0 at fdc0 drive 0'
+`disk fd1 at fdc0 drive 1'
+`tape ft0 at fdc0 drive 2'
+ The `fdc' driver provides support for the standard PC floppy-disk
+ controller. The `fd' sub-driver supports 3.5- and 5.25-inch
+ floppy disks in the standard 360KB, 720KB, 1200KB, 1440KB, and
+ 2880KB formats, as well as a number of other formats not supported
+ by DOS. The `ft' driver is available for QIC-80 "floppy tape"
+ support. The drivers support formatting of both tapes and disks.
+ This driver is substantially improved from that shipped in
+ previous releases of FreeBSD.
+
+`device ie0 at isa? port 0x360 net irq 7 iomem 0xd0000 vector ieintr'
+ This network interface driver provides support for the AT&T
+ StarLAN 10 and EN100 family of controllers. Note that the
+ configuration specified here is not the default configuration, but
+ one which attempts to deal with the conflicts that arise in more
+ modern systems. (It is expected that this driver will be expanded
+ in the future to support other similar cards in the manner of
+ `ed'.)
+
+`device is0 at isa? port 0x280 net irq 10 drq 7 vector isintr'
+ The `is' network interface driver supports the Isolan 4141-0 and
+ Isolink 4110 Ethernet controllers.
+
+`device lpt0 at isa? port "IO_LPT1" tty'
+`device lpt0 at isa? port "IO_LPT1" tty irq 7 vector lptintr'
+`device lpt0 at isa? port ? tty irq 7 vector lptintr'
+`device lpt0 at isa? port ? tty'
+ The `lpt' driver provides support for the parallel printer driver
+ accessed as `/dev/lptN' (N=0, 1, ...). The current version of
+ this driver provides support for either polled or interrupt-driven
+ ports, a unification of the `lpt' and `lpa' drivers from FreeBSD
+ 1.1.
+
+ The first and second examples show explicit selection of a port
+ address. If the port is not specified, as in the third and fourth
+ examples, the driver defaults to whatever address the BIOS printer
+ driver would have used. The second and third examples select
+ interrupt-driven I/O; if polled mode is specified, as in the first
+ and fourth examples, it is impossible to enable interrupt-driven
+ access at run time.
+
+ If you receive "ISA strayintr 7" messages correlated with the use
+ of the polled mode of `lpt', chances are that your controller
+ supports interrupt-driven operation, and you should switch to that
+ mode.
+
+`device mcd0 at isa? port 0x300 bio irq 10 vector mcdintr'
+ This device provides support for the Mitsumi non-SCSI CD-ROM drive.
+ Performance is known to be quite slow.
+
+`device pc0 at isa? port "IO_KBD" tty irq 1 vector pcrint'
+`device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr'
+`options NCONS=VALUE'
+`options COMCONSOLE'
+ The `pc' and `sc' devices provide support for the system display
+ and keyboard, which is the default console. There might actually
+ be documentation somewhere for both of these. The `sc' device
+ requires the `NCONS' option to be defined to some value; it
+ represents the number of virtual consoles to be provided by the
+ driver; a reasonable value is 8. One of `pc' or `sc' is presently
+ required unless `COMCONSOLE' is enabled, in which case a serial
+ port is made into the console.
+
+`device psm0 at isa? port "IO_KBD" tty irq 12 vector psmintr'
+ This driver provides support for the IBM-style PS/2 mouse now
+ popular on many PCs. This driver shares an address with the
+ console driver and therefore requires that the option
+ `ALLOW_CONFLICT_IOADDR' also be set. It is also important that
+ the console driver (`pc' or `sc') *preceed* this driver in your
+ kernel configuration file in order to get priority. All in all,
+ this driver is a hack and should really be integrated into the
+ console driver itself, evidence of which can be easily seen when
+ trying to use the mouse and keyboard at the same time in X (try
+ it). Volunteers willing to clean this up and do it properly are
+ most welcome!
+
+`device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr'
+`device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr'
+`device sio2 at isa? port "IO_COM3" tty irq 5 vector siointr'
+`device sio3 at isa? port "IO_COM4" tty irq 9 vector siointr'
+ The `sio' driver provides support for high-speed serial
+ communications using the standard 8250, 16450, and 16550 UART
+ chips. It provides a standard tty interface for these devices as
+ `/dev/ttyUNIT', and, when enabled with the `comcontrol' program, a
+ call-out capability as `/dev/cuaUNIT' (UNIT is two digits,
+ zero-padded in both cases). Certain multi-port systems are also
+ supported.
+
+`device uha0 at isa? port "IO_UHA0" bio irq 14 drq 5 vector uhaintr'
+ This device supports the Ultrastor 14F and related SCSI
+ controllers. It is included in the `GENERICBT' distribution
+ kernel, and requires `scbus' (*note SCSI::.) as a prerequisite.
+ The Ultrastor 24F is not supported.
+
+`controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr'
+`disk wd0 at wdc0 drive 0'
+`disk wd1 at wdc0 drive 1'
+ The `wd' device supports standard ST-506, RLL, ESDI, and IDE hard
+ disks, as controlled by the Western Digital WD100x series of
+ controllers (and compatible hardware). This version is
+ substantially improved from that provided in FreeBSD 1.0.
+
+`device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr'
+ This driver supports Archive QIC-02 and Wangtek QIC-02 and QIC-36
+ cartridge tape controllers.
+
+`device ze0 at isa? port 0x300 net irq 5 iomem 0xd8000 vector zeintr'
+ This driver supports certain PCMCIA ethernet cards. It was
+ originally written for the IBM Credit Card Adapter and has also
+ been tested with the National Semi `InfoMover' PCMCIA card.
+
+EISA-bus Devices and Options
+============================
+
+ There is presently only one EISA-specific device driver.
+
+`controller ahb0 at isa? bio irq 11 vector ahbintr'
+ The `ahb' driver provides support for the Adaptec AHA-174x series
+ of SCSI controllers. This controller is included in the
+ `GENERICAH' distribution kernel, and requires the `scbus' driver
+ (*note SCSI::.) as a prerequisite.
+
+Micro Channel Devices and Options
+=================================
+
+ We don't support Micro Channel right now. Anyone interested in
+working on Micro Channel support should send mail to
+`FreeBSD-Questions@freefall.cdrom.com' for information on how to help.
+
+PCI Devices and Options
+=======================
+
+ We don't support PCI, either. Anyone interested in working on PCI
+support should send mail to `FreeBSD-Questions@freefall.cdrom.com' for
+information on how to help.
+
+The SCSI Subsystem
+==================
+
+ The SCSI subsystem consists of a set of adaptor-specific driver
+routines, which were described in the previous sections, and the generic
+SCSI device drivers, which handle the standardized interactions with
+devices on the SCSI bus.
+
+`device cd0'
+ The `cd' device provides support for CD-ROM drives. Only one `cd'
+ device need be configured, as the driver automatically allocates
+ units for each CD-ROM drive found. Playing of audio CDs is also
+ supported, on drives which support it, through `ioctl' calls.
+ Support for retrieval of CD audio over the SCSI bus is not
+ presently available.
+
+`device ch0'
+ The `ch' driver supports SCSI media changers; this may include
+ tape, removable disk, and CD changers. One `ch' device should be
+ configured for each changer you expect to support.
+
+`device scbus0'
+ This driver forms the core of the SCSI subsystem. It provides the
+ device-independent routines that manage SCSI transactions, keep
+ track of attached devices, and act as glue between
+ SCSI-device-specific drivers and system-specific host adaptors.
+ This device is *mandatory* for all SCSI systems.
+
+`device sd0'
+ The `sd' driver provides access to non-removable SCSI disks. One
+ `sd' device should be defined for each disk you expect to have
+ simultaneously connected to the system.
+
+`device st0'
+ The `st' driver supports generic SCSI tape drives. One `st'
+ device should be defined for each tape drive you wish to access.
+ See the `st' manual page for information about how to manipulate
+ the parameters of this device.
+
+`device uk0'
+ The `uk' driver provides an attachment point for all otherwise
+ unrecognized SCSI devices. You can't actually do anything with
+ such a device, except perhaps send it an inquiry command using the
+ `scsi' program (q.v.).
+
+Internal Use Only
+*****************
+
+ Eventually, this chapter will document some of the kernel manifest
+constants which are not defines, but which can be tweaked in various
+header files.
+
diff --git a/sys/i386/doc/options.texi b/sys/doc/options.texi
index 4313cf009459..7df30b8b442b 100644
--- a/sys/i386/doc/options.texi
+++ b/sys/doc/options.texi
@@ -1,4 +1,10 @@
\input texinfo @c -*- texinfo -*-
+@c -----------------------------------------------------------------------
+@c Thus spoke the elders in days long gone by:
+@c How to edit: use an existing entry as template, keep the file sorted
+@c using the most keyword-ish thing. When done, make sure /usr/gnu/bin
+@c is in your path, run "make" and THEN "cvs commit".
+@c -----------------------------------------------------------------------
@c %**start of header
@setfilename options.info
@settitle Configuration Options for FreeBSD
@@ -10,7 +16,7 @@
@c %**end of header
@ifinfo
-$Id: options.texi,v 1.4.2.1 1994/03/07 01:51:59 rgrimes Exp $
+$Id: options.texi,v 1.11 1994/06/28 06:10:40 jkh Exp $
This file documents the configuration options available in the FreeBSD
operating system.
@@ -33,7 +39,7 @@ Trademarks are property of their respective owners.
@titlepage
@title Configuration Options in FreeBSD
-@subtitle for FreeBSD 1.1
+@subtitle for FreeBSD 1.1.5
@author Garrett A. Wollman
@author FreeBSD Project
@@ -71,12 +77,12 @@ authorship.
@top FreeBSD Configuration Options
This document describes kernel configuration options relevant to the
-FreeBSD operating system version 1.1. It is intended for readers who
-already have a general understanding of the process of configuring a BSD
-kernel and wish to get a general overview of the meaning of various
-configuration options. This document covers configurable options and
-pseudo-devices; it is intended that devices may be added at a later
-date.
+FreeBSD operating system between versions 1.1 and 1.2. It is intended
+for readers who already have a general understanding of the process of
+configuring a BSD kernel and wish to get a general overview of the
+meaning of various configuration options. This document covers
+configurable options and pseudo-devices; it is intended that devices may
+be added at a later date.
@menu
* Subsystems:: Controlling subsystems.
@@ -118,6 +124,8 @@ The @samp{CCITT} option enables support for the ITU-T X.25(1980)
network-layer protocol. Nobody we know has a direct X.25 connection to
anything, so this code has never been tested.
+This option will likely be removed in a future release of FreeBSD.
+
@item options "COMPAT_42"
@findex COMPAT_42
@cindex UDP Checksums
@@ -130,6 +138,9 @@ stuck trying to communicate with an old 4.2BSD machine, or one running
something derived from 4.2 like SunOS 3.5 or Ultrix 2.0, this may be
necessary in order to successfully receive UDP packets.
+This option will be replaced by run-time configuration in a future
+release of FreeBSD.
+
@item options "COMPAT_43"
@findex COMPAT_43
@cindex 4.3 Compatibility
@@ -141,6 +152,16 @@ on these obsolescent system calls being present. At some future date,
this will probably be split up into two separate options, one for binary
compatibility and one for the old but useful system calls.
+@item options "COMPAT_102"
+@findex COMPAT_102
+@cindex FreeBSD 1.0.2 compatibility
+@cindex 1.0.2 Compatibility
+@cindex Compatibility options
+This option, which is not yet implemented, will control whether certain
+entry points which were system calls in FreeBSD 1.0.2 but have been
+replaced with library routines, are supported in the kernel for
+backwards compatiblity.
+
@item options "DIRECTED_BROADCAST"
@findex DIRECTED_BROADCAST
@cindex IP
@@ -153,6 +174,18 @@ on subnets @samp{132.198.3} and @samp{132.198.4}, and the
@samp{132.198.4.255}, it will forward the packet as a broadcast on that
subnet.
+This option will likely be replaced by run-time configuration in a
+future release of FreeBSD.
+
+@item options "DISKLABEL_UNPROTECTED"
+@findex DISKLABEL_UNPROTECTED
+@cindex disk
+@cindex disklabel
+@cindex rawdisk
+This options disables the checks which normally protects the disklabel from
+being overwritten. This allows dd of=/dev/rwd0d if=file bs=8k to restore
+an diskimage.
+
@item pseudo-device ether
@findex ether
@cindex Ethernet
@@ -173,6 +206,8 @@ Connectionless-Mode Network Protocol, tunnelled through IP version 4.
configured by adding ISO routes with IP destinations. At present, both
the pseudo-device and option declaration are necessary.
+This option will likely be removed in a future release of FreeBSD.
+
@item options FIFO
@findex FIFO
@cindex Named pipes
@@ -202,6 +237,9 @@ forwarded or not; @var{value} should be either @samp{0} or @samp{1}.
@samp{ipsendredirects} variable (default is one, but should be changed
to zero); its @var{value} should also be either @samp{0} or @samp{1}.
+This option will be replaced by run-time configuration in a future
+release of FreeBSD.
+
@item options INET
@findex INET
@cindex IP
@@ -230,7 +268,10 @@ These options control the inclusion of ISO OSI networking protocols.
The TPIP option includes just enough support to run ISO Transport
Protocol class 4 over IP, supporing the @samp{SOCK_SEQPACKET}
abstraction. The ISO option includes support for CLNP, TP class 0,
-ISO 9542 ESIS, and IEEE 802.2 logical link control class 0 (for CLNP only).
+ISO 9542 ESIS, and IEEE 802.2 logical link control class 0 (for CLNP
+only).
+
+This option will likely be removed in a future release of FreeBSD.
@item options ISOFS
@findex ISOFS
@@ -248,11 +289,13 @@ filesystem, including RockRidge extensions.
This option controls whether ISO 9542 ESIS is run over ITU-T X.25 link
layers. This requires the @samp{CCITT} option to be enabled as well.
+This option will likely be removed in a future release of FreeBSD.
+
@item options KTRACE
@findex KTRACE
@cindex Kernel tracing
This option enables the tracing of several classes of internal kernel
-events. See the @samp{ktrace} command for more details.
+events. See the @samp{ktrace} command for more details. Recommended.
@item pseudo-device log
@findex log
@@ -286,6 +329,20 @@ filesystem can dramatically increase the speed of
temporary-space-intensive operations such as compilations. See the
@samp{mount_mfs} manual page for more details.
+@item options MULTICAST
+@findex MULTICAST
+@cindex Multicast IP
+@cindex Networking
+Enable multicast support for things like vat, nv, etc.
+
+
+@item options MROUTING
+@findex MROUTING
+@cindex Multicast Routing
+@cindex Networking
+Enable multicast routing support (generally goes hand-in-hand with the
+above). See also mrouted(1).
+
@item options NFS
@findex NFS
@cindex Network File System
@@ -313,16 +370,17 @@ Service protocol family. At the present time, it is not known whether
this code even works; testers are welcome. The @samp{NSIP} option
enables encapsulation of XNS IDP over IP.
-@item options PANICDELAY
-@itemx options PANICWAIT
-@findex PANICDELAY
-@findex PANICWAIT
+These options will likely be removed in a future release of FreeBSD.
+
+@item options "PANIC_REBOOT_WAIT_TIME=@var{time}"
+@findex PANIC_REBOOT_WAIT_TIME
@cindex Kernel panics
-These options control whether the system waits after a panic. This is
-necessary on some systems which do not support crash dumps, so that the
-actual panic message can be read. The @samp{PANICDELAY} option inserts
-a delay of twenty seconds before self-destructing; the @samp{PANICWAIT}
-option instead waits for a key to be pressed on the console.
+This option controls how long the system waits after a panic before it
+reboots. If a @var{time} of zero is specified, it reboots immediately;
+otherwise, @var{time} is the number of seconds to wait before rebooting.
+If, during the waiting period, a key is hit on the console, the
+countdown stops and the system will wait for the user to copy down the
+panic message and hit another key before rebooting.
@item options PCFS
@findex PCFS
@@ -395,22 +453,6 @@ under this mechanism. The @samp{SYSVSEM} option provides emulation of
System V-compatible semaphores, and likewise @samp{SYSVMSG} for message
queues.
-@item options RMP
-@findex RMP
-@cindex Remote maintenance protocol
-@cindex Networking domains
-This option should control the inclusion of support for HP's remote
-maintenance protocol, but the source code is not included in FreeBSD at
-present, so enabling it will not result in any good.
-
-@item pseudo-device tb
-@findex tb
-@cindex Tablet line discipline
-The @samp{tb} pseudo-device provides support for the `tablet' line
-discipline. Nobody on the FreeBSD team actually has one of the tablets
-in question, so we have no idea if this actually works or not. It may
-not even compile.
-
@item options "TCP_COMPAT_42"
@findex TCP_COMPAT_42
@cindex 4.2 Compatibility
@@ -420,6 +462,9 @@ This option controls the perpetuation of several bugs inherited from the
4.2BSD implementation of TCP. It should only be defined in the
circumstances outlined for @samp{COMPAT_42}, above.
+This option will likely be replaced by run-time configuration in a
+future release of FreeBSD.
+
@item pseudo-device tun
@findex tun
@cindex Network interfaces
@@ -436,20 +481,7 @@ to do both at some time in the past.
This option allows any old user to grab kernel output away from the
console and send it to the tty of their choice. It presents an
incredile security hole for some systems, but is necessary in order to
-allow programs like @samp{xconsole} to operate. (The alternative,
-making @samp{xconsole} set-uid root, opens the exact same security
-hole.)
-
-@item options XE
-@findex XE
-@cindex X.25
-@cindex IEEE 802.2 LLC
-@cindex Network interfaces
-@cindex Ethernet
-This option should control the inclusion of support for running X.25
-over IEEE 802.2 LLC class 2, but that code was not included in the
-Networking/2 release, so enabling it will disable kernel compilation.
-Requires @samp{CCITT}.
+allow programs like @samp{xconsole} to operate.
@item options XSERVER
@findex XSERVER
@@ -521,16 +553,12 @@ over a serial connection. The present code does not work, but users are
invited to hack on it and contribute the changes back to the FreeBSD
team.
-@item options MCLSHIFT=@var{value}
-@findex MCLSHIFT
-@cindex Network parameters
-This option controls the number of bytes in an mbuf cluster, which is
-one of the basic units through which network data is managed. It is
-equal to the log base two of @samp{MCLBYTES}, the size of an mbuf
-cluster, and defaults to eleven (for an @samp{MCLBYTES} of 2048). It
-will likely eventually be bumped up to twelve (4096), so that the
-network code can take advantage of page flipping to reduce the numer of
-copies necessary.
+@item options MAXMEM=@var{size}
+@findex MAXMEM
+The @samp{MAXMEM} option controls how much memory the kernel will
+recognize on bootup, specified in kilobytes. This may be useful for
+dealing with certain broken attachment busses (or the adapters thereon)
+which are unable to deal with memory beyond a certain address.
@item options SUBNETSARELOCAL
@findex SUBNETSARELOCAL
@@ -551,6 +579,21 @@ statically allocated in the debugger source code to hold the kernel
symbol table that @samp{dbsym} sticks there. Eventually this will be
dynamically allocated at load time. The default @var{value} is 63000
bytes.
+
+@item options "UPDATE_INTERVAL=@var{value}"
+@findex UPDATE_INTERVAL
+@cindex Update process
+This option controls the wait time between successive @samp{sync}
+operations run by the @samp{update} system process (pid 3). This option
+will be replaced by run-time configuration in a future release of
+FreeBSD.
+
+@item options DUMMY_NOPS
+@findex DUMMY_NOPS
+@cindex Fast i/o bus operations
+This option controls the use of real Nops for bus operations.
+This might break on older systems so should be used with care.
+
@end table
@node Devices, Internals, Performance, Top
@@ -637,7 +680,9 @@ listed in this section. It provides the basic support for the ISA-bus
glue logic, including DMA and autoconfiguration.
@item controller aha0 at isa? port "IO_AHA0" bio irq 11 drq 5 vector ahaintr
+@item options "TUNE_1542"
@findex aha
+@findex TUNE_1542
@cindex Adaptec 154x
@cindex SCSI host adaptors
The @samp{aha} device supports the Adaptec 154x series of SCSI
@@ -647,6 +692,13 @@ This device is included in the @samp{GENERICAH} distribution kernel.
The @samp{scbus} device (@pxref{SCSI}) is a prerequisite for this
device.
+Some older versions of this code would attempt to set the controller's
+bus access speed to the fastest possible without losing data; we have
+found that this makes the driver unusable for some users. If you wish
+to enable this optimization, or if you suspect that your SCSI transfers
+are running slower than they should, then you can use the @samp{TUNE_1542}
+option to enable bus-timing detection.
+
@item controller bt0 at isa? port "IO_BT0" bio irq 12 vector btintr
@findex bt
@cindex Bustek 742
@@ -655,14 +707,27 @@ This device supports the Bustek 742 SCSI controller. It is included in
the @samp{GENERICBT} distribution kernel; the @samp{scbus} device
(@pxref{SCSI}) is a prerequisite.
-@item options COM_BIDIR
-@findex COM_BIDIR
-@cindex Bi-directional serial ports
-@cindex Serial ports
-This option enables bi-directional support in the @samp{sio} serial
-driver. This option is slated for removal, at which time bi-directional
-support will always be enabled. See the @samp{comcontrol} manual page
-for more information.
+@item options ALLOW_CONFLICT_IOADDR
+@findex ALLOW_CONFLICT_IOADDR
+@cindex Allow IO Address Conflict
+@cindex ISA device management
+Allow devices on the ISA bus to share conflicting IO address spaces.
+This is generally an error, though things like PS/2 mouse drivers which
+are implemented seperately from the keyboard driver will require this
+option to be set. Note that this is almost always sub-optimal, and the
+current PS/2 mouse driver will, in fact, frequently fight with the
+keyboard if you try to use them concurrently. Needing this option
+enabled is a sure sign that you need to consider a different design for
+your driver.
+
+@item options ALLOW_CONFLICT_IRQ
+@findex ALLOW_CONFLICT_IRQ
+@cindex Allow IRQ Conflict
+@cindex ISA device management
+
+Allow devices on the ISA bus to share conflicting IRQ's. This is often
+necessary for multiport serial cards which have several devices at the
+same IRQ. Enable this only with caution!
@item options COM_MULTIPORT
@findex COM_MULTIPORT
@@ -742,21 +807,31 @@ Isolink 4110 Ethernet controllers.
@c source tree. When it is made available, this information will be
@c updated.
-@item device lpa0 at isa? port "IO_LPT1" tty
+@item device lpt0 at isa? port "IO_LPT1" tty
@itemx device lpt0 at isa? port "IO_LPT1" tty irq 7 vector lptintr
+@itemx device lpt0 at isa? port ? tty irq 7 vector lptintr
+@itemx device lpt0 at isa? port ? tty
@findex lpa
@findex lpt
@cindex Parallel printers
-The @samp{lpa} device provides support for the parallel printer driver
-accessed as @file{/dev/lp}. The @samp{lpt} driver provides the same
-functionality, but only works with those printer controllers which
-support interrupt-driven operations. If you receive @samp{ISA strayintr
-7} messages correlated with the use of the @samp{lpa} driver, chances
-are that your controller supports interrupt-driven operation, and you
-should switch to the @samp{lpt} driver.
-The @samp{lpa} driver is obsolete, and will be removed in release 1.2,
-to be replaced by special flags to the @samp{lpt} driver.
+The @samp{lpt} driver provides support for the parallel printer driver
+accessed as @file{/dev/lpt@var{N}} (@var{N}=0, 1, @dots{}). The current
+version of this driver provides support for either polled or
+interrupt-driven ports, a unification of the @samp{lpt} and @samp{lpa}
+drivers from FreeBSD 1.1.
+
+The first and second examples show explicit selection of a port address.
+If the port is not specified, as in the third and fourth examples, the
+driver defaults to whatever address the BIOS printer driver would have
+used. The second and third examples select interrupt-driven I/O; if
+polled mode is specified, as in the first and fourth examples, it is
+impossible to enable interrupt-driven access at run time.
+
+If you receive ``ISA strayintr 7'' messages correlated with the use of
+the polled mode of @samp{lpt}, chances are that your controller supports
+interrupt-driven operation, and you should switch to that mode.
+
@item device mcd0 at isa? port 0x300 bio irq 10 vector mcdintr
@findex mcd
@@ -786,9 +861,24 @@ actually be documentation somewhere for both of these. The @samp{sc}
device requires the @samp{NCONS} option to be defined to some value; it
represents the number of virtual consoles to be provided by the driver;
a reasonable value is 8. One of @samp{pc} or @samp{sc} is presently
-required unless @samp{COMSONSOLE} is enabled, in which case a serial
+required unless @samp{COMCONSOLE} is enabled, in which case a serial
port is made into the console.
+@item device psm0 at isa? port "IO_KBD" tty irq 12 vector psmintr
+@findex psm
+@cindex PS/2 mouse
+@cindex Mouse
+This driver provides support for the IBM-style PS/2 mouse now popular
+on many PCs. This driver shares an address with the console driver
+and therefore requires that the option @samp{ALLOW_CONFLICT_IOADDR}
+also be set. It is also important that the console driver
+(@samp{pc} or @samp{sc}) *preceed* this driver in your kernel configuration
+file in order to get priority. All in all, this driver is a hack and
+should really be integrated into the console driver itself, evidence of
+which can be easily seen when trying to use the mouse and keyboard at the
+same time in X (try it). Volunteers willing to clean this up and do it
+properly are most welcome!
+
@c sb, anyone?
@item device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
@@ -844,6 +934,16 @@ that provided in FreeBSD 1.0.
@cindex Quarter-Inch-Cartridge (QIC) tape drives
This driver supports Archive QIC-02 and Wangtek QIC-02 and QIC-36
cartridge tape controllers.
+
+@item device ze0 at isa? port 0x300 net irq 5 iomem 0xd8000 vector zeintr
+@findex ze
+@cindex Ethernet
+@cindex Network Interfaces
+@cindex PCMCIA
+@cindex PCMCIA Ethernet Cards
+This driver supports certain PCMCIA ethernet cards. It was originally
+written for the IBM Credit Card Adapter and has also been tested
+with the National Semi `InfoMover' PCMCIA card.
@end table
@node EISA, MCA, ISA, Devices
diff --git a/sys/doc/seagate.doc b/sys/doc/seagate.doc
new file mode 100644
index 000000000000..b22f2c9bca4e
--- /dev/null
+++ b/sys/doc/seagate.doc
@@ -0,0 +1,125 @@
+This is a low level driver for Seagate ST01/02, Future Domain TMC-885, TMC-950
+SCSI host adapter that uses Julian Elishers SCSI code.
+
+This driver is the result of looking at code written by the following people:
+
+ Drew Eckhardt
+ Julian Elischer
+ Glen Overby
+ Gary Close
+
+Special thank to
+
+ Robert Knier
+
+that made the fast blind transfer routines, and also helped with debugging.
+
+I am very grateful to these people.
+
+
+Operating system requirements:
+
+This driver uses the latest version of Julian Elischers scsi code, available
+at FreeBSD.cdrom.com in the file called newscsi3.tar.gz. The driver has been
+tested on FreeBSD 1.1-BETA, FreeBSD 1.0.2, 386bsd 0.1. I don't know if will
+work with NetBSD. (I hope it will.)
+
+
+The hardware:
+
+The ST01/02, and Future Domain 950 are very simple SCSI controllers. They are
+not busmastering, so the processor must do all transfers a la IDE. They support
+blind transfer by adding wait states (up to a certain limit). Interrupt is
+generated for reconnect and parity errors (maybe also for some other events).
+
+The card consists of one command port that writes to scsi control lines, reads
+status lines, and a data port that read/writes to the 8 data lines. The address
+decoding gives both data and control ports large memory areas to a single
+port. This is used by the code.
+
+The ST01/02 differs from the FD950 in memory address location and SCSI id.
+
+Probing for the card:
+
+A card is recognized by comparing the BIOS signature with known signatures. A
+new card may not be recognized if the BIOS signature has changed. Please send
+new signatures to me.
+
+Driver function:
+
+A scsi command is sent to scsi_cmd function. The command is either placed in
+the queue or an retryable message is returned. The routine may wait for
+completion of the command depending on the supplied flags. A timer is started
+for every command placed in the queue. The commands are added in the order they
+are received. There is a possiblity to make all REQUEST SENSE commands be
+queued before all other commands, but I dont think it is a good thing (Linux
+do however use this).
+
+The card is mostly controlled by the sea_main function. It is called by
+scsi_cmd, the interrupt routine, and the timeout routine. The sea_main routine
+runs as long there are something to do (transfer data, issue queued commands,
+and handle reconnected commands).
+
+The data transfers may be done in two different ways: Blind and polled
+transfers. They differ in the way the driver does it handshaking with the
+target. During a blind transfer, the driver code blindly transfers a block
+of data without checking for changed phase. During polled transfers, the
+phase is checked between every character transfered. The polled transfers
+are always used for status information and command transfers.
+
+Because the card does not use dma in any way, there is no need to handle
+physical addresses. There is no problem with the isa-bus address limit of
+16MB, making bounce-buffers unnecessary.
+
+The data structures:
+
+Every card has a sea_data structure keeping the queues of commands waiting to
+be issued, and commands currently disconnected. The type of card (Seagate or
+Future Domain), data and control port addresses, scsi id, busy flags for all
+possible targets, and interrupt vector for the card.
+
+Every scsi command to be issued are stored in a sea_scb structure. It contains
+a flag describing status/error of the command, current data buffer position,
+and number of bytes remaining to be transfered.
+
+
+INSTALLATION
+
+1) Alter defines in /sys/i386/isa/seagate.c if you don't
+ want to use blind transfers and/or disconnects. Please note that
+ interrupts must be enabled on the board if disconnects are used.
+2) Create a new config file in /sys/i386/conf containing defines for Julian's
+ scsi code (see GENERICAH or GENERICBT). Replace the aha or bt controller
+ with:
+ controller sea0 at isa? bio irq 5 iomem 0xC8000 iosiz 0x2000 vector seaintr
+3) config, make depend, make, cp, shutdown -r
+
+You should now have a working kernel booted.
+
+I have tested the code on the following hardware: 386DX 24MHz 8MB AMI BIOS,
+Maxtor 7120A IDE, Seagate ST02, Maxtor LXT340S scsi disk, SONY CDU-8003 cdrom,
+(short test with) WANGTEK 6200HS DAT drive.
+
+
+PROBLEMS
+
+I have had problems getting the ST02 boot using FreeBSD boot floppies. I think
+is some problem with BIOS calls not working. It is unfortunately impossible to
+disconnect the ST02 floppy controller.
+
+I have had problems getting the driver to talk to a 40 MB Seagate disk. I
+don't have access to it any more, so I can't do any more checking on it.
+
+NOTE: The ST02 creates its own description of the disk attached. This is not
+the same as the disk says. This translation problem may cause problems when
+sharing a disk between both DOS and BSD. It is however not impossible.
+
+
+/Kent
+
+
+Kent Palmkvist
+kentp@isy.liu.se
+
+
+$Id: seagate.doc,v 1.1 1994/06/28 15:47:12 jkh Exp $
diff --git a/sys/doc/sound.doc b/sys/doc/sound.doc
new file mode 100644
index 000000000000..0c2f10034287
--- /dev/null
+++ b/sys/doc/sound.doc
@@ -0,0 +1,80 @@
+NOTE! Check that there is no #define EXCLUDE_<cardname> lines for
+ the cards you are configuring in the sound/local.h. Otherwise
+ the low level driver for the card is not compiled in the kernel.
+You may add one or more of the following depending on what you do NOT
+want compiled into your kernel. Only use the options for which you
+do NOT have a card to support it, or if you do not want a particular
+functionality.
+
+ options EXCLUDE_AUDIO # NO digital audio support
+ options EXCLUDE_SEQUENCER # NO sequencer support
+ options "EXCLUDE_MPU401" # NO MPU401 support
+ options EXCLUDE_GUS # NO GUS support
+ options EXCLUDE_GUS_IODETECT # NO GUS io detection
+ options EXCLUDE_SB # NO SB support
+ options EXCLUDE_SB_EMULATION # NO PAS SB emulation support
+ options EXCLUDE_SBPRO # NO SB Pro support
+ options "EXCLUDE_SB16" # NO SB 16 support
+ options "EXCLUDE_YM3812" # NO AdLib support
+ options "EXCLUDE_OPL3" # NO OPL3 chip support
+ options EXCLUDE_PAS # NO Pro Audio Studio support
+ options EXCLUDE_PRO_MIDI # NO PAS MIDI support
+ options EXCLUDE_CHIP_MIDI # NO MIDI chip support
+ options EXCLUDE_MIDI # NO MIDI support whatsoever
+
+To enable sound card support, you need to uncomment and add one or more of
+the following lines to your kernel configuration file according to the
+directions below:
+
+#device snd5 at isa? port 0x330 irq 6 vector mpuintr
+#device snd4 at isa? port 0x220 irq 15 drq 6 vector gusintr
+#device snd3 at isa? port 0x388 irq 10 drq 6 vector pasintr
+#device snd2 at isa? port 0x220 irq 7 drq 1 vector sbintr
+#device snd6 at isa? port 0x220 irq 7 drq 5 vector sbintr
+#device snd7 at isa? port 0x300
+#device snd1 at isa? port 0x388
+
+Note for PAS user: you should change snd1 line to
+#device snd1 at isa? port 0x38a
+(next stereo port) to avoid conflict with snd3
+
+ Unit numbers are:
+ 1 for Yamaha FM synth
+ 2 for SB/SB Pro DSP
+ 3 for PAS PCM and Midi
+ 4 for GUS
+ 5 for MPU-401 (there is separate driver for the SB16)
+ 6 for SB16 (DSP)
+ 7 for SB16 Midi (MPU-401 emulation)
+
+ If you have ProAudioSpectrum, uncomment units 3, 2 and 1
+ If you have SoundBlaster 1.0 to 2.0 or SB Pro, uncomment 2 and 1.
+ If you have SoundBlaster 16, uncomment 2, 1, 6 and 7.
+ (use the same IRQ for the cards 2, 6 and 7. The DMA of the
+ card 2 is the 8 bit one and the DMA of the card 6 is the 16 bit one.
+ the port address of the card 7 is the Midi I/O address of the SB16.
+ If you have GravisUltrasound, uncomment 4
+ If you have MPU-401, uncomment 5
+
+NOTE: The MPU-401 driver may or may not work, and is unfortunately
+unverifiable since no one I know has one. If you can test this,
+please let me know! Also note that you will have to change these
+settings if your soundcard is set for a non-standard address or IRQ.
+Please check your documentation (or verify with any provided DOS utilities
+that may have come with your card) and set the IRQ or address fields
+accordingly.
+
+Also: Some systems with the OPTI chipset will require you to #define
+BROKEN_BUS_CLOCK in /sys/i386/sound/pas2_card.c. Symptoms are that
+you will hear a lot of clicking and popping sounds, like a geiger counter,
+coming out of the PAS even when is not playing anything.
+
+Probing problems: Since the SB16 uses the same IRQ and addresses for
+the different drivers, some of the snd dirvers will not be probed because
+the kernel thinks there is a conflict. Until a real solution is implemented,
+to get all the snd drivers to work, immediately return(0) to the haveseen()
+call in /sys/i386/isa/isa.c on your local copy. (Warning: doing this
+will bypass checks for ALL drivers, so be careful)
+
+ - Jordan Hubbard (jkh@freefall.cdrom.com)
+ - Steven Wallace (swallace@freefall.cdrom.com)
diff --git a/sys/i386/doc/vm_layout.doc b/sys/doc/vm_layout.doc
index 3734fd8ab088..6b95bcaf85d6 100644
--- a/sys/i386/doc/vm_layout.doc
+++ b/sys/doc/vm_layout.doc
@@ -29,4 +29,4 @@ PTDI Address pmap.h/param.h Calculation to locate it in vm space
FDC00000 PTmap PTDPTDI << PDRSHIFT
3F7 FDC00000 PTDPTDI #define (KPTDI-1)
-$Id: vm_layout.doc,v 1.6 1993/10/16 19:25:07 rgrimes Exp $
+$Id: vm_layout.doc,v 1.1 1994/03/30 20:36:36 wollman Exp $
diff --git a/sys/i386/doc/wt.doc b/sys/doc/wt.doc
index 1e9f1bafec8a..1e9f1bafec8a 100644
--- a/sys/i386/doc/wt.doc
+++ b/sys/doc/wt.doc
diff --git a/sys/gnu/fpemul/Changelog b/sys/gnu/fpemul/Changelog
new file mode 100644
index 000000000000..a2fbccd15c2c
--- /dev/null
+++ b/sys/gnu/fpemul/Changelog
@@ -0,0 +1,36 @@
+This file contains the changes made to W. Metzenthem's 387 FPU
+emulator to make it work under NetBSD.
+
+a, Changes to make it compile:
+
+ 1 - Changed the #include's to get the appropriate .h files.
+ 2 - Renamed .S to .s, to satisfy the kernel Makefile.
+ 3 - Changed the C++ style // comments to /* */
+ 4 - Changed the FPU_ORIG_EIP macro. A letter from bde included
+ in the package suggested using tf_isp for using instead
+ of the linux __orig_eip. This later turned out to interfere
+ with the user stack, so i created a separate variable, stored
+ in the i387_union.
+ 5 - Changed the get_fs_.. put_fs_.. fns to fubyte,fuword,subyte,
+ suword.
+ 6 - Removed the verify_area fns. I don't really know what they do,
+ i suppose they verify access to memory. The sufu routines
+ should do this.
+
+b, Changes to make it work:
+
+ 1 - Made math_emulate() to return 0 when successful, so trap() won't
+ try to generate a signal.
+ 2 - Changed the size of the save87 struct in /sys/arch/i387/include/
+ npx.h to accomodate the i387_union.
+
+d, Other changes:
+
+ 1 - Removed obsolate and/or linux specific stuff.
+ 2 - Changed the RE_ENTRANT_CHECK_[ON|OFF] macro to
+ REENTRANT_CHECK([ON|OFF]) so indent can grok it.
+ 3 - Re-indented to Berkeley style.
+ 4 - Limited max no of lookaheads. LOOKAHEAD_LIMIT in fpu_entry.c
+
+
+ Szabolcs Szigeti (pink@fsz.bme.hu)
diff --git a/sys/gnu/fpemul/README b/sys/gnu/fpemul/README
new file mode 100644
index 000000000000..0cef6c456fc7
--- /dev/null
+++ b/sys/gnu/fpemul/README
@@ -0,0 +1,277 @@
+/*
+ * wm-FPU-emu an FPU emulator for 80386 and 80486SX microprocessors.
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ */
+
+wm-FPU-emu is an FPU emulator for Linux. It is derived from wm-emu387
+which is my 80387 emulator for djgpp (gcc under msdos); wm-emu387 was
+in turn based upon emu387 which was written by DJ Delorie for djgpp.
+The interface to the Linux kernel is based upon the original Linux
+math emulator by Linus Torvalds.
+
+My target FPU for wm-FPU-emu is that described in the Intel486
+Programmer's Reference Manual (1992 edition). Numerous facets of the
+functioning of the FPU are not well covered in the Reference Manual;
+in the absence of clear details I have made guesses about the most
+reasonable behaviour. Recently, this situation has improved because
+I now have some access to the results produced by a real 80486 FPU.
+
+wm-FPU-emu does not implement all of the behaviour of the 80486 FPU.
+See "Limitations" later in this file for a partial list of some
+differences. I believe that the missing features are never used by
+normal C or FORTRAN programs.
+
+
+Please report bugs, etc to me at:
+ apm233m@vaxc.cc.monash.edu.au
+
+
+--Bill Metzenthen
+ May 1993
+
+
+----------------------- Internals of wm-FPU-emu -----------------------
+
+Numeric algorithms:
+(1) Add, subtract, and multiply. Nothing remarkable in these.
+(2) Divide has been tuned to get reasonable performance. The algorithm
+ is not the obvious one which most people seem to use, but is designed
+ to take advantage of the characteristics of the 80386. I expect that
+ it has been invented many times before I discovered it, but I have not
+ seen it. It is based upon one of those ideas which one carries around
+ for years without ever bothering to check it out.
+(3) The sqrt function has been tuned to get good performance. It is based
+ upon Newton's classic method. Performance was improved by capitalizing
+ upon the properties of Newton's method, and the code is once again
+ structured taking account of the 80386 characteristics.
+(4) The trig, log, and exp functions are based in each case upon quasi-
+ "optimal" polynomial approximations. My definition of "optimal" was
+ based upon getting good accuracy with reasonable speed.
+
+The code of the emulator is complicated slightly by the need to
+account for a limited form of re-entrancy. Normally, the emulator will
+emulate each FPU instruction to completion without interruption.
+However, it may happen that when the emulator is accessing the user
+memory space, swapping may be needed. In this case the emulator may be
+temporarily suspended while disk i/o takes place. During this time
+another process may use the emulator, thereby changing some static
+variables (eg FPU_st0_ptr, etc). The code which accesses user memory
+is confined to five files:
+ fpu_entry.c
+ reg_ld_str.c
+ load_store.c
+ get_address.c
+ errors.c
+
+----------------------- Limitations of wm-FPU-emu -----------------------
+
+There are a number of differences between the current wm-FPU-emu
+(version beta 1.4) and the 80486 FPU (apart from bugs). Some of the
+more important differences are listed below:
+
+All internal computations are performed at 64 bit or higher precision
+and rounded etc as required by the PC bits of the FPU control word.
+Under the crt0 version for Linux current at March 1993, the FPU PC
+bits specify 53 bits precision.
+
+The precision flag (PE of the FPU status word) and the Roundup flag
+(C1 of the status word) are now partially implemented. Does anyone
+write code which uses these features?
+
+The functions which load/store the FPU state are partially implemented,
+but the implementation should be sufficient for handling FPU errors etc
+in 32 bit protected mode.
+
+The implementation of the exception mechanism is flawed for unmasked
+interrupts.
+
+Detection of certain conditions, such as denormal operands, is not yet
+complete.
+
+----------------------- Performance of wm-FPU-emu -----------------------
+
+Speed.
+-----
+
+The speed of floating point computation with the emulator will depend
+upon instruction mix. Relative performance is best for the instructions
+which require most computation. The simple instructions are adversely
+affected by the fpu instruction trap overhead.
+
+
+Timing: Some simple timing tests have been made on the emulator functions.
+The times include load/store instructions. All times are in microseconds
+measured on a 33MHz 386 with 64k cache. The Turbo C tests were under
+ms-dos, the next two columns are for emulators running with the djgpp
+ms-dos extender. The final column is for wm-FPU-emu in Linux 0.97,
+using libm4.0 (hard).
+
+function Turbo C djgpp 1.06 WM-emu387 wm-FPU-emu
+
+ + 60.5 154.8 76.5 139.4
+ - 61.1-65.5 157.3-160.8 76.2-79.5 142.9-144.7
+ * 71.0 190.8 79.6 146.6
+ / 61.2-75.0 261.4-266.9 75.3-91.6 142.2-158.1
+
+ sin() 310.8 4692.0 319.0 398.5
+ cos() 284.4 4855.2 308.0 388.7
+ tan() 495.0 8807.1 394.9 504.7
+ atan() 328.9 4866.4 601.1 419.5-491.9
+
+ sqrt() 128.7 crashed 145.2 227.0
+ log() 413.1-419.1 5103.4-5354.21 254.7-282.2 409.4-437.1
+ exp() 479.1 6619.2 469.1 850.8
+
+
+The performance under Linux is improved by the use of look-ahead code.
+The following results show the improvement which is obtained under
+Linux due to the look-ahead code. Also given are the times for the
+original Linux emulator with the 4.1 'soft' lib.
+
+ [ Linus' note: I changed look-ahead to be the default under linux, as
+ there was no reason not to use it after I had edited it to be
+ disabled during tracing ]
+
+ wm-FPU-emu w original w
+ look-ahead 'soft' lib
+ + 106.4 190.2
+ - 108.6-111.6 192.4-216.2
+ * 113.4 193.1
+ / 108.8-124.4 700.1-706.2
+
+ sin() 390.5 2642.0
+ cos() 381.5 2767.4
+ tan() 496.5 3153.3
+ atan() 367.2-435.5 2439.4-3396.8
+
+ sqrt() 195.1 4732.5
+ log() 358.0-387.5 3359.2-3390.3
+ exp() 619.3 4046.4
+
+
+These figures are now somewhat out-of-date. The emulator has become
+progressively slower for most functions as more of the 80486 features
+have been implemented.
+
+
+----------------------- Accuracy of wm-FPU-emu -----------------------
+
+
+Accuracy: The following table gives the accuracy of the sqrt(), trig
+and log functions. Each function was tested at about 400 points. Ideal
+results would be 64 bits. The reduced accuracy of cos() and tan() for
+arguments greater than pi/4 can be thought of as being due to the
+precision of the argument x; e.g. an argument of pi/2-(1e-10) which is
+accurate to 64 bits can result in a relative accuracy in cos() of about
+64 + log2(cos(x)) = 31 bits. Results for the Turbo C emulator are given
+in the last column.
+
+
+Function Tested x range Worst result (bits) Turbo C
+
+sqrt(x) 1 .. 2 64.1 63.2
+atan(x) 1e-10 .. 200 62.6 62.8
+cos(x) 0 .. pi/2-(1e-10) 63.2 (x <= pi/4) 62.4
+ 35.2 (x = pi/2-(1e-10)) 31.9
+sin(x) 1e-10 .. pi/2 63.0 62.8
+tan(x) 1e-10 .. pi/2-(1e-10) 62.4 (x <= pi/4) 62.1
+ 35.2 (x = pi/2-(1e-10)) 31.9
+exp(x) 0 .. 1 63.1 62.9
+log(x) 1+1e-6 .. 2 62.4 62.1
+
+
+As of version 1.3 of the emulator, the accuracy of the basic
+arithmetic has been improved (by a small fraction of a bit). Care has
+been taken to ensure full accuracy of the rounding of the basic
+arithmetic functions (+,-,*,/,and fsqrt), and they all now produce
+results which are exact to the 64th bit (unless there are any bugs
+left). To ensure this, it was necessary to effectively get information
+of up to about 128 bits precision. The emulator now passes the
+"paranoia" tests (compiled with gcc 2.3.3) for 'float' variables (24
+bit precision numbers) when precision control is set to 24, 53 or 64
+bits, and for 'double' variables (53 bit precision numbers) when
+precision control is set to 53 bits (a properly performing FPU cannot
+pass the 'paranoia' tests for 'double' variables when precision
+control is set to 64 bits).
+
+------------------------- Contributors -------------------------------
+
+A number of people have contributed to the development of the
+emulator, often by just reporting bugs, sometimes with a suggested
+fix, and a few kind people have provided me with access in one way or
+another to an 80486 machine. Contributors include (to those people who
+I have forgotten, please excuse me):
+
+Linus Torvalds
+Tommy.Thorn@daimi.aau.dk
+Andrew.Tridgell@anu.edu.au
+Nick Holloway alfie@dcs.warwick.ac.uk
+Hermano Moura moura@dcs.gla.ac.uk
+Jon Jagger J.Jagger@scp.ac.uk
+Lennart Benschop
+Brian Gallew geek+@CMU.EDU
+Thomas Staniszewski ts3v+@andrew.cmu.edu
+Martin Howell mph@plasma.apana.org.au
+M Saggaf alsaggaf@athena.mit.edu
+Peter Barker PETER@socpsy.sci.fau.edu
+tom@vlsivie.tuwien.ac.at
+Dan Russel russed@rpi.edu
+Daniel Carosone danielce@ee.mu.oz.au
+cae@jpmorgan.com
+Hamish Coleman t933093@minyos.xx.rmit.oz.au
+
+...and numerous others who responded to my request for help with
+a real 80486.
+
diff --git a/sys/gnu/fpemul/control_w.h b/sys/gnu/fpemul/control_w.h
new file mode 100644
index 000000000000..2f3dc2ec854a
--- /dev/null
+++ b/sys/gnu/fpemul/control_w.h
@@ -0,0 +1,95 @@
+/*
+ * control_w.h
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: control_w.h,v 1.3 1994/06/10 07:44:07 rich Exp $
+ *
+ */
+
+#ifndef _CONTROLW_H_
+#define _CONTROLW_H_
+
+#ifdef LOCORE
+#define _Const_(x) $/**/x
+#else
+#define _Const_(x) x
+#endif
+
+#define CW_RC _Const_(0x0C00) /* rounding control */
+#define CW_PC _Const_(0x0300) /* precision control */
+
+#define CW_Precision Const_(0x0020) /* loss of precision mask */
+#define CW_Underflow Const_(0x0010) /* underflow mask */
+#define CW_Overflow Const_(0x0008) /* overflow mask */
+#define CW_ZeroDiv Const_(0x0004) /* divide by zero mask */
+#define CW_Denormal Const_(0x0002) /* denormalized operand mask */
+#define CW_Invalid Const_(0x0001) /* invalid operation mask */
+
+#define CW_Exceptions _Const_(0x003f) /* all masks */
+
+#define RC_RND _Const_(0x0000)
+#define RC_DOWN _Const_(0x0400)
+#define RC_UP _Const_(0x0800)
+#define RC_CHOP _Const_(0x0C00)
+
+/* p 15-5: Precision control bits affect only the following:
+ ADD, SUB(R), MUL, DIV(R), and SQRT */
+#define PR_24_BITS _Const_(0x000)
+#define PR_53_BITS _Const_(0x200)
+#define PR_64_BITS _Const_(0x300)
+/* FULL_PRECISION simulates all exceptions masked */
+#define FULL_PRECISION (PR_64_BITS | RC_RND | 0x3f)
+
+#endif /* _CONTROLW_H_ */
diff --git a/sys/gnu/fpemul/div_small.s b/sys/gnu/fpemul/div_small.s
new file mode 100644
index 000000000000..aff2738fe43f
--- /dev/null
+++ b/sys/gnu/fpemul/div_small.s
@@ -0,0 +1,101 @@
+ .file "div_small.S"
+/*
+ * div_small.S
+ *
+ * Divide a 64 bit integer by a 32 bit integer & return remainder.
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: div_small.s,v 1.3 1994/06/10 07:44:08 rich Exp $
+ *
+ */
+
+/*---------------------------------------------------------------------------+
+ | unsigned long div_small(unsigned long long *x, unsigned long y) |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_asm.h"
+
+.text
+ .align 2,144
+
+.globl _div_small
+
+_div_small:
+ pushl %ebp
+ movl %esp,%ebp
+
+ pushl %esi
+
+ movl PARAM1,%esi /* pointer to num */
+ movl PARAM2,%ecx /* The denominator */
+
+ movl 4(%esi),%eax /* Get the current num msw */
+ xorl %edx,%edx
+ divl %ecx
+
+ movl %eax,4(%esi)
+
+ movl (%esi),%eax /* Get the num lsw */
+ divl %ecx
+
+ movl %eax,(%esi)
+
+ movl %edx,%eax /* Return the remainder in eax */
+
+ popl %esi
+
+ leave
+ ret
+
diff --git a/sys/gnu/fpemul/errors.c b/sys/gnu/fpemul/errors.c
new file mode 100644
index 000000000000..dd8f1b2a1692
--- /dev/null
+++ b/sys/gnu/fpemul/errors.c
@@ -0,0 +1,612 @@
+/*
+ * errors.c
+ *
+ * The error handling functions for wm-FPU-emu
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: errors.c,v 1.3 1994/06/10 07:44:10 rich Exp $
+ *
+ */
+
+/*---------------------------------------------------------------------------+
+ | Note: |
+ | The file contains code which accesses user memory. |
+ | Emulator static data may change when user memory is accessed, due to |
+ | other processes using the emulator while swapping is in progress. |
+ +---------------------------------------------------------------------------*/
+
+
+
+
+
+#include "param.h"
+#include "proc.h"
+#include "machine/cpu.h"
+#include "machine/pcb.h"
+
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "exception.h"
+#include "status_w.h"
+#include "control_w.h"
+#include "reg_constant.h"
+#include "version.h"
+
+/* */
+#undef PRINT_MESSAGES
+/* */
+
+
+void
+Un_impl(void)
+{
+ unsigned char byte1, FPU_modrm;
+
+ REENTRANT_CHECK(OFF);
+ byte1 = fubyte((unsigned char *) FPU_ORIG_EIP);
+ FPU_modrm = fubyte(1 + (unsigned char *) FPU_ORIG_EIP);
+
+ printf("Unimplemented FPU Opcode at eip=%p : %02x ",
+ FPU_ORIG_EIP, byte1);
+
+ if (FPU_modrm >= 0300)
+ printf("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
+ else
+ printf("/%d\n", (FPU_modrm >> 3) & 7);
+ REENTRANT_CHECK(ON);
+
+ EXCEPTION(EX_Invalid);
+
+}
+
+
+
+
+void
+emu_printall()
+{
+ int i;
+ static char *tag_desc[] = {"Valid", "Zero", "ERROR", "ERROR",
+ "DeNorm", "Inf", "NaN", "Empty"};
+ unsigned char byte1, FPU_modrm;
+
+ REENTRANT_CHECK(OFF);
+ byte1 = fubyte((unsigned char *) FPU_ORIG_EIP);
+ FPU_modrm = fubyte(1 + (unsigned char *) FPU_ORIG_EIP);
+
+#ifdef DEBUGGING
+ if (status_word & SW_Backward)
+ printf("SW: backward compatibility\n");
+ if (status_word & SW_C3)
+ printf("SW: condition bit 3\n");
+ if (status_word & SW_C2)
+ printf("SW: condition bit 2\n");
+ if (status_word & SW_C1)
+ printf("SW: condition bit 1\n");
+ if (status_word & SW_C0)
+ printf("SW: condition bit 0\n");
+ if (status_word & SW_Summary)
+ printf("SW: exception summary\n");
+ if (status_word & SW_Stack_Fault)
+ printf("SW: stack fault\n");
+ if (status_word & SW_Precision)
+ printf("SW: loss of precision\n");
+ if (status_word & SW_Underflow)
+ printf("SW: underflow\n");
+ if (status_word & SW_Overflow)
+ printf("SW: overflow\n");
+ if (status_word & SW_Zero_Div)
+ printf("SW: divide by zero\n");
+ if (status_word & SW_Denorm_Op)
+ printf("SW: denormalized operand\n");
+ if (status_word & SW_Invalid)
+ printf("SW: invalid operation\n");
+#endif /* DEBUGGING */
+
+ status_word = status_word & ~SW_Top;
+ status_word |= (top & 7) << SW_Top_Shift;
+
+ printf("At %p: %02x ", FPU_ORIG_EIP, byte1);
+ if (FPU_modrm >= 0300)
+ printf("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
+ else
+ printf("/%d, mod=%d rm=%d\n",
+ (FPU_modrm >> 3) & 7, (FPU_modrm >> 6) & 3, FPU_modrm & 7);
+
+ printf(" SW: b=%d st=%d es=%d sf=%d cc=%d%d%d%d ef=%d%d%d%d%d%d\n",
+ status_word & 0x8000 ? 1 : 0, /* busy */
+ (status_word & 0x3800) >> 11, /* stack top pointer */
+ status_word & 0x80 ? 1 : 0, /* Error summary status */
+ status_word & 0x40 ? 1 : 0, /* Stack flag */
+ status_word & SW_C3 ? 1 : 0, status_word & SW_C2 ? 1 : 0, /* cc */
+ status_word & SW_C1 ? 1 : 0, status_word & SW_C0 ? 1 : 0, /* cc */
+ status_word & SW_Precision ? 1 : 0, status_word & SW_Underflow ? 1 : 0,
+ status_word & SW_Overflow ? 1 : 0, status_word & SW_Zero_Div ? 1 : 0,
+ status_word & SW_Denorm_Op ? 1 : 0, status_word & SW_Invalid ? 1 : 0);
+
+ printf(" CW: ic=%d rc=%d%d pc=%d%d iem=%d ef=%d%d%d%d%d%d\n",
+ control_word & 0x1000 ? 1 : 0,
+ (control_word & 0x800) >> 11, (control_word & 0x400) >> 10,
+ (control_word & 0x200) >> 9, (control_word & 0x100) >> 8,
+ control_word & 0x80 ? 1 : 0,
+ control_word & SW_Precision ? 1 : 0, control_word & SW_Underflow ? 1 : 0,
+ control_word & SW_Overflow ? 1 : 0, control_word & SW_Zero_Div ? 1 : 0,
+ control_word & SW_Denorm_Op ? 1 : 0, control_word & SW_Invalid ? 1 : 0);
+
+ for (i = 0; i < 8; i++) {
+ FPU_REG *r = &st(i);
+ switch (r->tag) {
+ case TW_Empty:
+ continue;
+ break;
+ case TW_Zero:
+ printf("st(%d) %c .0000 0000 0000 0000 ",
+ i, r->sign ? '-' : '+');
+ break;
+ case TW_Valid:
+ case TW_NaN:
+ case TW_Denormal:
+ case TW_Infinity:
+ printf("st(%d) %c .%04x %04x %04x %04x e%+-6d ", i,
+ r->sign ? '-' : '+',
+ (long) (r->sigh >> 16),
+ (long) (r->sigh & 0xFFFF),
+ (long) (r->sigl >> 16),
+ (long) (r->sigl & 0xFFFF),
+ r->exp - EXP_BIAS + 1);
+ break;
+ default:
+ printf("Whoops! Error in errors.c ");
+ break;
+ }
+ printf("%s\n", tag_desc[(int) (unsigned) r->tag]);
+ }
+
+ printf("[data] %c .%04x %04x %04x %04x e%+-6d ",
+ FPU_loaded_data.sign ? '-' : '+',
+ (long) (FPU_loaded_data.sigh >> 16),
+ (long) (FPU_loaded_data.sigh & 0xFFFF),
+ (long) (FPU_loaded_data.sigl >> 16),
+ (long) (FPU_loaded_data.sigl & 0xFFFF),
+ FPU_loaded_data.exp - EXP_BIAS + 1);
+ printf("%s\n", tag_desc[(int) (unsigned) FPU_loaded_data.tag]);
+ REENTRANT_CHECK(ON);
+
+}
+
+static struct {
+ int type;
+ char *name;
+} exception_names[] = {
+ {
+ EX_StackOver, "stack overflow"
+ },
+ {
+ EX_StackUnder, "stack underflow"
+ },
+ {
+ EX_Precision, "loss of precision"
+ },
+ {
+ EX_Underflow, "underflow"
+ },
+ {
+ EX_Overflow, "overflow"
+ },
+ {
+ EX_ZeroDiv, "divide by zero"
+ },
+ {
+ EX_Denormal, "denormalized operand"
+ },
+ {
+ EX_Invalid, "invalid operation"
+ },
+ {
+ EX_INTERNAL, "INTERNAL BUG in " FPU_VERSION
+ },
+ {
+ 0, NULL
+ }
+};
+/*
+ EX_INTERNAL is always given with a code which indicates where the
+ error was detected.
+
+ Internal error types:
+ 0x14 in e14.c
+ 0x1nn in a *.c file:
+ 0x101 in reg_add_sub.c
+ 0x102 in reg_mul.c
+ 0x103 in poly_sin.c
+ 0x104 in poly_tan.c
+ 0x105 in reg_mul.c
+ 0x106 in reg_mov.c
+ 0x107 in fpu_trig.c
+ 0x108 in reg_compare.c
+ 0x109 in reg_compare.c
+ 0x110 in reg_add_sub.c
+ 0x111 in interface.c
+ 0x112 in fpu_trig.c
+ 0x113 in reg_add_sub.c
+ 0x114 in reg_ld_str.c
+ 0x115 in fpu_trig.c
+ 0x116 in fpu_trig.c
+ 0x117 in fpu_trig.c
+ 0x118 in fpu_trig.c
+ 0x119 in fpu_trig.c
+ 0x120 in poly_atan.c
+ 0x121 in reg_compare.c
+ 0x122 in reg_compare.c
+ 0x123 in reg_compare.c
+ 0x2nn in an *.s file:
+ 0x201 in reg_u_add.S
+ 0x202 in reg_u_div.S
+ 0x203 in reg_u_div.S
+ 0x204 in reg_u_div.S
+ 0x205 in reg_u_mul.S
+ 0x206 in reg_u_sub.S
+ 0x207 in wm_sqrt.S
+ 0x208 in reg_div.S
+ 0x209 in reg_u_sub.S
+ 0x210 in reg_u_sub.S
+ 0x211 in reg_u_sub.S
+ 0x212 in reg_u_sub.S
+ 0x213 in wm_sqrt.S
+ 0x214 in wm_sqrt.S
+ 0x215 in wm_sqrt.S
+ 0x216 in reg_round.S
+ 0x217 in reg_round.S
+ 0x218 in reg_round.S
+ */
+
+void
+exception(int n)
+{
+ int i, int_type;
+
+ int_type = 0; /* Needed only to stop compiler warnings */
+ if (n & EX_INTERNAL) {
+ int_type = n - EX_INTERNAL;
+ n = EX_INTERNAL;
+ /* Set lots of exception bits! */
+ status_word |= (SW_Exc_Mask | SW_Summary | FPU_BUSY);
+ } else {
+ /* Extract only the bits which we use to set the status word */
+ n &= (SW_Exc_Mask);
+ /* Set the corresponding exception bit */
+ status_word |= n;
+ if (status_word & ~control_word & CW_Exceptions)
+ status_word |= SW_Summary;
+ if (n & (SW_Stack_Fault | EX_Precision)) {
+ if (!(n & SW_C1))
+ /* This bit distinguishes over- from underflow
+ * for a stack fault, and roundup from
+ * round-down for precision loss. */
+ status_word &= ~SW_C1;
+ }
+ }
+
+ REENTRANT_CHECK(OFF);
+ if ((~control_word & n & CW_Exceptions) || (n == EX_INTERNAL)) {
+#ifdef PRINT_MESSAGES
+ /* My message from the sponsor */
+ printf(FPU_VERSION " " __DATE__ " (C) W. Metzenthen.\n");
+#endif /* PRINT_MESSAGES */
+
+ /* Get a name string for error reporting */
+ for (i = 0; exception_names[i].type; i++)
+ if ((exception_names[i].type & n) == exception_names[i].type)
+ break;
+
+ if (exception_names[i].type) {
+#ifdef PRINT_MESSAGES
+ printf("FP Exception: %s!\n", exception_names[i].name);
+#endif /* PRINT_MESSAGES */
+ } else
+ printf("FP emulator: Unknown Exception: 0x%04x!\n", n);
+
+ if (n == EX_INTERNAL) {
+ printf("FP emulator: Internal error type 0x%04x\n", int_type);
+ emu_printall();
+ }
+#ifdef PRINT_MESSAGES
+ else
+ emu_printall();
+#endif /* PRINT_MESSAGES */
+
+ /* The 80486 generates an interrupt on the next non-control
+ * FPU instruction. So we need some means of flagging it. We
+ * use the ES (Error Summary) bit for this, assuming that this
+ * is the way a real FPU does it (until I can check it out),
+ * if not, then some method such as the following kludge might
+ * be needed. */
+/* regs[0].tag |= TW_FPU_Interrupt; */
+ }
+ REENTRANT_CHECK(ON);
+
+#ifdef __DEBUG__
+ math_abort(SIGFPE);
+#endif /* __DEBUG__ */
+
+}
+
+
+/* Real operation attempted on two operands, one a NaN */
+void
+real_2op_NaN(FPU_REG * a, FPU_REG * b, FPU_REG * dest)
+{
+ FPU_REG *x;
+ int signalling;
+
+ x = a;
+ if (a->tag == TW_NaN) {
+ if (b->tag == TW_NaN) {
+ signalling = !(a->sigh & b->sigh & 0x40000000);
+ /* find the "larger" */
+ if (*(long long *) &(a->sigl) < *(long long *) &(b->sigl))
+ x = b;
+ } else {
+ /* return the quiet version of the NaN in a */
+ signalling = !(a->sigh & 0x40000000);
+ }
+ } else
+#ifdef PARANOID
+ if (b->tag == TW_NaN)
+#endif /* PARANOID */
+ {
+ signalling = !(b->sigh & 0x40000000);
+ x = b;
+ }
+#ifdef PARANOID
+ else {
+ signalling = 0;
+ EXCEPTION(EX_INTERNAL | 0x113);
+ x = &CONST_QNaN;
+ }
+#endif /* PARANOID */
+
+ if (!signalling) {
+ if (!(x->sigh & 0x80000000)) /* pseudo-NaN ? */
+ x = &CONST_QNaN;
+ reg_move(x, dest);
+ return;
+ }
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ if (!(x->sigh & 0x80000000)) /* pseudo-NaN ? */
+ x = &CONST_QNaN;
+ reg_move(x, dest);
+ /* ensure a Quiet NaN */
+ dest->sigh |= 0x40000000;
+ }
+ EXCEPTION(EX_Invalid);
+
+ return;
+}
+/* Invalid arith operation on Valid registers */
+void
+arith_invalid(FPU_REG * dest)
+{
+
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ reg_move(&CONST_QNaN, dest);
+ }
+ EXCEPTION(EX_Invalid);
+
+ return;
+
+}
+
+
+/* Divide a finite number by zero */
+void
+divide_by_zero(int sign, FPU_REG * dest)
+{
+
+ if (control_word & CW_ZeroDiv) {
+ /* The masked response */
+ reg_move(&CONST_INF, dest);
+ dest->sign = (unsigned char) sign;
+ }
+ EXCEPTION(EX_ZeroDiv);
+
+ return;
+
+}
+
+
+/* This may be called often, so keep it lean */
+void
+set_precision_flag_up(void)
+{
+ if (control_word & CW_Precision)
+ status_word |= (SW_Precision | SW_C1); /* The masked response */
+ else
+ exception(EX_Precision | SW_C1);
+
+}
+
+
+/* This may be called often, so keep it lean */
+void
+set_precision_flag_down(void)
+{
+ if (control_word & CW_Precision) { /* The masked response */
+ status_word &= ~SW_C1;
+ status_word |= SW_Precision;
+ } else
+ exception(EX_Precision);
+}
+
+
+int
+denormal_operand(void)
+{
+ if (control_word & CW_Denormal) { /* The masked response */
+ status_word |= SW_Denorm_Op;
+ return 0;
+ } else {
+ exception(EX_Denormal);
+ return 1;
+ }
+}
+
+
+void
+arith_overflow(FPU_REG * dest)
+{
+
+ if (control_word & CW_Overflow) {
+ char sign;
+ /* The masked response */
+/* **** The response here depends upon the rounding mode */
+ sign = dest->sign;
+ reg_move(&CONST_INF, dest);
+ dest->sign = sign;
+ } else {
+ /* Subtract the magic number from the exponent */
+ dest->exp -= (3 * (1 << 13));
+ }
+
+ /* By definition, precision is lost. It appears that the roundup bit
+ * (C1) is also set by convention. */
+ EXCEPTION(EX_Overflow | EX_Precision | SW_C1);
+
+ return;
+
+}
+
+
+void
+arith_underflow(FPU_REG * dest)
+{
+
+ if (control_word & CW_Underflow) {
+ /* The masked response */
+ if (dest->exp <= EXP_UNDER - 63)
+ reg_move(&CONST_Z, dest);
+ } else {
+ /* Add the magic number to the exponent */
+ dest->exp += (3 * (1 << 13));
+ }
+
+ EXCEPTION(EX_Underflow);
+
+ return;
+}
+
+
+void
+stack_overflow(void)
+{
+
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ top--;
+ reg_move(&CONST_QNaN, FPU_st0_ptr = &st(0));
+ }
+ EXCEPTION(EX_StackOver);
+
+ return;
+
+}
+
+
+void
+stack_underflow(void)
+{
+
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ reg_move(&CONST_QNaN, FPU_st0_ptr);
+ }
+ EXCEPTION(EX_StackUnder);
+
+ return;
+
+}
+
+
+void
+stack_underflow_i(int i)
+{
+
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ reg_move(&CONST_QNaN, &(st(i)));
+ }
+ EXCEPTION(EX_StackUnder);
+
+ return;
+
+}
+
+
+void
+stack_underflow_pop(int i)
+{
+
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ reg_move(&CONST_QNaN, &(st(i)));
+ pop();
+ }
+ EXCEPTION(EX_StackUnder);
+
+ return;
+
+}
diff --git a/sys/gnu/fpemul/exception.h b/sys/gnu/fpemul/exception.h
new file mode 100644
index 000000000000..af814f1d5191
--- /dev/null
+++ b/sys/gnu/fpemul/exception.h
@@ -0,0 +1,102 @@
+/*
+ * exception.h
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: exception.h,v 1.3 1994/06/10 07:44:12 rich Exp $
+ *
+ *
+ */
+
+#ifndef _EXCEPTION_H_
+#define _EXCEPTION_H_
+
+
+#ifdef LOCORE
+#define Const_(x) $/**/x
+#else
+#define Const_(x) x
+#endif
+
+#ifndef SW_C1
+#include "fpu_emu.h"
+#endif /* SW_C1 */
+
+#define FPU_BUSY Const_(0x8000) /* FPU busy bit (8087 compatibility) */
+#define EX_ErrorSummary Const_(0x0080) /* Error summary status */
+/* Special exceptions: */
+#define EX_INTERNAL Const_(0x8000) /* Internal error in wm-FPU-emu */
+#define EX_StackOver Const_(0x0041|SW_C1) /* stack overflow */
+#define EX_StackUnder Const_(0x0041) /* stack underflow */
+/* Exception flags: */
+#define EX_Precision Const_(0x0020) /* loss of precision */
+#define EX_Underflow Const_(0x0010) /* underflow */
+#define EX_Overflow Const_(0x0008) /* overflow */
+#define EX_ZeroDiv Const_(0x0004) /* divide by zero */
+#define EX_Denormal Const_(0x0002) /* denormalized operand */
+#define EX_Invalid Const_(0x0001) /* invalid operation */
+
+
+#ifndef LOCORE
+
+#ifdef DEBUG
+#define EXCEPTION(x) { printf("exception in %s at line %d\n", \
+ __FILE__, __LINE__); exception(x); }
+#else
+#define EXCEPTION(x) exception(x)
+#endif
+
+#endif /* LOCORE */
+
+#endif /* _EXCEPTION_H_ */
diff --git a/sys/gnu/fpemul/fpu_arith.c b/sys/gnu/fpemul/fpu_arith.c
new file mode 100644
index 000000000000..0ffb6615e70b
--- /dev/null
+++ b/sys/gnu/fpemul/fpu_arith.c
@@ -0,0 +1,235 @@
+/*
+ * fpu_arith.c
+ *
+ * Code to implement the FPU register/register arithmetic instructions
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: fpu_arith.c,v 1.3 1994/06/10 07:44:14 rich Exp $
+ *
+ */
+
+
+
+
+#include "param.h"
+#include "proc.h"
+#include "machine/cpu.h"
+#include "machine/pcb.h"
+
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "control_w.h"
+
+
+void
+fadd__()
+{
+ /* fadd st,st(i) */
+ reg_add(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word);
+}
+
+
+void
+fmul__()
+{
+ /* fmul st,st(i) */
+ reg_mul(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word);
+}
+
+
+
+void
+fsub__()
+{
+ /* fsub st,st(i) */
+ reg_sub(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word);
+}
+
+
+void
+fsubr_()
+{
+ /* fsubr st,st(i) */
+ reg_sub(&st(FPU_rm), FPU_st0_ptr, FPU_st0_ptr, control_word);
+}
+
+
+void
+fdiv__()
+{
+ /* fdiv st,st(i) */
+ reg_div(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word);
+}
+
+
+void
+fdivr_()
+{
+ /* fdivr st,st(i) */
+ reg_div(&st(FPU_rm), FPU_st0_ptr, FPU_st0_ptr, control_word);
+}
+
+
+
+void
+fadd_i()
+{
+ /* fadd st(i),st */
+ reg_add(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
+}
+
+
+void
+fmul_i()
+{
+ /* fmul st(i),st */
+ reg_mul(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word);
+}
+
+
+void
+fsubri()
+{
+ /* fsubr st(i),st */
+ /* This is the sense of the 80486 manual reg_sub(&st(FPU_rm),
+ * FPU_st0_ptr, &st(FPU_rm), control_word); */
+ reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
+}
+
+
+void
+fsub_i()
+{
+ /* fsub st(i),st */
+ /* This is the sense of the 80486 manual reg_sub(FPU_st0_ptr,
+ * &st(FPU_rm), &st(FPU_rm), control_word); */
+ reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word);
+}
+
+
+void
+fdivri()
+{
+ /* fdivr st(i),st */
+ reg_div(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
+}
+
+
+void
+fdiv_i()
+{
+ /* fdiv st(i),st */
+ reg_div(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word);
+}
+
+
+
+void
+faddp_()
+{
+ /* faddp st(i),st */
+ reg_add(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
+ pop();
+}
+
+
+void
+fmulp_()
+{
+ /* fmulp st(i),st */
+ reg_mul(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word);
+ pop();
+}
+
+
+
+void
+fsubrp()
+{
+ /* fsubrp st(i),st */
+ /* This is the sense of the 80486 manual reg_sub(&st(FPU_rm),
+ * FPU_st0_ptr, &st(FPU_rm), control_word); */
+ reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
+ pop();
+}
+
+
+void
+fsubp_()
+{
+ /* fsubp st(i),st */
+ /* This is the sense of the 80486 manual reg_sub(FPU_st0_ptr,
+ * &st(FPU_rm), &st(FPU_rm), control_word); */
+ reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word);
+ pop();
+}
+
+
+void
+fdivrp()
+{
+ /* fdivrp st(i),st */
+ reg_div(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
+ pop();
+}
+
+
+void
+fdivp_()
+{
+ /* fdivp st(i),st */
+ reg_div(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word);
+ pop();
+}
diff --git a/sys/gnu/fpemul/fpu_asm.h b/sys/gnu/fpemul/fpu_asm.h
new file mode 100644
index 000000000000..2f6e58a65410
--- /dev/null
+++ b/sys/gnu/fpemul/fpu_asm.h
@@ -0,0 +1,82 @@
+/*
+ * fpu_asm.h
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: fpu_asm.h,v 1.3 1994/06/10 07:44:16 rich Exp $
+ *
+ */
+
+#ifndef _FPU_ASM_H_
+#define _FPU_ASM_H_
+
+#include "fpu_emu.h"
+
+#define EXCEPTION _exception
+
+
+#define PARAM1 8(%ebp)
+#define PARAM2 12(%ebp)
+#define PARAM3 16(%ebp)
+#define PARAM4 20(%ebp)
+
+#define SIGL_OFFSET 8
+#define SIGN(x) (x)
+#define TAG(x) 1(x)
+#define EXP(x) 4(x)
+#define SIG(x) SIGL_OFFSET/**/(x)
+#define SIGL(x) SIGL_OFFSET/**/(x)
+#define SIGH(x) 12(x)
+
+#endif /* _FPU_ASM_H_ */
diff --git a/sys/gnu/fpemul/fpu_aux.c b/sys/gnu/fpemul/fpu_aux.c
new file mode 100644
index 000000000000..135fef9e105f
--- /dev/null
+++ b/sys/gnu/fpemul/fpu_aux.c
@@ -0,0 +1,233 @@
+/*
+ * fpu_aux.c
+ *
+ * Code to implement some of the FPU auxiliary instructions.
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: fpu_aux.c,v 1.3 1994/06/10 07:44:17 rich Exp $
+ *
+ */
+
+
+#include "param.h"
+#include "proc.h"
+#include "machine/cpu.h"
+#include "machine/pcb.h"
+
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "exception.h"
+#include "status_w.h"
+
+
+
+void
+fclex(void)
+{
+ status_word &= ~(SW_Backward | SW_Summary | SW_Stack_Fault | SW_Precision |
+ SW_Underflow | SW_Overflow | SW_Zero_Div | SW_Denorm_Op |
+ SW_Invalid);
+ FPU_entry_eip = ip_offset; /* We want no net effect */
+}
+/* Needs to be externally visible */
+void
+finit()
+{
+ int r;
+ control_word = 0x037f;
+ status_word = 0;
+ top = 0; /* We don't keep top in the status word
+ * internally. */
+ for (r = 0; r < 8; r++) {
+ regs[r].tag = TW_Empty;
+ }
+ FPU_entry_eip = ip_offset = 0;
+}
+
+static FUNC finit_table[] = {
+ Un_impl, Un_impl, fclex, finit, Un_impl, Un_impl, Un_impl, Un_impl
+};
+
+void
+finit_()
+{
+ (finit_table[FPU_rm]) ();
+}
+
+
+static void
+fstsw_ax(void)
+{
+
+ status_word &= ~SW_Top;
+ status_word |= (top & 7) << SW_Top_Shift;
+
+ *(short *) &FPU_EAX = status_word;
+
+}
+
+static FUNC fstsw_table[] = {
+ fstsw_ax, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl
+};
+
+void
+fstsw_()
+{
+ (fstsw_table[FPU_rm]) ();
+}
+
+
+
+static void
+fnop(void)
+{
+}
+
+FUNC fp_nop_table[] = {
+ fnop, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl
+};
+
+void
+fp_nop()
+{
+ (fp_nop_table[FPU_rm]) ();
+}
+
+
+void
+fld_i_()
+{
+ FPU_REG *st_new_ptr;
+
+ if (STACK_OVERFLOW) {
+ stack_overflow();
+ return;
+ }
+ /* fld st(i) */
+ if (NOT_EMPTY(FPU_rm)) {
+ reg_move(&st(FPU_rm), st_new_ptr);
+ push();
+ } else {
+ if (control_word & EX_Invalid) {
+ /* The masked response */
+ push();
+ stack_underflow();
+ } else
+ EXCEPTION(EX_StackUnder);
+ }
+
+}
+
+
+void
+fxch_i()
+{
+ /* fxch st(i) */
+ FPU_REG t;
+ register FPU_REG *sti_ptr = &st(FPU_rm);
+
+ if (FPU_st0_tag == TW_Empty) {
+ if (sti_ptr->tag == TW_Empty) {
+ stack_underflow();
+ stack_underflow_i(FPU_rm);
+ return;
+ }
+ reg_move(sti_ptr, FPU_st0_ptr);
+ stack_underflow_i(FPU_rm);
+ return;
+ }
+ if (sti_ptr->tag == TW_Empty) {
+ reg_move(FPU_st0_ptr, sti_ptr);
+ stack_underflow();
+ return;
+ }
+ reg_move(FPU_st0_ptr, &t);
+ reg_move(sti_ptr, FPU_st0_ptr);
+ reg_move(&t, sti_ptr);
+}
+
+
+void
+ffree_()
+{
+ /* ffree st(i) */
+ st(FPU_rm).tag = TW_Empty;
+}
+
+
+void
+ffreep()
+{
+ /* ffree st(i) + pop - unofficial code */
+ st(FPU_rm).tag = TW_Empty;
+ pop();
+}
+
+
+void
+fst_i_()
+{
+ /* fst st(i) */
+ reg_move(FPU_st0_ptr, &st(FPU_rm));
+}
+
+
+void
+fstp_i()
+{
+ /* fstp st(i) */
+ reg_move(FPU_st0_ptr, &st(FPU_rm));
+ pop();
+}
diff --git a/sys/gnu/fpemul/fpu_emu.h b/sys/gnu/fpemul/fpu_emu.h
new file mode 100644
index 000000000000..b81a85127fec
--- /dev/null
+++ b/sys/gnu/fpemul/fpu_emu.h
@@ -0,0 +1,188 @@
+/*
+ * fpu_emu.h
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: fpu_emu.h,v 1.3 1994/06/10 07:44:19 rich Exp $
+ *
+ */
+
+
+#ifndef _FPU_EMU_H_
+#define _FPU_EMU_H_
+
+/*
+ * Define DENORM_OPERAND to make the emulator detect denormals
+ * and use the denormal flag of the status word. Note: this only
+ * affects the flag and corresponding interrupt, the emulator
+ * will always generate denormals and operate upon them as required.
+ */
+#define DENORM_OPERAND
+
+/*
+ * Define PECULIAR_486 to get a closer approximation to 80486 behaviour,
+ * rather than behaviour which appears to be cleaner.
+ * This is a matter of opinion: for all I know, the 80486 may simply
+ * be complying with the IEEE spec. Maybe one day I'll get to see the
+ * spec...
+ */
+#define PECULIAR_486
+
+#ifdef LOCORE
+#include "fpu_asm.h"
+#define Const(x) $/**/x
+#else
+#define Const(x) x
+#endif
+
+#define EXP_BIAS Const(0)
+#define EXP_OVER Const(0x4000) /* smallest invalid large exponent */
+#define EXP_UNDER Const(-0x3fff) /* largest invalid small exponent */
+
+#define SIGN_POS Const(0)
+#define SIGN_NEG Const(1)
+
+/* Keep the order TW_Valid, TW_Zero, TW_Denormal */
+#define TW_Valid Const(0)/* valid */
+#define TW_Zero Const(1)/* zero */
+/* The following fold to 2 (Special) in the Tag Word */
+#define TW_Denormal Const(4)/* De-normal */
+#define TW_Infinity Const(5)/* + or - infinity */
+#define TW_NaN Const(6)/* Not a Number */
+
+#define TW_Empty Const(7)/* empty */
+
+ /* #define TW_FPU_Interrupt Const(0x80) *//* Signals an interrupt */
+
+
+#ifndef LOCORE
+
+#include "types.h"
+#include "math_emu.h"
+
+#ifdef PARANOID
+extern char emulating;
+#define REENTRANT_CHECK(state) emulating = (state)
+#define ON 1
+#define OFF 0
+#else
+#define REENTRANT_CHECK(state)
+#endif /* PARANOID */
+
+typedef void (*FUNC) (void);
+typedef struct fpu_reg FPU_REG;
+
+#define st(x) ( regs[((top+x) &7 )] )
+
+#define STACK_OVERFLOW (st_new_ptr = &st(-1), st_new_ptr->tag != TW_Empty)
+#define NOT_EMPTY(i) (st(i).tag != TW_Empty)
+#define NOT_EMPTY_0 (FPU_st0_tag ^ TW_Empty)
+
+extern unsigned char FPU_rm;
+
+extern char FPU_st0_tag;
+extern FPU_REG *FPU_st0_ptr;
+
+extern void *FPU_data_address;
+
+extern FPU_REG FPU_loaded_data;
+
+#define pop() { FPU_st0_ptr->tag = TW_Empty; top++; }
+
+/* push() does not affect the tags */
+#define push() { top--; FPU_st0_ptr = st_new_ptr; }
+
+
+#define reg_move(x, y) { \
+ *(short *)&((y)->sign) = *(short *)&((x)->sign); \
+ *(long *)&((y)->exp) = *(long *)&((x)->exp); \
+ *(long long *)&((y)->sigl) = *(long long *)&((x)->sigl); }
+
+
+/*----- Prototypes for functions written in assembler -----*/
+/* extern void reg_move(FPU_REG *a, FPU_REG *b); */
+
+extern void mul64(long long *a, long long *b, long long *result);
+extern void poly_div2(long long *x);
+extern void poly_div4(long long *x);
+extern void poly_div16(long long *x);
+extern void
+polynomial(unsigned accum[], unsigned x[],
+ unsigned short terms[][4], int n);
+ extern void normalize(FPU_REG * x);
+ extern void normalize_nuo(FPU_REG * x);
+ extern void reg_div(FPU_REG * arg1, FPU_REG * arg2, FPU_REG * answ,
+ unsigned int control_w);
+ extern void reg_u_sub(FPU_REG * arg1, FPU_REG * arg2, FPU_REG * answ,
+ unsigned int control_w);
+ extern void reg_u_mul(FPU_REG * arg1, FPU_REG * arg2, FPU_REG * answ,
+ unsigned int control_w);
+ extern void reg_u_div(FPU_REG * arg1, FPU_REG * arg2, FPU_REG * answ,
+ unsigned int control_w);
+ extern void reg_u_add(FPU_REG * arg1, FPU_REG * arg2, FPU_REG * answ,
+ unsigned int control_w);
+ extern void wm_sqrt(FPU_REG * n, unsigned int control_w);
+ extern unsigned shrx(void *l, unsigned x);
+ extern unsigned shrxs(void *v, unsigned x);
+ extern unsigned long div_small(unsigned long long *x, unsigned long y);
+ extern void round_reg(FPU_REG * arg, unsigned int extent,
+ unsigned int control_w);
+
+#ifndef MAKING_PROTO
+#include "fpu_proto.h"
+#endif
+
+#endif /* LOCORE */
+
+#endif /* _FPU_EMU_H_ */
diff --git a/sys/gnu/fpemul/fpu_entry.c b/sys/gnu/fpemul/fpu_entry.c
new file mode 100644
index 000000000000..7a882227bcdb
--- /dev/null
+++ b/sys/gnu/fpemul/fpu_entry.c
@@ -0,0 +1,483 @@
+/*
+ * fpu_entry.c
+ *
+ * The entry function for wm-FPU-emu
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ * $Id: fpu_entry.c,v 1.4 1994/06/22 05:52:14 jkh Exp $
+ *
+ */
+
+/*---------------------------------------------------------------------------+
+ | Note: |
+ | The file contains code which accesses user memory. |
+ | Emulator static data may change when user memory is accessed, due to |
+ | other processes using the emulator while swapping is in progress. |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | math_emulate() is the sole entry point for wm-FPU-emu |
+ +---------------------------------------------------------------------------*/
+
+
+#include "param.h"
+#include "systm.h"
+#include "proc.h"
+#include "machine/cpu.h"
+#include "machine/pcb.h"
+
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "exception.h"
+#include "control_w.h"
+#include "status_w.h"
+
+
+#define __BAD__ Un_impl /* Not implemented */
+
+#define FPU_LOOKAHEAD 1 /* For performance boost */
+
+#if FPU_LOOKAHEAD != 0 /* I think thet we have to limit the */
+#define LOOKAHEAD_LIMIT 7 /* Max number of lookahead instructions*/
+#endif /* Or else a prog consisting of a million */
+ /* fnops will spend all its time in kernel*/
+
+#ifndef NO_UNDOC_CODE /* Un-documented FPU op-codes supported by
+ * default. */
+
+/* WARNING: These codes are not documented by Intel in their 80486 manual
+ and may not work on FPU clones or later Intel FPUs. */
+
+/* Changes to support the un-doc codes provided by Linus Torvalds. */
+
+#define _d9_d8_ fstp_i /* unofficial code (19) */
+#define _dc_d0_ fcom_st /* unofficial code (14) */
+#define _dc_d8_ fcompst /* unofficial code (1c) */
+#define _dd_c8_ fxch_i /* unofficial code (0d) */
+#define _de_d0_ fcompst /* unofficial code (16) */
+#define _df_c0_ ffreep /* unofficial code (07) ffree + pop */
+#define _df_c8_ fxch_i /* unofficial code (0f) */
+#define _df_d0_ fstp_i /* unofficial code (17) */
+#define _df_d8_ fstp_i /* unofficial code (1f) */
+
+static FUNC st_instr_table[64] = {
+ fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, _df_c0_,
+ fmul__, fxch_i, __BAD__, __BAD__, fmul_i, _dd_c8_, fmulp_, _df_c8_,
+ fcom_st, fp_nop, __BAD__, __BAD__, _dc_d0_, fst_i_, _de_d0_, _df_d0_,
+ fcompst, _d9_d8_, __BAD__, __BAD__, _dc_d8_, fstp_i, fcompp, _df_d8_,
+ fsub__, fp_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
+ fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
+ fdiv__, trig_a, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
+ fdivr_, trig_b, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
+};
+#else /* Support only documented FPU op-codes */
+
+static FUNC st_instr_table[64] = {
+ fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, __BAD__,
+ fmul__, fxch_i, __BAD__, __BAD__, fmul_i, __BAD__, fmulp_, __BAD__,
+ fcom_st, fp_nop, __BAD__, __BAD__, __BAD__, fst_i_, __BAD__, __BAD__,
+ fcompst, __BAD__, __BAD__, __BAD__, __BAD__, fstp_i, fcompp, __BAD__,
+ fsub__, fp_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
+ fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
+ fdiv__, trig_a, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
+ fdivr_, trig_b, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
+};
+#endif /* NO_UNDOC_CODE */
+
+
+#define _NONE_ 0 /* Take no special action */
+#define _REG0_ 1 /* Need to check for not empty st(0) */
+#define _REGI_ 2 /* Need to check for not empty st(0) and
+ * st(rm) */
+#define _REGi_ 0 /* Uses st(rm) */
+#define _PUSH_ 3 /* Need to check for space to push onto stack */
+#define _null_ 4 /* Function illegal or not implemented */
+#define _REGIi 5 /* Uses st(0) and st(rm), result to st(rm) */
+#define _REGIp 6 /* Uses st(0) and st(rm), result to st(rm)
+ * then pop */
+#define _REGIc 0 /* Compare st(0) and st(rm) */
+#define _REGIn 0 /* Uses st(0) and st(rm), but handle checks
+ * later */
+
+#ifndef NO_UNDOC_CODE
+
+/* Un-documented FPU op-codes supported by default. (see above) */
+
+static unsigned char type_table[64] = {
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _REGi_,
+ _REGI_, _REGIn, _null_, _null_, _REGIi, _REGI_, _REGIp, _REGI_,
+ _REGIc, _NONE_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
+ _REGIc, _REG0_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
+ _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
+ _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
+};
+#else /* Support only documented FPU op-codes */
+
+static unsigned char type_table[64] = {
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _null_,
+ _REGI_, _REGIn, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
+ _REGIc, _NONE_, _null_, _null_, _null_, _REG0_, _null_, _null_,
+ _REGIc, _null_, _null_, _null_, _null_, _REG0_, _REGIc, _null_,
+ _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
+ _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
+};
+#endif /* NO_UNDOC_CODE */
+
+/* Be careful when using any of these global variables...
+ they might change if swapping is triggered */
+unsigned char FPU_rm;
+char FPU_st0_tag;
+FPU_REG *FPU_st0_ptr;
+
+#ifdef PARANOID
+char emulating = 0;
+#endif /* PARANOID */
+
+#define bswapw(x) __asm__("xchgb %%al,%%ah":"=a" (x):"0" ((short)x))
+#define math_abort(signo) \
+ FPU_EIP = FPU_ORIG_EIP;REENTRANT_CHECK(OFF);return(signo);
+
+int
+math_emulate(struct trapframe * tframe)
+{
+
+ unsigned char FPU_modrm;
+ unsigned short code;
+#ifdef LOOKAHEAD_LIMIT
+ int lookahead_limit = LOOKAHEAD_LIMIT;
+#endif
+#ifdef PARANOID
+ if (emulating) {
+ printf("ERROR: wm-FPU-emu is not RE-ENTRANT!\n");
+ }
+ REENTRANT_CHECK(ON);
+#endif /* PARANOID */
+
+ if ((((struct pcb *) curproc->p_addr)->pcb_flags & FP_SOFTFP) == 0) {
+ finit();
+ control_word = __INITIAL_NPXCW__;
+ ((struct pcb *) curproc->p_addr)->pcb_flags |= FP_SOFTFP;
+ }
+ FPU_info = tframe;
+ FPU_ORIG_EIP = FPU_EIP; /* --pink-- */
+
+ if (FPU_CS != 0x001f) {
+ printf("math_emulate: %x : %x\n", FPU_CS, FPU_EIP);
+ panic("FPU emulation in kernel");
+ }
+#ifdef notyet
+ /* We cannot handle emulation in v86-mode */
+ if (FPU_EFLAGS & 0x00020000) {
+ FPU_ORIG_EIP = FPU_EIP;
+ math_abort(FPU_info, SIGILL);
+ }
+#endif
+
+ FPU_lookahead = FPU_LOOKAHEAD;
+ if (curproc->p_flag & STRC)
+ FPU_lookahead = 0;
+
+do_another_FPU_instruction:
+
+ REENTRANT_CHECK(OFF);
+ code = fuword((u_int *) FPU_EIP);
+ REENTRANT_CHECK(ON);
+ if ((code & 0xff) == 0x9b) { /* fwait */
+ if (status_word & SW_Summary)
+ goto do_the_FPU_interrupt;
+ else {
+ FPU_EIP++;
+ goto FPU_instruction_done;
+ }
+ }
+ if (status_word & SW_Summary) {
+ /* Ignore the error for now if the current instruction is a
+ * no-wait control instruction */
+ /* The 80486 manual contradicts itself on this topic, so I use
+ * the following list of such instructions until I can check
+ * on a real 80486: fninit, fnstenv, fnsave, fnstsw, fnstenv,
+ * fnclex. */
+ if (!((((code & 0xf803) == 0xe003) || /* fnclex, fninit,
+ * fnstsw */
+ (((code & 0x3003) == 0x3001) && /* fnsave, fnstcw,
+ * fnstenv, fnstsw */
+ ((code & 0xc000) != 0xc000))))) {
+ /* This is a guess about what a real FPU might do to
+ * this bit: */
+/* status_word &= ~SW_Summary; ****/
+
+ /* We need to simulate the action of the kernel to FPU
+ * interrupts here. Currently, the "real FPU" part of
+ * the kernel (0.99.10) clears the exception flags,
+ * sets the registers to empty, and passes information
+ * back to the interrupted process via the cs selector
+ * and operand selector, so we do the same. */
+ do_the_FPU_interrupt:
+ cs_selector &= 0xffff0000;
+ cs_selector |= (status_word & ~SW_Top) | ((top & 7) << SW_Top_Shift);
+ operand_selector = tag_word();
+ status_word = 0;
+ top = 0;
+ {
+ int r;
+ for (r = 0; r < 8; r++) {
+ regs[r].tag = TW_Empty;
+ }
+ }
+ REENTRANT_CHECK(OFF);
+ math_abort(SIGFPE);
+ }
+ }
+ FPU_entry_eip = FPU_ORIG_EIP = FPU_EIP;
+
+ if ((code & 0xff) == 0x66) { /* size prefix */
+ FPU_EIP++;
+ REENTRANT_CHECK(OFF);
+ code = fuword((u_int *) FPU_EIP);
+ REENTRANT_CHECK(ON);
+ }
+ FPU_EIP += 2;
+
+ FPU_modrm = code >> 8;
+ FPU_rm = FPU_modrm & 7;
+
+ if (FPU_modrm < 0300) {
+ /* All of these instructions use the mod/rm byte to get a data
+ * address */
+ get_address(FPU_modrm);
+ if (!(code & 1)) {
+ unsigned short status1 = status_word;
+ FPU_st0_ptr = &st(0);
+ FPU_st0_tag = FPU_st0_ptr->tag;
+
+ /* Stack underflow has priority */
+ if (NOT_EMPTY_0) {
+ switch ((code >> 1) & 3) {
+ case 0:
+ reg_load_single();
+ break;
+ case 1:
+ reg_load_int32();
+ break;
+ case 2:
+ reg_load_double();
+ break;
+ case 3:
+ reg_load_int16();
+ break;
+ }
+
+ /* No more access to user memory, it is safe
+ * to use static data now */
+ FPU_st0_ptr = &st(0);
+ FPU_st0_tag = FPU_st0_ptr->tag;
+
+ /* NaN operands have the next priority. */
+ /* We have to delay looking at st(0) until
+ * after loading the data, because that data
+ * might contain an SNaN */
+ if ((FPU_st0_tag == TW_NaN) ||
+ (FPU_loaded_data.tag == TW_NaN)) {
+ /* Restore the status word; we might
+ * have loaded a denormal. */
+ status_word = status1;
+ if ((FPU_modrm & 0x30) == 0x10) {
+ /* fcom or fcomp */
+ EXCEPTION(EX_Invalid);
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ if (FPU_modrm & 0x08)
+ pop(); /* fcomp, so we pop. */
+ } else
+ real_2op_NaN(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr);
+ goto reg_mem_instr_done;
+ }
+ switch ((FPU_modrm >> 3) & 7) {
+ case 0: /* fadd */
+ reg_add(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr, control_word);
+ break;
+ case 1: /* fmul */
+ reg_mul(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr, control_word);
+ break;
+ case 2: /* fcom */
+ compare_st_data();
+ break;
+ case 3: /* fcomp */
+ compare_st_data();
+ pop();
+ break;
+ case 4: /* fsub */
+ reg_sub(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr, control_word);
+ break;
+ case 5: /* fsubr */
+ reg_sub(&FPU_loaded_data, FPU_st0_ptr, FPU_st0_ptr, control_word);
+ break;
+ case 6: /* fdiv */
+ reg_div(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr, control_word);
+ break;
+ case 7: /* fdivr */
+ if (FPU_st0_tag == TW_Zero)
+ status_word = status1; /* Undo any denorm tag,
+ * zero-divide has
+ * priority. */
+ reg_div(&FPU_loaded_data, FPU_st0_ptr, FPU_st0_ptr, control_word);
+ break;
+ }
+ } else {
+ if ((FPU_modrm & 0x30) == 0x10) {
+ /* The instruction is fcom or fcomp */
+ EXCEPTION(EX_StackUnder);
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ if (FPU_modrm & 0x08)
+ pop(); /* fcomp, Empty or not,
+ * we pop. */
+ } else
+ stack_underflow();
+ }
+ } else {
+ load_store_instr(((FPU_modrm & 0x38) | (code & 6)) >> 1);
+ }
+
+reg_mem_instr_done:
+
+ data_operand_offset = (unsigned long) FPU_data_address;
+ } else {
+ /* None of these instructions access user memory */
+ unsigned char instr_index = (FPU_modrm & 0x38) | (code & 7);
+
+ FPU_st0_ptr = &st(0);
+ FPU_st0_tag = FPU_st0_ptr->tag;
+ switch (type_table[(int) instr_index]) {
+ case _NONE_: /* also _REGIc: _REGIn */
+ break;
+ case _REG0_:
+ if (!NOT_EMPTY_0) {
+ stack_underflow();
+ goto FPU_instruction_done;
+ }
+ break;
+ case _REGIi:
+ if (!NOT_EMPTY_0 || !NOT_EMPTY(FPU_rm)) {
+ stack_underflow_i(FPU_rm);
+ goto FPU_instruction_done;
+ }
+ break;
+ case _REGIp:
+ if (!NOT_EMPTY_0 || !NOT_EMPTY(FPU_rm)) {
+ stack_underflow_i(FPU_rm);
+ pop();
+ goto FPU_instruction_done;
+ }
+ break;
+ case _REGI_:
+ if (!NOT_EMPTY_0 || !NOT_EMPTY(FPU_rm)) {
+ stack_underflow();
+ goto FPU_instruction_done;
+ }
+ break;
+ case _PUSH_: /* Only used by the fld st(i) instruction */
+ break;
+ case _null_:
+ Un_impl();
+ goto FPU_instruction_done;
+ default:
+ EXCEPTION(EX_INTERNAL | 0x111);
+ goto FPU_instruction_done;
+ }
+ (*st_instr_table[(int) instr_index]) ();
+ }
+
+FPU_instruction_done:
+
+ ip_offset = FPU_entry_eip;
+ bswapw(code);
+ *(1 + (unsigned short *) &cs_selector) = code & 0x7ff;
+
+#ifdef DEBUG
+ REENTRANT_CHECK(OFF);
+ emu_printall();
+ REENTRANT_CHECK(ON);
+#endif /* DEBUG */
+#ifdef LOOKAHEAD_LIMIT
+if (--lookahead_limit)
+#endif
+ if (FPU_lookahead) {
+ unsigned char next;
+
+ /* (This test should generate no machine code) */
+ while (1) {
+ REENTRANT_CHECK(OFF);
+ next = fubyte((u_char *) FPU_EIP);
+ REENTRANT_CHECK(ON);
+ if (((next & 0xf8) == 0xd8) || (next == 0x9b)) { /* fwait */
+ goto do_another_FPU_instruction;
+ } else
+ if (next == 0x66) { /* size prefix */
+ REENTRANT_CHECK(OFF);
+ next = fubyte((u_char *) (FPU_EIP + 1));
+ REENTRANT_CHECK(ON);
+ if ((next & 0xf8) == 0xd8) {
+ FPU_EIP++;
+ goto do_another_FPU_instruction;
+ }
+ }
+ break;
+ }
+ }
+ REENTRANT_CHECK(OFF);
+ return (0); /* --pink-- */
+}
diff --git a/sys/gnu/fpemul/fpu_etc.c b/sys/gnu/fpemul/fpu_etc.c
new file mode 100644
index 000000000000..9993d3bddfd4
--- /dev/null
+++ b/sys/gnu/fpemul/fpu_etc.c
@@ -0,0 +1,175 @@
+/*
+ * fpu_etc.c
+ *
+ * Implement a few FPU instructions.
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: fpu_etc.c,v 1.3 1994/06/10 07:44:24 rich Exp $
+ *
+ */
+
+#include "param.h"
+#include "proc.h"
+#include "machine/cpu.h"
+#include "machine/pcb.h"
+
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "exception.h"
+#include "status_w.h"
+#include "reg_constant.h"
+
+
+static void
+fchs(void)
+{
+ if (NOT_EMPTY_0) {
+ FPU_st0_ptr->sign ^= SIGN_POS ^ SIGN_NEG;
+ status_word &= ~SW_C1;
+ } else
+ stack_underflow();
+}
+
+static void
+fabs(void)
+{
+ if (FPU_st0_tag ^ TW_Empty) {
+ FPU_st0_ptr->sign = SIGN_POS;
+ status_word &= ~SW_C1;
+ } else
+ stack_underflow();
+}
+
+
+static void
+ftst_(void)
+{
+ switch (FPU_st0_tag) {
+ case TW_Zero:
+ setcc(SW_C3);
+ break;
+ case TW_Valid:
+
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ if (FPU_st0_ptr->sign == SIGN_POS)
+ setcc(0);
+ else
+ setcc(SW_C0);
+ break;
+ case TW_NaN:
+ setcc(SW_C0 | SW_C2 | SW_C3); /* Operand is not comparable */
+ EXCEPTION(EX_Invalid);
+ break;
+ case TW_Infinity:
+ if (FPU_st0_ptr->sign == SIGN_POS)
+ setcc(0);
+ else
+ setcc(SW_C0);
+ EXCEPTION(EX_Invalid);
+ break;
+ case TW_Empty:
+ setcc(SW_C0 | SW_C2 | SW_C3);
+ EXCEPTION(EX_StackUnder);
+ break;
+ default:
+ setcc(SW_C0 | SW_C2 | SW_C3); /* Operand is not comparable */
+ EXCEPTION(EX_INTERNAL | 0x14);
+ break;
+ }
+}
+
+static void
+fxam(void)
+{
+ int c = 0;
+ switch (FPU_st0_tag) {
+ case TW_Empty:
+ c = SW_C3 | SW_C0;
+ break;
+ case TW_Zero:
+ c = SW_C3;
+ break;
+ case TW_Valid:
+ /* This will need to be changed if TW_Denormal is ever used. */
+ if (FPU_st0_ptr->exp <= EXP_UNDER)
+ c = SW_C2 | SW_C3; /* Denormal */
+ else
+ c = SW_C3;
+ break;
+ case TW_NaN:
+ c = SW_C0;
+ break;
+ case TW_Infinity:
+ c = SW_C2 | SW_C0;
+ break;
+ }
+ if (FPU_st0_ptr->sign == SIGN_NEG)
+ c |= SW_C1;
+ setcc(c);
+}
+
+static FUNC fp_etc_table[] = {
+ fchs, fabs, Un_impl, Un_impl, ftst_, fxam, Un_impl, Un_impl
+};
+
+void
+fp_etc()
+{
+ (fp_etc_table[FPU_rm]) ();
+}
diff --git a/sys/gnu/fpemul/fpu_proto.h b/sys/gnu/fpemul/fpu_proto.h
new file mode 100644
index 000000000000..463f31b7d7be
--- /dev/null
+++ b/sys/gnu/fpemul/fpu_proto.h
@@ -0,0 +1,115 @@
+/*
+ *
+ * $Id: fpu_proto.h,v 1.2 1994/04/29 21:16:23 gclarkii Exp $
+ *
+ */
+
+
+/* errors.c */
+extern void Un_impl(void);
+extern void emu_printall(void);
+extern void exception(int n);
+extern void real_2op_NaN(FPU_REG * a, FPU_REG * b, FPU_REG * dest);
+extern void arith_invalid(FPU_REG * dest);
+extern void divide_by_zero(int sign, FPU_REG * dest);
+extern void set_precision_flag_up(void);
+extern void set_precision_flag_down(void);
+extern int denormal_operand(void);
+extern void arith_overflow(FPU_REG * dest);
+extern void arith_underflow(FPU_REG * dest);
+extern void stack_overflow(void);
+extern void stack_underflow(void);
+extern void stack_underflow_i(int i);
+extern void stack_underflow_pop(int i);
+/* fpu_arith.c */
+extern void fadd__(void);
+extern void fmul__(void);
+extern void fsub__(void);
+extern void fsubr_(void);
+extern void fdiv__(void);
+extern void fdivr_(void);
+extern void fadd_i(void);
+extern void fmul_i(void);
+extern void fsubri(void);
+extern void fsub_i(void);
+extern void fdivri(void);
+extern void fdiv_i(void);
+extern void faddp_(void);
+extern void fmulp_(void);
+extern void fsubrp(void);
+extern void fsubp_(void);
+extern void fdivrp(void);
+extern void fdivp_(void);
+/* fpu_aux.c */
+extern void fclex(void);
+extern void finit(void);
+extern void finit_(void);
+extern void fstsw_(void);
+extern void fp_nop(void);
+extern void fld_i_(void);
+extern void fxch_i(void);
+extern void ffree_(void);
+extern void ffreep(void);
+extern void fst_i_(void);
+extern void fstp_i(void);
+/* fpu_entry.c */
+extern int math_emulate(struct trapframe * info);
+/* fpu_etc.c */
+extern void fp_etc(void);
+/* fpu_trig.c */
+extern void convert_l2reg(long *arg, FPU_REG * dest);
+extern void trig_a(void);
+extern void trig_b(void);
+/* get_address.c */
+extern void get_address(unsigned char FPU_modrm);
+/* load_store.c */
+extern void load_store_instr(char type);
+/* poly_2xm1.c */
+extern int poly_2xm1(FPU_REG * arg, FPU_REG * result);
+/* poly_atan.c */
+extern void poly_atan(FPU_REG * arg);
+extern void poly_add_1(FPU_REG * src);
+/* poly_l2.c */
+extern void poly_l2(FPU_REG * arg, FPU_REG * result);
+extern int poly_l2p1(FPU_REG * arg, FPU_REG * result);
+/* poly_sin.c */
+extern void poly_sine(FPU_REG * arg, FPU_REG * result);
+/* poly_tan.c */
+extern void poly_tan(FPU_REG * arg, FPU_REG * y_reg);
+/* reg_add_sub.c */
+extern void reg_add(FPU_REG * a, FPU_REG * b, FPU_REG * dest, int control_w);
+extern void reg_sub(FPU_REG * a, FPU_REG * b, FPU_REG * dest, int control_w);
+/* reg_compare.c */
+extern int compare(FPU_REG * b);
+extern int compare_st_data(void);
+extern void fcom_st(void);
+extern void fcompst(void);
+extern void fcompp(void);
+extern void fucom_(void);
+extern void fucomp(void);
+extern void fucompp(void);
+/* reg_constant.c */
+extern void fconst(void);
+/* reg_ld_str.c */
+extern void reg_load_extended(void);
+extern void reg_load_double(void);
+extern void reg_load_single(void);
+extern void reg_load_int64(void);
+extern void reg_load_int32(void);
+extern void reg_load_int16(void);
+extern void reg_load_bcd(void);
+extern int reg_store_extended(void);
+extern int reg_store_double(void);
+extern int reg_store_single(void);
+extern int reg_store_int64(void);
+extern int reg_store_int32(void);
+extern int reg_store_int16(void);
+extern int reg_store_bcd(void);
+extern int round_to_int(FPU_REG * r);
+extern char *fldenv(void);
+extern void frstor(void);
+extern unsigned short tag_word(void);
+extern char *fstenv(void);
+extern void fsave(void);
+/* reg_mul.c */
+extern void reg_mul(FPU_REG * a, FPU_REG * b, FPU_REG * dest, unsigned int control_w);
diff --git a/sys/gnu/fpemul/fpu_system.h b/sys/gnu/fpemul/fpu_system.h
new file mode 100644
index 000000000000..ac5263615b5f
--- /dev/null
+++ b/sys/gnu/fpemul/fpu_system.h
@@ -0,0 +1,97 @@
+/*
+ * fpu_system.h
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: fpu_system.h,v 1.3 1994/06/10 07:44:25 rich Exp $
+ *
+ */
+
+
+#ifndef _FPU_SYSTEM_H
+#define _FPU_SYSTEM_H
+
+/* system dependent definitions */
+
+/*
+#include <linux/sched.h>
+#include <linux/kernel.h>
+*/
+
+#define I387 (*(union i387_union *)&(((struct pcb *)curproc->p_addr)->pcb_savefpu))
+#define FPU_info (I387.soft.frame)
+
+#define FPU_CS (*(unsigned short *) &(FPU_info->tf_cs))
+#define FPU_DS (*(unsigned short *) &(FPU_info->tf_ds))
+#define FPU_EAX (FPU_info->tf_eax)
+#define FPU_EFLAGS (FPU_info->tf_eflags)
+#define FPU_EIP (FPU_info->tf_eip)
+/*#define FPU_ORIG_EIP (FPU_info->___orig_eip) */
+/*#define FPU_ORIG_EIP (FPU_info->tf_isp)*/
+#define FPU_ORIG_EIP (I387.soft.orig_eip)
+
+#define FPU_lookahead (I387.soft.lookahead)
+#define FPU_entry_eip (I387.soft.entry_eip)
+
+#define status_word (I387.soft.swd)
+#define control_word (I387.soft.cwd)
+#define regs (I387.soft.regs)
+#define top (I387.soft.top)
+
+#define ip_offset (I387.soft.fip)
+#define cs_selector (I387.soft.fcs)
+#define data_operand_offset (I387.soft.foo)
+#define operand_selector (I387.soft.fos)
+
+#endif
diff --git a/sys/gnu/fpemul/fpu_trig.c b/sys/gnu/fpemul/fpu_trig.c
new file mode 100644
index 000000000000..af2bd0553ce9
--- /dev/null
+++ b/sys/gnu/fpemul/fpu_trig.c
@@ -0,0 +1,1367 @@
+/*
+ * fpu_trig.c
+ *
+ * Implementation of the FPU "transcendental" functions.
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: fpu_trig.c,v 1.4 1994/06/10 07:44:27 rich Exp $
+ *
+ */
+
+
+#include "param.h"
+#include "proc.h"
+#include "machine/cpu.h"
+#include "machine/pcb.h"
+
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "exception.h"
+#include "status_w.h"
+#include "reg_constant.h"
+#include "control_w.h"
+
+static int
+trig_arg(FPU_REG * X)
+{
+ FPU_REG tmp, quot;
+ int rv;
+ long long q;
+ int old_cw = control_word;
+
+ control_word &= ~CW_RC;
+ control_word |= RC_CHOP;
+
+ reg_move(X, &quot);
+ reg_div(&quot, &CONST_PI2, &quot, FULL_PRECISION);
+
+ reg_move(&quot, &tmp);
+ round_to_int(&tmp);
+ if (tmp.sigh & 0x80000000)
+ return -1; /* |Arg| is >= 2^63 */
+ tmp.exp = EXP_BIAS + 63;
+ q = *(long long *) &(tmp.sigl);
+ normalize(&tmp);
+
+ reg_sub(&quot, &tmp, X, FULL_PRECISION);
+ rv = q & 7;
+
+ control_word = old_cw;
+ return rv;;
+}
+
+
+/* Convert a long to register */
+void
+convert_l2reg(long *arg, FPU_REG * dest)
+{
+ long num = *arg;
+
+ if (num == 0) {
+ reg_move(&CONST_Z, dest);
+ return;
+ }
+ if (num > 0)
+ dest->sign = SIGN_POS;
+ else {
+ num = -num;
+ dest->sign = SIGN_NEG;
+ }
+
+ dest->sigh = num;
+ dest->sigl = 0;
+ dest->exp = EXP_BIAS + 31;
+ dest->tag = TW_Valid;
+ normalize(dest);
+}
+
+
+static void
+single_arg_error(void)
+{
+ switch (FPU_st0_tag) {
+ case TW_NaN:
+ if (!(FPU_st0_ptr->sigh & 0x40000000)) { /* Signaling ? */
+ EXCEPTION(EX_Invalid);
+ /* Convert to a QNaN */
+ FPU_st0_ptr->sigh |= 0x40000000;
+ }
+ break; /* return with a NaN in st(0) */
+ case TW_Empty:
+ stack_underflow(); /* Puts a QNaN in st(0) */
+ break;
+#ifdef PARANOID
+ default:
+ EXCEPTION(EX_INTERNAL | 0x0112);
+#endif /* PARANOID */
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+static void
+f2xm1(void)
+{
+ switch (FPU_st0_tag) {
+ case TW_Valid:
+ {
+ FPU_REG rv, tmp;
+
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ if (FPU_st0_ptr->sign == SIGN_POS) {
+ /* poly_2xm1(x) requires 0 < x < 1. */
+ if (poly_2xm1(FPU_st0_ptr, &rv))
+ return; /* error */
+ reg_mul(&rv, FPU_st0_ptr, FPU_st0_ptr, FULL_PRECISION);
+ } else {
+/* **** Should change poly_2xm1() to at least handle numbers near 0 */
+ /* poly_2xm1(x) doesn't handle negative
+ * numbers. */
+ /* So we compute (poly_2xm1(x+1)-1)/2, for -1
+ * < x < 0 */
+ reg_add(FPU_st0_ptr, &CONST_1, &tmp, FULL_PRECISION);
+ poly_2xm1(&tmp, &rv);
+ reg_mul(&rv, &tmp, &tmp, FULL_PRECISION);
+ reg_sub(&tmp, &CONST_1, FPU_st0_ptr, FULL_PRECISION);
+ FPU_st0_ptr->exp--;
+ if (FPU_st0_ptr->exp <= EXP_UNDER)
+ arith_underflow(FPU_st0_ptr);
+ }
+ return;
+ }
+ case TW_Zero:
+ return;
+ case TW_Infinity:
+ if (FPU_st0_ptr->sign == SIGN_NEG) {
+ /* -infinity gives -1 (p16-10) */
+ reg_move(&CONST_1, FPU_st0_ptr);
+ FPU_st0_ptr->sign = SIGN_NEG;
+ }
+ return;
+ default:
+ single_arg_error();
+ }
+}
+
+static void
+fptan(void)
+{
+ FPU_REG *st_new_ptr;
+ int q;
+ char arg_sign = FPU_st0_ptr->sign;
+
+ if (STACK_OVERFLOW) {
+ stack_overflow();
+ return;
+ }
+ switch (FPU_st0_tag) {
+ case TW_Valid:
+
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ FPU_st0_ptr->sign = SIGN_POS;
+ if ((q = trig_arg(FPU_st0_ptr)) != -1) {
+ if (q & 1)
+ reg_sub(&CONST_1, FPU_st0_ptr, FPU_st0_ptr, FULL_PRECISION);
+
+ poly_tan(FPU_st0_ptr, FPU_st0_ptr);
+
+ FPU_st0_ptr->sign = (q & 1) ^ arg_sign;
+
+ if (FPU_st0_ptr->exp <= EXP_UNDER)
+ arith_underflow(FPU_st0_ptr);
+
+ push();
+ reg_move(&CONST_1, FPU_st0_ptr);
+ setcc(0);
+ } else {
+ /* Operand is out of range */
+ setcc(SW_C2);
+ FPU_st0_ptr->sign = arg_sign; /* restore st(0) */
+ return;
+ }
+ break;
+ case TW_Infinity:
+ /* Operand is out of range */
+ setcc(SW_C2);
+ FPU_st0_ptr->sign = arg_sign; /* restore st(0) */
+ return;
+ case TW_Zero:
+ push();
+ reg_move(&CONST_1, FPU_st0_ptr);
+ setcc(0);
+ break;
+ default:
+ single_arg_error();
+ break;
+ }
+}
+
+
+static void
+fxtract(void)
+{
+ FPU_REG *st_new_ptr;
+ register FPU_REG *st1_ptr = FPU_st0_ptr; /* anticipate */
+
+ if (STACK_OVERFLOW) {
+ stack_overflow();
+ return;
+ }
+ if (!(FPU_st0_tag ^ TW_Valid)) {
+ long e;
+
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ push();
+ reg_move(st1_ptr, FPU_st0_ptr);
+ FPU_st0_ptr->exp = EXP_BIAS;
+ e = st1_ptr->exp - EXP_BIAS;
+ convert_l2reg(&e, st1_ptr);
+ return;
+ } else
+ if (FPU_st0_tag == TW_Zero) {
+ char sign = FPU_st0_ptr->sign;
+ divide_by_zero(SIGN_NEG, FPU_st0_ptr);
+ push();
+ reg_move(&CONST_Z, FPU_st0_ptr);
+ FPU_st0_ptr->sign = sign;
+ return;
+ } else
+ if (FPU_st0_tag == TW_Infinity) {
+ char sign = FPU_st0_ptr->sign;
+ FPU_st0_ptr->sign = SIGN_POS;
+ push();
+ reg_move(&CONST_INF, FPU_st0_ptr);
+ FPU_st0_ptr->sign = sign;
+ return;
+ } else
+ if (FPU_st0_tag == TW_NaN) {
+ if (!(FPU_st0_ptr->sigh & 0x40000000)) { /* Signaling ? */
+ EXCEPTION(EX_Invalid);
+ /* Convert to a QNaN */
+ FPU_st0_ptr->sigh |= 0x40000000;
+ }
+ push();
+ reg_move(st1_ptr, FPU_st0_ptr);
+ return;
+ } else
+ if (FPU_st0_tag == TW_Empty) {
+ /* Is this the correct
+ * behaviour? */
+ if (control_word & EX_Invalid) {
+ stack_underflow();
+ push();
+ stack_underflow();
+ } else
+ EXCEPTION(EX_StackUnder);
+ }
+#ifdef PARANOID
+ else
+ EXCEPTION(EX_INTERNAL | 0x119);
+#endif /* PARANOID */
+}
+
+
+static void
+fdecstp(void)
+{
+ top--; /* FPU_st0_ptr will be fixed in math_emulate()
+ * before the next instr */
+}
+
+static void
+fincstp(void)
+{
+ top++; /* FPU_st0_ptr will be fixed in math_emulate()
+ * before the next instr */
+}
+
+
+static void
+fsqrt_(void)
+{
+ if (!(FPU_st0_tag ^ TW_Valid)) {
+ int expon;
+
+ if (FPU_st0_ptr->sign == SIGN_NEG) {
+ arith_invalid(FPU_st0_ptr); /* sqrt(negative) is
+ * invalid */
+ return;
+ }
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ expon = FPU_st0_ptr->exp - EXP_BIAS;
+ FPU_st0_ptr->exp = EXP_BIAS + (expon & 1); /* make st(0) in [1.0
+ * .. 4.0) */
+
+ wm_sqrt(FPU_st0_ptr, control_word); /* Do the computation */
+
+ FPU_st0_ptr->exp += expon >> 1;
+ FPU_st0_ptr->sign = SIGN_POS;
+ } else
+ if (FPU_st0_tag == TW_Zero)
+ return;
+ else
+ if (FPU_st0_tag == TW_Infinity) {
+ if (FPU_st0_ptr->sign == SIGN_NEG)
+ arith_invalid(FPU_st0_ptr); /* sqrt(-Infinity) is
+ * invalid */
+ return;
+ } else {
+ single_arg_error();
+ return;
+ }
+
+}
+
+
+static void
+frndint_(void)
+{
+ if (!(FPU_st0_tag ^ TW_Valid)) {
+ if (FPU_st0_ptr->exp > EXP_BIAS + 63)
+ return;
+
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ round_to_int(FPU_st0_ptr); /* Fortunately, this can't
+ * overflow to 2^64 */
+ FPU_st0_ptr->exp = EXP_BIAS + 63;
+ normalize(FPU_st0_ptr);
+ return;
+ } else
+ if ((FPU_st0_tag == TW_Zero) || (FPU_st0_tag == TW_Infinity))
+ return;
+ else
+ single_arg_error();
+}
+
+
+static void
+fsin(void)
+{
+ char arg_sign = FPU_st0_ptr->sign;
+
+ if (FPU_st0_tag == TW_Valid) {
+ int q;
+ FPU_st0_ptr->sign = SIGN_POS;
+
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ if ((q = trig_arg(FPU_st0_ptr)) != -1) {
+ FPU_REG rv;
+
+ if (q & 1)
+ reg_sub(&CONST_1, FPU_st0_ptr, FPU_st0_ptr, FULL_PRECISION);
+
+ poly_sine(FPU_st0_ptr, &rv);
+
+ setcc(0);
+ if (q & 2)
+ rv.sign ^= SIGN_POS ^ SIGN_NEG;
+ rv.sign ^= arg_sign;
+ reg_move(&rv, FPU_st0_ptr);
+
+ if (FPU_st0_ptr->exp <= EXP_UNDER)
+ arith_underflow(FPU_st0_ptr);
+
+ set_precision_flag_up(); /* We do not really know
+ * if up or down */
+
+ return;
+ } else {
+ /* Operand is out of range */
+ setcc(SW_C2);
+ FPU_st0_ptr->sign = arg_sign; /* restore st(0) */
+ return;
+ }
+ } else
+ if (FPU_st0_tag == TW_Zero) {
+ setcc(0);
+ return;
+ } else
+ if (FPU_st0_tag == TW_Infinity) {
+ /* Operand is out of range */
+ setcc(SW_C2);
+ FPU_st0_ptr->sign = arg_sign; /* restore st(0) */
+ return;
+ } else
+ single_arg_error();
+}
+
+
+static int
+f_cos(FPU_REG * arg)
+{
+ char arg_sign = arg->sign;
+
+ if (arg->tag == TW_Valid) {
+ int q;
+
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return 1;
+#endif /* DENORM_OPERAND */
+
+ arg->sign = SIGN_POS;
+ if ((q = trig_arg(arg)) != -1) {
+ FPU_REG rv;
+
+ if (!(q & 1))
+ reg_sub(&CONST_1, arg, arg, FULL_PRECISION);
+
+ poly_sine(arg, &rv);
+
+ setcc(0);
+ if ((q + 1) & 2)
+ rv.sign ^= SIGN_POS ^ SIGN_NEG;
+ reg_move(&rv, arg);
+
+ set_precision_flag_up(); /* We do not really know
+ * if up or down */
+
+ return 0;
+ } else {
+ /* Operand is out of range */
+ setcc(SW_C2);
+ arg->sign = arg_sign; /* restore st(0) */
+ return 1;
+ }
+ } else
+ if (arg->tag == TW_Zero) {
+ reg_move(&CONST_1, arg);
+ setcc(0);
+ return 0;
+ } else
+ if (FPU_st0_tag == TW_Infinity) {
+ /* Operand is out of range */
+ setcc(SW_C2);
+ arg->sign = arg_sign; /* restore st(0) */
+ return 1;
+ } else {
+ single_arg_error(); /* requires arg ==
+ * &st(0) */
+ return 1;
+ }
+}
+
+
+static void
+fcos(void)
+{
+ f_cos(FPU_st0_ptr);
+}
+
+
+static void
+fsincos(void)
+{
+ FPU_REG *st_new_ptr;
+ FPU_REG arg;
+
+ if (STACK_OVERFLOW) {
+ stack_overflow();
+ return;
+ }
+ reg_move(FPU_st0_ptr, &arg);
+ if (!f_cos(&arg)) {
+ fsin();
+ push();
+ reg_move(&arg, FPU_st0_ptr);
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* The following all require two arguments: st(0) and st(1) */
+
+/* remainder of st(0) / st(1) */
+/* Assumes that st(0) and st(1) are both TW_Valid */
+static void
+fprem_kernel(int round)
+{
+ FPU_REG *st1_ptr = &st(1);
+ char st1_tag = st1_ptr->tag;
+
+ if (!((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid))) {
+ FPU_REG tmp;
+ int old_cw = control_word;
+ int expdif = FPU_st0_ptr->exp - (st1_ptr)->exp;
+
+#ifdef DENORM_OPERAND
+ if (((FPU_st0_ptr->exp <= EXP_UNDER) ||
+ (st1_ptr->exp <= EXP_UNDER)) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ control_word &= ~CW_RC;
+ control_word |= round;
+
+ if (expdif < 64) {
+ /* This should be the most common case */
+ long long q;
+ int c = 0;
+
+ reg_div(FPU_st0_ptr, st1_ptr, &tmp, FULL_PRECISION);
+
+ round_to_int(&tmp); /* Fortunately, this can't
+ * overflow to 2^64 */
+ tmp.exp = EXP_BIAS + 63;
+ q = *(long long *) &(tmp.sigl);
+ normalize(&tmp);
+
+ reg_mul(st1_ptr, &tmp, &tmp, FULL_PRECISION);
+ reg_sub(FPU_st0_ptr, &tmp, FPU_st0_ptr, FULL_PRECISION);
+
+ if (q & 4)
+ c |= SW_C3;
+ if (q & 2)
+ c |= SW_C1;
+ if (q & 1)
+ c |= SW_C0;
+
+ setcc(c);
+ } else {
+ /* There is a large exponent difference ( >= 64 ) */
+ int N_exp;
+
+ reg_div(FPU_st0_ptr, st1_ptr, &tmp, FULL_PRECISION);
+ /* N is 'a number between 32 and 63' (p26-113) */
+ N_exp = (tmp.exp & 31) + 32;
+ tmp.exp = EXP_BIAS + N_exp;
+
+ round_to_int(&tmp); /* Fortunately, this can't
+ * overflow to 2^64 */
+ tmp.exp = EXP_BIAS + 63;
+ normalize(&tmp);
+
+ tmp.exp = EXP_BIAS + expdif - N_exp;
+
+ reg_mul(st1_ptr, &tmp, &tmp, FULL_PRECISION);
+ reg_sub(FPU_st0_ptr, &tmp, FPU_st0_ptr, FULL_PRECISION);
+
+ setcc(SW_C2);
+ }
+ control_word = old_cw;
+
+ if (FPU_st0_ptr->exp <= EXP_UNDER)
+ arith_underflow(FPU_st0_ptr);
+ return;
+ } else
+ if ((FPU_st0_tag == TW_Empty) | (st1_tag == TW_Empty)) {
+ stack_underflow();
+ return;
+ } else
+ if (FPU_st0_tag == TW_Zero) {
+ if (st1_tag == TW_Valid) {
+
+#ifdef DENORM_OPERAND
+ if ((st1_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ setcc(0);
+ return;
+ } else
+ if (st1_tag == TW_Zero) {
+ arith_invalid(FPU_st0_ptr);
+ return;
+ }
+ /* fprem(?,0) always invalid */
+ else
+ if (st1_tag == TW_Infinity) {
+ setcc(0);
+ return;
+ }
+ } else
+ if (FPU_st0_tag == TW_Valid) {
+ if (st1_tag == TW_Zero) {
+ arith_invalid(FPU_st0_ptr); /* fprem(Valid,Zero) is
+ * invalid */
+ return;
+ } else
+ if (st1_tag != TW_NaN) {
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ if (st1_tag == TW_Infinity) {
+ /* fprem(Valid,
+ * Infinity)
+ * is o.k. */
+ setcc(0);
+ return;
+ }
+ }
+ } else
+ if (FPU_st0_tag == TW_Infinity) {
+ if (st1_tag != TW_NaN) {
+ arith_invalid(FPU_st0_ptr); /* fprem(Infinity,?) is
+ * invalid */
+ return;
+ }
+ }
+ /* One of the registers must contain a NaN is we got here. */
+
+#ifdef PARANOID
+ if ((FPU_st0_tag != TW_NaN) && (st1_tag != TW_NaN))
+ EXCEPTION(EX_INTERNAL | 0x118);
+#endif /* PARANOID */
+
+ real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr);
+
+}
+
+
+/* ST(1) <- ST(1) * log ST; pop ST */
+static void
+fyl2x(void)
+{
+ FPU_REG *st1_ptr = &st(1);
+ char st1_tag = st1_ptr->tag;
+
+ if (!((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid))) {
+ if (FPU_st0_ptr->sign == SIGN_POS) {
+ int saved_control, saved_status;
+
+#ifdef DENORM_OPERAND
+ if (((FPU_st0_ptr->exp <= EXP_UNDER) ||
+ (st1_ptr->exp <= EXP_UNDER)) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ /* We use the general purpose arithmetic, so we need
+ * to save these. */
+ saved_status = status_word;
+ saved_control = control_word;
+ control_word = FULL_PRECISION;
+
+ poly_l2(FPU_st0_ptr, FPU_st0_ptr);
+
+ /* Enough of the basic arithmetic is done now */
+ control_word = saved_control;
+ status_word = saved_status;
+
+ /* Let the multiply set the flags */
+ reg_mul(FPU_st0_ptr, st1_ptr, st1_ptr, FULL_PRECISION);
+
+ pop();
+ FPU_st0_ptr = &st(0);
+ } else {
+ /* negative */
+ pop();
+ FPU_st0_ptr = &st(0);
+ arith_invalid(FPU_st0_ptr); /* st(0) cannot be
+ * negative */
+ return;
+ }
+ } else
+ if ((FPU_st0_tag == TW_Empty) || (st1_tag == TW_Empty)) {
+ stack_underflow_pop(1);
+ return;
+ } else
+ if ((FPU_st0_tag == TW_NaN) || (st1_tag == TW_NaN)) {
+ real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr);
+ pop();
+ return;
+ } else
+ if ((FPU_st0_tag <= TW_Zero) && (st1_tag <= TW_Zero)) {
+ /* one of the args is zero, the other
+ * valid, or both zero */
+ if (FPU_st0_tag == TW_Zero) {
+ pop();
+ FPU_st0_ptr = &st(0);
+ if (FPU_st0_ptr->tag == TW_Zero)
+ arith_invalid(FPU_st0_ptr); /* Both args zero is
+ * invalid */
+#ifdef PECULIAR_486
+ /* This case is not
+ * specifically covered in the
+ * manual, but divide-by-zero
+ * would seem to be the best
+ * response. However, a real
+ * 80486 does it this way... */
+ else
+ if (FPU_st0_ptr->tag == TW_Infinity) {
+ reg_move(&CONST_INF, FPU_st0_ptr);
+ return;
+ }
+#endif /* PECULIAR_486 */
+ else
+ divide_by_zero(st1_ptr->sign ^ SIGN_NEG ^ SIGN_POS, FPU_st0_ptr);
+ return;
+ } else {
+ /* st(1) contains zero, st(0)
+ * valid <> 0 */
+ /* Zero is the valid answer */
+ char sign = st1_ptr->sign;
+
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+ if (FPU_st0_ptr->sign == SIGN_NEG) {
+ pop();
+ FPU_st0_ptr = &st(0);
+ arith_invalid(FPU_st0_ptr); /* log(negative) */
+ return;
+ }
+ if (FPU_st0_ptr->exp < EXP_BIAS)
+ sign ^= SIGN_NEG ^ SIGN_POS;
+ pop();
+ FPU_st0_ptr = &st(0);
+ reg_move(&CONST_Z, FPU_st0_ptr);
+ FPU_st0_ptr->sign = sign;
+ return;
+ }
+ }
+ /* One or both arg must be an infinity */
+ else
+ if (FPU_st0_tag == TW_Infinity) {
+ if ((FPU_st0_ptr->sign == SIGN_NEG) || (st1_tag == TW_Zero)) {
+ pop();
+ FPU_st0_ptr = &st(0);
+ arith_invalid(FPU_st0_ptr); /* log(-infinity) or
+ * 0*log(infinity) */
+ return;
+ } else {
+ char sign = st1_ptr->sign;
+
+#ifdef DENORM_OPERAND
+ if ((st1_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ pop();
+ FPU_st0_ptr = &st(0);
+ reg_move(&CONST_INF, FPU_st0_ptr);
+ FPU_st0_ptr->sign = sign;
+ return;
+ }
+ }
+ /* st(1) must be infinity here */
+ else
+ if ((FPU_st0_tag == TW_Valid) && (FPU_st0_ptr->sign == SIGN_POS)) {
+ if (FPU_st0_ptr->exp >= EXP_BIAS) {
+ if ((FPU_st0_ptr->exp == EXP_BIAS) &&
+ (FPU_st0_ptr->sigh == 0x80000000) &&
+ (FPU_st0_ptr->sigl == 0)) {
+ /* st(0
+ * )
+ * hold
+ * s
+ * 1.0 */
+ pop();
+ FPU_st0_ptr = &st(0);
+ arith_invalid(FPU_st0_ptr); /* infinity*log(1) */
+ return;
+ }
+ /* st(0) is
+ * positive
+ * and > 1.0 */
+ pop();
+ } else {
+ /* st(0) is
+ * positive
+ * and < 1.0 */
+
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ st1_ptr->sign ^= SIGN_NEG;
+ pop();
+ }
+ return;
+ } else {
+ /* st(0) must be zero
+ * or negative */
+ if (FPU_st0_ptr->tag == TW_Zero) {
+ pop();
+ FPU_st0_ptr = st1_ptr;
+ st1_ptr->sign ^= SIGN_NEG ^ SIGN_POS;
+ /* This should
+ * be invalid,
+ * but a real
+ * 80486 is
+ * happy with
+ * it. */
+#ifndef PECULIAR_486
+ divide_by_zero(st1_ptr->sign, FPU_st0_ptr);
+#endif /* PECULIAR_486 */
+ } else {
+ pop();
+ FPU_st0_ptr = st1_ptr;
+ arith_invalid(FPU_st0_ptr); /* log(negative) */
+ }
+ return;
+ }
+}
+
+
+static void
+fpatan(void)
+{
+ FPU_REG *st1_ptr = &st(1);
+ char st1_tag = st1_ptr->tag;
+
+ if (!((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid))) {
+ int saved_control, saved_status;
+ FPU_REG sum;
+ int quadrant = st1_ptr->sign | ((FPU_st0_ptr->sign) << 1);
+
+#ifdef DENORM_OPERAND
+ if (((FPU_st0_ptr->exp <= EXP_UNDER) ||
+ (st1_ptr->exp <= EXP_UNDER)) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ /* We use the general purpose arithmetic so we need to save
+ * these. */
+ saved_status = status_word;
+ saved_control = control_word;
+ control_word = FULL_PRECISION;
+
+ st1_ptr->sign = FPU_st0_ptr->sign = SIGN_POS;
+ if (compare(st1_ptr) == COMP_A_lt_B) {
+ quadrant |= 4;
+ reg_div(FPU_st0_ptr, st1_ptr, &sum, FULL_PRECISION);
+ } else
+ reg_div(st1_ptr, FPU_st0_ptr, &sum, FULL_PRECISION);
+
+ poly_atan(&sum);
+
+ if (quadrant & 4) {
+ reg_sub(&CONST_PI2, &sum, &sum, FULL_PRECISION);
+ }
+ if (quadrant & 2) {
+ reg_sub(&CONST_PI, &sum, &sum, FULL_PRECISION);
+ }
+ if (quadrant & 1)
+ sum.sign ^= SIGN_POS ^ SIGN_NEG;
+
+ /* All of the basic arithmetic is done now */
+ control_word = saved_control;
+ status_word = saved_status;
+
+ reg_move(&sum, st1_ptr);
+ } else
+ if ((FPU_st0_tag == TW_Empty) || (st1_tag == TW_Empty)) {
+ stack_underflow_pop(1);
+ return;
+ } else
+ if ((FPU_st0_tag == TW_NaN) || (st1_tag == TW_NaN)) {
+ real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr);
+ pop();
+ return;
+ } else
+ if ((FPU_st0_tag == TW_Infinity) || (st1_tag == TW_Infinity)) {
+ char sign = st1_ptr->sign;
+ if (FPU_st0_tag == TW_Infinity) {
+ if (st1_tag == TW_Infinity) {
+ if (FPU_st0_ptr->sign == SIGN_POS) {
+ reg_move(&CONST_PI4, st1_ptr);
+ } else
+ reg_add(&CONST_PI4, &CONST_PI2, st1_ptr, FULL_PRECISION);
+ } else {
+
+#ifdef DENORM_OPERAND
+ if ((st1_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ if (FPU_st0_ptr->sign == SIGN_POS) {
+ reg_move(&CONST_Z, st1_ptr);
+ pop();
+ return;
+ } else
+ reg_move(&CONST_PI, st1_ptr);
+ }
+ } else {
+ /* st(1) is infinity, st(0)
+ * not infinity */
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ reg_move(&CONST_PI2, st1_ptr);
+ }
+ st1_ptr->sign = sign;
+ } else
+ if (st1_tag == TW_Zero) {
+ /* st(0) must be valid or zero */
+ char sign = st1_ptr->sign;
+
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ if (FPU_st0_ptr->sign == SIGN_POS) {
+ reg_move(&CONST_Z, st1_ptr);
+ pop();
+ return;
+ } else
+ reg_move(&CONST_PI, st1_ptr);
+ st1_ptr->sign = sign;
+ } else
+ if (FPU_st0_tag == TW_Zero) {
+ /* st(1) must be
+ * TW_Valid here */
+ char sign = st1_ptr->sign;
+
+#ifdef DENORM_OPERAND
+ if ((st1_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ reg_move(&CONST_PI2, st1_ptr);
+ st1_ptr->sign = sign;
+ }
+#ifdef PARANOID
+ else
+ EXCEPTION(EX_INTERNAL | 0x220);
+#endif /* PARANOID */
+
+ pop();
+ set_precision_flag_up();/* We do not really know if up or down */
+}
+
+
+static void
+fprem(void)
+{
+ fprem_kernel(RC_CHOP);
+}
+
+
+static void
+fprem1(void)
+{
+ fprem_kernel(RC_RND);
+}
+
+
+static void
+fyl2xp1(void)
+{
+ FPU_REG *st1_ptr = &st(1);
+ char st1_tag = st1_ptr->tag;
+
+ if (!((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid))) {
+ int saved_control, saved_status;
+
+#ifdef DENORM_OPERAND
+ if (((FPU_st0_ptr->exp <= EXP_UNDER) ||
+ (st1_ptr->exp <= EXP_UNDER)) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ /* We use the general purpose arithmetic so we need to save
+ * these. */
+ saved_status = status_word;
+ saved_control = control_word;
+ control_word = FULL_PRECISION;
+
+ if (poly_l2p1(FPU_st0_ptr, FPU_st0_ptr)) {
+ arith_invalid(st1_ptr); /* poly_l2p1() returned
+ * invalid */
+ pop();
+ return;
+ }
+ /* Enough of the basic arithmetic is done now */
+ control_word = saved_control;
+ status_word = saved_status;
+
+ /* Let the multiply set the flags */
+ reg_mul(FPU_st0_ptr, st1_ptr, st1_ptr, FULL_PRECISION);
+
+ pop();
+ } else
+ if ((FPU_st0_tag == TW_Empty) | (st1_tag == TW_Empty)) {
+ stack_underflow_pop(1);
+ return;
+ } else
+ if (FPU_st0_tag == TW_Zero) {
+ if (st1_tag <= TW_Zero) {
+
+#ifdef DENORM_OPERAND
+ if ((st1_tag == TW_Valid) && (st1_ptr->exp <= EXP_UNDER) &&
+ (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ st1_ptr->sign ^= FPU_st0_ptr->sign;
+ reg_move(FPU_st0_ptr, st1_ptr);
+ } else
+ if (st1_tag == TW_Infinity) {
+ arith_invalid(st1_ptr); /* Infinity*log(1) */
+ pop();
+ return;
+ } else
+ if (st1_tag == TW_NaN) {
+ real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr);
+ pop();
+ return;
+ }
+#ifdef PARANOID
+ else {
+ EXCEPTION(EX_INTERNAL | 0x116);
+ return;
+ }
+#endif /* PARANOID */
+ pop();
+ return;
+ } else
+ if (FPU_st0_tag == TW_Valid) {
+ if (st1_tag == TW_Zero) {
+ if (FPU_st0_ptr->sign == SIGN_NEG) {
+ if (FPU_st0_ptr->exp >= EXP_BIAS) {
+ /* st(0) holds
+ * <= -1.0 */
+ arith_invalid(st1_ptr); /* infinity*log(1) */
+ pop();
+ return;
+ }
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+ st1_ptr->sign ^= SIGN_POS ^ SIGN_NEG;
+ pop();
+ return;
+ }
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+ pop();
+ return;
+ }
+ if (st1_tag == TW_Infinity) {
+ if (FPU_st0_ptr->sign == SIGN_NEG) {
+ if ((FPU_st0_ptr->exp >= EXP_BIAS) &&
+ !((FPU_st0_ptr->sigh == 0x80000000) &&
+ (FPU_st0_ptr->sigl == 0))) {
+ /* st(0) holds
+ * < -1.0 */
+ arith_invalid(st1_ptr);
+ pop();
+ return;
+ }
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+ st1_ptr->sign ^= SIGN_POS ^ SIGN_NEG;
+ pop();
+ return;
+ }
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+ pop();
+ return;
+ }
+ if (st1_tag == TW_NaN) {
+ real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr);
+ pop();
+ return;
+ }
+ } else
+ if (FPU_st0_tag == TW_NaN) {
+ real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr);
+ pop();
+ return;
+ } else
+ if (FPU_st0_tag == TW_Infinity) {
+ if (st1_tag == TW_NaN) {
+ real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr);
+ pop();
+ return;
+ } else
+ if ((FPU_st0_ptr->sign == SIGN_NEG) ||
+ (st1_tag == TW_Zero)) {
+ arith_invalid(st1_ptr); /* log(infinity) */
+ pop();
+ return;
+ }
+ /* st(1) must be valid
+ * here. */
+
+#ifdef DENORM_OPERAND
+ if ((st1_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ /* The Manual says
+ * that log(Infinity)
+ * is invalid, but a
+ * real 80486 sensibly
+ * says that it is
+ * o.k. */
+ {
+ char sign = st1_ptr->sign;
+ reg_move(&CONST_INF, st1_ptr);
+ st1_ptr->sign = sign;
+ }
+ pop();
+ return;
+ }
+#ifdef PARANOID
+ else {
+ EXCEPTION(EX_INTERNAL | 0x117);
+ }
+#endif /* PARANOID */
+}
+
+
+static void
+emu_fscale(void)
+{
+ FPU_REG *st1_ptr = &st(1);
+ char st1_tag = st1_ptr->tag;
+ int old_cw = control_word;
+
+ if (!((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid))) {
+ long scale;
+ FPU_REG tmp;
+
+#ifdef DENORM_OPERAND
+ if (((FPU_st0_ptr->exp <= EXP_UNDER) ||
+ (st1_ptr->exp <= EXP_UNDER)) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ if (st1_ptr->exp > EXP_BIAS + 30) {
+ /* 2^31 is far too large, would require 2^(2^30) or
+ * 2^(-2^30) */
+ char sign;
+
+ if (st1_ptr->sign == SIGN_POS) {
+ EXCEPTION(EX_Overflow);
+ sign = FPU_st0_ptr->sign;
+ reg_move(&CONST_INF, FPU_st0_ptr);
+ FPU_st0_ptr->sign = sign;
+ } else {
+ EXCEPTION(EX_Underflow);
+ sign = FPU_st0_ptr->sign;
+ reg_move(&CONST_Z, FPU_st0_ptr);
+ FPU_st0_ptr->sign = sign;
+ }
+ return;
+ }
+ control_word &= ~CW_RC;
+ control_word |= RC_CHOP;
+ reg_move(st1_ptr, &tmp);
+ round_to_int(&tmp); /* This can never overflow here */
+ control_word = old_cw;
+ scale = st1_ptr->sign ? -tmp.sigl : tmp.sigl;
+ scale += FPU_st0_ptr->exp;
+ FPU_st0_ptr->exp = scale;
+
+ /* Use round_reg() to properly detect under/overflow etc */
+ round_reg(FPU_st0_ptr, 0, control_word);
+
+ return;
+ } else
+ if (FPU_st0_tag == TW_Valid) {
+ if (st1_tag == TW_Zero) {
+
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ return;
+ }
+ if (st1_tag == TW_Infinity) {
+ char sign = st1_ptr->sign;
+
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ if (sign == SIGN_POS) {
+ reg_move(&CONST_INF, FPU_st0_ptr);
+ } else
+ reg_move(&CONST_Z, FPU_st0_ptr);
+ FPU_st0_ptr->sign = sign;
+ return;
+ }
+ if (st1_tag == TW_NaN) {
+ real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr);
+ return;
+ }
+ } else
+ if (FPU_st0_tag == TW_Zero) {
+ if (st1_tag == TW_Valid) {
+
+#ifdef DENORM_OPERAND
+ if ((st1_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ return;
+ } else
+ if (st1_tag == TW_Zero) {
+ return;
+ } else
+ if (st1_tag == TW_Infinity) {
+ if (st1_ptr->sign == SIGN_NEG)
+ return;
+ else {
+ arith_invalid(FPU_st0_ptr); /* Zero scaled by
+ * +Infinity */
+ return;
+ }
+ } else
+ if (st1_tag == TW_NaN) {
+ real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr);
+ return;
+ }
+ } else
+ if (FPU_st0_tag == TW_Infinity) {
+ if (st1_tag == TW_Valid) {
+
+#ifdef DENORM_OPERAND
+ if ((st1_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return;
+#endif /* DENORM_OPERAND */
+
+ return;
+ }
+ if (((st1_tag == TW_Infinity) && (st1_ptr->sign == SIGN_POS))
+ || (st1_tag == TW_Zero))
+ return;
+ else
+ if (st1_tag == TW_Infinity) {
+ arith_invalid(FPU_st0_ptr); /* Infinity scaled by
+ * -Infinity */
+ return;
+ } else
+ if (st1_tag == TW_NaN) {
+ real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr);
+ return;
+ }
+ } else
+ if (FPU_st0_tag == TW_NaN) {
+ if (st1_tag != TW_Empty) {
+ real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr);
+ return;
+ }
+ }
+#ifdef PARANOID
+ if (!((FPU_st0_tag == TW_Empty) || (st1_tag == TW_Empty))) {
+ EXCEPTION(EX_INTERNAL | 0x115);
+ return;
+ }
+#endif
+
+ /* At least one of st(0), st(1) must be empty */
+ stack_underflow();
+
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+static FUNC trig_table_a[] = {
+ f2xm1, fyl2x, fptan, fpatan, fxtract, fprem1, fdecstp, fincstp
+};
+
+void
+trig_a(void)
+{
+ (trig_table_a[FPU_rm]) ();
+}
+
+
+static FUNC trig_table_b[] =
+{
+ fprem, fyl2xp1, fsqrt_, fsincos, frndint_, emu_fscale, fsin, fcos
+};
+
+void
+trig_b(void)
+{
+ (trig_table_b[FPU_rm]) ();
+}
diff --git a/sys/gnu/fpemul/get_address.c b/sys/gnu/fpemul/get_address.c
new file mode 100644
index 000000000000..957ea4e2eeba
--- /dev/null
+++ b/sys/gnu/fpemul/get_address.c
@@ -0,0 +1,203 @@
+/*
+ * get_address.c
+ *
+ * Get the effective address from an FPU instruction.
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: get_address.c,v 1.3 1994/06/10 07:44:29 rich Exp $
+ *
+ */
+
+/*---------------------------------------------------------------------------+
+ | Note: |
+ | The file contains code which accesses user memory. |
+ | Emulator static data may change when user memory is accessed, due to |
+ | other processes using the emulator while swapping is in progress. |
+ +---------------------------------------------------------------------------*/
+
+#include "param.h"
+#include "proc.h"
+#include "systm.h"
+#include "machine/cpu.h"
+#include "machine/pcb.h"
+#include "machine/reg.h"
+
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "exception.h"
+
+static int reg_offset[] = {
+tEAX, tECX, tEDX, tEBX, tESP, tEBP, tESI, tEDI};
+#define REG_(x) (*(((int*)FPU_info) + reg_offset[(x)]))
+
+void *FPU_data_address;
+
+
+/* Decode the SIB byte. This function assumes mod != 0 */
+static void *
+sib(int mod)
+{
+ unsigned char ss, index, base;
+ long offset;
+
+ REENTRANT_CHECK(OFF);
+ base = fubyte((char *) FPU_EIP); /* The SIB byte */
+ REENTRANT_CHECK(ON);
+ FPU_EIP++;
+ ss = base >> 6;
+ index = (base >> 3) & 7;
+ base &= 7;
+
+ if ((mod == 0) && (base == 5))
+ offset = 0; /* No base register */
+ else
+ offset = REG_(base);
+
+ if (index == 4) {
+ /* No index register */
+ /* A non-zero ss is illegal */
+ if (ss)
+ EXCEPTION(EX_Invalid);
+ } else {
+ offset += (REG_(index)) << ss;
+ }
+
+ if (mod == 1) {
+ /* 8 bit signed displacement */
+ REENTRANT_CHECK(OFF);
+ offset += (signed char) fubyte((char *) FPU_EIP);
+ REENTRANT_CHECK(ON);
+ FPU_EIP++;
+ } else
+ if (mod == 2 || base == 5) { /* The second condition also
+ * has mod==0 */
+ /* 32 bit displacment */
+ REENTRANT_CHECK(OFF);
+ offset += (signed) fuword((unsigned long *) FPU_EIP);
+ REENTRANT_CHECK(ON);
+ FPU_EIP += 4;
+ }
+ return (void *) offset;
+}
+
+
+/*
+ MOD R/M byte: MOD == 3 has a special use for the FPU
+ SIB byte used iff R/M = 100b
+
+ 7 6 5 4 3 2 1 0
+ ..... ......... .........
+ MOD OPCODE(2) R/M
+
+
+ SIB byte
+
+ 7 6 5 4 3 2 1 0
+ ..... ......... .........
+ SS INDEX BASE
+
+*/
+
+void
+get_address(unsigned char FPU_modrm)
+{
+ unsigned char mod;
+ long *cpu_reg_ptr;
+ int offset = 0; /* Initialized just to stop compiler warnings. */
+
+ mod = (FPU_modrm >> 6) & 3;
+
+ if (FPU_rm == 4 && mod != 3) {
+ FPU_data_address = sib(mod);
+ return;
+ }
+ cpu_reg_ptr = (long *) &REG_(FPU_rm);
+ switch (mod) {
+ case 0:
+ if (FPU_rm == 5) {
+ /* Special case: disp32 */
+ REENTRANT_CHECK(OFF);
+ offset = fuword((unsigned long *) FPU_EIP);
+ REENTRANT_CHECK(ON);
+ FPU_EIP += 4;
+ FPU_data_address = (void *) offset;
+ return;
+ } else {
+ FPU_data_address = (void *) *cpu_reg_ptr; /* Just return the
+ * contents of the cpu
+ * register */
+ return;
+ }
+ case 1:
+ /* 8 bit signed displacement */
+ REENTRANT_CHECK(OFF);
+ offset = (signed char) fubyte((char *) FPU_EIP);
+ REENTRANT_CHECK(ON);
+ FPU_EIP++;
+ break;
+ case 2:
+ /* 32 bit displacement */
+ REENTRANT_CHECK(OFF);
+ offset = (signed) fuword((unsigned long *) FPU_EIP);
+ REENTRANT_CHECK(ON);
+ FPU_EIP += 4;
+ break;
+ case 3:
+ /* Not legal for the FPU */
+ EXCEPTION(EX_Invalid);
+ }
+
+ FPU_data_address = offset + (char *) *cpu_reg_ptr;
+}
diff --git a/sys/gnu/fpemul/load_store.c b/sys/gnu/fpemul/load_store.c
new file mode 100644
index 000000000000..a86a2fd3ec82
--- /dev/null
+++ b/sys/gnu/fpemul/load_store.c
@@ -0,0 +1,269 @@
+/*
+ * load_store.c
+ *
+ * This file contains most of the code to interpret the FPU instructions
+ * which load and store from user memory.
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: load_store.c,v 1.3 1994/06/10 07:44:30 rich Exp $
+ *
+ */
+
+/*---------------------------------------------------------------------------+
+ | Note: |
+ | The file contains code which accesses user memory. |
+ | Emulator static data may change when user memory is accessed, due to |
+ | other processes using the emulator while swapping is in progress. |
+ +---------------------------------------------------------------------------*/
+
+#include "param.h"
+#include "proc.h"
+#include "systm.h"
+#include "machine/cpu.h"
+#include "machine/pcb.h"
+
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "exception.h"
+#include "status_w.h"
+
+
+#define _NONE_ 0 /* FPU_st0_ptr etc not needed */
+#define _REG0_ 1 /* Will be storing st(0) */
+#define _PUSH_ 3 /* Need to check for space to push onto stack */
+#define _null_ 4 /* Function illegal or not implemented */
+
+#define pop_0() { pop_ptr->tag = TW_Empty; top++; }
+
+
+static unsigned char type_table[32] = {
+ _PUSH_, _PUSH_, _PUSH_, _PUSH_,
+ _null_, _null_, _null_, _null_,
+ _REG0_, _REG0_, _REG0_, _REG0_,
+ _REG0_, _REG0_, _REG0_, _REG0_,
+ _NONE_, _null_, _NONE_, _PUSH_,
+ _NONE_, _PUSH_, _null_, _PUSH_,
+ _NONE_, _null_, _NONE_, _REG0_,
+ _NONE_, _REG0_, _NONE_, _REG0_
+};
+
+void
+load_store_instr(char type)
+{
+ FPU_REG *pop_ptr; /* We need a version of FPU_st0_ptr which
+ * won't change. */
+
+ pop_ptr = NULL; /* Initialized just to stop compiler warnings. */
+
+
+ switch (type_table[(int) (unsigned) type]) {
+ case _NONE_:
+ break;
+ case _REG0_:
+ pop_ptr = &st(0); /* Some of these instructions pop
+ * after storing */
+
+ FPU_st0_ptr = pop_ptr; /* Set the global variables. */
+ FPU_st0_tag = FPU_st0_ptr->tag;
+ break;
+ case _PUSH_:
+ {
+ pop_ptr = &st(-1);
+ if (pop_ptr->tag != TW_Empty) {
+ stack_overflow();
+ return;
+ }
+ top--;
+ }
+ break;
+ case _null_:
+ return Un_impl();
+#ifdef PARANOID
+ default:
+ return EXCEPTION(EX_INTERNAL);
+#endif /* PARANOID */
+ }
+
+ switch (type) {
+ case 000: /* fld m32real */
+ reg_load_single();
+ setcc(0); /* Clear the SW_C1 bit, "other bits undefined" */
+ reg_move(&FPU_loaded_data, pop_ptr);
+ break;
+ case 001: /* fild m32int */
+ reg_load_int32();
+ setcc(0); /* Clear the SW_C1 bit, "other bits undefined" */
+ reg_move(&FPU_loaded_data, pop_ptr);
+ break;
+ case 002: /* fld m64real */
+ reg_load_double();
+ setcc(0); /* Clear the SW_C1 bit, "other bits undefined" */
+ reg_move(&FPU_loaded_data, pop_ptr);
+ break;
+ case 003: /* fild m16int */
+ reg_load_int16();
+ setcc(0); /* Clear the SW_C1 bit, "other bits undefined" */
+ reg_move(&FPU_loaded_data, pop_ptr);
+ break;
+ case 010: /* fst m32real */
+ reg_store_single();
+ break;
+ case 011: /* fist m32int */
+ reg_store_int32();
+ break;
+ case 012: /* fst m64real */
+ reg_store_double();
+ break;
+ case 013: /* fist m16int */
+ reg_store_int16();
+ break;
+ case 014: /* fstp m32real */
+ if (reg_store_single())
+ pop_0();/* pop only if the number was actually stored
+ * (see the 80486 manual p16-28) */
+ break;
+ case 015: /* fistp m32int */
+ if (reg_store_int32())
+ pop_0();/* pop only if the number was actually stored
+ * (see the 80486 manual p16-28) */
+ break;
+ case 016: /* fstp m64real */
+ if (reg_store_double())
+ pop_0();/* pop only if the number was actually stored
+ * (see the 80486 manual p16-28) */
+ break;
+ case 017: /* fistp m16int */
+ if (reg_store_int16())
+ pop_0();/* pop only if the number was actually stored
+ * (see the 80486 manual p16-28) */
+ break;
+ case 020: /* fldenv m14/28byte */
+ fldenv();
+ break;
+ case 022: /* frstor m94/108byte */
+ frstor();
+ break;
+ case 023: /* fbld m80dec */
+ reg_load_bcd();
+ setcc(0); /* Clear the SW_C1 bit, "other bits undefined" */
+ reg_move(&FPU_loaded_data, pop_ptr);
+ break;
+ case 024: /* fldcw */
+ REENTRANT_CHECK(OFF);
+ control_word = fuword((unsigned short *) FPU_data_address);
+ REENTRANT_CHECK(ON);
+#ifdef NO_UNDERFLOW_TRAP
+ if (!(control_word & EX_Underflow)) {
+ control_word |= EX_Underflow;
+ }
+#endif
+ FPU_data_address = (void *) data_operand_offset; /* We want no net effect */
+ FPU_entry_eip = ip_offset; /* We want no net effect */
+ break;
+ case 025: /* fld m80real */
+ reg_load_extended();
+ setcc(0); /* Clear the SW_C1 bit, "other bits undefined" */
+ reg_move(&FPU_loaded_data, pop_ptr);
+ break;
+ case 027: /* fild m64int */
+ reg_load_int64();
+ setcc(0); /* Clear the SW_C1 bit, "other bits undefined" */
+ reg_move(&FPU_loaded_data, pop_ptr);
+ break;
+ case 030: /* fstenv m14/28byte */
+ fstenv();
+ FPU_data_address = (void *) data_operand_offset; /* We want no net effect */
+ FPU_entry_eip = ip_offset; /* We want no net effect */
+ break;
+ case 032: /* fsave */
+ fsave();
+ FPU_data_address = (void *) data_operand_offset; /* We want no net effect */
+ FPU_entry_eip = ip_offset; /* We want no net effect */
+ break;
+ case 033: /* fbstp m80dec */
+ if (reg_store_bcd())
+ pop_0();/* pop only if the number was actually stored
+ * (see the 80486 manual p16-28) */
+ break;
+ case 034: /* fstcw m16int */
+ REENTRANT_CHECK(OFF);
+/* verify_area(VERIFY_WRITE, FPU_data_address, 2);*/
+ suword( (short *) FPU_data_address,control_word);
+ REENTRANT_CHECK(ON);
+ FPU_data_address = (void *) data_operand_offset; /* We want no net effect */
+ FPU_entry_eip = ip_offset; /* We want no net effect */
+ break;
+ case 035: /* fstp m80real */
+ if (reg_store_extended())
+ pop_0();/* pop only if the number was actually stored
+ * (see the 80486 manual p16-28) */
+ break;
+ case 036: /* fstsw m2byte */
+ status_word &= ~SW_Top;
+ status_word |= (top & 7) << SW_Top_Shift;
+ REENTRANT_CHECK(OFF);
+/* verify_area(VERIFY_WRITE, FPU_data_address, 2);*/
+ suword( (short *) FPU_data_address,status_word);
+ REENTRANT_CHECK(ON);
+ FPU_data_address = (void *) data_operand_offset; /* We want no net effect */
+ FPU_entry_eip = ip_offset; /* We want no net effect */
+ break;
+ case 037: /* fistp m64int */
+ if (reg_store_int64())
+ pop_0();/* pop only if the number was actually stored
+ * (see the 80486 manual p16-28) */
+ break;
+ }
+}
diff --git a/sys/gnu/fpemul/math_emu.h b/sys/gnu/fpemul/math_emu.h
new file mode 100644
index 000000000000..031d391595b5
--- /dev/null
+++ b/sys/gnu/fpemul/math_emu.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * $Id: math_emu.h,v 1.2 1994/04/29 21:23:24 gclarkii Exp $
+ *
+ */
+
+#ifndef _MATH_EMU_H
+#define _MATH_EMU_H
+
+struct fpu_reg {
+ char sign;
+ char tag;
+ long exp;
+ u_long sigl;
+ u_long sigh;
+};
+
+union i387_union {
+ struct i387_hard_struct {
+ long cwd;
+ long swd;
+ long twd;
+ long fip;
+ long fcs;
+ long foo;
+ long fos;
+ long st_space[20]; /* 8*10 bytes for each FP-reg = 80
+ * bytes */
+ } hard;
+ struct i387_soft_struct {
+ long cwd;
+ long swd;
+ long twd;
+ long fip;
+ long fcs;
+ long foo;
+ long fos;
+ long top;
+ struct fpu_reg regs[8]; /* 8*16 bytes for each FP-reg = 128
+ * bytes */
+ unsigned char lookahead;
+ struct trapframe *frame;
+ unsigned long entry_eip;
+ int orig_eip;
+ } soft;
+};
+#endif
diff --git a/sys/gnu/fpemul/poly_2xm1.c b/sys/gnu/fpemul/poly_2xm1.c
new file mode 100644
index 000000000000..d4da1bb81527
--- /dev/null
+++ b/sys/gnu/fpemul/poly_2xm1.c
@@ -0,0 +1,141 @@
+/*
+ * poly_2xm1.c
+ *
+ * Function to compute 2^x-1 by a polynomial approximation.
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: poly_2xm1.c,v 1.3 1994/06/10 07:44:32 rich Exp $
+ *
+ */
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+
+
+
+#define HIPOWER 13
+static unsigned short lterms[HIPOWER][4] =
+{
+ {0x79b5, 0xd1cf, 0x17f7, 0xb172},
+ {0x1b56, 0x058b, 0x7bff, 0x3d7f},
+ {0x8bb0, 0x8250, 0x846b, 0x0e35},
+ {0xbc65, 0xf747, 0x556d, 0x0276},
+ {0x17cb, 0x9e39, 0x61ff, 0x0057},
+ {0xe018, 0x9776, 0x1848, 0x000a},
+ {0x66f2, 0xff30, 0xffe5, 0x0000},
+ {0x682f, 0xffb6, 0x162b, 0x0000},
+ {0xb7ca, 0x2956, 0x01b5, 0x0000},
+ {0xcd3e, 0x4817, 0x001e, 0x0000},
+ {0xb7e2, 0xecbe, 0x0001, 0x0000},
+ {0x0ed5, 0x1a27, 0x0000, 0x0000},
+ {0x101d, 0x0222, 0x0000, 0x0000},
+};
+
+
+/*--- poly_2xm1() -----------------------------------------------------------+
+ | |
+ +---------------------------------------------------------------------------*/
+int
+poly_2xm1(FPU_REG * arg, FPU_REG * result)
+{
+ short exponent;
+ long long Xll;
+ FPU_REG accum;
+
+
+ exponent = arg->exp - EXP_BIAS;
+
+ if (arg->tag == TW_Zero) {
+ /* Return 0.0 */
+ reg_move(&CONST_Z, result);
+ return 0;
+ }
+ if (exponent >= 0) { /* Can't hack a number >= 1.0 */
+ arith_invalid(result); /* Number too large */
+ return 1;
+ }
+ if (arg->sign != SIGN_POS) { /* Can't hack a number < 0.0 */
+ arith_invalid(result); /* Number negative */
+ return 1;
+ }
+ if (exponent < -64) {
+ reg_move(&CONST_LN2, result);
+ return 0;
+ }
+ *(unsigned *) &Xll = arg->sigl;
+ *(((unsigned *) &Xll) + 1) = arg->sigh;
+ if (exponent < -1) {
+ /* shift the argument right by the required places */
+ if (shrx(&Xll, -1 - exponent) >= (unsigned)0x80000000)
+ Xll++; /* round up */
+ }
+ *(short *) &(accum.sign) = 0; /* will be a valid positive nr with
+ * expon = 0 */
+ accum.exp = 0;
+
+ /* Do the basic fixed point polynomial evaluation */
+ polynomial((unsigned *) &accum.sigl, (unsigned *) &Xll, lterms, HIPOWER - 1);
+
+ /* Convert to 64 bit signed-compatible */
+ accum.exp += EXP_BIAS - 1;
+
+ reg_move(&accum, result);
+
+ normalize(result);
+
+ return 0;
+
+}
diff --git a/sys/gnu/fpemul/poly_atan.c b/sys/gnu/fpemul/poly_atan.c
new file mode 100644
index 000000000000..f597ed9af43e
--- /dev/null
+++ b/sys/gnu/fpemul/poly_atan.c
@@ -0,0 +1,252 @@
+/*
+ * p_atan.c
+ *
+ * Compute the tan of a FPU_REG, using a polynomial approximation.
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: poly_atan.c,v 1.4 1994/06/10 07:44:34 rich Exp $
+ *
+ */
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+
+#define HIPOWERon 6 /* odd poly, negative terms */
+static unsigned oddnegterms[HIPOWERon][2] =
+{
+ {0x00000000, 0x00000000}, /* for + 1.0 */
+ {0x763b6f3d, 0x1adc4428},
+ {0x20f0630b, 0x0502909d},
+ {0x4e825578, 0x0198ce38},
+ {0x22b7cb87, 0x008da6e3},
+ {0x9b30ca03, 0x00239c79}
+};
+#define HIPOWERop 6 /* odd poly, positive terms */
+static unsigned oddplterms[HIPOWERop][2] =
+{
+ {0xa6f67cb8, 0x94d910bd},
+ {0xa02ffab4, 0x0a43cb45},
+ {0x04265e6b, 0x02bf5655},
+ {0x0a728914, 0x00f280f7},
+ {0x6d640e01, 0x004d6556},
+ {0xf1dd2dbf, 0x000a530a}
+};
+
+
+static unsigned denomterm[2] =
+{0xfc4bd208, 0xea2e6612};
+
+
+
+/*--- poly_atan() -----------------------------------------------------------+
+ | |
+ +---------------------------------------------------------------------------*/
+void
+poly_atan(FPU_REG * arg)
+{
+ char recursions = 0;
+ short exponent;
+ FPU_REG odd_poly, even_poly, pos_poly, neg_poly;
+ FPU_REG argSq;
+ long long arg_signif, argSqSq;
+
+
+#ifdef PARANOID
+ if (arg->sign != 0) { /* Can't hack a number < 0.0 */
+ arith_invalid(arg);
+ return;
+ } /* Need a positive number */
+#endif /* PARANOID */
+
+ exponent = arg->exp - EXP_BIAS;
+
+ if (arg->tag == TW_Zero) {
+ /* Return 0.0 */
+ reg_move(&CONST_Z, arg);
+ return;
+ }
+ if (exponent >= -2) {
+ /* argument is in the range [0.25 .. 1.0] */
+ if (exponent >= 0) {
+#ifdef PARANOID
+ if ((exponent == 0) &&
+ (arg->sigl == 0) && (arg->sigh == 0x80000000))
+#endif /* PARANOID */
+ {
+ reg_move(&CONST_PI4, arg);
+ return;
+ }
+#ifdef PARANOID
+ EXCEPTION(EX_INTERNAL | 0x104); /* There must be a logic
+ * error */
+#endif /* PARANOID */
+ }
+ /* If the argument is greater than sqrt(2)-1 (=0.414213562...) */
+ /* convert the argument by an identity for atan */
+ if ((exponent >= -1) || (arg->sigh > 0xd413ccd0)) {
+ FPU_REG numerator, denom;
+
+ recursions++;
+
+ arg_signif = *(long long *) &(arg->sigl);
+ if (exponent < -1) {
+ if (shrx(&arg_signif, -1 - exponent) >= (unsigned)0x80000000)
+ arg_signif++; /* round up */
+ }
+ *(long long *) &(numerator.sigl) = -arg_signif;
+ numerator.exp = EXP_BIAS - 1;
+ normalize(&numerator); /* 1 - arg */
+
+ arg_signif = *(long long *) &(arg->sigl);
+ if (shrx(&arg_signif, -exponent) >= (unsigned)0x80000000)
+ arg_signif++; /* round up */
+ *(long long *) &(denom.sigl) = arg_signif;
+ denom.sigh |= 0x80000000; /* 1 + arg */
+
+ arg->exp = numerator.exp;
+ reg_u_div(&numerator, &denom, arg, FULL_PRECISION);
+
+ exponent = arg->exp - EXP_BIAS;
+ }
+ }
+ *(long long *) &arg_signif = *(long long *) &(arg->sigl);
+
+#ifdef PARANOID
+ /* This must always be true */
+ if (exponent >= -1) {
+ EXCEPTION(EX_INTERNAL | 0x120); /* There must be a logic error */
+ }
+#endif /* PARANOID */
+
+ /* shift the argument right by the required places */
+ if (shrx(&arg_signif, -1 - exponent) >= (unsigned)0x80000000)
+ arg_signif++; /* round up */
+
+ /* Now have arg_signif with binary point at the left .1xxxxxxxx */
+ mul64(&arg_signif, &arg_signif, (long long *) (&argSq.sigl));
+ mul64((long long *) (&argSq.sigl), (long long *) (&argSq.sigl), &argSqSq);
+
+ /* will be a valid positive nr with expon = 0 */
+ *(short *) &(pos_poly.sign) = 0;
+ pos_poly.exp = EXP_BIAS;
+
+ /* Do the basic fixed point polynomial evaluation */
+ polynomial((u_int *) &pos_poly.sigl, (unsigned *) &argSqSq,
+ (unsigned short (*)[4]) oddplterms, HIPOWERop - 1);
+ mul64((long long *) (&argSq.sigl), (long long *) (&pos_poly.sigl),
+ (long long *) (&pos_poly.sigl));
+
+ /* will be a valid positive nr with expon = 0 */
+ *(short *) &(neg_poly.sign) = 0;
+ neg_poly.exp = EXP_BIAS;
+
+ /* Do the basic fixed point polynomial evaluation */
+ polynomial((u_int *) &neg_poly.sigl, (unsigned *) &argSqSq,
+ (unsigned short (*)[4]) oddnegterms, HIPOWERon - 1);
+
+ /* Subtract the mantissas */
+ *((long long *) (&pos_poly.sigl)) -= *((long long *) (&neg_poly.sigl));
+
+ reg_move(&pos_poly, &odd_poly);
+ poly_add_1(&odd_poly);
+
+ /* The complete odd polynomial */
+ reg_u_mul(&odd_poly, arg, &odd_poly, FULL_PRECISION);
+
+ /* will be a valid positive nr with expon = 0 */
+ *(short *) &(even_poly.sign) = 0;
+
+ mul64((long long *) (&argSq.sigl),
+ (long long *) (&denomterm), (long long *) (&even_poly.sigl));
+
+ poly_add_1(&even_poly);
+
+ reg_div(&odd_poly, &even_poly, arg, FULL_PRECISION);
+
+ if (recursions)
+ reg_sub(&CONST_PI4, arg, arg, FULL_PRECISION);
+}
+
+
+/* The argument to this function must be polynomial() compatible,
+ i.e. have an exponent (not checked) of EXP_BIAS-1 but need not
+ be normalized.
+ This function adds 1.0 to the (assumed positive) argument. */
+void
+poly_add_1(FPU_REG * src)
+{
+/* Rounding in a consistent direction produces better results
+ for the use of this function in poly_atan. Simple truncation
+ is used here instead of round-to-nearest. */
+
+#ifdef OBSOLETE
+ char round = (src->sigl & 3) == 3;
+#endif /* OBSOLETE */
+
+ shrx(&src->sigl, 1);
+
+#ifdef OBSOLETE
+ if (round)
+ (*(long long *) &src->sigl)++; /* Round to even */
+#endif /* OBSOLETE */
+
+ src->sigh |= 0x80000000;
+
+ src->exp = EXP_BIAS;
+
+}
diff --git a/sys/gnu/fpemul/poly_div.s b/sys/gnu/fpemul/poly_div.s
new file mode 100644
index 000000000000..dce95ed82aae
--- /dev/null
+++ b/sys/gnu/fpemul/poly_div.s
@@ -0,0 +1,144 @@
+ .file "poly_div.S"
+/*
+ * poly_div.S
+ *
+ * A set of functions to divide 64 bit integers by fixed numbers.
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: poly_div.s,v 1.3 1994/06/10 07:44:36 rich Exp $
+ *
+ */
+
+#include "fpu_asm.h"
+
+.text
+
+/*---------------------------------------------------------------------------*/
+ .align 2,144
+.globl _poly_div2
+_poly_div2:
+ pushl %ebp
+ movl %esp,%ebp
+
+ movl PARAM1,%ecx
+ movw (%ecx),%ax
+
+ shrl $1,4(%ecx)
+ rcrl $1,(%ecx)
+
+ testw $1,%ax
+ je poly_div2_exit
+
+ addl $1,(%ecx)
+ adcl $0,4(%ecx)
+poly_div2_exit:
+
+ leave
+ ret
+/*---------------------------------------------------------------------------*/
+ .align 2,144
+.globl _poly_div4
+_poly_div4:
+ pushl %ebp
+ movl %esp,%ebp
+
+ movl PARAM1,%ecx
+ movw (%ecx),%ax
+
+ movl 4(%ecx),%edx
+ shll $30,%edx
+
+ shrl $2,4(%ecx)
+ shrl $2,(%ecx)
+
+ orl %edx,(%ecx)
+
+ testw $2,%ax
+ je poly_div4_exit
+
+ addl $1,(%ecx)
+ adcl $0,4(%ecx)
+poly_div4_exit:
+
+ leave
+ ret
+/*---------------------------------------------------------------------------*/
+ .align 2,144
+.globl _poly_div16
+_poly_div16:
+ pushl %ebp
+ movl %esp,%ebp
+
+ movl PARAM1,%ecx
+ movw (%ecx),%ax
+
+ movl 4(%ecx),%edx
+ shll $28,%edx
+
+ shrl $4,4(%ecx)
+ shrl $4,(%ecx)
+
+ orl %edx,(%ecx)
+
+ testw $8,%ax
+ je poly_div16_exit
+
+ addl $1,(%ecx)
+ adcl $0,4(%ecx)
+poly_div16_exit:
+
+ leave
+ ret
+/*---------------------------------------------------------------------------*/
diff --git a/sys/gnu/fpemul/poly_l2.c b/sys/gnu/fpemul/poly_l2.c
new file mode 100644
index 000000000000..7c44103fd049
--- /dev/null
+++ b/sys/gnu/fpemul/poly_l2.c
@@ -0,0 +1,318 @@
+/*
+ * poly_l2.c
+ *
+ * Compute the base 2 log of a FPU_REG, using a polynomial approximation.
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: poly_l2.c,v 1.5 1994/06/10 07:44:38 rich Exp $
+ *
+ */
+
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+
+
+#define HIPOWER 9
+static unsigned short lterms[HIPOWER][4] =
+{
+ /* Ideal computation with these coeffs gives about 64.6 bit rel
+ * accuracy. */
+ {0xe177, 0xb82f, 0x7652, 0x7154},
+ {0xee0f, 0xe80f, 0x2770, 0x7b1c},
+ {0x0fc0, 0xbe87, 0xb143, 0x49dd},
+ {0x78b9, 0xdadd, 0xec54, 0x34c2},
+ {0x003a, 0x5de9, 0x628b, 0x2909},
+ {0x5588, 0xed16, 0x4abf, 0x2193},
+ {0xb461, 0x85f7, 0x347a, 0x1c6a},
+ {0x0975, 0x87b3, 0xd5bf, 0x1876},
+ {0xe85c, 0xcec9, 0x84e7, 0x187d}
+};
+
+
+
+
+/*--- poly_l2() -------------------------------------------------------------+
+ | Base 2 logarithm by a polynomial approximation. |
+ +---------------------------------------------------------------------------*/
+void
+poly_l2(FPU_REG * arg, FPU_REG * result)
+{
+ short exponent;
+ char zero; /* flag for an Xx == 0 */
+ unsigned short bits, shift;
+ long long Xsq;
+ FPU_REG accum, denom, num, Xx;
+
+
+ exponent = arg->exp - EXP_BIAS;
+
+ accum.tag = TW_Valid; /* set the tags to Valid */
+
+ if (arg->sigh > (unsigned) 0xb504f334) {
+ /* This is good enough for the computation of the polynomial
+ * sum, but actually results in a loss of precision for the
+ * computation of Xx. This will matter only if exponent
+ * becomes zero. */
+ exponent++;
+ accum.sign = 1; /* sign to negative */
+ num.exp = EXP_BIAS; /* needed to prevent errors in div
+ * routine */
+ reg_u_div(&CONST_1, arg, &num, FULL_PRECISION);
+ } else {
+ accum.sign = 0; /* set the sign to positive */
+ num.sigl = arg->sigl; /* copy the mantissa */
+ num.sigh = arg->sigh;
+ }
+
+
+ /* shift num left, lose the ms bit */
+ num.sigh <<= 1;
+ if (num.sigl & 0x80000000)
+ num.sigh |= 1;
+ num.sigl <<= 1;
+
+ denom.sigl = num.sigl;
+ denom.sigh = num.sigh;
+ poly_div4((long long *) &(denom.sigl));
+ denom.sigh += 0x80000000; /* set the msb */
+ Xx.exp = EXP_BIAS; /* needed to prevent errors in div routine */
+ reg_u_div(&num, &denom, &Xx, FULL_PRECISION);
+
+ zero = !(Xx.sigh | Xx.sigl);
+
+ mul64((long long *) &Xx.sigl, (long long *) &Xx.sigl, &Xsq);
+ poly_div16(&Xsq);
+
+ accum.exp = -1; /* exponent of accum */
+
+ /* Do the basic fixed point polynomial evaluation */
+ polynomial((unsigned *) &accum.sigl, (unsigned *) &Xsq, lterms, HIPOWER - 1);
+
+ if (!exponent) {
+ /* If the exponent is zero, then we would lose precision by
+ * sticking to fixed point computation here */
+ /* We need to re-compute Xx because of loss of precision. */
+ FPU_REG lXx;
+ char sign;
+
+ sign = accum.sign;
+ accum.sign = 0;
+
+ /* make accum compatible and normalize */
+ accum.exp = EXP_BIAS + accum.exp;
+ normalize(&accum);
+
+ if (zero) {
+ reg_move(&CONST_Z, result);
+ } else {
+ /* we need to re-compute lXx to better accuracy */
+ num.tag = TW_Valid; /* set the tags to Vaild */
+ num.sign = 0; /* set the sign to positive */
+ num.exp = EXP_BIAS - 1;
+ if (sign) {
+ /* The argument is of the form 1-x */
+ /* Use 1-1/(1-x) = x/(1-x) */
+ *((long long *) &num.sigl) = -*((long long *) &(arg->sigl));
+ normalize(&num);
+ reg_div(&num, arg, &num, FULL_PRECISION);
+ } else {
+ normalize(&num);
+ }
+
+ denom.tag = TW_Valid; /* set the tags to Valid */
+ denom.sign = SIGN_POS; /* set the sign to positive */
+ denom.exp = EXP_BIAS;
+
+ reg_div(&num, &denom, &lXx, FULL_PRECISION);
+
+ reg_u_mul(&lXx, &accum, &accum, FULL_PRECISION);
+
+ reg_u_add(&lXx, &accum, result, FULL_PRECISION);
+
+ normalize(result);
+ }
+
+ result->sign = sign;
+ return;
+ }
+ mul64((long long *) &accum.sigl,
+ (long long *) &Xx.sigl, (long long *) &accum.sigl);
+
+ *((long long *) (&accum.sigl)) += *((long long *) (&Xx.sigl));
+
+ if (Xx.sigh > accum.sigh) {
+ /* There was an overflow */
+
+ poly_div2((long long *) &accum.sigl);
+ accum.sigh |= 0x80000000;
+ accum.exp++;
+ }
+ /* When we add the exponent to the accum result later, we will require
+ * that their signs are the same. Here we ensure that this is so. */
+ if (exponent && ((exponent < 0) ^ (accum.sign))) {
+ /* signs are different */
+
+ accum.sign = !accum.sign;
+
+ /* An exceptional case is when accum is zero */
+ if (accum.sigl | accum.sigh) {
+ /* find 1-accum */
+ /* Shift to get exponent == 0 */
+ if (accum.exp < 0) {
+ poly_div2((long long *) &accum.sigl);
+ accum.exp++;
+ }
+ /* Just negate, but throw away the sign */
+ *((long long *) &(accum.sigl)) = -*((long long *) &(accum.sigl));
+ if (exponent < 0)
+ exponent++;
+ else
+ exponent--;
+ }
+ }
+ shift = exponent >= 0 ? exponent : -exponent;
+ bits = 0;
+ if (shift) {
+ if (accum.exp) {
+ accum.exp++;
+ poly_div2((long long *) &accum.sigl);
+ }
+ while (shift) {
+ poly_div2((long long *) &accum.sigl);
+ if (shift & 1)
+ accum.sigh |= 0x80000000;
+ shift >>= 1;
+ bits++;
+ }
+ }
+ /* Convert to 64 bit signed-compatible */
+ accum.exp += bits + EXP_BIAS - 1;
+
+ reg_move(&accum, result);
+ normalize(result);
+
+ return;
+}
+
+
+/*--- poly_l2p1() -----------------------------------------------------------+
+ | Base 2 logarithm by a polynomial approximation. |
+ | log2(x+1) |
+ +---------------------------------------------------------------------------*/
+int
+poly_l2p1(FPU_REG * arg, FPU_REG * result)
+{
+ char sign = 0;
+ long long Xsq;
+ FPU_REG arg_pl1, denom, accum, local_arg, poly_arg;
+
+
+ sign = arg->sign;
+
+ reg_add(arg, &CONST_1, &arg_pl1, FULL_PRECISION);
+
+ if ((arg_pl1.sign) | (arg_pl1.tag)) { /* We need a valid positive
+ * number! */
+ return 1;
+ }
+ reg_add(&CONST_1, &arg_pl1, &denom, FULL_PRECISION);
+ reg_div(arg, &denom, &local_arg, FULL_PRECISION);
+ local_arg.sign = 0; /* Make the sign positive */
+
+ /* Now we need to check that |local_arg| is less than 3-2*sqrt(2) =
+ * 0.17157.. = .0xafb0ccc0 * 2^-2 */
+
+ if (local_arg.exp >= EXP_BIAS - 3) {
+ if ((local_arg.exp > EXP_BIAS - 3) ||
+ (local_arg.sigh > (unsigned) 0xafb0ccc0)) {
+ /* The argument is large */
+ poly_l2(&arg_pl1, result);
+ return 0;
+ }
+ }
+ /* Make a copy of local_arg */
+ reg_move(&local_arg, &poly_arg);
+
+ /* Get poly_arg bits aligned as required */
+ shrx((unsigned *) &(poly_arg.sigl), -(poly_arg.exp - EXP_BIAS + 3));
+
+ mul64((long long *) &(poly_arg.sigl), (long long *) &(poly_arg.sigl), &Xsq);
+ poly_div16(&Xsq);
+
+ /* Do the basic fixed point polynomial evaluation */
+ polynomial((u_int *) &accum.sigl, (unsigned *) &Xsq, lterms, HIPOWER - 1);
+
+ accum.tag = TW_Valid; /* set the tags to Valid */
+ accum.sign = SIGN_POS; /* and make accum positive */
+
+ /* make accum compatible and normalize */
+ accum.exp = EXP_BIAS - 1;
+ normalize(&accum);
+
+ reg_u_mul(&local_arg, &accum, &accum, FULL_PRECISION);
+
+ reg_u_add(&local_arg, &accum, result, FULL_PRECISION);
+
+ /* Multiply the result by 2 */
+ result->exp++;
+
+ result->sign = sign;
+
+ return 0;
+}
diff --git a/sys/gnu/fpemul/poly_mul64.s b/sys/gnu/fpemul/poly_mul64.s
new file mode 100644
index 000000000000..be5a136a1299
--- /dev/null
+++ b/sys/gnu/fpemul/poly_mul64.s
@@ -0,0 +1,124 @@
+/*
+ * poly_mul64.S
+ *
+ * Multiply two 64 bit integers.
+ *
+ * Call from C as:
+ * void mul64(long long *a, long long *b, long long *result)
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: poly_mul64.s,v 1.3 1994/06/10 07:44:39 rich Exp $
+ *
+ */
+
+
+#include "fpu_asm.h"
+
+.text
+ .align 2,144
+.globl _mul64
+_mul64:
+ pushl %ebp
+ movl %esp,%ebp
+ subl $16,%esp
+ pushl %esi
+ pushl %ebx
+
+ movl PARAM1,%esi
+ movl PARAM2,%ecx
+ movl PARAM3,%ebx
+
+ xor %eax,%eax
+ movl %eax,-4(%ebp)
+ movl %eax,-8(%ebp)
+
+ movl (%esi),%eax
+ mull (%ecx)
+ movl %eax,-16(%ebp) /* Not used */
+ movl %edx,-12(%ebp)
+
+ movl (%esi),%eax
+ mull 4(%ecx)
+ addl %eax,-12(%ebp)
+ adcl %edx,-8(%ebp)
+ adcl $0,-4(%ebp)
+
+ movl 4(%esi),%eax
+ mull (%ecx)
+ addl %eax,-12(%ebp)
+ adcl %edx,-8(%ebp)
+ adcl $0,-4(%ebp)
+
+ movl 4(%esi),%eax
+ mull 4(%ecx)
+ addl %eax,-8(%ebp)
+ adcl %edx,-4(%ebp)
+
+ testb $128,-9(%ebp)
+ je L_no_round
+
+ addl $1,-8(%ebp)
+ adcl $0,-4(%ebp)
+
+L_no_round:
+ movl -8(%ebp),%esi
+ movl %esi,(%ebx)
+ movl -4(%ebp),%esi
+ movl %esi,4(%ebx)
+
+ popl %ebx
+ popl %esi
+ leave
+ ret
diff --git a/sys/gnu/fpemul/poly_sin.c b/sys/gnu/fpemul/poly_sin.c
new file mode 100644
index 000000000000..c48cacee24dc
--- /dev/null
+++ b/sys/gnu/fpemul/poly_sin.c
@@ -0,0 +1,192 @@
+/*
+ * poly_sin.c
+ *
+ * Computation of an approximation of the sin function by a polynomial
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: poly_sin.c,v 1.4 1994/06/10 07:44:41 rich Exp $
+ *
+ */
+
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+
+#define HIPOWER 5
+static unsigned short lterms[HIPOWER][4] =
+{
+ {0x846a, 0x42d1, 0xb544, 0x921f},
+ {0xe110, 0x75aa, 0xbc67, 0x1466},
+ {0x503d, 0xa43f, 0x83c1, 0x000a},
+ {0x8f9d, 0x7a19, 0x00f4, 0x0000},
+ {0xda03, 0x06aa, 0x0000, 0x0000},
+};
+
+static unsigned short negterms[HIPOWER][4] =
+{
+ {0x95ed, 0x2df2, 0xe731, 0xa55d},
+ {0xd159, 0xe62b, 0xd2cc, 0x0132},
+ {0x6342, 0xe9fb, 0x3c60, 0x0000},
+ {0x6256, 0xdf5a, 0x0002, 0x0000},
+ {0xf279, 0x000b, 0x0000, 0x0000},
+};
+
+
+/*--- poly_sine() -----------------------------------------------------------+
+ | |
+ +---------------------------------------------------------------------------*/
+void
+poly_sine(FPU_REG * arg, FPU_REG * result)
+{
+ short exponent;
+ FPU_REG Xx, Xx2, Xx4, accum, negaccum;
+
+
+ exponent = arg->exp - EXP_BIAS;
+
+ if (arg->tag == TW_Zero) {
+ /* Return 0.0 */
+ reg_move(&CONST_Z, result);
+ return;
+ }
+#ifdef PARANOID
+ if (arg->sign != 0) { /* Can't hack a number < 0.0 */
+ EXCEPTION(EX_Invalid);
+ reg_move(&CONST_QNaN, result);
+ return;
+ }
+ if (exponent >= 0) { /* Can't hack a number > 1.0 */
+ if ((exponent == 0) && (arg->sigl == 0) && (arg->sigh == 0x80000000)) {
+ reg_move(&CONST_1, result);
+ return;
+ }
+ EXCEPTION(EX_Invalid);
+ reg_move(&CONST_QNaN, result);
+ return;
+ }
+#endif /* PARANOID */
+
+ Xx.sigl = arg->sigl;
+ Xx.sigh = arg->sigh;
+ if (exponent < -1) {
+ /* shift the argument right by the required places */
+ if (shrx(&(Xx.sigl), -1 - exponent) >= (unsigned)0x80000000)
+ (*((long long *) (&(Xx.sigl))))++; /* round up */
+ }
+ mul64((long long *) &(Xx.sigl), (long long *) &(Xx.sigl),
+ (long long *) &(Xx2.sigl));
+ mul64((long long *) &(Xx2.sigl), (long long *) &(Xx2.sigl),
+ (long long *) &(Xx4.sigl));
+
+ /* will be a valid positive nr with expon = 0 */
+ *(short *) &(accum.sign) = 0;
+ accum.exp = 0;
+
+ /* Do the basic fixed point polynomial evaluation */
+ polynomial((u_int *) &(accum.sigl), &(Xx4.sigl), lterms, HIPOWER - 1);
+
+ /* will be a valid positive nr with expon = 0 */
+ *(short *) &(negaccum.sign) = 0;
+ negaccum.exp = 0;
+
+ /* Do the basic fixed point polynomial evaluation */
+ polynomial((u_int *) &(negaccum.sigl), &(Xx4.sigl), negterms, HIPOWER - 1);
+ mul64((long long *) &(Xx2.sigl), (long long *) &(negaccum.sigl),
+ (long long *) &(negaccum.sigl));
+
+ /* Subtract the mantissas */
+ *((long long *) (&(accum.sigl))) -= *((long long *) (&(negaccum.sigl)));
+
+ /* Convert to 64 bit signed-compatible */
+ accum.exp = EXP_BIAS - 1 + accum.exp;
+
+ *(short *) &(result->sign) = *(short *) &(accum.sign);
+ result->exp = accum.exp;
+ result->sigl = accum.sigl;
+ result->sigh = accum.sigh;
+
+ normalize(result);
+
+ reg_mul(result, arg, result, FULL_PRECISION);
+ reg_u_add(result, arg, result, FULL_PRECISION);
+
+ /* A small overflow may be possible... but an illegal result. */
+ if (result->exp >= EXP_BIAS) {
+ if ((result->exp > EXP_BIAS) /* Larger or equal 2.0 */
+ ||(result->sigl > 1) /* Larger than 1.0+msb */
+ ||(result->sigh != 0x80000000) /* Much > 1.0 */
+ ) {
+#ifdef DEBUGGING
+ RE_ENTRANT_CHECK_OFF
+ printk("\nEXP=%d, MS=%08x, LS=%08x\n", result->exp,
+ result->sigh, result->sigl);
+ RE_ENTRANT_CHECK_ON
+#endif /* DEBUGGING */
+ EXCEPTION(EX_INTERNAL | 0x103);
+ }
+#ifdef DEBUGGING
+ RE_ENTRANT_CHECK_OFF
+ printk("\n***CORRECTING ILLEGAL RESULT*** in poly_sin() computation\n");
+ printk("EXP=%d, MS=%08x, LS=%08x\n", result->exp,
+ result->sigh, result->sigl);
+ RE_ENTRANT_CHECK_ON
+#endif /* DEBUGGING */
+
+ result->sigl = 0; /* Truncate the result to 1.00 */
+ }
+}
diff --git a/sys/gnu/fpemul/poly_tan.c b/sys/gnu/fpemul/poly_tan.c
new file mode 100644
index 000000000000..b167bd51a904
--- /dev/null
+++ b/sys/gnu/fpemul/poly_tan.c
@@ -0,0 +1,229 @@
+/*
+ * poly_tan.c
+ *
+ * Compute the tan of a FPU_REG, using a polynomial approximation.
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: poly_tan.c,v 1.4 1994/06/10 07:44:42 rich Exp $
+ *
+ */
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+
+#define HIPOWERop 3 /* odd poly, positive terms */
+static unsigned short oddplterms[HIPOWERop][4] =
+{
+ {0x846a, 0x42d1, 0xb544, 0x921f},
+ {0x6fb2, 0x0215, 0x95c0, 0x099c},
+ {0xfce6, 0x0cc8, 0x1c9a, 0x0000}
+};
+#define HIPOWERon 2 /* odd poly, negative terms */
+static unsigned short oddnegterms[HIPOWERon][4] =
+{
+ {0x6906, 0xe205, 0x25c8, 0x8838},
+ {0x1dd7, 0x3fe3, 0x944e, 0x002c}
+};
+#define HIPOWERep 2 /* even poly, positive terms */
+static unsigned short evenplterms[HIPOWERep][4] =
+{
+ {0xdb8f, 0x3761, 0x1432, 0x2acf},
+ {0x16eb, 0x13c1, 0x3099, 0x0003}
+};
+#define HIPOWERen 2 /* even poly, negative terms */
+static unsigned short evennegterms[HIPOWERen][4] =
+{
+ {0x3a7c, 0xe4c5, 0x7f87, 0x2945},
+ {0x572b, 0x664c, 0xc543, 0x018c}
+};
+
+
+/*--- poly_tan() ------------------------------------------------------------+
+ | |
+ +---------------------------------------------------------------------------*/
+void
+poly_tan(FPU_REG * arg, FPU_REG * y_reg)
+{
+ char invert = 0;
+ short exponent;
+ FPU_REG odd_poly, even_poly, pos_poly, neg_poly;
+ FPU_REG argSq;
+ long long arg_signif, argSqSq;
+
+
+ exponent = arg->exp - EXP_BIAS;
+
+ if (arg->tag == TW_Zero) {
+ /* Return 0.0 */
+ reg_move(&CONST_Z, y_reg);
+ return;
+ }
+ if (exponent >= -1) {
+ /* argument is in the range [0.5 .. 1.0] */
+ if (exponent >= 0) {
+#ifdef PARANOID
+ if ((exponent == 0) &&
+ (arg->sigl == 0) && (arg->sigh == 0x80000000))
+#endif /* PARANOID */
+ {
+ arith_overflow(y_reg);
+ return;
+ }
+#ifdef PARANOID
+ EXCEPTION(EX_INTERNAL | 0x104); /* There must be a logic
+ * error */
+ return;
+#endif /* PARANOID */
+ }
+ /* The argument is in the range [0.5 .. 1.0) */
+ /* Convert the argument to a number in the range (0.0 .. 0.5] */
+ *((long long *) (&arg->sigl)) = -*((long long *) (&arg->sigl));
+ normalize(arg); /* Needed later */
+ exponent = arg->exp - EXP_BIAS;
+ invert = 1;
+ }
+#ifdef PARANOID
+ if (arg->sign != 0) { /* Can't hack a number < 0.0 */
+ arith_invalid(y_reg);
+ return;
+ } /* Need a positive number */
+#endif /* PARANOID */
+
+ *(long long *) &arg_signif = *(long long *) &(arg->sigl);
+ if (exponent < -1) {
+ /* shift the argument right by the required places */
+ if (shrx(&arg_signif, -1 - exponent) >= (unsigned)0x80000000)
+ arg_signif++; /* round up */
+ }
+ mul64(&arg_signif, &arg_signif, (long long *) (&argSq.sigl));
+ mul64((long long *) (&argSq.sigl), (long long *) (&argSq.sigl), &argSqSq);
+
+ /* will be a valid positive nr with expon = 0 */
+ *(short *) &(pos_poly.sign) = 0;
+ pos_poly.exp = EXP_BIAS;
+
+ /* Do the basic fixed point polynomial evaluation */
+ polynomial((u_int *) &pos_poly.sigl, (unsigned *) &argSqSq, oddplterms, HIPOWERop - 1);
+
+ /* will be a valid positive nr with expon = 0 */
+ *(short *) &(neg_poly.sign) = 0;
+ neg_poly.exp = EXP_BIAS;
+
+ /* Do the basic fixed point polynomial evaluation */
+ polynomial((u_int *) &neg_poly.sigl, (unsigned *) &argSqSq, oddnegterms, HIPOWERon - 1);
+ mul64((long long *) (&argSq.sigl), (long long *) (&neg_poly.sigl),
+ (long long *) (&neg_poly.sigl));
+
+ /* Subtract the mantissas */
+ *((long long *) (&pos_poly.sigl)) -= *((long long *) (&neg_poly.sigl));
+
+ /* Convert to 64 bit signed-compatible */
+ pos_poly.exp -= 1;
+
+ reg_move(&pos_poly, &odd_poly);
+ normalize(&odd_poly);
+
+ reg_mul(&odd_poly, arg, &odd_poly, FULL_PRECISION);
+ reg_u_add(&odd_poly, arg, &odd_poly, FULL_PRECISION); /* This is just the odd
+ * polynomial */
+
+
+ /* will be a valid positive nr with expon = 0 */
+ *(short *) &(pos_poly.sign) = 0;
+ pos_poly.exp = EXP_BIAS;
+
+ /* Do the basic fixed point polynomial evaluation */
+ polynomial((u_int *) &pos_poly.sigl, (unsigned *) &argSqSq, evenplterms, HIPOWERep - 1);
+ mul64((long long *) (&argSq.sigl),
+ (long long *) (&pos_poly.sigl), (long long *) (&pos_poly.sigl));
+
+ /* will be a valid positive nr with expon = 0 */
+ *(short *) &(neg_poly.sign) = 0;
+ neg_poly.exp = EXP_BIAS;
+
+ /* Do the basic fixed point polynomial evaluation */
+ polynomial((u_int *) &neg_poly.sigl, (unsigned *) &argSqSq, evennegterms, HIPOWERen - 1);
+
+ /* Subtract the mantissas */
+ *((long long *) (&neg_poly.sigl)) -= *((long long *) (&pos_poly.sigl));
+ /* and multiply by argSq */
+
+ /* Convert argSq to a valid reg number */
+ *(short *) &(argSq.sign) = 0;
+ argSq.exp = EXP_BIAS - 1;
+ normalize(&argSq);
+
+ /* Convert to 64 bit signed-compatible */
+ neg_poly.exp -= 1;
+
+ reg_move(&neg_poly, &even_poly);
+ normalize(&even_poly);
+
+ reg_mul(&even_poly, &argSq, &even_poly, FULL_PRECISION);
+ reg_add(&even_poly, &argSq, &even_poly, FULL_PRECISION);
+ reg_sub(&CONST_1, &even_poly, &even_poly, FULL_PRECISION); /* This is just the even
+ * polynomial */
+
+ /* Now ready to copy the results */
+ if (invert) {
+ reg_div(&even_poly, &odd_poly, y_reg, FULL_PRECISION);
+ } else {
+ reg_div(&odd_poly, &even_poly, y_reg, FULL_PRECISION);
+ }
+
+}
diff --git a/sys/gnu/fpemul/polynomial.s b/sys/gnu/fpemul/polynomial.s
new file mode 100644
index 000000000000..8f48ff4183ae
--- /dev/null
+++ b/sys/gnu/fpemul/polynomial.s
@@ -0,0 +1,192 @@
+/*
+ * polynomial.S
+ *
+ * Fixed point arithmetic polynomial evaluation.
+ *
+ * Call from C as:
+ * void polynomial(unsigned accum[], unsigned x[], unsigned terms[][2],
+ * int n)
+ *
+ * Computes:
+ * terms[0] + (terms[1] + (terms[2] + ... + (terms[n-1]*x)*x)*x)*x) ... )*x
+ * The result is returned in accum.
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: polynomial.s,v 1.3 1994/06/10 07:44:43 rich Exp $
+ *
+ */
+
+ .file "fpolynom.s"
+
+#include "fpu_asm.h"
+
+
+/* #define EXTRA_PRECISE*/
+
+#define TERM_SIZE $8
+
+
+.text
+ .align 2,144
+.globl _polynomial
+_polynomial:
+ pushl %ebp
+ movl %esp,%ebp
+ subl $32,%esp
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl PARAM1,%esi /* accum */
+ movl PARAM2,%edi /* x */
+ movl PARAM3,%ebx /* terms */
+ movl PARAM4,%ecx /* n */
+
+ movl TERM_SIZE,%eax
+ mull %ecx
+ movl %eax,%ecx
+
+ movl 4(%ebx,%ecx,1),%edx /* terms[n] */
+ movl %edx,-20(%ebp)
+ movl (%ebx,%ecx,1),%edx /* terms[n] */
+ movl %edx,-24(%ebp)
+ xor %eax,%eax
+ movl %eax,-28(%ebp)
+
+ subl TERM_SIZE,%ecx
+ js L_accum_done
+
+L_accum_loop:
+ xor %eax,%eax
+ movl %eax,-4(%ebp)
+ movl %eax,-8(%ebp)
+
+#ifdef EXTRA_PRECISE
+ movl -28(%ebp),%eax
+ mull 4(%edi) /* x ms long */
+ movl %edx,-12(%ebp)
+#endif EXTRA_PRECISE
+
+ movl -24(%ebp),%eax
+ mull (%edi) /* x ls long */
+/* movl %eax,-16(%ebp) */ /* Not needed */
+ addl %edx,-12(%ebp)
+ adcl $0,-8(%ebp)
+
+ movl -24(%ebp),%eax
+ mull 4(%edi) /* x ms long */
+ addl %eax,-12(%ebp)
+ adcl %edx,-8(%ebp)
+ adcl $0,-4(%ebp)
+
+ movl -20(%ebp),%eax
+ mull (%edi)
+ addl %eax,-12(%ebp)
+ adcl %edx,-8(%ebp)
+ adcl $0,-4(%ebp)
+
+ movl -20(%ebp),%eax
+ mull 4(%edi)
+ addl %eax,-8(%ebp)
+ adcl %edx,-4(%ebp)
+
+/* Now add the next term */
+ movl (%ebx,%ecx,1),%eax
+ addl %eax,-8(%ebp)
+ movl 4(%ebx,%ecx,1),%eax
+ adcl %eax,-4(%ebp)
+
+/* And put into the second register */
+ movl -4(%ebp),%eax
+ movl %eax,-20(%ebp)
+ movl -8(%ebp),%eax
+ movl %eax,-24(%ebp)
+
+#ifdef EXTRA_PRECISE
+ movl -12(%ebp),%eax
+ movl %eax,-28(%ebp)
+#else
+ testb $128,-25(%ebp)
+ je L_no_poly_round
+
+ addl $1,-24(%ebp)
+ adcl $0,-20(%ebp)
+L_no_poly_round:
+#endif EXTRA_PRECISE
+
+ subl TERM_SIZE,%ecx
+ jns L_accum_loop
+
+L_accum_done:
+#ifdef EXTRA_PRECISE
+/* And round the result */
+ testb $128,-25(%ebp)
+ je L_poly_done
+
+ addl $1,-24(%ebp)
+ adcl $0,-20(%ebp)
+#endif EXTRA_PRECISE
+
+L_poly_done:
+ movl -24(%ebp),%eax
+ movl %eax,(%esi)
+ movl -20(%ebp),%eax
+ movl %eax,4(%esi)
+
+ popl %ebx
+ popl %edi
+ popl %esi
+ leave
+ ret
diff --git a/sys/gnu/fpemul/reg_add_sub.c b/sys/gnu/fpemul/reg_add_sub.c
new file mode 100644
index 000000000000..ff8b0ea37c2e
--- /dev/null
+++ b/sys/gnu/fpemul/reg_add_sub.c
@@ -0,0 +1,303 @@
+/*
+ * reg_add_sub.c
+ *
+ * Functions to add or subtract two registers and put the result in a third.
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: reg_add_sub.c,v 1.3 1994/06/10 07:44:44 rich Exp $
+ *
+ */
+
+/*---------------------------------------------------------------------------+
+ | For each function, the destination may be any FPU_REG, including one of |
+ | the source FPU_REGs. |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+#include "fpu_system.h"
+
+
+void
+reg_add(FPU_REG * a, FPU_REG * b, FPU_REG * dest, int control_w)
+{
+ int diff;
+
+ if (!(a->tag | b->tag)) {
+ /* Both registers are valid */
+ if (!(a->sign ^ b->sign)) {
+ /* signs are the same */
+ reg_u_add(a, b, dest, control_w);
+ dest->sign = a->sign;
+ return;
+ }
+ /* The signs are different, so do a subtraction */
+ diff = a->exp - b->exp;
+ if (!diff) {
+ diff = a->sigh - b->sigh; /* Works only if ms bits
+ * are identical */
+ if (!diff) {
+ diff = a->sigl > b->sigl;
+ if (!diff)
+ diff = -(a->sigl < b->sigl);
+ }
+ }
+ if (diff > 0) {
+ reg_u_sub(a, b, dest, control_w);
+ dest->sign = a->sign;
+ } else
+ if (diff == 0) {
+ reg_move(&CONST_Z, dest);
+ /* sign depends upon rounding mode */
+ dest->sign = ((control_w & CW_RC) != RC_DOWN)
+ ? SIGN_POS : SIGN_NEG;
+ } else {
+ reg_u_sub(b, a, dest, control_w);
+ dest->sign = b->sign;
+ }
+ return;
+ } else {
+ if ((a->tag == TW_NaN) || (b->tag == TW_NaN)) {
+ real_2op_NaN(a, b, dest);
+ return;
+ } else
+ if (a->tag == TW_Zero) {
+ if (b->tag == TW_Zero) {
+ char different_signs = a->sign ^ b->sign;
+ /* Both are zero, result will be zero. */
+ reg_move(a, dest);
+ if (different_signs) {
+ /* Signs are different. */
+ /* Sign of answer depends upon
+ * rounding mode. */
+ dest->sign = ((control_w & CW_RC) != RC_DOWN)
+ ? SIGN_POS : SIGN_NEG;
+ }
+ } else {
+#ifdef DENORM_OPERAND
+ if ((b->tag == TW_Valid) && (b->exp <= EXP_UNDER) &&
+ denormal_operand())
+ return;
+#endif /* DENORM_OPERAND */
+ reg_move(b, dest);
+ }
+ return;
+ } else
+ if (b->tag == TW_Zero) {
+#ifdef DENORM_OPERAND
+ if ((a->tag == TW_Valid) && (a->exp <= EXP_UNDER) &&
+ denormal_operand())
+ return;
+#endif /* DENORM_OPERAND */
+ reg_move(a, dest);
+ return;
+ } else
+ if (a->tag == TW_Infinity) {
+ if (b->tag != TW_Infinity) {
+#ifdef DENORM_OPERAND
+ if ((b->tag == TW_Valid) && (b->exp <= EXP_UNDER) &&
+ denormal_operand())
+ return;
+#endif /* DENORM_OPERAND */
+ reg_move(a, dest);
+ return;
+ }
+ if (a->sign == b->sign) {
+ /* They are both + or
+ * - infinity */
+ reg_move(a, dest);
+ return;
+ }
+ arith_invalid(dest); /* Infinity-Infinity is
+ * undefined. */
+ return;
+ } else
+ if (b->tag == TW_Infinity) {
+#ifdef DENORM_OPERAND
+ if ((a->tag == TW_Valid) && (a->exp <= EXP_UNDER) &&
+ denormal_operand())
+ return;
+#endif /* DENORM_OPERAND */
+ reg_move(b, dest);
+ return;
+ }
+ }
+#ifdef PARANOID
+ EXCEPTION(EX_INTERNAL | 0x101);
+#endif
+}
+
+
+/* Subtract b from a. (a-b) -> dest */
+void
+reg_sub(FPU_REG * a, FPU_REG * b, FPU_REG * dest, int control_w)
+{
+ int diff;
+
+ if (!(a->tag | b->tag)) {
+ /* Both registers are valid */
+ diff = a->exp - b->exp;
+ if (!diff) {
+ diff = a->sigh - b->sigh; /* Works only if ms bits
+ * are identical */
+ if (!diff) {
+ diff = a->sigl > b->sigl;
+ if (!diff)
+ diff = -(a->sigl < b->sigl);
+ }
+ }
+ switch (a->sign * 2 + b->sign) {
+ case 0: /* P - P */
+ case 3: /* N - N */
+ if (diff > 0) {
+ reg_u_sub(a, b, dest, control_w);
+ dest->sign = a->sign;
+ } else
+ if (diff == 0) {
+#ifdef DENORM_OPERAND
+ if ((b->tag == TW_Valid) && (b->exp <= EXP_UNDER) &&
+ denormal_operand())
+ return;
+#endif /* DENORM_OPERAND */
+ reg_move(&CONST_Z, dest);
+ /* sign depends upon rounding mode */
+ dest->sign = ((control_w & CW_RC) != RC_DOWN)
+ ? SIGN_POS : SIGN_NEG;
+ } else {
+ reg_u_sub(b, a, dest, control_w);
+ dest->sign = a->sign ^ SIGN_POS ^ SIGN_NEG;
+ }
+ return;
+ case 1: /* P - N */
+ reg_u_add(a, b, dest, control_w);
+ dest->sign = SIGN_POS;
+ return;
+ case 2: /* N - P */
+ reg_u_add(a, b, dest, control_w);
+ dest->sign = SIGN_NEG;
+ return;
+ }
+ } else {
+ if ((a->tag == TW_NaN) || (b->tag == TW_NaN)) {
+ real_2op_NaN(a, b, dest);
+ return;
+ } else
+ if (b->tag == TW_Zero) {
+ if (a->tag == TW_Zero) {
+ char same_signs = !(a->sign ^ b->sign);
+ /* Both are zero, result will be zero. */
+ reg_move(a, dest); /* Answer for different
+ * signs. */
+ if (same_signs) {
+ /* Sign depends upon rounding
+ * mode */
+ dest->sign = ((control_w & CW_RC) != RC_DOWN)
+ ? SIGN_POS : SIGN_NEG;
+ }
+ } else {
+#ifdef DENORM_OPERAND
+ if ((a->tag == TW_Valid) && (a->exp <= EXP_UNDER) &&
+ denormal_operand())
+ return;
+#endif /* DENORM_OPERAND */
+ reg_move(a, dest);
+ }
+ return;
+ } else
+ if (a->tag == TW_Zero) {
+#ifdef DENORM_OPERAND
+ if ((b->tag == TW_Valid) && (b->exp <= EXP_UNDER) &&
+ denormal_operand())
+ return;
+#endif /* DENORM_OPERAND */
+ reg_move(b, dest);
+ dest->sign ^= SIGN_POS ^ SIGN_NEG;
+ return;
+ } else
+ if (a->tag == TW_Infinity) {
+ if (b->tag != TW_Infinity) {
+#ifdef DENORM_OPERAND
+ if ((b->tag == TW_Valid) && (b->exp <= EXP_UNDER) &&
+ denormal_operand())
+ return;
+#endif /* DENORM_OPERAND */
+ reg_move(a, dest);
+ return;
+ }
+ /* Both args are Infinity */
+ if (a->sign == b->sign) {
+ arith_invalid(dest); /* Infinity-Infinity is
+ * undefined. */
+ return;
+ }
+ reg_move(a, dest);
+ return;
+ } else
+ if (b->tag == TW_Infinity) {
+#ifdef DENORM_OPERAND
+ if ((a->tag == TW_Valid) && (a->exp <= EXP_UNDER) &&
+ denormal_operand())
+ return;
+#endif /* DENORM_OPERAND */
+ reg_move(b, dest);
+ dest->sign ^= SIGN_POS ^ SIGN_NEG;
+ return;
+ }
+ }
+#ifdef PARANOID
+ EXCEPTION(EX_INTERNAL | 0x110);
+#endif
+}
diff --git a/sys/gnu/fpemul/reg_compare.c b/sys/gnu/fpemul/reg_compare.c
new file mode 100644
index 000000000000..692cdc3910f8
--- /dev/null
+++ b/sys/gnu/fpemul/reg_compare.c
@@ -0,0 +1,384 @@
+/*
+ * reg_compare.c
+ *
+ * Compare two floating point registers
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: reg_compare.c,v 1.3 1994/06/10 07:44:47 rich Exp $
+ *
+ */
+
+/*---------------------------------------------------------------------------+
+ | compare() is the core FPU_REG comparison function |
+ +---------------------------------------------------------------------------*/
+#include "param.h"
+#include "proc.h"
+#include "systm.h"
+#include "machine/cpu.h"
+#include "machine/pcb.h"
+
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "exception.h"
+#include "control_w.h"
+#include "status_w.h"
+
+
+int
+compare(FPU_REG * b)
+{
+ int diff;
+
+ if (FPU_st0_ptr->tag | b->tag) {
+ if (FPU_st0_ptr->tag == TW_Zero) {
+ if (b->tag == TW_Zero)
+ return COMP_A_eq_B;
+ if (b->tag == TW_Valid) {
+#ifdef DENORM_OPERAND
+ if ((b->exp <= EXP_UNDER) && (denormal_operand()))
+ return COMP_Denormal;
+#endif /* DENORM_OPERAND */
+ return (b->sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B;
+ }
+ } else
+ if (b->tag == TW_Zero) {
+ if (FPU_st0_ptr->tag == TW_Valid) {
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
+ return COMP_Denormal;
+#endif /* DENORM_OPERAND */
+ return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B;
+ }
+ }
+ if (FPU_st0_ptr->tag == TW_Infinity) {
+ if ((b->tag == TW_Valid) || (b->tag == TW_Zero)) {
+#ifdef DENORM_OPERAND
+ if ((b->tag == TW_Valid) && (b->exp <= EXP_UNDER)
+ && (denormal_operand()))
+ return COMP_Denormal;
+#endif /* DENORM_OPERAND */
+ return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B;
+ } else
+ if (b->tag == TW_Infinity) {
+ /* The 80486 book says that infinities
+ * can be equal! */
+ return (FPU_st0_ptr->sign == b->sign) ? COMP_A_eq_B :
+ ((FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
+ }
+ /* Fall through to the NaN code */
+ } else
+ if (b->tag == TW_Infinity) {
+ if ((FPU_st0_ptr->tag == TW_Valid) || (FPU_st0_ptr->tag == TW_Zero)) {
+#ifdef DENORM_OPERAND
+ if ((FPU_st0_ptr->tag == TW_Valid)
+ && (FPU_st0_ptr->exp <= EXP_UNDER)
+ && (denormal_operand()))
+ return COMP_Denormal;
+#endif /* DENORM_OPERAND */
+ return (b->sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B;
+ }
+ /* Fall through to the NaN code */
+ }
+ /* The only possibility now should be that one of the
+ * arguments is a NaN */
+ if ((FPU_st0_ptr->tag == TW_NaN) || (b->tag == TW_NaN)) {
+ if (((FPU_st0_ptr->tag == TW_NaN) && !(FPU_st0_ptr->sigh & 0x40000000))
+ || ((b->tag == TW_NaN) && !(b->sigh & 0x40000000)))
+ /* At least one arg is a signaling NaN */
+ return COMP_No_Comp | COMP_SNaN | COMP_NaN;
+ else
+ /* Neither is a signaling NaN */
+ return COMP_No_Comp | COMP_NaN;
+ }
+ EXCEPTION(EX_Invalid);
+ }
+#ifdef PARANOID
+ if (!(FPU_st0_ptr->sigh & 0x80000000))
+ EXCEPTION(EX_Invalid);
+ if (!(b->sigh & 0x80000000))
+ EXCEPTION(EX_Invalid);
+#endif /* PARANOID */
+
+#ifdef DENORM_OPERAND
+ if (((FPU_st0_ptr->exp <= EXP_UNDER) ||
+ (b->exp <= EXP_UNDER)) && (denormal_operand()))
+ return COMP_Denormal;
+#endif /* DENORM_OPERAND */
+
+ if (FPU_st0_ptr->sign != b->sign)
+ return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B;
+
+ diff = FPU_st0_ptr->exp - b->exp;
+ if (diff == 0) {
+ diff = FPU_st0_ptr->sigh - b->sigh; /* Works only if ms bits
+ * are identical */
+ if (diff == 0) {
+ diff = FPU_st0_ptr->sigl > b->sigl;
+ if (diff == 0)
+ diff = -(FPU_st0_ptr->sigl < b->sigl);
+ }
+ }
+ if (diff > 0)
+ return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B;
+ if (diff < 0)
+ return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B;
+ return COMP_A_eq_B;
+
+}
+
+
+/* This function requires that st(0) is not empty */
+int
+compare_st_data(void)
+{
+ int f, c;
+
+ c = compare(&FPU_loaded_data);
+
+ if (c & (COMP_NaN | COMP_Denormal)) {
+ if (c & COMP_NaN) {
+ EXCEPTION(EX_Invalid);
+ f = SW_C3 | SW_C2 | SW_C0;
+ } else {
+ /* One of the operands is a de-normal */
+ return 0;
+ }
+ } else
+ switch (c) {
+ case COMP_A_lt_B:
+ f = SW_C0;
+ break;
+ case COMP_A_eq_B:
+ f = SW_C3;
+ break;
+ case COMP_A_gt_B:
+ f = 0;
+ break;
+ case COMP_No_Comp:
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
+#ifdef PARANOID
+ default:
+ EXCEPTION(EX_INTERNAL | 0x121);
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
+#endif /* PARANOID */
+ }
+ setcc(f);
+ return 1;
+}
+
+
+static int
+compare_st_st(int nr)
+{
+ int f, c;
+
+ if (!NOT_EMPTY_0 || !NOT_EMPTY(nr)) {
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ /* Stack fault */
+ EXCEPTION(EX_StackUnder);
+ return control_word & CW_Invalid;
+ }
+ c = compare(&st(nr));
+ if (c & (COMP_NaN | COMP_Denormal)) {
+ if (c & COMP_NaN) {
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ EXCEPTION(EX_Invalid);
+ return control_word & CW_Invalid;
+ } else {
+ /* One of the operands is a de-normal */
+ return control_word & CW_Denormal;
+ }
+ } else
+ switch (c) {
+ case COMP_A_lt_B:
+ f = SW_C0;
+ break;
+ case COMP_A_eq_B:
+ f = SW_C3;
+ break;
+ case COMP_A_gt_B:
+ f = 0;
+ break;
+ case COMP_No_Comp:
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
+#ifdef PARANOID
+ default:
+ EXCEPTION(EX_INTERNAL | 0x122);
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
+#endif /* PARANOID */
+ }
+ setcc(f);
+ return 1;
+}
+
+
+static int
+compare_u_st_st(int nr)
+{
+ int f, c;
+
+ if (!NOT_EMPTY_0 || !NOT_EMPTY(nr)) {
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ /* Stack fault */
+ EXCEPTION(EX_StackUnder);
+ return control_word & CW_Invalid;
+ }
+ c = compare(&st(nr));
+ if (c & (COMP_NaN | COMP_Denormal)) {
+ if (c & COMP_NaN) {
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ if (c & COMP_SNaN) { /* This is the only difference
+ * between un-ordered and
+ * ordinary comparisons */
+ EXCEPTION(EX_Invalid);
+ return control_word & CW_Invalid;
+ }
+ return 1;
+ } else {
+ /* One of the operands is a de-normal */
+ return control_word & CW_Denormal;
+ }
+ } else
+ switch (c) {
+ case COMP_A_lt_B:
+ f = SW_C0;
+ break;
+ case COMP_A_eq_B:
+ f = SW_C3;
+ break;
+ case COMP_A_gt_B:
+ f = 0;
+ break;
+ case COMP_No_Comp:
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
+#ifdef PARANOID
+ default:
+ EXCEPTION(EX_INTERNAL | 0x123);
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
+#endif /* PARANOID */
+ }
+ setcc(f);
+ return 1;
+}
+/*---------------------------------------------------------------------------*/
+
+void
+fcom_st()
+{
+ /* fcom st(i) */
+ compare_st_st(FPU_rm);
+}
+
+
+void
+fcompst()
+{
+ /* fcomp st(i) */
+ if (compare_st_st(FPU_rm))
+ pop();
+}
+
+
+void
+fcompp()
+{
+ /* fcompp */
+ if (FPU_rm != 1)
+ return Un_impl();
+ if (compare_st_st(1)) {
+ pop();
+ FPU_st0_ptr = &st(0);
+ pop();
+ }
+}
+
+
+void
+fucom_()
+{
+ /* fucom st(i) */
+ compare_u_st_st(FPU_rm);
+
+}
+
+
+void
+fucomp()
+{
+ /* fucomp st(i) */
+ if (compare_u_st_st(FPU_rm))
+ pop();
+}
+
+
+void
+fucompp()
+{
+ /* fucompp */
+ if (FPU_rm == 1) {
+ if (compare_u_st_st(1)) {
+ pop();
+ FPU_st0_ptr = &st(0);
+ pop();
+ }
+ } else
+ Un_impl();
+}
diff --git a/sys/gnu/fpemul/reg_constant.c b/sys/gnu/fpemul/reg_constant.c
new file mode 100644
index 000000000000..f33427358e1c
--- /dev/null
+++ b/sys/gnu/fpemul/reg_constant.c
@@ -0,0 +1,175 @@
+/*
+ * reg_constant.c
+ *
+ * All of the constant FPU_REGs
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $id:$
+ *
+ */
+
+
+
+#include "param.h"
+#include "proc.h"
+#include "systm.h"
+#include "machine/cpu.h"
+#include "machine/pcb.h"
+
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "status_w.h"
+#include "reg_constant.h"
+
+
+FPU_REG CONST_1 = {SIGN_POS, TW_Valid, EXP_BIAS,
+0x00000000, 0x80000000};
+FPU_REG CONST_2 = {SIGN_POS, TW_Valid, EXP_BIAS + 1,
+0x00000000, 0x80000000};
+FPU_REG CONST_HALF = {SIGN_POS, TW_Valid, EXP_BIAS - 1,
+0x00000000, 0x80000000};
+FPU_REG CONST_L2T = {SIGN_POS, TW_Valid, EXP_BIAS + 1,
+0xcd1b8afe, 0xd49a784b};
+FPU_REG CONST_L2E = {SIGN_POS, TW_Valid, EXP_BIAS,
+0x5c17f0bc, 0xb8aa3b29};
+FPU_REG CONST_PI = {SIGN_POS, TW_Valid, EXP_BIAS + 1,
+0x2168c235, 0xc90fdaa2};
+FPU_REG CONST_PI2 = {SIGN_POS, TW_Valid, EXP_BIAS,
+0x2168c235, 0xc90fdaa2};
+FPU_REG CONST_PI4 = {SIGN_POS, TW_Valid, EXP_BIAS - 1,
+0x2168c235, 0xc90fdaa2};
+FPU_REG CONST_LG2 = {SIGN_POS, TW_Valid, EXP_BIAS - 2,
+0xfbcff799, 0x9a209a84};
+FPU_REG CONST_LN2 = {SIGN_POS, TW_Valid, EXP_BIAS - 1,
+0xd1cf79ac, 0xb17217f7};
+/* Only the sign (and tag) is used in internal zeroes */
+FPU_REG CONST_Z = {SIGN_POS, TW_Zero, 0, 0x0, 0x0};
+/* Only the sign and significand (and tag) are used in internal NaNs */
+/* The 80486 never generates one of these
+FPU_REG CONST_SNAN = { SIGN_POS, TW_NaN, EXP_OVER, 0x00000001, 0x80000000 };
+ */
+/* This is the real indefinite QNaN */
+FPU_REG CONST_QNaN = {SIGN_NEG, TW_NaN, EXP_OVER, 0x00000000, 0xC0000000};
+/* Only the sign (and tag) is used in internal infinities */
+FPU_REG CONST_INF = {SIGN_POS, TW_Infinity, EXP_OVER, 0x00000000, 0x80000000};
+
+
+
+static void
+fld_const(FPU_REG * c)
+{
+ FPU_REG *st_new_ptr;
+
+ if (STACK_OVERFLOW) {
+ stack_overflow();
+ return;
+ }
+ push();
+ reg_move(c, FPU_st0_ptr);
+ status_word &= ~SW_C1;
+}
+
+
+static void
+fld1(void)
+{
+ fld_const(&CONST_1);
+}
+
+static void
+fldl2t(void)
+{
+ fld_const(&CONST_L2T);
+}
+
+static void
+fldl2e(void)
+{
+ fld_const(&CONST_L2E);
+}
+
+static void
+fldpi(void)
+{
+ fld_const(&CONST_PI);
+}
+
+static void
+fldlg2(void)
+{
+ fld_const(&CONST_LG2);
+}
+
+static void
+fldln2(void)
+{
+ fld_const(&CONST_LN2);
+}
+
+static void
+fldz(void)
+{
+ fld_const(&CONST_Z);
+}
+
+static FUNC constants_table[] = {
+ fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, Un_impl
+};
+
+void
+fconst(void)
+{
+ (constants_table[FPU_rm]) ();
+}
diff --git a/sys/gnu/fpemul/reg_constant.h b/sys/gnu/fpemul/reg_constant.h
new file mode 100644
index 000000000000..d64a3d55f91b
--- /dev/null
+++ b/sys/gnu/fpemul/reg_constant.h
@@ -0,0 +1,82 @@
+/*
+ * reg_constant.h
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: reg_constant.h,v 1.3 1994/06/10 07:44:49 rich Exp $
+ *
+ */
+
+#ifndef _REG_CONSTANT_H_
+#define _REG_CONSTANT_H_
+
+#include "fpu_emu.h"
+
+extern FPU_REG CONST_1;
+extern FPU_REG CONST_2;
+extern FPU_REG CONST_HALF;
+extern FPU_REG CONST_L2T;
+extern FPU_REG CONST_L2E;
+extern FPU_REG CONST_PI;
+extern FPU_REG CONST_PI2;
+extern FPU_REG CONST_PI4;
+extern FPU_REG CONST_LG2;
+extern FPU_REG CONST_LN2;
+extern FPU_REG CONST_Z;
+extern FPU_REG CONST_PINF;
+extern FPU_REG CONST_INF;
+extern FPU_REG CONST_MINF;
+extern FPU_REG CONST_QNaN;
+
+#endif /* _REG_CONSTANT_H_ */
diff --git a/sys/gnu/fpemul/reg_div.s b/sys/gnu/fpemul/reg_div.s
new file mode 100644
index 000000000000..8f7357530b7e
--- /dev/null
+++ b/sys/gnu/fpemul/reg_div.s
@@ -0,0 +1,295 @@
+ .file "reg_div.S"
+/*
+ * reg_div.S
+ *
+ * Divide one FPU_REG by another and put the result in a destination FPU_REG.
+ *
+ * Call from C as:
+ * void reg_div(FPU_REG *a, FPU_REG *b, FPU_REG *dest,
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: reg_div.s,v 1.3 1994/06/10 07:44:50 rich Exp $
+ *
+ */
+
+#include "exception.h"
+#include "fpu_asm.h"
+#include "control_w.h"
+
+.text
+ .align 2
+
+.globl _reg_div
+_reg_div:
+ pushl %ebp
+ movl %esp,%ebp
+
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl PARAM1,%esi
+ movl PARAM2,%ebx
+ movl PARAM3,%edi
+
+ movb TAG(%esi),%al
+ orb TAG(%ebx),%al
+
+ jne L_div_special /* Not (both numbers TW_Valid) */
+
+#ifdef DENORM_OPERAND
+/* Check for denormals */
+ cmpl EXP_UNDER,EXP(%esi)
+ jg xL_arg1_not_denormal
+
+ call _denormal_operand
+ orl %eax,%eax
+ jnz FPU_Arith_exit
+
+xL_arg1_not_denormal:
+ cmpl EXP_UNDER,EXP(%ebx)
+ jg xL_arg2_not_denormal
+
+ call _denormal_operand
+ orl %eax,%eax
+ jnz FPU_Arith_exit
+
+xL_arg2_not_denormal:
+#endif DENORM_OPERAND
+
+/* Both arguments are TW_Valid */
+ movb TW_Valid,TAG(%edi)
+
+ movb SIGN(%esi),%cl
+ cmpb %cl,SIGN(%ebx)
+ setne (%edi) /* Set the sign, requires SIGN_NEG=1, SIGN_POS=0 */
+
+ movl EXP(%esi),%edx
+ movl EXP(%ebx),%eax
+ subl %eax,%edx
+ addl EXP_BIAS,%edx
+ movl %edx,EXP(%edi)
+
+ jmp _divide_kernel
+
+
+/*-----------------------------------------------------------------------*/
+L_div_special:
+ cmpb TW_NaN,TAG(%esi) /* A NaN with anything to give NaN */
+ je L_arg1_NaN
+
+ cmpb TW_NaN,TAG(%ebx) /* A NaN with anything to give NaN */
+ jne L_no_NaN_arg
+
+/* Operations on NaNs */
+L_arg1_NaN:
+L_arg2_NaN:
+ pushl %edi /* Destination */
+ pushl %ebx
+ pushl %esi
+ call _real_2op_NaN
+ jmp LDiv_exit
+
+/* Invalid operations */
+L_zero_zero:
+L_inf_inf:
+ pushl %edi /* Destination */
+ call _arith_invalid /* 0/0 or Infinity/Infinity */
+ jmp LDiv_exit
+
+L_no_NaN_arg:
+ cmpb TW_Infinity,TAG(%esi)
+ jne L_arg1_not_inf
+
+ cmpb TW_Infinity,TAG(%ebx)
+ je L_inf_inf /* invalid operation */
+
+ cmpb TW_Valid,TAG(%ebx)
+ je L_inf_valid
+
+#ifdef PARANOID
+ /* arg2 must be zero or valid */
+ cmpb TW_Zero,TAG(%ebx)
+ ja L_unknown_tags
+#endif PARANOID
+
+ /* Note that p16-9 says that infinity/0 returns infinity */
+ jmp L_copy_arg1 /* Answer is Inf */
+
+L_inf_valid:
+#ifdef DENORM_OPERAND
+ cmpl EXP_UNDER,EXP(%ebx)
+ jg L_copy_arg1 /* Answer is Inf */
+
+ call _denormal_operand
+ orl %eax,%eax
+ jnz FPU_Arith_exit
+#endif DENORM_OPERAND
+
+ jmp L_copy_arg1 /* Answer is Inf */
+
+L_arg1_not_inf:
+ cmpb TW_Zero,TAG(%ebx) /* Priority to div-by-zero error */
+ jne L_arg2_not_zero
+
+ cmpb TW_Zero,TAG(%esi)
+ je L_zero_zero /* invalid operation */
+
+#ifdef PARANOID
+ /* arg1 must be valid */
+ cmpb TW_Valid,TAG(%esi)
+ ja L_unknown_tags
+#endif PARANOID
+
+/* Division by zero error */
+ pushl %edi /* destination */
+ movb SIGN(%esi),%al
+ xorb SIGN(%ebx),%al
+ pushl %eax /* lower 8 bits have the sign */
+ call _divide_by_zero
+ jmp LDiv_exit
+
+L_arg2_not_zero:
+ cmpb TW_Infinity,TAG(%ebx)
+ jne L_arg2_not_inf
+
+#ifdef DENORM_OPERAND
+ cmpb TW_Valid,TAG(%esi)
+ jne L_return_zero
+
+ cmpl EXP_UNDER,EXP(%esi)
+ jg L_return_zero /* Answer is zero */
+
+ call _denormal_operand
+ orl %eax,%eax
+ jnz FPU_Arith_exit
+#endif DENORM_OPERAND
+
+ jmp L_return_zero /* Answer is zero */
+
+L_arg2_not_inf:
+
+#ifdef PARANOID
+ cmpb TW_Zero,TAG(%esi)
+ jne L_unknown_tags
+#endif PARANOID
+
+ /* arg1 is zero, arg2 is not Infinity or a NaN */
+
+#ifdef DENORM_OPERAND
+ cmpl EXP_UNDER,EXP(%ebx)
+ jg L_copy_arg1 /* Answer is zero */
+
+ call _denormal_operand
+ orl %eax,%eax
+ jnz FPU_Arith_exit
+#endif DENORM_OPERAND
+
+L_copy_arg1:
+ movb TAG(%esi),%ax
+ movb %ax,TAG(%edi)
+ movl EXP(%esi),%eax
+ movl %eax,EXP(%edi)
+ movl SIGL(%esi),%eax
+ movl %eax,SIGL(%edi)
+ movl SIGH(%esi),%eax
+ movl %eax,SIGH(%edi)
+
+ movb SIGN(%esi),%cl
+ cmpb %cl,SIGN(%ebx)
+ jne LDiv_negative_result
+
+ movb SIGN_POS,SIGN(%edi)
+ jmp LDiv_exit
+
+LDiv_set_result_sign:
+ movb SIGN(%esi),%cl
+ cmpb %cl,SIGN(%edi)
+ jne LDiv_negative_result
+
+ movb SIGN_POS,SIGN(%ebx)
+ jmp LDiv_exit
+
+LDiv_negative_result:
+ movb SIGN_NEG,SIGN(%edi)
+
+LDiv_exit:
+ leal -12(%ebp),%esp
+
+ popl %ebx
+ popl %edi
+ popl %esi
+ leave
+ ret
+
+
+L_return_zero:
+ movb TW_Zero,TAG(%edi)
+ jmp LDiv_set_result_sign
+
+#ifdef PARANOID
+L_unknown_tags:
+ push EX_INTERNAL | 0x208
+ call EXCEPTION
+
+ /* Generate a NaN for unknown tags */
+ movl _CONST_QNaN,%eax
+ movl %eax,(%edi)
+ movl _CONST_QNaN+4,%eax
+ movl %eax,SIGL(%edi)
+ movl _CONST_QNaN+8,%eax
+ movl %eax,SIGH(%edi)
+ jmp LDiv_exit
+#endif PARANOID
diff --git a/sys/gnu/fpemul/reg_ld_str.c b/sys/gnu/fpemul/reg_ld_str.c
new file mode 100644
index 000000000000..37b69a6bbfe2
--- /dev/null
+++ b/sys/gnu/fpemul/reg_ld_str.c
@@ -0,0 +1,1387 @@
+/*
+ * reg_ld_str.c
+ *
+ * All of the functions which transfer data between user memory and FPU_REGs.
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: reg_ld_str.c,v 1.3 1994/06/10 07:44:52 rich Exp $
+ *
+ */
+
+
+/*---------------------------------------------------------------------------+
+ | Note: |
+ | The file contains code which accesses user memory. |
+ | Emulator static data may change when user memory is accessed, due to |
+ | other processes using the emulator while swapping is in progress. |
+ +---------------------------------------------------------------------------*/
+#include "param.h"
+#include "proc.h"
+#include "systm.h"
+#include "machine/cpu.h"
+#include "machine/pcb.h"
+
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "exception.h"
+#include "reg_constant.h"
+#include "control_w.h"
+#include "status_w.h"
+
+
+#define EXTENDED_Emax 0x3fff /* largest valid exponent */
+#define EXTENDED_Ebias 0x3fff
+#define EXTENDED_Emin (-0x3ffe) /* smallest valid exponent */
+
+#define DOUBLE_Emax 1023 /* largest valid exponent */
+#define DOUBLE_Ebias 1023
+#define DOUBLE_Emin (-1022) /* smallest valid exponent */
+
+#define SINGLE_Emax 127 /* largest valid exponent */
+#define SINGLE_Ebias 127
+#define SINGLE_Emin (-126) /* smallest valid exponent */
+
+#define LOST_UP (EX_Precision | SW_C1)
+#define LOST_DOWN EX_Precision
+
+FPU_REG FPU_loaded_data;
+
+
+/* Get a long double from user memory */
+void
+reg_load_extended(void)
+{
+ long double *s = (long double *) FPU_data_address;
+ unsigned long sigl, sigh, exp;
+
+ REENTRANT_CHECK(OFF);
+ /* Use temporary variables here because FPU_loaded data is static and
+ * hence re-entrancy problems can arise */
+ sigl = fuword((unsigned long *) s);
+ sigh = fuword(1 + (unsigned long *) s);
+ exp = fuword(4 + (unsigned short *) s);
+ REENTRANT_CHECK(ON);
+
+ FPU_loaded_data.sigl = sigl;
+ FPU_loaded_data.sigh = sigh;
+ FPU_loaded_data.exp = exp;
+
+ if (FPU_loaded_data.exp & 0x8000)
+ FPU_loaded_data.sign = SIGN_NEG;
+ else
+ FPU_loaded_data.sign = SIGN_POS;
+ if ((FPU_loaded_data.exp &= 0x7fff) == 0) {
+ if (!(FPU_loaded_data.sigl | FPU_loaded_data.sigh)) {
+ FPU_loaded_data.tag = TW_Zero;
+ return;
+ }
+ /* The number is a de-normal or pseudodenormal. */
+ /* The 80486 doesn't regard pseudodenormals as denormals here. */
+ if (!(FPU_loaded_data.sigh & 0x80000000))
+ EXCEPTION(EX_Denormal);
+ FPU_loaded_data.exp++;
+
+ /* The default behaviour will now take care of it. */
+ } else
+ if (FPU_loaded_data.exp == 0x7fff) {
+ FPU_loaded_data.exp = EXTENDED_Emax;
+ if ((FPU_loaded_data.sigh == 0x80000000)
+ && (FPU_loaded_data.sigl == 0)) {
+ FPU_loaded_data.tag = TW_Infinity;
+ return;
+ } else
+ if (!(FPU_loaded_data.sigh & 0x80000000)) {
+ /* Unsupported NaN data type */
+ EXCEPTION(EX_Invalid);
+ FPU_loaded_data.tag = TW_NaN;
+ return;
+ }
+ FPU_loaded_data.tag = TW_NaN;
+ return;
+ }
+ FPU_loaded_data.exp = (FPU_loaded_data.exp & 0x7fff) - EXTENDED_Ebias
+ + EXP_BIAS;
+ FPU_loaded_data.tag = TW_Valid;
+
+ if (!(sigh & 0x80000000)) {
+ /* Unsupported data type */
+ EXCEPTION(EX_Invalid);
+ normalize_nuo(&FPU_loaded_data);
+ }
+}
+
+
+/* Get a double from user memory */
+void
+reg_load_double(void)
+{
+ double *dfloat = (double *) FPU_data_address;
+ int exp;
+ unsigned m64, l64;
+
+ REENTRANT_CHECK(OFF);
+ m64 = fuword(1 + (unsigned long *) dfloat);
+ l64 = fuword((unsigned long *) dfloat);
+ REENTRANT_CHECK(ON);
+
+ if (m64 & 0x80000000)
+ FPU_loaded_data.sign = SIGN_NEG;
+ else
+ FPU_loaded_data.sign = SIGN_POS;
+ exp = ((m64 & 0x7ff00000) >> 20) - DOUBLE_Ebias;
+ m64 &= 0xfffff;
+ if (exp > DOUBLE_Emax) {
+ /* Infinity or NaN */
+ if ((m64 == 0) && (l64 == 0)) {
+ /* +- infinity */
+ FPU_loaded_data.exp = EXTENDED_Emax;
+ FPU_loaded_data.tag = TW_Infinity;
+ return;
+ } else {
+ /* Must be a signaling or quiet NaN */
+ FPU_loaded_data.exp = EXTENDED_Emax;
+ FPU_loaded_data.tag = TW_NaN;
+ FPU_loaded_data.sigh = (m64 << 11) | 0x80000000;
+ FPU_loaded_data.sigh |= l64 >> 21;
+ FPU_loaded_data.sigl = l64 << 11;
+ return;
+ }
+ } else
+ if (exp < DOUBLE_Emin) {
+ /* Zero or de-normal */
+ if ((m64 == 0) && (l64 == 0)) {
+ /* Zero */
+ int c = FPU_loaded_data.sign;
+ reg_move(&CONST_Z, &FPU_loaded_data);
+ FPU_loaded_data.sign = c;
+ return;
+ } else {
+ /* De-normal */
+ EXCEPTION(EX_Denormal);
+ FPU_loaded_data.exp = DOUBLE_Emin + EXP_BIAS;
+ FPU_loaded_data.tag = TW_Valid;
+ FPU_loaded_data.sigh = m64 << 11;
+ FPU_loaded_data.sigh |= l64 >> 21;
+ FPU_loaded_data.sigl = l64 << 11;
+ normalize_nuo(&FPU_loaded_data);
+ return;
+ }
+ } else {
+ FPU_loaded_data.exp = exp + EXP_BIAS;
+ FPU_loaded_data.tag = TW_Valid;
+ FPU_loaded_data.sigh = (m64 << 11) | 0x80000000;
+ FPU_loaded_data.sigh |= l64 >> 21;
+ FPU_loaded_data.sigl = l64 << 11;
+
+ return;
+ }
+}
+
+
+/* Get a float from user memory */
+void
+reg_load_single(void)
+{
+ float *single = (float *) FPU_data_address;
+ unsigned m32;
+ int exp;
+
+ REENTRANT_CHECK(OFF);
+ m32 = fuword((unsigned long *) single);
+ REENTRANT_CHECK(ON);
+
+ if (m32 & 0x80000000)
+ FPU_loaded_data.sign = SIGN_NEG;
+ else
+ FPU_loaded_data.sign = SIGN_POS;
+ if (!(m32 & 0x7fffffff)) {
+ /* Zero */
+ int c = FPU_loaded_data.sign;
+ reg_move(&CONST_Z, &FPU_loaded_data);
+ FPU_loaded_data.sign = c;
+ return;
+ }
+ exp = ((m32 & 0x7f800000) >> 23) - SINGLE_Ebias;
+ m32 = (m32 & 0x7fffff) << 8;
+ if (exp < SINGLE_Emin) {
+ /* De-normals */
+ EXCEPTION(EX_Denormal);
+ FPU_loaded_data.exp = SINGLE_Emin + EXP_BIAS;
+ FPU_loaded_data.tag = TW_Valid;
+ FPU_loaded_data.sigh = m32;
+ FPU_loaded_data.sigl = 0;
+ normalize_nuo(&FPU_loaded_data);
+ return;
+ } else
+ if (exp > SINGLE_Emax) {
+ /* Infinity or NaN */
+ if (m32 == 0) {
+ /* +- infinity */
+ FPU_loaded_data.exp = EXTENDED_Emax;
+ FPU_loaded_data.tag = TW_Infinity;
+ return;
+ } else {
+ /* Must be a signaling or quiet NaN */
+ FPU_loaded_data.exp = EXTENDED_Emax;
+ FPU_loaded_data.tag = TW_NaN;
+ FPU_loaded_data.sigh = m32 | 0x80000000;
+ FPU_loaded_data.sigl = 0;
+ return;
+ }
+ } else {
+ FPU_loaded_data.exp = exp + EXP_BIAS;
+ FPU_loaded_data.sigh = m32 | 0x80000000;
+ FPU_loaded_data.sigl = 0;
+ FPU_loaded_data.tag = TW_Valid;
+ }
+}
+
+
+/* Get a long long from user memory */
+void
+reg_load_int64(void)
+{
+ long long *_s = (long long *) FPU_data_address;
+ int e;
+ long long s;
+
+ REENTRANT_CHECK(OFF);
+ ((unsigned long *) &s)[0] = fuword((unsigned long *) _s);
+ ((unsigned long *) &s)[1] = fuword(1 + (unsigned long *) _s);
+ REENTRANT_CHECK(ON);
+
+ if (s == 0) {
+ reg_move(&CONST_Z, &FPU_loaded_data);
+ return;
+ }
+ if (s > 0)
+ FPU_loaded_data.sign = SIGN_POS;
+ else {
+ s = -s;
+ FPU_loaded_data.sign = SIGN_NEG;
+ }
+
+ e = EXP_BIAS + 63;
+ *((long long *) &FPU_loaded_data.sigl) = s;
+ FPU_loaded_data.exp = e;
+ FPU_loaded_data.tag = TW_Valid;
+ normalize_nuo(&FPU_loaded_data);
+}
+
+
+/* Get a long from user memory */
+void
+reg_load_int32(void)
+{
+ long *_s = (long *) FPU_data_address;
+ long s;
+ int e;
+
+ REENTRANT_CHECK(OFF);
+ s = (long) fuword((unsigned long *) _s);
+ REENTRANT_CHECK(ON);
+
+ if (s == 0) {
+ reg_move(&CONST_Z, &FPU_loaded_data);
+ return;
+ }
+ if (s > 0)
+ FPU_loaded_data.sign = SIGN_POS;
+ else {
+ s = -s;
+ FPU_loaded_data.sign = SIGN_NEG;
+ }
+
+ e = EXP_BIAS + 31;
+ FPU_loaded_data.sigh = s;
+ FPU_loaded_data.sigl = 0;
+ FPU_loaded_data.exp = e;
+ FPU_loaded_data.tag = TW_Valid;
+ normalize_nuo(&FPU_loaded_data);
+}
+
+
+/* Get a short from user memory */
+void
+reg_load_int16(void)
+{
+ short *_s = (short *) FPU_data_address;
+ int s, e;
+
+ REENTRANT_CHECK(OFF);
+ /* Cast as short to get the sign extended. */
+ s = (short) fuword((unsigned short *) _s);
+ REENTRANT_CHECK(ON);
+
+ if (s == 0) {
+ reg_move(&CONST_Z, &FPU_loaded_data);
+ return;
+ }
+ if (s > 0)
+ FPU_loaded_data.sign = SIGN_POS;
+ else {
+ s = -s;
+ FPU_loaded_data.sign = SIGN_NEG;
+ }
+
+ e = EXP_BIAS + 15;
+ FPU_loaded_data.sigh = s << 16;
+
+ FPU_loaded_data.sigl = 0;
+ FPU_loaded_data.exp = e;
+ FPU_loaded_data.tag = TW_Valid;
+ normalize_nuo(&FPU_loaded_data);
+}
+
+
+/* Get a packed bcd array from user memory */
+void
+reg_load_bcd(void)
+{
+ char *s = (char *) FPU_data_address;
+ int pos;
+ unsigned char bcd;
+ long long l = 0;
+
+ for (pos = 8; pos >= 0; pos--) {
+ l *= 10;
+ REENTRANT_CHECK(OFF);
+ bcd = (unsigned char) fubyte((unsigned char *) s + pos);
+ REENTRANT_CHECK(ON);
+ l += bcd >> 4;
+ l *= 10;
+ l += bcd & 0x0f;
+ }
+
+ /* Finish all access to user memory before putting stuff into the
+ * static FPU_loaded_data */
+ REENTRANT_CHECK(OFF);
+ FPU_loaded_data.sign =
+ ((unsigned char) fubyte((unsigned char *) s + 9)) & 0x80 ?
+ SIGN_NEG : SIGN_POS;
+ REENTRANT_CHECK(ON);
+
+ if (l == 0) {
+ char sign = FPU_loaded_data.sign;
+ reg_move(&CONST_Z, &FPU_loaded_data);
+ FPU_loaded_data.sign = sign;
+ } else {
+ *((long long *) &FPU_loaded_data.sigl) = l;
+ FPU_loaded_data.exp = EXP_BIAS + 63;
+ FPU_loaded_data.tag = TW_Valid;
+ normalize_nuo(&FPU_loaded_data);
+ }
+}
+/*===========================================================================*/
+
+/* Put a long double into user memory */
+int
+reg_store_extended(void)
+{
+ long double *d = (long double *) FPU_data_address;
+ long e = FPU_st0_ptr->exp - EXP_BIAS + EXTENDED_Ebias;
+ unsigned short sign = FPU_st0_ptr->sign * 0x8000;
+ unsigned long ls, ms;
+
+
+ if (FPU_st0_tag == TW_Valid) {
+ if (e >= 0x7fff) {
+ EXCEPTION(EX_Overflow); /* Overflow */
+ /* This is a special case: see sec 16.2.5.1 of the
+ * 80486 book */
+ if (control_word & EX_Overflow) {
+ /* Overflow to infinity */
+ ls = 0;
+ ms = 0x80000000;
+ e = 0x7fff;
+ } else
+ return 0;
+ } else
+ if (e <= 0) {
+ if (e > -63) {
+ /* Correctly format the de-normal */
+ int precision_loss;
+ FPU_REG tmp;
+
+ EXCEPTION(EX_Denormal);
+ reg_move(FPU_st0_ptr, &tmp);
+ tmp.exp += -EXTENDED_Emin + 63; /* largest exp to be 62 */
+ if ((precision_loss = round_to_int(&tmp))) {
+ EXCEPTION(EX_Underflow | precision_loss);
+ /* This is a special case: see
+ * sec 16.2.5.1 of the 80486
+ * book */
+ if (!(control_word & EX_Underflow))
+ return 0;
+ }
+ e = 0;
+ ls = tmp.sigl;
+ ms = tmp.sigh;
+ } else {
+ /* ****** ??? This should not be
+ * possible */
+ EXCEPTION(EX_Underflow); /* Underflow */
+ /* This is a special case: see sec
+ * 16.2.5.1 of the 80486 book */
+ if (control_word & EX_Underflow) {
+ /* Underflow to zero */
+ ls = 0;
+ ms = 0;
+ e = FPU_st0_ptr->sign == SIGN_POS ? 0x7fff : 0xffff;
+ } else
+ return 0;
+ }
+ } else {
+ ls = FPU_st0_ptr->sigl;
+ ms = FPU_st0_ptr->sigh;
+ }
+ } else
+ if (FPU_st0_tag == TW_Zero) {
+ ls = ms = 0;
+ e = 0;
+ } else
+ if (FPU_st0_tag == TW_Infinity) {
+ ls = 0;
+ ms = 0x80000000;
+ e = 0x7fff;
+ } else
+ if (FPU_st0_tag == TW_NaN) {
+ ls = FPU_st0_ptr->sigl;
+ ms = FPU_st0_ptr->sigh;
+ e = 0x7fff;
+ } else
+ if (FPU_st0_tag == TW_Empty) {
+ /* Empty register (stack
+ * underflow) */
+ EXCEPTION(EX_StackUnder);
+ if (control_word & EX_Invalid) {
+ /* The masked response */
+ /* Put out the QNaN
+ * indefinite */
+ ls = 0;
+ ms = 0xc0000000;
+ e = 0xffff;
+ } else
+ return 0;
+ } else {
+ /* We don't use TW_Denormal
+ * yet ... perhaps never! */
+ EXCEPTION(EX_Invalid);
+ /* Store a NaN */
+ e = 0x7fff;
+ ls = 1;
+ ms = 0x80000000;
+ }
+ REENTRANT_CHECK(OFF);
+/* verify_area(VERIFY_WRITE, d, 10); */
+ suword((unsigned long *) d, ls);
+ suword(1 + (unsigned long *) d, ms);
+ suword(4 + (short *) d, (unsigned short) e | sign);
+ REENTRANT_CHECK(ON);
+
+ return 1;
+
+}
+
+
+/* Put a double into user memory */
+int
+reg_store_double(void)
+{
+ double *dfloat = (double *) FPU_data_address;
+ unsigned long l[2];
+ if (FPU_st0_tag == TW_Valid) {
+ int exp;
+ FPU_REG tmp;
+
+ reg_move(FPU_st0_ptr, &tmp);
+ exp = tmp.exp - EXP_BIAS;
+
+ if (exp < DOUBLE_Emin) { /* It may be a denormal */
+ /* Make a de-normal */
+ int precision_loss;
+
+ if (exp <= -EXTENDED_Ebias)
+ EXCEPTION(EX_Denormal);
+
+ tmp.exp += -DOUBLE_Emin + 52; /* largest exp to be 51 */
+
+ if ((precision_loss = round_to_int(&tmp))) {
+#ifdef PECULIAR_486
+ /* Did it round to a non-denormal ? */
+ /* This behaviour might be regarded as
+ * peculiar, it appears that the 80486 rounds
+ * to the dest precision, then converts to
+ * decide underflow. */
+ if ((tmp.sigh == 0x00100000) && (tmp.sigl == 0) &&
+ (FPU_st0_ptr->sigl & 0x000007ff))
+ EXCEPTION(precision_loss);
+ else
+#endif /* PECULIAR_486 */
+ {
+ EXCEPTION(EX_Underflow | precision_loss);
+ /* This is a special case: see sec
+ * 16.2.5.1 of the 80486 book */
+ if (!(control_word & EX_Underflow))
+ return 0;
+ }
+ }
+ l[0] = tmp.sigl;
+ l[1] = tmp.sigh;
+ } else {
+ if (tmp.sigl & 0x000007ff) {
+ unsigned long increment = 0; /* avoid gcc warnings */
+
+ switch (control_word & CW_RC) {
+ case RC_RND:
+ /* Rounding can get a little messy.. */
+ increment = ((tmp.sigl & 0x7ff) > 0x400) | /* nearest */
+ ((tmp.sigl & 0xc00) == 0xc00); /* odd -> even */
+ break;
+ case RC_DOWN: /* towards -infinity */
+ increment = (tmp.sign == SIGN_POS) ? 0 : tmp.sigl & 0x7ff;
+ break;
+ case RC_UP: /* towards +infinity */
+ increment = (tmp.sign == SIGN_POS) ? tmp.sigl & 0x7ff : 0;
+ break;
+ case RC_CHOP:
+ increment = 0;
+ break;
+ }
+
+ /* Truncate the mantissa */
+ tmp.sigl &= 0xfffff800;
+
+ if (increment) {
+ set_precision_flag_up();
+
+ if (tmp.sigl >= 0xfffff800) {
+ /* the sigl part overflows */
+ if (tmp.sigh == 0xffffffff) {
+ /* The sigh part
+ * overflows */
+ tmp.sigh = 0x80000000;
+ exp++;
+ if (exp >= EXP_OVER)
+ goto overflow;
+ } else {
+ tmp.sigh++;
+ }
+ tmp.sigl = 0x00000000;
+ } else {
+ /* We only need to increment
+ * sigl */
+ tmp.sigl += 0x00000800;
+ }
+ } else
+ set_precision_flag_down();
+ }
+ l[0] = (tmp.sigl >> 11) | (tmp.sigh << 21);
+ l[1] = ((tmp.sigh >> 11) & 0xfffff);
+
+ if (exp > DOUBLE_Emax) {
+ overflow:
+ EXCEPTION(EX_Overflow);
+ /* This is a special case: see sec 16.2.5.1 of
+ * the 80486 book */
+ if (control_word & EX_Overflow) {
+ /* Overflow to infinity */
+ l[0] = 0x00000000; /* Set to */
+ l[1] = 0x7ff00000; /* + INF */
+ } else
+ return 0;
+ } else {
+ /* Add the exponent */
+ l[1] |= (((exp + DOUBLE_Ebias) & 0x7ff) << 20);
+ }
+ }
+ } else
+ if (FPU_st0_tag == TW_Zero) {
+ /* Number is zero */
+ l[0] = 0;
+ l[1] = 0;
+ } else
+ if (FPU_st0_tag == TW_Infinity) {
+ l[0] = 0;
+ l[1] = 0x7ff00000;
+ } else
+ if (FPU_st0_tag == TW_NaN) {
+ /* See if we can get a valid NaN from
+ * the FPU_REG */
+ l[0] = (FPU_st0_ptr->sigl >> 11) | (FPU_st0_ptr->sigh << 21);
+ l[1] = ((FPU_st0_ptr->sigh >> 11) & 0xfffff);
+ if (!(l[0] | l[1])) {
+ /* This case does not seem to
+ * be handled by the 80486
+ * specs */
+ EXCEPTION(EX_Invalid);
+ /* Make the quiet NaN "real
+ * indefinite" */
+ goto put_indefinite;
+ }
+ l[1] |= 0x7ff00000;
+ } else
+ if (FPU_st0_tag == TW_Empty) {
+ /* Empty register (stack
+ * underflow) */
+ EXCEPTION(EX_StackUnder);
+ if (control_word & EX_Invalid) {
+ /* The masked response */
+ /* Put out the QNaN
+ * indefinite */
+ put_indefinite:
+ REENTRANT_CHECK(OFF);
+ /* verify_area(VERIFY_W
+ * RITE, (void *)
+ * dfloat, 8); */
+ suword((unsigned long *) dfloat, 0);
+ suword(1 + (unsigned long *) dfloat, 0xfff80000);
+ REENTRANT_CHECK(ON);
+ return 1;
+ } else
+ return 0;
+ }
+#if 0 /* TW_Denormal is not used yet, and probably
+ * won't be */
+ else
+ if (FPU_st0_tag == TW_Denormal) {
+ /* Extended real ->
+ * double real will
+ * always underflow */
+ l[0] = l[1] = 0;
+ EXCEPTION(EX_Underflow);
+ }
+#endif
+ if (FPU_st0_ptr->sign)
+ l[1] |= 0x80000000;
+
+ REENTRANT_CHECK(OFF);
+/* verify_area(VERIFY_WRITE, (void *) dfloat, 8);*/
+ suword((u_long *) dfloat, l[0]);
+ suword((u_long *) dfloat + 1, l[1]);
+/*
+ suword(l[0], (unsigned long *) dfloat);
+ suword(l[1], 1 + (unsigned long *) dfloat);*/
+ REENTRANT_CHECK(ON);
+
+ return 1;
+}
+
+
+/* Put a float into user memory */
+int
+reg_store_single(void)
+{
+ float *single = (float *) FPU_data_address;
+ long templ;
+
+ if (FPU_st0_tag == TW_Valid) {
+ int exp;
+ FPU_REG tmp;
+
+ reg_move(FPU_st0_ptr, &tmp);
+ exp = tmp.exp - EXP_BIAS;
+
+ if (exp < SINGLE_Emin) {
+ /* Make a de-normal */
+ int precision_loss;
+
+ if (exp <= -EXTENDED_Ebias)
+ EXCEPTION(EX_Denormal);
+
+ tmp.exp += -SINGLE_Emin + 23; /* largest exp to be 22 */
+
+ if ((precision_loss = round_to_int(&tmp))) {
+#ifdef PECULIAR_486
+ /* Did it round to a non-denormal ? */
+ /* This behaviour might be regarded as
+ * peculiar, it appears that the 80486 rounds
+ * to the dest precision, then converts to
+ * decide underflow. */
+ if ((tmp.sigl == 0x00800000) &&
+ ((FPU_st0_ptr->sigh & 0x000000ff) || FPU_st0_ptr->sigl))
+ EXCEPTION(precision_loss);
+ else
+#endif /* PECULIAR_486 */
+ {
+ EXCEPTION(EX_Underflow | precision_loss);
+ /* This is a special case: see sec
+ * 16.2.5.1 of the 80486 book */
+ if (!(control_word & EX_Underflow))
+ return 0;
+ }
+ }
+ templ = tmp.sigl;
+ } else {
+ if (tmp.sigl | (tmp.sigh & 0x000000ff)) {
+ unsigned long increment = 0; /* avoid gcc warnings */
+ unsigned long sigh = tmp.sigh;
+ unsigned long sigl = tmp.sigl;
+
+ switch (control_word & CW_RC) {
+ case RC_RND:
+ increment = ((sigh & 0xff) > 0x80) /* more than half */
+ ||(((sigh & 0xff) == 0x80) && sigl) /* more than half */
+ ||((sigh & 0x180) == 0x180); /* round to even */
+ break;
+ case RC_DOWN: /* towards -infinity */
+ increment = (tmp.sign == SIGN_POS)
+ ? 0 : (sigl | (sigh & 0xff));
+ break;
+ case RC_UP: /* towards +infinity */
+ increment = (tmp.sign == SIGN_POS)
+ ? (sigl | (sigh & 0xff)) : 0;
+ break;
+ case RC_CHOP:
+ increment = 0;
+ break;
+ }
+
+ /* Truncate part of the mantissa */
+ tmp.sigl = 0;
+
+ if (increment) {
+ set_precision_flag_up();
+
+ if (sigh >= 0xffffff00) {
+ /* The sigh part overflows */
+ tmp.sigh = 0x80000000;
+ exp++;
+ if (exp >= EXP_OVER)
+ goto overflow;
+ } else {
+ tmp.sigh &= 0xffffff00;
+ tmp.sigh += 0x100;
+ }
+ } else {
+ set_precision_flag_down();
+ tmp.sigh &= 0xffffff00; /* Finish the truncation */
+ }
+ }
+ templ = (tmp.sigh >> 8) & 0x007fffff;
+
+ if (exp > SINGLE_Emax) {
+ overflow:
+ EXCEPTION(EX_Overflow);
+ /* This is a special case: see sec 16.2.5.1 of
+ * the 80486 book */
+ if (control_word & EX_Overflow) {
+ /* Overflow to infinity */
+ templ = 0x7f800000;
+ } else
+ return 0;
+ } else
+ templ |= ((exp + SINGLE_Ebias) & 0xff) << 23;
+ }
+ } else
+ if (FPU_st0_tag == TW_Zero) {
+ templ = 0;
+ } else
+ if (FPU_st0_tag == TW_Infinity) {
+ templ = 0x7f800000;
+ } else
+ if (FPU_st0_tag == TW_NaN) {
+ /* See if we can get a valid NaN from
+ * the FPU_REG */
+ templ = FPU_st0_ptr->sigh >> 8;
+ if (!(templ & 0x3fffff)) {
+ /* This case does not seem to
+ * be handled by the 80486
+ * specs */
+ EXCEPTION(EX_Invalid);
+ /* Make the quiet NaN "real
+ * indefinite" */
+ goto put_indefinite;
+ }
+ templ |= 0x7f800000;
+ } else
+ if (FPU_st0_tag == TW_Empty) {
+ /* Empty register (stack
+ * underflow) */
+ EXCEPTION(EX_StackUnder);
+ if (control_word & EX_Invalid) {
+ /* The masked response */
+ /* Put out the QNaN
+ * indefinite */
+ put_indefinite:
+ REENTRANT_CHECK(OFF);
+/* verify_area(VERIFY_WRITE, (void *) single, 4); */
+ suword((unsigned long *) single, 0xffc00000);
+ REENTRANT_CHECK(ON);
+ return 1;
+ } else
+ return 0;
+ }
+#if 0 /* TW_Denormal is not used yet, and probably
+ * won't be */
+ else
+ if (FPU_st0_tag == TW_Denormal) {
+ /* Extended real ->
+ * real will always
+ * underflow */
+ templ = 0;
+ EXCEPTION(EX_Underflow);
+ }
+#endif
+#ifdef PARANOID
+ else {
+ EXCEPTION(EX_INTERNAL | 0x106);
+ return 0;
+ }
+#endif
+ if (FPU_st0_ptr->sign)
+ templ |= 0x80000000;
+
+ REENTRANT_CHECK(OFF);
+/* verify_area(VERIFY_WRITE, (void *) single, 4); */
+ suword((unsigned long *) single, templ);
+ REENTRANT_CHECK(ON);
+
+ return 1;
+}
+
+
+/* Put a long long into user memory */
+int
+reg_store_int64(void)
+{
+ long long *d = (long long *) FPU_data_address;
+ FPU_REG t;
+ long long tll;
+
+ if (FPU_st0_tag == TW_Empty) {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ if (control_word & EX_Invalid) {
+ /* The masked response */
+ /* Put out the QNaN indefinite */
+ goto put_indefinite;
+ } else
+ return 0;
+ }
+ reg_move(FPU_st0_ptr, &t);
+ round_to_int(&t);
+ ((long *) &tll)[0] = t.sigl;
+ ((long *) &tll)[1] = t.sigh;
+ if ((t.sigh & 0x80000000) &&
+ !((t.sigh == 0x80000000) && (t.sigl == 0) && (t.sign == SIGN_NEG))) {
+ EXCEPTION(EX_Invalid);
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+ if (control_word & EX_Invalid) {
+ /* Produce "indefinite" */
+ put_indefinite:
+ ((long *) &tll)[1] = 0x80000000;
+ ((long *) &tll)[0] = 0;
+ } else
+ return 0;
+ } else
+ if (t.sign)
+ tll = -tll;
+
+ REENTRANT_CHECK(OFF);
+/* verify_area(VERIFY_WRITE, (void *) d, 8); */
+ suword((unsigned long *) d, ((long *) &tll)[0]);
+ suword(1 + (unsigned long *) d, ((long *) &tll)[1]);
+ REENTRANT_CHECK(ON);
+
+ return 1;
+}
+
+
+/* Put a long into user memory */
+int
+reg_store_int32(void)
+{
+ long *d = (long *) FPU_data_address;
+ FPU_REG t;
+
+ if (FPU_st0_tag == TW_Empty) {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ if (control_word & EX_Invalid) {
+ /* The masked response */
+ /* Put out the QNaN indefinite */
+ REENTRANT_CHECK(OFF);
+/* verify_area(VERIFY_WRITE, d, 4);*/
+ suword((unsigned long *) d, 0x80000000);
+ REENTRANT_CHECK(ON);
+ return 1;
+ } else
+ return 0;
+ }
+ reg_move(FPU_st0_ptr, &t);
+ round_to_int(&t);
+ if (t.sigh ||
+ ((t.sigl & 0x80000000) &&
+ !((t.sigl == 0x80000000) && (t.sign == SIGN_NEG)))) {
+ EXCEPTION(EX_Invalid);
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+ if (control_word & EX_Invalid) {
+ /* Produce "indefinite" */
+ t.sigl = 0x80000000;
+ } else
+ return 0;
+ } else
+ if (t.sign)
+ t.sigl = -(long) t.sigl;
+
+ REENTRANT_CHECK(OFF);
+/* verify_area(VERIFY_WRITE, d, 4); */
+ suword((unsigned long *) d, t.sigl);
+ REENTRANT_CHECK(ON);
+
+ return 1;
+}
+
+
+/* Put a short into user memory */
+int
+reg_store_int16(void)
+{
+ short *d = (short *) FPU_data_address;
+ FPU_REG t;
+ short ts;
+
+ if (FPU_st0_tag == TW_Empty) {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ if (control_word & EX_Invalid) {
+ /* The masked response */
+ /* Put out the QNaN indefinite */
+ REENTRANT_CHECK(OFF);
+/* verify_area(VERIFY_WRITE, d, 2);*/
+ suword((unsigned short *) d, 0x8000);
+ REENTRANT_CHECK(ON);
+ return 1;
+ } else
+ return 0;
+ }
+ reg_move(FPU_st0_ptr, &t);
+ round_to_int(&t);
+ if (t.sigh ||
+ ((t.sigl & 0xffff8000) &&
+ !((t.sigl == 0x8000) && (t.sign == SIGN_NEG)))) {
+ EXCEPTION(EX_Invalid);
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+ if (control_word & EX_Invalid) {
+ /* Produce "indefinite" */
+ ts = 0x8000;
+ } else
+ return 0;
+ } else
+ if (t.sign)
+ t.sigl = -t.sigl;
+
+ REENTRANT_CHECK(OFF);
+/* verify_area(VERIFY_WRITE, d, 2); */
+ suword((short *) d, (short) t.sigl);
+ REENTRANT_CHECK(ON);
+
+ return 1;
+}
+
+
+/* Put a packed bcd array into user memory */
+int
+reg_store_bcd(void)
+{
+ char *d = (char *) FPU_data_address;
+ FPU_REG t;
+ long long ll;
+ unsigned char b;
+ int i;
+ unsigned char sign = (FPU_st0_ptr->sign == SIGN_NEG) ? 0x80 : 0;
+
+ if (FPU_st0_tag == TW_Empty) {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ if (control_word & EX_Invalid) {
+ /* The masked response */
+ /* Put out the QNaN indefinite */
+ goto put_indefinite;
+ } else
+ return 0;
+ }
+ reg_move(FPU_st0_ptr, &t);
+ round_to_int(&t);
+ ll = *(long long *) (&t.sigl);
+
+ /* Check for overflow, by comparing with 999999999999999999 decimal. */
+ if ((t.sigh > 0x0de0b6b3) ||
+ ((t.sigh == 0x0de0b6b3) && (t.sigl > 0xa763ffff))) {
+ EXCEPTION(EX_Invalid);
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+ if (control_word & EX_Invalid) {
+ put_indefinite:
+ /* Produce "indefinite" */
+ REENTRANT_CHECK(OFF);
+/* verify_area(VERIFY_WRITE, d, 10);*/
+ subyte((unsigned char *) d + 7, 0xff);
+ subyte((unsigned char *) d + 8, 0xff);
+ subyte((unsigned char *) d + 9, 0xff);
+ REENTRANT_CHECK(ON);
+ return 1;
+ } else
+ return 0;
+ }
+/* verify_area(VERIFY_WRITE, d, 10);*/
+ for (i = 0; i < 9; i++) {
+ b = div_small(&ll, 10);
+ b |= (div_small(&ll, 10)) << 4;
+ REENTRANT_CHECK(OFF);
+ subyte((unsigned char *) d + i, b);
+ REENTRANT_CHECK(ON);
+ }
+ REENTRANT_CHECK(OFF);
+ subyte((unsigned char *) d + 9, sign);
+ REENTRANT_CHECK(ON);
+
+ return 1;
+}
+/*===========================================================================*/
+
+/* r gets mangled such that sig is int, sign:
+ it is NOT normalized */
+/* The return value (in eax) is zero if the result is exact,
+ if bits are changed due to rounding, truncation, etc, then
+ a non-zero value is returned */
+/* Overflow is signalled by a non-zero return value (in eax).
+ In the case of overflow, the returned significand always has the
+ the largest possible value */
+/* The value returned in eax is never actually needed :-) */
+int
+round_to_int(FPU_REG * r)
+{
+ char very_big;
+ unsigned eax;
+
+ if (r->tag == TW_Zero) {
+ /* Make sure that zero is returned */
+ *(long long *) &r->sigl = 0;
+ return 0; /* o.k. */
+ }
+ if (r->exp > EXP_BIAS + 63) {
+ r->sigl = r->sigh = ~0; /* The largest representable number */
+ return 1; /* overflow */
+ }
+ eax = shrxs(&r->sigl, EXP_BIAS + 63 - r->exp);
+ very_big = !(~(r->sigh) | ~(r->sigl)); /* test for 0xfff...fff */
+#define half_or_more (eax & 0x80000000)
+#define frac_part (eax)
+#define more_than_half ((eax & 0x80000001) == 0x80000001)
+ switch (control_word & CW_RC) {
+ case RC_RND:
+ if (more_than_half /* nearest */
+ || (half_or_more && (r->sigl & 1))) { /* odd -> even */
+ if (very_big)
+ return 1; /* overflow */
+ (*(long long *) (&r->sigl))++;
+ return LOST_UP;
+ }
+ break;
+ case RC_DOWN:
+ if (frac_part && r->sign) {
+ if (very_big)
+ return 1; /* overflow */
+ (*(long long *) (&r->sigl))++;
+ return LOST_UP;
+ }
+ break;
+ case RC_UP:
+ if (frac_part && !r->sign) {
+ if (very_big)
+ return 1; /* overflow */
+ (*(long long *) (&r->sigl))++;
+ return LOST_UP;
+ }
+ break;
+ case RC_CHOP:
+ break;
+ }
+
+ return eax ? LOST_DOWN : 0;
+
+}
+/*===========================================================================*/
+
+char *
+fldenv(void)
+{
+ char *s = (char *) FPU_data_address;
+ unsigned short tag_word = 0;
+ unsigned char tag;
+ int i;
+
+ REENTRANT_CHECK(OFF);
+ control_word = fuword((unsigned short *) s);
+ status_word = fuword((unsigned short *) (s + 4));
+ tag_word = fuword((unsigned short *) (s + 8));
+ ip_offset = fuword((unsigned long *) (s + 0x0c));
+ cs_selector = fuword((unsigned long *) (s + 0x10));
+ data_operand_offset = fuword((unsigned long *) (s + 0x14));
+ operand_selector = fuword((unsigned long *) (s + 0x18));
+ REENTRANT_CHECK(ON);
+
+ top = (status_word >> SW_Top_Shift) & 7;
+
+ for (i = 0; i < 8; i++) {
+ tag = tag_word & 3;
+ tag_word >>= 2;
+
+ switch (tag) {
+ case 0:
+ regs[i].tag = TW_Valid;
+ break;
+ case 1:
+ regs[i].tag = TW_Zero;
+ break;
+ case 2:
+ regs[i].tag = TW_NaN;
+ break;
+ case 3:
+ regs[i].tag = TW_Empty;
+ break;
+ }
+ }
+
+ FPU_data_address = (void *) data_operand_offset; /* We want no net effect */
+ FPU_entry_eip = ip_offset; /* We want no net effect */
+
+ return s + 0x1c;
+}
+
+
+void
+frstor(void)
+{
+ int i, stnr;
+ unsigned char tag;
+ unsigned short saved_status, saved_control;
+ char *s = (char *) fldenv();
+
+ saved_status = status_word;
+ saved_control = control_word;
+ control_word = 0x037f; /* Mask all interrupts while we load. */
+ for (i = 0; i < 8; i++) {
+ /* load each register */
+ FPU_data_address = (void *) (s + i * 10);
+ reg_load_extended();
+ stnr = (i + top) & 7;
+ tag = regs[stnr].tag; /* derived from the loaded tag word */
+ reg_move(&FPU_loaded_data, &regs[stnr]);
+ if (tag == TW_NaN) {
+ /* The current data is a special, i.e. NaN,
+ * unsupported, infinity, or denormal */
+ unsigned char t = regs[stnr].tag; /* derived from the new
+ * data */
+ if ( /* (t == TW_Valid) || *** */ (t == TW_Zero))
+ regs[stnr].tag = TW_NaN;
+ } else
+ regs[stnr].tag = tag;
+ }
+ control_word = saved_control;
+ status_word = saved_status;
+
+ FPU_data_address = (void *) data_operand_offset; /* We want no net effect */
+}
+
+
+unsigned short
+tag_word(void)
+{
+ unsigned short word = 0;
+ unsigned char tag;
+ int i;
+
+ for (i = 7; i >= 0; i--) {
+ switch (tag = regs[i].tag) {
+#if 0 /* TW_Denormal is not used yet, and probably
+ * won't be */
+ case TW_Denormal:
+#endif
+ case TW_Valid:
+ if (regs[i].exp <= (EXP_BIAS - EXTENDED_Ebias))
+ tag = 2;
+ break;
+ case TW_Infinity:
+ case TW_NaN:
+ tag = 2;
+ break;
+ case TW_Empty:
+ tag = 3;
+ break;
+ /* TW_Valid and TW_Zero already have the correct value */
+ }
+ word <<= 2;
+ word |= tag;
+ }
+ return word;
+}
+
+
+char *
+fstenv(void)
+{
+ char *d = (char *) FPU_data_address;
+
+/* verify_area(VERIFY_WRITE, d, 28);*/
+
+#if 0 /****/
+ *(unsigned short *) &cs_selector = fpu_cs;
+ *(unsigned short *) &operand_selector = fpu_os;
+#endif /****/
+
+ REENTRANT_CHECK(OFF);
+ suword((unsigned short *) d, control_word);
+ suword((unsigned short *) (d + 4), (status_word & ~SW_Top) | ((top & 7) << SW_Top_Shift));
+ suword((unsigned short *) (d + 8), tag_word());
+ suword((unsigned long *) (d + 0x0c), ip_offset);
+ suword((unsigned long *) (d + 0x10), cs_selector);
+ suword((unsigned long *) (d + 0x14), data_operand_offset);
+ suword((unsigned long *) (d + 0x18), operand_selector);
+ REENTRANT_CHECK(ON);
+
+ return d + 0x1c;
+}
+
+
+void
+fsave(void)
+{
+ char *d;
+ FPU_REG tmp, *rp;
+ int i;
+ short e;
+
+ d = fstenv();
+/* verify_area(VERIFY_WRITE, d, 80);*/
+ for (i = 0; i < 8; i++) {
+ /* Store each register in the order: st(0), st(1), ... */
+ rp = &regs[(top + i) & 7];
+
+ e = rp->exp - EXP_BIAS + EXTENDED_Ebias;
+
+ if (rp->tag == TW_Valid) {
+ if (e >= 0x7fff) {
+ /* Overflow to infinity */
+ REENTRANT_CHECK(OFF);
+ suword((unsigned long *) (d + i * 10), 0);
+ suword((unsigned long *) (d + i * 10 + 4), 0);
+ REENTRANT_CHECK(ON);
+ e = 0x7fff;
+ } else
+ if (e <= 0) {
+ if (e > -63) {
+ /* Make a de-normal */
+ reg_move(rp, &tmp);
+ tmp.exp += -EXTENDED_Emin + 63; /* largest exp to be 62 */
+ round_to_int(&tmp);
+ REENTRANT_CHECK(OFF);
+ suword((unsigned long *) (d + i * 10), tmp.sigl);
+ suword((unsigned long *) (d + i * 10 + 4), tmp.sigh);
+ REENTRANT_CHECK(ON);
+ } else {
+ /* Underflow to zero */
+ REENTRANT_CHECK(OFF);
+ suword((unsigned long *) (d + i * 10), 0);
+ suword((unsigned long *) (d + i * 10 + 4), 0);
+ REENTRANT_CHECK(ON);
+ }
+ e = 0;
+ } else {
+ REENTRANT_CHECK(OFF);
+ suword((unsigned long *) (d + i * 10), rp->sigl);
+ suword((unsigned long *) (d + i * 10 + 4), rp->sigh);
+ REENTRANT_CHECK(ON);
+ }
+ } else
+ if (rp->tag == TW_Zero) {
+ REENTRANT_CHECK(OFF);
+ suword((unsigned long *) (d + i * 10), 0);
+ suword((unsigned long *) (d + i * 10 + 4), 0);
+ REENTRANT_CHECK(ON);
+ e = 0;
+ } else
+ if (rp->tag == TW_Infinity) {
+ REENTRANT_CHECK(OFF);
+ suword((unsigned long *) (d + i * 10), 0);
+ suword((unsigned long *) (d + i * 10 + 4), 0x80000000);
+ REENTRANT_CHECK(ON);
+ e = 0x7fff;
+ } else
+ if (rp->tag == TW_NaN) {
+ REENTRANT_CHECK(OFF);
+ suword((unsigned long *) (d + i * 10), rp->sigl);
+ suword((unsigned long *) (d + i * 10 + 4), rp->sigh);
+ REENTRANT_CHECK(ON);
+ e = 0x7fff;
+ } else
+ if (rp->tag == TW_Empty) {
+ /* just copy the reg */
+ REENTRANT_CHECK(OFF);
+ suword((unsigned long *) (d + i * 10), rp->sigl);
+ suword((unsigned long *) (d + i * 10 + 4), rp->sigh);
+ REENTRANT_CHECK(ON);
+ }
+ e |= rp->sign == SIGN_POS ? 0 : 0x8000;
+ REENTRANT_CHECK(OFF);
+ suword((unsigned short *) (d + i * 10 + 8), e);
+ REENTRANT_CHECK(ON);
+ }
+
+ finit();
+
+}
+/*===========================================================================*/
diff --git a/sys/gnu/fpemul/reg_mul.c b/sys/gnu/fpemul/reg_mul.c
new file mode 100644
index 000000000000..5924e5e75df2
--- /dev/null
+++ b/sys/gnu/fpemul/reg_mul.c
@@ -0,0 +1,162 @@
+/*
+ * reg_mul.c
+ *
+ * Multiply one FPU_REG by another, put the result in a destination FPU_REG.
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: reg_mul.c,v 1.3 1994/06/10 07:44:53 rich Exp $
+ *
+ */
+
+/*---------------------------------------------------------------------------+
+ | The destination may be any FPU_REG, including one of the source FPU_REGs. |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "fpu_system.h"
+
+
+/* This routine must be called with non-empty source registers */
+void
+reg_mul(FPU_REG * a, FPU_REG * b, FPU_REG * dest, unsigned int control_w)
+{
+ char sign = (a->sign ^ b->sign);
+
+ if (!(a->tag | b->tag)) {
+ /* This should be the most common case */
+ reg_u_mul(a, b, dest, control_w);
+ dest->sign = sign;
+ return;
+ } else
+ if ((a->tag <= TW_Zero) && (b->tag <= TW_Zero)) {
+#ifdef DENORM_OPERAND
+ if (((b->tag == TW_Valid) && (b->exp <= EXP_UNDER)) ||
+ ((a->tag == TW_Valid) && (a->exp <= EXP_UNDER))) {
+ if (denormal_operand())
+ return;
+ }
+#endif /* DENORM_OPERAND */
+ /* Must have either both arguments == zero, or one
+ * valid and the other zero. The result is therefore
+ * zero. */
+ reg_move(&CONST_Z, dest);
+#ifdef PECULIAR_486
+ /* The 80486 book says that the answer is +0, but a
+ * real 80486 appears to behave this way... */
+ dest->sign = sign;
+#endif /* PECULIAR_486 */
+ return;
+ }
+#if 0 /* TW_Denormal is not used yet... perhaps
+ * never will be. */
+ else
+ if ((a->tag <= TW_Denormal) && (b->tag <= TW_Denormal)) {
+ /* One or both arguments are de-normalized */
+ /* Internal de-normalized numbers are not
+ * supported yet */
+ EXCEPTION(EX_INTERNAL | 0x105);
+ reg_move(&CONST_Z, dest);
+ }
+#endif
+ else {
+ /* Must have infinities, NaNs, etc */
+ if ((a->tag == TW_NaN) || (b->tag == TW_NaN)) {
+ real_2op_NaN(a, b, dest);
+ return;
+ } else
+ if (a->tag == TW_Infinity) {
+ if (b->tag == TW_Zero) {
+ arith_invalid(dest);
+ return;
+ }
+ /* Zero*Infinity is invalid */
+ else {
+#ifdef DENORM_OPERAND
+ if ((b->tag == TW_Valid) && (b->exp <= EXP_UNDER) &&
+ denormal_operand())
+ return;
+#endif /* DENORM_OPERAND */
+ reg_move(a, dest);
+ dest->sign = sign;
+ }
+ return;
+ } else
+ if (b->tag == TW_Infinity) {
+ if (a->tag == TW_Zero) {
+ arith_invalid(dest);
+ return;
+ }
+ /* Zero*Infinity is
+ * invalid */
+ else {
+#ifdef DENORM_OPERAND
+ if ((a->tag == TW_Valid) && (a->exp <= EXP_UNDER) &&
+ denormal_operand())
+ return;
+#endif /* DENORM_OPERAND */
+ reg_move(b, dest);
+ dest->sign = sign;
+ }
+ return;
+ }
+#ifdef PARANOID
+ else {
+ EXCEPTION(EX_INTERNAL | 0x102);
+ }
+#endif /* PARANOID */
+ }
+}
diff --git a/sys/gnu/fpemul/reg_norm.s b/sys/gnu/fpemul/reg_norm.s
new file mode 100644
index 000000000000..37b080e0271b
--- /dev/null
+++ b/sys/gnu/fpemul/reg_norm.s
@@ -0,0 +1,182 @@
+/*
+ * reg_norm.s
+ *
+ * Normalize the value in a FPU_REG.
+ *
+ * Call from C as:
+ * void normalize(FPU_REG *n)
+ *
+ * void normalize_nuo(FPU_REG *n)
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: reg_norm.s,v 1.3 1994/06/10 07:44:54 rich Exp $
+ *
+ */
+
+
+#include "fpu_asm.h"
+
+
+.text
+
+ .align 2,144
+.globl _normalize
+
+_normalize:
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %ebx
+
+ movl PARAM1,%ebx
+
+ movl SIGH(%ebx),%edx
+ movl SIGL(%ebx),%eax
+
+ orl %edx,%edx /* ms bits */
+ js L_done /* Already normalized */
+ jnz L_shift_1 /* Shift left 1 - 31 bits */
+
+ orl %eax,%eax
+ jz L_zero /* The contents are zero */
+
+/* L_shift_32: */
+ movl %eax,%edx
+ xorl %eax,%eax
+ subl $32,EXP(%ebx) /* This can cause an underflow */
+
+/* We need to shift left by 1 - 31 bits */
+L_shift_1:
+ bsrl %edx,%ecx /* get the required shift in %ecx */
+ subl $31,%ecx
+ negl %ecx
+ shld %cl,%eax,%edx
+ shl %cl,%eax
+ subl %ecx,EXP(%ebx) /* This can cause an underflow */
+
+ movl %edx,SIGH(%ebx)
+ movl %eax,SIGL(%ebx)
+
+L_done:
+ cmpl EXP_OVER,EXP(%ebx)
+ jge L_overflow
+
+ cmpl EXP_UNDER,EXP(%ebx)
+ jle L_underflow
+
+L_exit:
+ popl %ebx
+ leave
+ ret
+
+
+L_zero:
+ movl EXP_UNDER,EXP(%ebx)
+ movb TW_Zero,TAG(%ebx)
+ jmp L_exit
+
+L_underflow:
+ push %ebx
+ call _arith_underflow
+ pop %ebx
+ jmp L_exit
+
+L_overflow:
+ push %ebx
+ call _arith_overflow
+ pop %ebx
+ jmp L_exit
+
+
+
+/* Normalise without reporting underflow or overflow */
+ .align 2,144
+.globl _normalize_nuo
+
+_normalize_nuo:
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %ebx
+
+ movl PARAM1,%ebx
+
+ movl SIGH(%ebx),%edx
+ movl SIGL(%ebx),%eax
+
+ orl %edx,%edx /* ms bits */
+ js L_exit /* Already normalized */
+ jnz L_nuo_shift_1 /* Shift left 1 - 31 bits */
+
+ orl %eax,%eax
+ jz L_zero /* The contents are zero */
+
+/* L_nuo_shift_32: */
+ movl %eax,%edx
+ xorl %eax,%eax
+ subl $32,EXP(%ebx) /* This can cause an underflow */
+
+/* We need to shift left by 1 - 31 bits */
+L_nuo_shift_1:
+ bsrl %edx,%ecx /* get the required shift in %ecx */
+ subl $31,%ecx
+ negl %ecx
+ shld %cl,%eax,%edx
+ shl %cl,%eax
+ subl %ecx,EXP(%ebx) /* This can cause an underflow */
+
+ movl %edx,SIGH(%ebx)
+ movl %eax,SIGL(%ebx)
+ jmp L_exit
+
+
diff --git a/sys/gnu/fpemul/reg_round.s b/sys/gnu/fpemul/reg_round.s
new file mode 100644
index 000000000000..7490bbb31d7e
--- /dev/null
+++ b/sys/gnu/fpemul/reg_round.s
@@ -0,0 +1,653 @@
+ .file "reg_round.S"
+/*
+ * reg_round.S
+ *
+ * Rounding/truncation/etc for FPU basic arithmetic functions.
+ *
+ * This code has four possible entry points.
+ * The following must be entered by a jmp intruction:
+ * FPU_round, FPU_round_sqrt, and FPU_Arith_exit.
+ *
+ * The _round_reg entry point is intended to be used by C code.
+ * From C, call as:
+ * void round_reg(FPU_REG *arg, unsigned int extent, unsigned int control_w)
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: reg_round.s,v 1.3 1994/06/10 07:44:55 rich Exp $
+ *
+ */
+
+
+/*---------------------------------------------------------------------------+
+ | Four entry points. |
+ | |
+ | Needed by both the FPU_round and FPU_round_sqrt entry points: |
+ | %eax:%ebx 64 bit significand |
+ | %edx 32 bit extension of the significand |
+ | %edi pointer to an FPU_REG for the result to be stored |
+ | stack calling function must have set up a C stack frame and |
+ | pushed %esi, %edi, and %ebx |
+ | |
+ | Needed just for the FPU_round_sqrt entry point: |
+ | %cx A control word in the same format as the FPU control word. |
+ | Otherwise, PARAM4 must give such a value. |
+ | |
+ | |
+ | The significand and its extension are assumed to be exact in the |
+ | following sense: |
+ | If the significand by itself is the exact result then the significand |
+ | extension (%edx) must contain 0, otherwise the significand extension |
+ | must be non-zero. |
+ | If the significand extension is non-zero then the significand is |
+ | smaller than the magnitude of the correct exact result by an amount |
+ | greater than zero and less than one ls bit of the significand. |
+ | The significand extension is only required to have three possible |
+ | non-zero values: |
+ | less than 0x80000000 <=> the significand is less than 1/2 an ls |
+ | bit smaller than the magnitude of the |
+ | true exact result. |
+ | exactly 0x80000000 <=> the significand is exactly 1/2 an ls bit |
+ | smaller than the magnitude of the true |
+ | exact result. |
+ | greater than 0x80000000 <=> the significand is more than 1/2 an ls |
+ | bit smaller than the magnitude of the |
+ | true exact result. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | The code in this module has become quite complex, but it should handle |
+ | all of the FPU flags which are set at this stage of the basic arithmetic |
+ | computations. |
+ | There are a few rare cases where the results are not set identically to |
+ | a real FPU. These require a bit more thought because at this stage the |
+ | results of the code here appear to be more consistent... |
+ | This may be changed in a future version. |
+ +---------------------------------------------------------------------------*/
+
+
+#include "fpu_asm.h"
+#include "exception.h"
+#include "control_w.h"
+
+#define LOST_DOWN $1
+#define LOST_UP $2
+#define DENORMAL $1
+#define UNMASKED_UNDERFLOW $2
+
+.data
+ .align 2,0
+FPU_bits_lost:
+ .byte 0
+FPU_denormal:
+ .byte 0
+
+.text
+ .align 2,144
+.globl FPU_round
+.globl FPU_round_sqrt
+.globl FPU_Arith_exit
+.globl _round_reg
+
+/* Entry point when called from C */
+_round_reg:
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl PARAM1,%edi
+ movl SIGH(%edi),%eax
+ movl SIGL(%edi),%ebx
+ movl PARAM2,%edx
+ movl PARAM3,%ecx
+ jmp FPU_round_sqrt
+
+FPU_round: /* Normal entry point */
+ movl PARAM4,%ecx
+
+FPU_round_sqrt: /* Entry point from wm_sqrt.S */
+
+#ifdef PARANOID
+/* Cannot use this here yet */
+/* orl %eax,%eax */
+/* jns L_entry_bugged */
+#endif PARANOID
+
+ cmpl EXP_UNDER,EXP(%edi)
+ jle xMake_denorm /* The number is a de-normal*/
+
+ movb $0,FPU_denormal /* 0 -> not a de-normal*/
+
+xDenorm_done:
+ movb $0,FPU_bits_lost /*No bits yet lost in rounding*/
+
+ movl %ecx,%esi
+ andl CW_PC,%ecx
+ cmpl PR_64_BITS,%ecx
+ je LRound_To_64
+
+ cmpl PR_53_BITS,%ecx
+ je LRound_To_53
+
+ cmpl PR_24_BITS,%ecx
+ je LRound_To_24
+
+#ifdef PARANOID
+ jmp L_bugged /* There is no bug, just a bad control word */
+#endif PARANOID
+
+
+/* Round etc to 24 bit precision */
+LRound_To_24:
+ movl %esi,%ecx
+ andl CW_RC,%ecx
+ cmpl RC_RND,%ecx
+ je LRound_nearest_24
+
+ cmpl RC_CHOP,%ecx
+ je LCheck_truncate_24
+
+ cmpl RC_UP,%ecx /* Towards +infinity */
+ je LUp_24
+
+ cmpl RC_DOWN,%ecx /* Towards -infinity */
+ je LDown_24
+
+#ifdef PARANOID
+ jmp L_bugged
+#endif PARANOID
+
+LUp_24:
+ cmpb SIGN_POS,SIGN(%edi)
+ jne LCheck_truncate_24 /* If negative then up==truncate */
+
+ jmp LCheck_24_round_up
+
+LDown_24:
+ cmpb SIGN_POS,SIGN(%edi)
+ je LCheck_truncate_24 /* If positive then down==truncate */
+
+LCheck_24_round_up:
+ movl %eax,%ecx
+ andl $0x000000ff,%ecx
+ orl %ebx,%ecx
+ orl %edx,%ecx
+ jnz LDo_24_round_up
+ jmp LRe_normalise
+
+LRound_nearest_24:
+ /* Do rounding of the 24th bit if needed (nearest or even) */
+ movl %eax,%ecx
+ andl $0x000000ff,%ecx
+ cmpl $0x00000080,%ecx
+ jc LCheck_truncate_24 /*less than half, no increment needed*/
+
+ jne LGreater_Half_24 /* greater than half, increment needed*/
+
+ /* Possibly half, we need to check the ls bits */
+ orl %ebx,%ebx
+ jnz LGreater_Half_24 /* greater than half, increment needed*/
+
+ orl %edx,%edx
+ jnz LGreater_Half_24 /* greater than half, increment needed*/
+
+ /* Exactly half, increment only if 24th bit is 1 (round to even)*/
+ testl $0x00000100,%eax
+ jz LDo_truncate_24
+
+LGreater_Half_24: /*Rounding: increment at the 24th bit*/
+LDo_24_round_up:
+ andl $0xffffff00,%eax /*Truncate to 24 bits*/
+ xorl %ebx,%ebx
+ movb LOST_UP,FPU_bits_lost
+ addl $0x00000100,%eax
+ jmp LCheck_Round_Overflow
+
+LCheck_truncate_24:
+ movl %eax,%ecx
+ andl $0x000000ff,%ecx
+ orl %ebx,%ecx
+ orl %edx,%ecx
+ jz LRe_normalise /* No truncation needed*/
+
+LDo_truncate_24:
+ andl $0xffffff00,%eax /* Truncate to 24 bits*/
+ xorl %ebx,%ebx
+ movb LOST_DOWN,FPU_bits_lost
+ jmp LRe_normalise
+
+
+/* Round etc to 53 bit precision */
+LRound_To_53:
+ movl %esi,%ecx
+ andl CW_RC,%ecx
+ cmpl RC_RND,%ecx
+ je LRound_nearest_53
+
+ cmpl RC_CHOP,%ecx
+ je LCheck_truncate_53
+
+ cmpl RC_UP,%ecx /* Towards +infinity*/
+ je LUp_53
+
+ cmpl RC_DOWN,%ecx /* Towards -infinity*/
+ je LDown_53
+
+#ifdef PARANOID
+ jmp L_bugged
+#endif PARANOID
+
+LUp_53:
+ cmpb SIGN_POS,SIGN(%edi)
+ jne LCheck_truncate_53 /* If negative then up==truncate*/
+
+ jmp LCheck_53_round_up
+
+LDown_53:
+ cmpb SIGN_POS,SIGN(%edi)
+ je LCheck_truncate_53 /* If positive then down==truncate*/
+
+LCheck_53_round_up:
+ movl %ebx,%ecx
+ andl $0x000007ff,%ecx
+ orl %edx,%ecx
+ jnz LDo_53_round_up
+ jmp LRe_normalise
+
+LRound_nearest_53:
+ /*Do rounding of the 53rd bit if needed (nearest or even)*/
+ movl %ebx,%ecx
+ andl $0x000007ff,%ecx
+ cmpl $0x00000400,%ecx
+ jc LCheck_truncate_53 /* less than half, no increment needed*/
+
+ jnz LGreater_Half_53 /* greater than half, increment needed*/
+
+ /*Possibly half, we need to check the ls bits*/
+ orl %edx,%edx
+ jnz LGreater_Half_53 /* greater than half, increment needed*/
+
+ /* Exactly half, increment only if 53rd bit is 1 (round to even)*/
+ testl $0x00000800,%ebx
+ jz LTruncate_53
+
+LGreater_Half_53: /*Rounding: increment at the 53rd bit*/
+LDo_53_round_up:
+ movb LOST_UP,FPU_bits_lost
+ andl $0xfffff800,%ebx /* Truncate to 53 bits*/
+ addl $0x00000800,%ebx
+ adcl $0,%eax
+ jmp LCheck_Round_Overflow
+
+LCheck_truncate_53:
+ movl %ebx,%ecx
+ andl $0x000007ff,%ecx
+ orl %edx,%ecx
+ jz LRe_normalise
+
+LTruncate_53:
+ movb LOST_DOWN,FPU_bits_lost
+ andl $0xfffff800,%ebx /* Truncate to 53 bits*/
+ jmp LRe_normalise
+
+
+/* Round etc to 64 bit precision*/
+LRound_To_64:
+ movl %esi,%ecx
+ andl CW_RC,%ecx
+ cmpl RC_RND,%ecx
+ je LRound_nearest_64
+
+ cmpl RC_CHOP,%ecx
+ je LCheck_truncate_64
+
+ cmpl RC_UP,%ecx /* Towards +infinity*/
+ je LUp_64
+
+ cmpl RC_DOWN,%ecx /* Towards -infinity*/
+ je LDown_64
+
+#ifdef PARANOID
+ jmp L_bugged
+#endif PARANOID
+
+LUp_64:
+ cmpb SIGN_POS,SIGN(%edi)
+ jne LCheck_truncate_64 /* If negative then up==truncate*/
+
+ orl %edx,%edx
+ jnz LDo_64_round_up
+ jmp LRe_normalise
+
+LDown_64:
+ cmpb SIGN_POS,SIGN(%edi)
+ je LCheck_truncate_64 /*If positive then down==truncate*/
+
+ orl %edx,%edx
+ jnz LDo_64_round_up
+ jmp LRe_normalise
+
+LRound_nearest_64:
+ cmpl $0x80000000,%edx
+ jc LCheck_truncate_64
+
+ jne LDo_64_round_up
+
+ /* Now test for round-to-even */
+ testb $1,%ebx
+ jz LCheck_truncate_64
+
+LDo_64_round_up:
+ movb LOST_UP,FPU_bits_lost
+ addl $1,%ebx
+ adcl $0,%eax
+
+LCheck_Round_Overflow:
+ jnc LRe_normalise /* Rounding done, no overflow */
+
+ /* Overflow, adjust the result (to 1.0) */
+ rcrl $1,%eax
+ rcrl $1,%ebx
+ incl EXP(%edi)
+ jmp LRe_normalise
+
+LCheck_truncate_64:
+ orl %edx,%edx
+ jz LRe_normalise
+
+LTruncate_64:
+ movb LOST_DOWN,FPU_bits_lost
+
+LRe_normalise:
+ testb $0xff,FPU_denormal
+ jnz xNormalise_result
+
+xL_Normalised:
+ cmpb LOST_UP,FPU_bits_lost
+ je xL_precision_lost_up
+
+ cmpb LOST_DOWN,FPU_bits_lost
+ je xL_precision_lost_down
+
+xL_no_precision_loss:
+ cmpl EXP_OVER,EXP(%edi)
+ jge L_overflow
+
+ /* store the result */
+ movb TW_Valid,TAG(%edi)
+
+xL_Store_significand:
+ movl %eax,SIGH(%edi)
+ movl %ebx,SIGL(%edi)
+
+FPU_Arith_exit:
+ popl %ebx
+ popl %edi
+ popl %esi
+ leave
+ ret
+
+
+/* Set the FPU status flags to represent precision loss due to*/
+/* round-up.*/
+xL_precision_lost_up:
+ push %eax
+ call _set_precision_flag_up
+ popl %eax
+ jmp xL_no_precision_loss
+
+/* Set the FPU status flags to represent precision loss due to*/
+/* truncation.*/
+xL_precision_lost_down:
+ push %eax
+ call _set_precision_flag_down
+ popl %eax
+ jmp xL_no_precision_loss
+
+
+/* The number is a denormal (which might get rounded up to a normal)
+// Shift the number right the required number of bits, which will
+// have to be undone later...*/
+xMake_denorm:
+ /* The action to be taken depends upon whether the underflow
+ // exception is masked*/
+ testb CW_Underflow,%cl /* Underflow mask.*/
+ jz xUnmasked_underflow /* Do not make a denormal.*/
+
+ movb DENORMAL,FPU_denormal
+
+ pushl %ecx /* Save*/
+ movl EXP(%edi),%ecx
+ subl EXP_UNDER+1,%ecx
+ negl %ecx
+
+ cmpl $64,%ecx /* shrd only works for 0..31 bits */
+ jnc xDenorm_shift_more_than_63
+
+ cmpl $32,%ecx /* shrd only works for 0..31 bits */
+ jnc xDenorm_shift_more_than_32
+
+/* We got here without jumps by assuming that the most common requirement
+// is for a small de-normalising shift.
+// Shift by [1..31] bits */
+ addl %ecx,EXP(%edi)
+ orl %edx,%edx /* extension*/
+ setne %ch
+ xorl %edx,%edx
+ shrd %cl,%ebx,%edx
+ shrd %cl,%eax,%ebx
+ shr %cl,%eax
+ orb %ch,%dl
+ popl %ecx
+ jmp xDenorm_done
+
+/* Shift by [32..63] bits*/
+xDenorm_shift_more_than_32:
+ addl %ecx,EXP(%edi)
+ subb $32,%cl
+ orl %edx,%edx
+ setne %ch
+ orb %ch,%bl
+ xorl %edx,%edx
+ shrd %cl,%ebx,%edx
+ shrd %cl,%eax,%ebx
+ shr %cl,%eax
+ orl %edx,%edx /*test these 32 bits*/
+ setne %cl
+ orb %ch,%bl
+ orb %cl,%bl
+ movl %ebx,%edx
+ movl %eax,%ebx
+ xorl %eax,%eax
+ popl %ecx
+ jmp xDenorm_done
+
+/* Shift by [64..) bits*/
+xDenorm_shift_more_than_63:
+ cmpl $64,%ecx
+ jne xDenorm_shift_more_than_64
+
+/* Exactly 64 bit shift*/
+ addl %ecx,EXP(%edi)
+ xorl %ecx,%ecx
+ orl %edx,%edx
+ setne %cl
+ orl %ebx,%ebx
+ setne %ch
+ orb %ch,%cl
+ orb %cl,%al
+ movl %eax,%edx
+ xorl %eax,%eax
+ xorl %ebx,%ebx
+ popl %ecx
+ jmp xDenorm_done
+
+xDenorm_shift_more_than_64:
+ movl EXP_UNDER+1,EXP(%edi)
+/* This is easy, %eax must be non-zero, so..*/
+ movl $1,%edx
+ xorl %eax,%eax
+ xorl %ebx,%ebx
+ popl %ecx
+ jmp xDenorm_done
+
+
+xUnmasked_underflow:
+ /* Increase the exponent by the magic number*/
+ addl $(3*(1<<13)),EXP(%edi)
+ movb UNMASKED_UNDERFLOW,FPU_denormal
+ jmp xDenorm_done
+
+
+/* Undo the de-normalisation.*/
+xNormalise_result:
+ cmpb UNMASKED_UNDERFLOW,FPU_denormal
+ je xSignal_underflow
+
+/* The number must be a denormal if we got here.*/
+#ifdef PARANOID
+ /* But check it... just in case.*/
+ cmpl EXP_UNDER+1,EXP(%edi)
+ jne L_norm_bugged
+#endif PARANOID
+
+ orl %eax,%eax /* ms bits*/
+ jnz LNormalise_shift_up_to_31 /* Shift left 0 - 31 bits*/
+
+ orl %ebx,%ebx
+ jz L_underflow_to_zero /* The contents are zero*/
+
+/* Shift left 32 - 63 bits*/
+ movl %ebx,%eax
+ xorl %ebx,%ebx
+ subl $32,EXP(%edi)
+
+LNormalise_shift_up_to_31:
+ bsrl %eax,%ecx /* get the required shift in %ecx */
+ subl $31,%ecx
+ negl %ecx
+ shld %cl,%ebx,%eax
+ shl %cl,%ebx
+ subl %ecx,EXP(%edi)
+
+LNormalise_shift_done:
+ testb $0xff,FPU_bits_lost /* bits lost == underflow*/
+ jz xL_Normalised
+
+ /* There must be a masked underflow*/
+ push %eax
+ pushl EX_Underflow
+ call _exception
+ popl %eax
+ popl %eax
+ jmp xL_Normalised
+
+
+/* The operations resulted in a number too small to represent.
+// Masked response.*/
+L_underflow_to_zero:
+ push %eax
+ call _set_precision_flag_down
+ popl %eax
+
+ push %eax
+ pushl EX_Underflow
+ call _exception
+ popl %eax
+ popl %eax
+
+ movb TW_Zero,TAG(%edi)
+ jmp xL_Store_significand
+
+
+/* The operations resulted in a number too large to represent.*/
+L_overflow:
+ push %edi
+ call _arith_overflow
+ pop %edi
+ jmp FPU_Arith_exit
+
+
+xSignal_underflow:
+ push %eax
+ pushl EX_Underflow
+ call EXCEPTION
+ popl %eax
+ popl %eax
+ jmp xL_Normalised
+
+
+#ifdef PARANOID
+/* If we ever get here then we have problems! */
+L_bugged:
+ pushl EX_INTERNAL|0x201
+ call EXCEPTION
+ popl %ebx
+ jmp FPU_Arith_exit
+
+L_norm_bugged:
+ pushl EX_INTERNAL|0x216
+ call EXCEPTION
+ popl %ebx
+ jmp FPU_Arith_exit
+
+L_entry_bugged:
+ pushl EX_INTERNAL|0x217
+ call EXCEPTION
+ popl %ebx
+ jmp FPU_Arith_exit
+#endif PARANOID
diff --git a/sys/gnu/fpemul/reg_u_add.s b/sys/gnu/fpemul/reg_u_add.s
new file mode 100644
index 000000000000..35b5025643d7
--- /dev/null
+++ b/sys/gnu/fpemul/reg_u_add.s
@@ -0,0 +1,244 @@
+ .file "reg_u_add.S"
+/*
+ * reg_u_add.S
+ *
+ * Add two valid (TW_Valid) FPU_REG numbers, of the same sign, and put the
+ * result in a destination FPU_REG.
+ *
+ * Call from C as:
+ * void reg_u_add(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
+ * int control_w)
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: reg_u_add.s,v 1.3 1994/06/10 07:44:56 rich Exp $
+ *
+ */
+
+
+/*
+ | Kernel addition routine reg_u_add(reg *arg1, reg *arg2, reg *answ).
+ | Takes two valid reg f.p. numbers (TW_Valid), which are
+ | treated as unsigned numbers,
+ | and returns their sum as a TW_Valid or TW_S f.p. number.
+ | The returned number is normalized.
+ | Basic checks are performed if PARANOID is defined.
+ */
+
+#include "exception.h"
+#include "fpu_asm.h"
+#include "control_w.h"
+
+.text
+ .align 2,144
+.globl _reg_u_add
+_reg_u_add:
+ pushl %ebp
+ movl %esp,%ebp
+/* subl $16,%esp*/
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl PARAM1,%esi /* source 1 */
+ movl PARAM2,%edi /* source 2 */
+
+#ifdef DENORM_OPERAND
+ cmpl EXP_UNDER,EXP(%esi)
+ jg xOp1_not_denorm
+
+ call _denormal_operand
+ orl %eax,%eax
+ jnz FPU_Arith_exit
+
+xOp1_not_denorm:
+ cmpl EXP_UNDER,EXP(%edi)
+ jg xOp2_not_denorm
+
+ call _denormal_operand
+ orl %eax,%eax
+ jnz FPU_Arith_exit
+
+xOp2_not_denorm:
+#endif DENORM_OPERAND
+
+/* xorl %ecx,%ecx*/
+ movl EXP(%esi),%ecx
+ subl EXP(%edi),%ecx /* exp1 - exp2 */
+/* jnc L_arg1_larger*/
+ jge L_arg1_larger
+
+ /* num1 is smaller */
+ movl SIGL(%esi),%ebx
+ movl SIGH(%esi),%eax
+
+ movl %edi,%esi
+ negw %cx
+ jmp L_accum_loaded
+
+L_arg1_larger:
+ /* num1 has larger or equal exponent */
+ movl SIGL(%edi),%ebx
+ movl SIGH(%edi),%eax
+
+L_accum_loaded:
+ movl PARAM3,%edi /* destination */
+ movb SIGN(%esi),%dl
+ movb %dl,SIGN(%edi) /* Copy the sign from the first arg */
+
+
+ movl EXP(%esi),%edx
+ movl %edx,EXP(%edi) /* Copy exponent to destination */
+
+ xorl %edx,%edx /* clear the extension */
+
+#ifdef PARANOID
+ testl $0x80000000,%eax
+ je L_bugged
+
+ testl $0x80000000,SIGH(%esi)
+ je L_bugged
+#endif PARANOID
+
+/* The number to be shifted is in %eax:%ebx:%edx*/
+ cmpw $32,%cx /* shrd only works for 0..31 bits */
+ jnc L_more_than_31
+
+/* less than 32 bits */
+ shrd %cl,%ebx,%edx
+ shrd %cl,%eax,%ebx
+ shr %cl,%eax
+ jmp L_shift_done
+
+L_more_than_31:
+ cmpw $64,%cx
+ jnc L_more_than_63
+
+ subb $32,%cl
+ jz L_exactly_32
+
+ shrd %cl,%eax,%edx
+ shr %cl,%eax
+ orl %ebx,%ebx
+ jz L_more_31_no_low /* none of the lowest bits is set*/
+
+ orl $1,%edx /* record the fact in the extension*/
+
+L_more_31_no_low:
+ movl %eax,%ebx
+ xorl %eax,%eax
+ jmp L_shift_done
+
+L_exactly_32:
+ movl %ebx,%edx
+ movl %eax,%ebx
+ xorl %eax,%eax
+ jmp L_shift_done
+
+L_more_than_63:
+ cmpw $65,%cx
+ jnc L_more_than_64
+
+ movl %eax,%edx
+ orl %ebx,%ebx
+ jz L_more_63_no_low
+
+ orl $1,%edx
+ jmp L_more_63_no_low
+
+L_more_than_64:
+ movl $1,%edx /* The shifted nr always at least one '1'*/
+
+L_more_63_no_low:
+ xorl %ebx,%ebx
+ xorl %eax,%eax
+
+L_shift_done:
+ /* Now do the addition */
+ addl SIGL(%esi),%ebx
+ adcl SIGH(%esi),%eax
+ jnc L_round_the_result
+
+ /* Overflow, adjust the result */
+ rcrl $1,%eax
+ rcrl $1,%ebx
+ rcrl $1,%edx
+ jnc L_no_bit_lost
+
+ orl $1,%edx
+
+L_no_bit_lost:
+ incl EXP(%edi)
+
+L_round_the_result:
+ jmp FPU_round /* Round the result*/
+
+
+
+#ifdef PARANOID
+/* If we ever get here then we have problems! */
+L_bugged:
+ pushl EX_INTERNAL|0x201
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+#endif PARANOID
+
+
+L_exit:
+ popl %ebx
+ popl %edi
+ popl %esi
+ leave
+ ret
diff --git a/sys/gnu/fpemul/reg_u_div.s b/sys/gnu/fpemul/reg_u_div.s
new file mode 100644
index 000000000000..7f61b057fd78
--- /dev/null
+++ b/sys/gnu/fpemul/reg_u_div.s
@@ -0,0 +1,506 @@
+ .file "reg_u_div.S"
+/*
+ * reg_u_div.S
+ *
+ * Core division routines
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: reg_u_div.s,v 1.3 1994/06/10 07:44:57 rich Exp $
+ *
+ */
+
+/*---------------------------------------------------------------------------+
+ | Kernel for the division routines. |
+ | |
+ | void reg_u_div(FPU_REG *a, FPU_REG *a, |
+ | FPU_REG *dest, unsigned int control_word) |
+ | |
+ | Does not compute the destination exponent, but does adjust it. |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_asm.h"
+#include "control_w.h"
+
+
+/* #define dSIGL(x) (x) */
+/* #define dSIGH(x) 4(x) */
+
+
+.data
+/*
+ Local storage:
+ Result: accum_3:accum_2:accum_1:accum_0
+ Overflow flag: ovfl_flag
+ */
+ .align 2,0
+accum_3:
+ .long 0
+accum_2:
+ .long 0
+accum_1:
+ .long 0
+accum_0:
+ .long 0
+result_1:
+ .long 0
+result_2:
+ .long 0
+ovfl_flag:
+ .byte 0
+
+
+.text
+ .align 2,144
+
+.globl _reg_u_div
+
+.globl _divide_kernel
+
+_reg_u_div:
+ pushl %ebp
+ movl %esp,%ebp
+
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl PARAM1,%esi /* pointer to num */
+ movl PARAM2,%ebx /* pointer to denom */
+ movl PARAM3,%edi /* pointer to answer */
+
+#ifdef DENORM_OPERAND
+ movl EXP(%esi),%eax
+ cmpl EXP_UNDER,%eax
+ jg xOp1_not_denorm
+
+ call _denormal_operand
+ orl %eax,%eax
+ jnz FPU_Arith_exit
+
+xOp1_not_denorm:
+ movl EXP(%ebx),%eax
+ cmpl EXP_UNDER,%eax
+ jg xOp2_not_denorm
+
+ call _denormal_operand
+ orl %eax,%eax
+ jnz FPU_Arith_exit
+
+xOp2_not_denorm:
+#endif DENORM_OPERAND
+
+_divide_kernel:
+#ifdef PARANOID
+/* testl $0x80000000, SIGH(%esi) *//* Dividend */
+/* je L_bugged */
+ testl $0x80000000, SIGH(%ebx) /* Divisor*/
+ je L_bugged
+#endif PARANOID
+
+/* Check if the divisor can be treated as having just 32 bits */
+ cmpl $0,SIGL(%ebx)
+ jnz L_Full_Division /* Can't do a quick divide */
+
+/* We should be able to zip through the division here */
+ movl SIGH(%ebx),%ecx /* The divisor */
+ movl SIGH(%esi),%edx /* Dividend */
+ movl SIGL(%esi),%eax /* Dividend */
+
+ cmpl %ecx,%edx
+ setaeb ovfl_flag /* Keep a record */
+ jb L_no_adjust
+
+ subl %ecx,%edx /* Prevent the overflow */
+
+L_no_adjust:
+ /* Divide the 64 bit number by the 32 bit denominator */
+ divl %ecx
+ movl %eax,result_2
+
+ /* Work on the remainder of the first division */
+ xorl %eax,%eax
+ divl %ecx
+ movl %eax,result_1
+
+ /* Work on the remainder of the 64 bit division */
+ xorl %eax,%eax
+ divl %ecx
+
+ testb $255,ovfl_flag /* was the num > denom ? */
+ je L_no_overflow
+
+ /* Do the shifting here */
+ /* increase the exponent */
+ incl EXP(%edi)
+
+ /* shift the mantissa right one bit */
+ stc /* To set the ms bit */
+ rcrl result_2
+ rcrl result_1
+ rcrl %eax
+
+L_no_overflow:
+ jmp LRound_precision /* Do the rounding as required*/
+
+
+/*---------------------------------------------------------------------------+
+ | Divide: Return arg1/arg2 to arg3. |
+ | |
+ | This routine does not use the exponents of arg1 and arg2, but does |
+ | adjust the exponent of arg3. |
+ | |
+ | The maximum returned value is (ignoring exponents) |
+ | .ffffffff ffffffff |
+ | ------------------ = 1.ffffffff fffffffe |
+ | .80000000 00000000 |
+ | and the minimum is |
+ | .80000000 00000000 |
+ | ------------------ = .80000000 00000001 (rounded) |
+ | .ffffffff ffffffff |
+ | |
+ +---------------------------------------------------------------------------*/
+
+
+L_Full_Division:
+ /* Save extended dividend in local register*/
+ movl SIGL(%esi),%eax
+ movl %eax,accum_2
+ movl SIGH(%esi),%eax
+ movl %eax,accum_3
+ xorl %eax,%eax
+ movl %eax,accum_1 /* zero the extension */
+ movl %eax,accum_0 /* zero the extension */
+
+ movl SIGL(%esi),%eax /* Get the current num */
+ movl SIGH(%esi),%edx
+
+/*----------------------------------------------------------------------*/
+/* Initialization done */
+/* Do the first 32 bits */
+
+ movb $0,ovfl_flag
+ cmpl SIGH(%ebx),%edx /* Test for imminent overflow */
+ jb LLess_than_1
+ ja LGreater_than_1
+
+ cmpl SIGL(%ebx),%eax
+ jb LLess_than_1
+
+LGreater_than_1:
+/* The dividend is greater or equal, would cause overflow */
+ setaeb ovfl_flag /* Keep a record */
+
+ subl SIGL(%ebx),%eax
+ sbbl SIGH(%ebx),%edx /* Prevent the overflow */
+ movl %eax,accum_2
+ movl %edx,accum_3
+
+LLess_than_1:
+/* At this point, we have a dividend < divisor, with a record of
+ adjustment in ovfl_flag */
+
+ /* We will divide by a number which is too large */
+ movl SIGH(%ebx),%ecx
+ addl $1,%ecx
+ jnc LFirst_div_not_1
+
+ /* here we need to divide by 100000000h,
+ i.e., no division at all.. */
+ mov %edx,%eax
+ jmp LFirst_div_done
+
+LFirst_div_not_1:
+ divl %ecx /* Divide the numerator by the augmented
+ denom ms dw */
+
+LFirst_div_done:
+ movl %eax,result_2 /* Put the result in the answer */
+
+ mull SIGH(%ebx) /* mul by the ms dw of the denom */
+
+ subl %eax,accum_2 /* Subtract from the num local reg */
+ sbbl %edx,accum_3
+
+ movl result_2,%eax /* Get the result back */
+ mull SIGL(%ebx) /* now mul the ls dw of the denom */
+
+ subl %eax,accum_1 /* Subtract from the num local reg */
+ sbbl %edx,accum_2
+ sbbl $0,accum_3
+ je LDo_2nd_32_bits /* Must check for non-zero result here */
+
+#ifdef PARANOID
+ jb L_bugged_1
+#endif PARANOID
+
+ /* need to subtract another once of the denom */
+ incl result_2 /* Correct the answer */
+
+ movl SIGL(%ebx),%eax
+ movl SIGH(%ebx),%edx
+ subl %eax,accum_1 /* Subtract from the num local reg */
+ sbbl %edx,accum_2
+
+#ifdef PARANOID
+ sbbl $0,accum_3
+ jne L_bugged_1 /* Must check for non-zero result here */
+#endif PARANOID
+
+/*----------------------------------------------------------------------*/
+/* Half of the main problem is done, there is just a reduced numerator
+ to handle now */
+/* Work with the second 32 bits, accum_0 not used from now on */
+LDo_2nd_32_bits:
+ movl accum_2,%edx /* get the reduced num */
+ movl accum_1,%eax
+
+ /* need to check for possible subsequent overflow */
+ cmpl SIGH(%ebx),%edx
+ jb LDo_2nd_div
+ ja LPrevent_2nd_overflow
+
+ cmpl SIGL(%ebx),%eax
+ jb LDo_2nd_div
+
+LPrevent_2nd_overflow:
+/* The numerator is greater or equal, would cause overflow */
+ /* prevent overflow */
+ subl SIGL(%ebx),%eax
+ sbbl SIGH(%ebx),%edx
+ movl %edx,accum_2
+ movl %eax,accum_1
+
+ incl result_2 /* Reflect the subtraction in the answer */
+
+#ifdef PARANOID
+ je L_bugged_2 /* Can't bump the result to 1.0 */
+#endif PARANOID
+
+LDo_2nd_div:
+ cmpl $0,%ecx /* augmented denom msw*/
+ jnz LSecond_div_not_1
+
+ /* %ecx == 0, we are dividing by 1.0 */
+ mov %edx,%eax
+ jmp LSecond_div_done
+
+LSecond_div_not_1:
+ divl %ecx /* Divide the numerator by the denom ms dw */
+
+LSecond_div_done:
+ movl %eax,result_1 /* Put the result in the answer */
+
+ mull SIGH(%ebx) /* mul by the ms dw of the denom */
+
+ subl %eax,accum_1 /* Subtract from the num local reg */
+ sbbl %edx,accum_2
+
+#ifdef PARANOID
+ jc L_bugged_2
+#endif PARANOID
+
+ movl result_1,%eax /* Get the result back */
+ mull SIGL(%ebx) /* now mul the ls dw of the denom */
+
+ subl %eax,accum_0 /* Subtract from the num local reg */
+ sbbl %edx,accum_1 /* Subtract from the num local reg */
+ sbbl $0,accum_2
+
+#ifdef PARANOID
+ jc L_bugged_2
+#endif PARANOID
+
+ jz LDo_3rd_32_bits
+
+#ifdef PARANOID
+ cmpl $1,accum_2
+ jne L_bugged_2
+#endif PARANOID
+
+ /* need to subtract another once of the denom */
+ movl SIGL(%ebx),%eax
+ movl SIGH(%ebx),%edx
+ subl %eax,accum_0 /* Subtract from the num local reg */
+ sbbl %edx,accum_1
+ sbbl $0,accum_2
+
+#ifdef PARANOID
+ jc L_bugged_2
+ jne L_bugged_2
+#endif PARANOID
+
+ addl $1,result_1 /* Correct the answer */
+ adcl $0,result_2
+
+#ifdef PARANOID
+ jc L_bugged_2 /* Must check for non-zero result here */
+#endif PARANOID
+
+/*----------------------------------------------------------------------*/
+/* The division is essentially finished here, we just need to perform
+ tidying operations. */
+/* deal with the 3rd 32 bits */
+LDo_3rd_32_bits:
+ movl accum_1,%edx /* get the reduced num */
+ movl accum_0,%eax
+
+ /* need to check for possible subsequent overflow */
+ cmpl SIGH(%ebx),%edx /* denom*/
+ jb LRound_prep
+ ja LPrevent_3rd_overflow
+
+ cmpl SIGL(%ebx),%eax /* denom */
+ jb LRound_prep
+
+LPrevent_3rd_overflow:
+ /* prevent overflow */
+ subl SIGL(%ebx),%eax
+ sbbl SIGH(%ebx),%edx
+ movl %edx,accum_1
+ movl %eax,accum_0
+
+ addl $1,result_1 /* Reflect the subtraction in the answer */
+ adcl $0,result_2
+ jne LRound_prep
+ jnc LRound_prep
+
+ /* This is a tricky spot, there is an overflow of the answer */
+ movb $255,ovfl_flag /* Overflow -> 1.000 */
+
+LRound_prep:
+/* Prepare for rounding.
+// To test for rounding, we just need to compare 2*accum with the
+// denom. */
+ movl accum_0,%ecx
+ movl accum_1,%edx
+ movl %ecx,%eax
+ orl %edx,%eax
+ jz LRound_ovfl /* The accumulator contains zero.*/
+
+ /* Multiply by 2 */
+ clc
+ rcll $1,%ecx
+ rcll $1,%edx
+ jc LRound_large /* No need to compare, denom smaller */
+
+ subl SIGL(%ebx),%ecx
+ sbbl SIGH(%ebx),%edx
+ jnc LRound_not_small
+
+ movl $0x70000000,%eax /* Denom was larger */
+ jmp LRound_ovfl
+
+LRound_not_small:
+ jnz LRound_large
+
+ movl $0x80000000,%eax /* Remainder was exactly 1/2 denom */
+ jmp LRound_ovfl
+
+LRound_large:
+ movl $0xff000000,%eax /* Denom was smaller */
+
+LRound_ovfl:
+/* We are now ready to deal with rounding, but first we must get
+ the bits properly aligned */
+ testb $255,ovfl_flag /* was the num > denom ? */
+ je LRound_precision
+
+ incl EXP(%edi)
+
+ /* shift the mantissa right one bit */
+ stc /* Will set the ms bit */
+ rcrl result_2
+ rcrl result_1
+ rcrl %eax
+
+/* Round the result as required */
+LRound_precision:
+ decl EXP(%edi) /* binary point between 1st & 2nd bits */
+
+ movl %eax,%edx
+ movl result_1,%ebx
+ movl result_2,%eax
+ jmp FPU_round
+
+
+#ifdef PARANOID
+/* The logic is wrong if we got here */
+L_bugged:
+ pushl EX_INTERNAL|0x202
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+
+L_bugged_1:
+ pushl EX_INTERNAL|0x203
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+
+L_bugged_2:
+ pushl EX_INTERNAL|0x204
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+
+L_exit:
+ popl %ebx
+ popl %edi
+ popl %esi
+
+ leave
+ ret
+#endif PARANOID
diff --git a/sys/gnu/fpemul/reg_u_mul.s b/sys/gnu/fpemul/reg_u_mul.s
new file mode 100644
index 000000000000..328d2b07da56
--- /dev/null
+++ b/sys/gnu/fpemul/reg_u_mul.s
@@ -0,0 +1,199 @@
+ .file "reg_u_mul.S"
+/*
+ * reg_u_mul.S
+ *
+ * Core multiplication routine
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: reg_u_mul.s,v 1.3 1994/06/10 07:44:58 rich Exp $
+ *
+ */
+
+/*---------------------------------------------------------------------------+
+ | Basic multiplication routine. |
+ | Does not check the resulting exponent for overflow/underflow |
+ | |
+ | reg_u_mul(FPU_REG *a, FPU_REG *b, FPU_REG *c, unsigned int cw); |
+ | |
+ | Internal working is at approx 128 bits. |
+ | Result is rounded to nearest 53 or 64 bits, using "nearest or even". |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_asm.h"
+#include "control_w.h"
+
+
+.data
+ .align 2,0
+accum_0:
+ .long 0
+accum_1:
+ .long 0
+
+
+.text
+ .align 2,144
+
+.globl _reg_u_mul
+_reg_u_mul:
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl PARAM1,%esi
+ movl PARAM2,%edi
+
+#ifdef PARANOID
+ testl $0x80000000,SIGH(%esi)
+ jz L_bugged
+ testl $0x80000000,SIGH(%edi)
+ jz L_bugged
+#endif PARANOID
+
+#ifdef DENORM_OPERAND
+ movl EXP(%esi),%eax
+ cmpl EXP_UNDER,%eax
+ jg xOp1_not_denorm
+
+ call _denormal_operand
+ orl %eax,%eax
+ jnz FPU_Arith_exit
+
+xOp1_not_denorm:
+ movl EXP(%edi),%eax
+ cmpl EXP_UNDER,%eax
+ jg xOp2_not_denorm
+
+ call _denormal_operand
+ orl %eax,%eax
+ jnz FPU_Arith_exit
+
+xOp2_not_denorm:
+#endif DENORM_OPERAND
+
+ xorl %ecx,%ecx
+ xorl %ebx,%ebx
+
+ movl SIGL(%esi),%eax
+ mull SIGL(%edi)
+ movl %eax,accum_0
+ movl %edx,accum_1
+
+ movl SIGL(%esi),%eax
+ mull SIGH(%edi)
+ addl %eax,accum_1
+ adcl %edx,%ebx
+/* adcl $0,%ecx *//* overflow here is not possible */
+
+ movl SIGH(%esi),%eax
+ mull SIGL(%edi)
+ addl %eax,accum_1
+ adcl %edx,%ebx
+ adcl $0,%ecx
+
+ movl SIGH(%esi),%eax
+ mull SIGH(%edi)
+ addl %eax,%ebx
+ adcl %edx,%ecx
+
+ movl EXP(%esi),%eax /* Compute the exponent */
+ addl EXP(%edi),%eax
+ subl EXP_BIAS-1,%eax
+/* Have now finished with the sources */
+ movl PARAM3,%edi /* Point to the destination */
+ movl %eax,EXP(%edi)
+
+/* Now make sure that the result is normalized */
+ testl $0x80000000,%ecx
+ jnz LResult_Normalised
+
+ /* Normalize by shifting left one bit */
+ shll $1,accum_0
+ rcll $1,accum_1
+ rcll $1,%ebx
+ rcll $1,%ecx
+ decl EXP(%edi)
+
+LResult_Normalised:
+ movl accum_0,%eax
+ movl accum_1,%edx
+ orl %eax,%eax
+ jz L_extent_zero
+
+ orl $1,%edx
+
+L_extent_zero:
+ movl %ecx,%eax
+ jmp FPU_round
+
+
+#ifdef PARANOID
+L_bugged:
+ pushl EX_INTERNAL|0x205
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+
+L_exit:
+ popl %ebx
+ popl %edi
+ popl %esi
+ leave
+ ret
+#endif PARANOID
+
diff --git a/sys/gnu/fpemul/reg_u_sub.s b/sys/gnu/fpemul/reg_u_sub.s
new file mode 100644
index 000000000000..7d6d8961669e
--- /dev/null
+++ b/sys/gnu/fpemul/reg_u_sub.s
@@ -0,0 +1,361 @@
+ .file "reg_u_sub.S"
+/*
+ * reg_u_sub.S
+ *
+ * Core floating point subtraction routine.
+ *
+ * Call from C as:
+ * void reg_u_sub(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
+ * int control_w)
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: reg_u_sub.s,v 1.3 1994/06/10 07:44:59 rich Exp $
+ *
+ */
+
+/*
+ | Kernel subtraction routine reg_u_sub(reg *arg1, reg *arg2, reg *answ).
+ | Takes two valid reg f.p. numbers (TW_Valid), which are
+ | treated as unsigned numbers,
+ | and returns their difference as a TW_Valid or TW_Zero f.p.
+ | number.
+ | The first number (arg1) must be the larger.
+ | The returned number is normalized.
+ | Basic checks are performed if PARANOID is defined.
+ */
+
+#include "exception.h"
+#include "fpu_asm.h"
+#include "control_w.h"
+
+.text
+ .align 2,144
+.globl _reg_u_sub
+_reg_u_sub:
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl PARAM1,%esi /* source 1 */
+ movl PARAM2,%edi /* source 2 */
+
+#ifdef DENORM_OPERAND
+ cmpl EXP_UNDER,EXP(%esi)
+ jg xOp1_not_denorm
+
+ call _denormal_operand
+ orl %eax,%eax
+ jnz FPU_Arith_exit
+
+xOp1_not_denorm:
+ cmpl EXP_UNDER,EXP(%edi)
+ jg xOp2_not_denorm
+
+ call _denormal_operand
+ orl %eax,%eax
+ jnz FPU_Arith_exit
+
+xOp2_not_denorm:
+#endif DENORM_OPERAND
+
+/* xorl %ecx,%ecx */
+ movl EXP(%esi),%ecx
+ subl EXP(%edi),%ecx /* exp1 - exp2 */
+
+#ifdef PARANOID
+ /* source 2 is always smaller than source 1 */
+/* jc L_bugged */
+ js L_bugged_1
+
+ testl $0x80000000,SIGH(%edi) /* The args are assumed to be be normalized */
+ je L_bugged_2
+
+ testl $0x80000000,SIGH(%esi)
+ je L_bugged_2
+#endif PARANOID
+
+/*--------------------------------------+
+ | Form a register holding the |
+ | smaller number |
+ +--------------------------------------*/
+ movl SIGH(%edi),%eax /* register ms word */
+ movl SIGL(%edi),%ebx /* register ls word */
+
+ movl PARAM3,%edi /* destination */
+ movl EXP(%esi),%edx
+ movl %edx,EXP(%edi) /* Copy exponent to destination */
+ movb SIGN(%esi),%dl
+ movb %dl,SIGN(%edi) /* Copy the sign from the first arg */
+
+ xorl %edx,%edx /* register extension */
+
+/*--------------------------------------+
+ | Shift the temporary register |
+ | right the required number of |
+ | places. |
+ +--------------------------------------*/
+L_shift_r:
+ cmpl $32,%ecx /* shrd only works for 0..31 bits */
+ jnc L_more_than_31
+
+/* less than 32 bits */
+ shrd %cl,%ebx,%edx
+ shrd %cl,%eax,%ebx
+ shr %cl,%eax
+ jmp L_shift_done
+
+L_more_than_31:
+ cmpl $64,%ecx
+ jnc L_more_than_63
+
+ subb $32,%cl
+ jz L_exactly_32
+
+ shrd %cl,%eax,%edx
+ shr %cl,%eax
+ orl %ebx,%ebx
+ jz L_more_31_no_low /* none of the lowest bits is set */
+
+ orl $1,%edx /* record the fact in the extension */
+
+L_more_31_no_low:
+ movl %eax,%ebx
+ xorl %eax,%eax
+ jmp L_shift_done
+
+L_exactly_32:
+ movl %ebx,%edx
+ movl %eax,%ebx
+ xorl %eax,%eax
+ jmp L_shift_done
+
+L_more_than_63:
+ cmpw $65,%cx
+ jnc L_more_than_64
+
+ /* Shift right by 64 bits */
+ movl %eax,%edx
+ orl %ebx,%ebx
+ jz L_more_63_no_low
+
+ orl $1,%edx
+ jmp L_more_63_no_low
+
+L_more_than_64:
+ jne L_more_than_65
+
+ /* Shift right by 65 bits */
+ /* Carry is clear if we get here */
+ movl %eax,%edx
+ rcrl %edx
+ jnc L_shift_65_nc
+
+ orl $1,%edx
+ jmp L_more_63_no_low
+
+L_shift_65_nc:
+ orl %ebx,%ebx
+ jz L_more_63_no_low
+
+ orl $1,%edx
+ jmp L_more_63_no_low
+
+L_more_than_65:
+ movl $1,%edx /* The shifted nr always at least one '1' */
+
+L_more_63_no_low:
+ xorl %ebx,%ebx
+ xorl %eax,%eax
+
+L_shift_done:
+L_subtr:
+/*------------------------------+
+ | Do the subtraction |
+ +------------------------------*/
+ xorl %ecx,%ecx
+ subl %edx,%ecx
+ movl %ecx,%edx
+ movl SIGL(%esi),%ecx
+ sbbl %ebx,%ecx
+ movl %ecx,%ebx
+ movl SIGH(%esi),%ecx
+ sbbl %eax,%ecx
+ movl %ecx,%eax
+
+#ifdef PARANOID
+ /* We can never get a borrow */
+ jc L_bugged
+#endif PARANOID
+
+/*--------------------------------------+
+ | Normalize the result |
+ +--------------------------------------*/
+ testl $0x80000000,%eax
+ jnz L_round /* no shifting needed */
+
+ orl %eax,%eax
+ jnz L_shift_1 /* shift left 1 - 31 bits */
+
+ orl %ebx,%ebx
+ jnz L_shift_32 /* shift left 32 - 63 bits */
+
+/* A rare case, the only one which is non-zero if we got here
+// is: 1000000 .... 0000
+// -0111111 .... 1111 1
+// --------------------
+// 0000000 .... 0000 1 */
+
+ cmpl $0x80000000,%edx
+ jnz L_must_be_zero
+
+ /* Shift left 64 bits */
+ subl $64,EXP(%edi)
+ movl %edx,%eax
+ jmp L_store
+
+L_must_be_zero:
+#ifdef PARANOID
+ orl %edx,%edx
+ jnz L_bugged_3
+#endif PARANOID
+
+ /* The result is zero */
+ movb TW_Zero,TAG(%edi)
+ movl $0,EXP(%edi) /* exponent */
+ movl $0,SIGL(%edi)
+ movl $0,SIGH(%edi)
+ jmp L_exit /* Does not underflow */
+
+L_shift_32:
+ movl %ebx,%eax
+ movl %edx,%ebx
+ movl $0,%edx
+ subl $32,EXP(%edi) /* Can get underflow here */
+
+/* We need to shift left by 1 - 31 bits */
+L_shift_1:
+ bsrl %eax,%ecx /* get the required shift in %ecx */
+ subl $31,%ecx
+ negl %ecx
+ shld %cl,%ebx,%eax
+ shld %cl,%edx,%ebx
+ shl %cl,%edx
+ subl %ecx,EXP(%edi) /* Can get underflow here */
+
+L_round:
+ jmp FPU_round /* Round the result */
+
+
+#ifdef PARANOID
+L_bugged_1:
+ pushl EX_INTERNAL|0x206
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+
+L_bugged_2:
+ pushl EX_INTERNAL|0x209
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+
+L_bugged_3:
+ pushl EX_INTERNAL|0x210
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+
+L_bugged_4:
+ pushl EX_INTERNAL|0x211
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+
+L_bugged:
+ pushl EX_INTERNAL|0x212
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+#endif PARANOID
+
+
+L_store:
+/*------------------------------+
+ | Store the result |
+ +------------------------------*/
+ movl %eax,SIGH(%edi)
+ movl %ebx,SIGL(%edi)
+
+ movb TW_Valid,TAG(%edi) /* Set the tags to TW_Valid */
+
+ cmpl EXP_UNDER,EXP(%edi)
+ jle L_underflow
+
+L_exit:
+ popl %ebx
+ popl %edi
+ popl %esi
+ leave
+ ret
+
+
+L_underflow:
+ push %edi
+ call _arith_underflow
+ pop %ebx
+ jmp L_exit
+
diff --git a/sys/gnu/fpemul/status_w.h b/sys/gnu/fpemul/status_w.h
new file mode 100644
index 000000000000..e54b36415c9d
--- /dev/null
+++ b/sys/gnu/fpemul/status_w.h
@@ -0,0 +1,106 @@
+/*
+ * status_w.h
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: status_w.h,v 1.3 1994/06/10 07:45:01 rich Exp $
+ *
+ */
+
+
+#ifndef _STATUS_H_
+#define _STATUS_H_
+
+
+#ifdef LOCORE
+#define Const__(x) $/**/x
+#else
+#define Const__(x) x
+#endif
+
+#define SW_Backward Const__(0x8000) /* backward compatibility */
+#define SW_C3 Const__(0x4000) /* condition bit 3 */
+#define SW_Top Const__(0x3800) /* top of stack */
+#define SW_Top_Shift Const__(11) /* shift for top of stack bits */
+#define SW_C2 Const__(0x0400) /* condition bit 2 */
+#define SW_C1 Const__(0x0200) /* condition bit 1 */
+#define SW_C0 Const__(0x0100) /* condition bit 0 */
+#define SW_Summary Const__(0x0080) /* exception summary */
+#define SW_Stack_Fault Const__(0x0040) /* stack fault */
+#define SW_Precision Const__(0x0020) /* loss of precision */
+#define SW_Underflow Const__(0x0010) /* underflow */
+#define SW_Overflow Const__(0x0008) /* overflow */
+#define SW_Zero_Div Const__(0x0004) /* divide by zero */
+#define SW_Denorm_Op Const__(0x0002) /* denormalized operand */
+#define SW_Invalid Const__(0x0001) /* invalid operation */
+
+#define SW_Exc_Mask Const__(0x27f) /* Status word exception bit mask */
+
+#ifndef LOCORE
+
+#define COMP_A_gt_B 1
+#define COMP_A_eq_B 2
+#define COMP_A_lt_B 3
+#define COMP_No_Comp 4
+#define COMP_Denormal 0x20
+#define COMP_NaN 0x40
+#define COMP_SNaN 0x80
+
+#define setcc(cc) ({ \
+ status_word &= ~(SW_C0|SW_C1|SW_C2|SW_C3); \
+ status_word |= (cc) & (SW_C0|SW_C1|SW_C2|SW_C3); })
+
+#endif /* LOCORE */
+
+#endif /* _STATUS_H_ */
diff --git a/sys/gnu/fpemul/version.h b/sys/gnu/fpemul/version.h
new file mode 100644
index 000000000000..40c4513175a3
--- /dev/null
+++ b/sys/gnu/fpemul/version.h
@@ -0,0 +1,61 @@
+/*
+ * version.h
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: version.h,v 1.3 1994/06/10 07:45:02 rich Exp $
+ *
+ */
+
+#define FPU_VERSION "wm-FPU-emu version BETA 1.4"
diff --git a/sys/gnu/fpemul/wm_shrx.s b/sys/gnu/fpemul/wm_shrx.s
new file mode 100644
index 000000000000..2044a682141e
--- /dev/null
+++ b/sys/gnu/fpemul/wm_shrx.s
@@ -0,0 +1,261 @@
+ .file "wm_shrx.S"
+/*
+ * wm_shrx.S
+ *
+ * 64 bit right shift functions
+ *
+ * Call from C as:
+ * unsigned shrx(void *arg1, unsigned arg2)
+ * and
+ * unsigned shrxs(void *arg1, unsigned arg2)
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: wm_shrx.s,v 1.3 1994/06/10 07:45:03 rich Exp $
+ *
+ */
+
+
+#include "fpu_asm.h"
+
+.text
+ .align 2,144
+
+/*---------------------------------------------------------------------------+
+ | unsigned shrx(void *arg1, unsigned arg2) |
+ | |
+ | Extended shift right function. |
+ | Fastest for small shifts. |
+ | Shifts the 64 bit quantity pointed to by the first arg (arg1) |
+ | right by the number of bits specified by the second arg (arg2). |
+ | Forms a 96 bit quantity from the 64 bit arg and eax: |
+ | [ 64 bit arg ][ eax ] |
+ | shift right ---------> |
+ | The eax register is initialized to 0 before the shifting. |
+ | Results returned in the 64 bit arg and eax. |
+ +---------------------------------------------------------------------------*/
+
+ .globl _shrx
+
+_shrx:
+ push %ebp
+ movl %esp,%ebp
+ pushl %esi
+ movl PARAM2,%ecx
+ movl PARAM1,%esi
+ cmpl $32,%ecx /* shrd only works for 0..31 bits */
+ jnc L_more_than_31
+
+/* less than 32 bits */
+ pushl %ebx
+ movl (%esi),%ebx /* lsl */
+ movl 4(%esi),%edx /* msl */
+ xorl %eax,%eax /* extension */
+ shrd %cl,%ebx,%eax
+ shrd %cl,%edx,%ebx
+ shr %cl,%edx
+ movl %ebx,(%esi)
+ movl %edx,4(%esi)
+ popl %ebx
+ popl %esi
+ leave
+ ret
+
+L_more_than_31:
+ cmpl $64,%ecx
+ jnc L_more_than_63
+
+ subb $32,%cl
+ movl (%esi),%eax /* lsl */
+ movl 4(%esi),%edx /* msl */
+ shrd %cl,%edx,%eax
+ shr %cl,%edx
+ movl %edx,(%esi)
+ movl $0,4(%esi)
+ popl %esi
+ leave
+ ret
+
+L_more_than_63:
+ cmpl $96,%ecx
+ jnc L_more_than_95
+
+ subb $64,%cl
+ movl 4(%esi),%eax /* msl */
+ shr %cl,%eax
+ xorl %edx,%edx
+ movl %edx,(%esi)
+ movl %edx,4(%esi)
+ popl %esi
+ leave
+ ret
+
+L_more_than_95:
+ xorl %eax,%eax
+ movl %eax,(%esi)
+ movl %eax,4(%esi)
+ popl %esi
+ leave
+ ret
+
+
+/*---------------------------------------------------------------------------+
+ | unsigned shrxs(void *arg1, unsigned arg2) |
+ | |
+ | Extended shift right function (optimized for small floating point |
+ | integers). |
+ | Shifts the 64 bit quantity pointed to by the first arg (arg1) |
+ | right by the number of bits specified by the second arg (arg2). |
+ | Forms a 96 bit quantity from the 64 bit arg and eax: |
+ | [ 64 bit arg ][ eax ] |
+ | shift right ---------> |
+ | The eax register is initialized to 0 before the shifting. |
+ | The lower 8 bits of eax are lost and replaced by a flag which is |
+ | set (to 0x01) if any bit, apart from the first one, is set in the |
+ | part which has been shifted out of the arg. |
+ | Results returned in the 64 bit arg and eax. |
+ +---------------------------------------------------------------------------*/
+ .globl _shrxs
+_shrxs:
+ push %ebp
+ movl %esp,%ebp
+ pushl %esi
+ pushl %ebx
+ movl PARAM2,%ecx
+ movl PARAM1,%esi
+ cmpl $64,%ecx /* shrd only works for 0..31 bits */
+ jnc Ls_more_than_63
+
+ cmpl $32,%ecx /* shrd only works for 0..31 bits */
+ jc Ls_less_than_32
+
+/* We got here without jumps by assuming that the most common requirement
+ is for small integers */
+/* Shift by [32..63] bits */
+ subb $32,%cl
+ movl (%esi),%eax /* lsl */
+ movl 4(%esi),%edx /* msl */
+ xorl %ebx,%ebx
+ shrd %cl,%eax,%ebx
+ shrd %cl,%edx,%eax
+ shr %cl,%edx
+ orl %ebx,%ebx /* test these 32 bits */
+ setne %bl
+ test $0x7fffffff,%eax /* and 31 bits here */
+ setne %bh
+ orw %bx,%bx /* Any of the 63 bit set ? */
+ setne %al
+ movl %edx,(%esi)
+ movl $0,4(%esi)
+ popl %ebx
+ popl %esi
+ leave
+ ret
+
+/* Shift by [0..31] bits */
+Ls_less_than_32:
+ movl (%esi),%ebx /* lsl */
+ movl 4(%esi),%edx /* msl */
+ xorl %eax,%eax /* extension */
+ shrd %cl,%ebx,%eax
+ shrd %cl,%edx,%ebx
+ shr %cl,%edx
+ test $0x7fffffff,%eax /* only need to look at eax here */
+ setne %al
+ movl %ebx,(%esi)
+ movl %edx,4(%esi)
+ popl %ebx
+ popl %esi
+ leave
+ ret
+
+/* Shift by [64..95] bits */
+Ls_more_than_63:
+ cmpl $96,%ecx
+ jnc Ls_more_than_95
+
+ subb $64,%cl
+ movl (%esi),%ebx /* lsl */
+ movl 4(%esi),%eax /* msl */
+ xorl %edx,%edx /* extension */
+ shrd %cl,%ebx,%edx
+ shrd %cl,%eax,%ebx
+ shr %cl,%eax
+ orl %ebx,%edx
+ setne %bl
+ test $0x7fffffff,%eax /* only need to look at eax here */
+ setne %bh
+ orw %bx,%bx
+ setne %al
+ xorl %edx,%edx
+ movl %edx,(%esi) /* set to zero */
+ movl %edx,4(%esi) /* set to zero */
+ popl %ebx
+ popl %esi
+ leave
+ ret
+
+Ls_more_than_95:
+/* Shift by [96..inf) bits */
+ xorl %eax,%eax
+ movl (%esi),%ebx
+ orl 4(%esi),%ebx
+ setne %al
+ xorl %ebx,%ebx
+ movl %ebx,(%esi)
+ movl %ebx,4(%esi)
+ popl %ebx
+ popl %esi
+ leave
+ ret
diff --git a/sys/gnu/fpemul/wm_sqrt.s b/sys/gnu/fpemul/wm_sqrt.s
new file mode 100644
index 000000000000..cbe0451f5f46
--- /dev/null
+++ b/sys/gnu/fpemul/wm_sqrt.s
@@ -0,0 +1,496 @@
+ .file "wm_sqrt.S"
+/*
+ * wm_sqrt.S
+ *
+ * Fixed point arithmetic square root evaluation.
+ *
+ * Call from C as:
+ * void wm_sqrt(FPU_REG *n, unsigned int control_word)
+ *
+ *
+ * Copyright (C) 1992,1993,1994
+ * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
+ * Australia. E-mail billm@vaxc.cc.monash.edu.au
+ * All rights reserved.
+ *
+ * This copyright notice covers the redistribution and use of the
+ * FPU emulator developed by W. Metzenthen. It covers only its use
+ * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
+ * use is not permitted under this copyright.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must include information specifying
+ * that source code for the emulator is freely available and include
+ * either:
+ * a) an offer to provide the source code for a nominal distribution
+ * fee, or
+ * b) list at least two alternative methods whereby the source
+ * can be obtained, e.g. a publically accessible bulletin board
+ * and an anonymous ftp site from which the software can be
+ * downloaded.
+ * 3. All advertising materials specifically mentioning features or use of
+ * this emulator must acknowledge that it was developed by W. Metzenthen.
+ * 4. The name of W. Metzenthen may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * The purpose of this copyright, based upon the Berkeley copyright, is to
+ * ensure that the covered software remains freely available to everyone.
+ *
+ * The software (with necessary differences) is also available, but under
+ * the terms of the GNU copyleft, for the Linux operating system and for
+ * the djgpp ms-dos extender.
+ *
+ * W. Metzenthen June 1994.
+ *
+ *
+ * $Id: wm_sqrt.s,v 1.3 1994/06/10 07:45:04 rich Exp $
+ *
+ */
+
+
+/*---------------------------------------------------------------------------+
+ | wm_sqrt(FPU_REG *n, unsigned int control_word) |
+ | returns the square root of n in n. |
+ | |
+ | Use Newton's method to compute the square root of a number, which must |
+ | be in the range [1.0 .. 4.0), to 64 bits accuracy. |
+ | Does not check the sign or tag of the argument. |
+ | Sets the exponent, but not the sign or tag of the result. |
+ | |
+ | The guess is kept in %esi:%edi |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_asm.h"
+
+
+.data
+/*
+ Local storage:
+ */
+ .align 4,0
+accum_3:
+ .long 0 /* ms word */
+accum_2:
+ .long 0
+accum_1:
+ .long 0
+accum_0:
+ .long 0
+
+/* The de-normalised argument:
+// sq_2 sq_1 sq_0
+// b b b b b b b ... b b b b b b .... b b b b 0 0 0 ... 0
+// ^ binary point here */
+fsqrt_arg_2:
+ .long 0 /* ms word */
+fsqrt_arg_1:
+ .long 0
+fsqrt_arg_0:
+ .long 0 /* ls word, at most the ms bit is set */
+
+.text
+ .align 2,144
+
+.globl _wm_sqrt
+
+_wm_sqrt:
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl PARAM1,%esi
+
+ movl SIGH(%esi),%eax
+ movl SIGL(%esi),%ecx
+ xorl %edx,%edx
+
+/* We use a rough linear estimate for the first guess.. */
+
+ cmpl EXP_BIAS,EXP(%esi)
+ jnz sqrt_arg_ge_2
+
+ shrl $1,%eax /* arg is in the range [1.0 .. 2.0) */
+ rcrl $1,%ecx
+ rcrl $1,%edx
+
+sqrt_arg_ge_2:
+/* From here on, n is never accessed directly again until it is
+// replaced by the answer. */
+
+ movl %eax,fsqrt_arg_2 /* ms word of n */
+ movl %ecx,fsqrt_arg_1
+ movl %edx,fsqrt_arg_0
+
+/* Make a linear first estimate */
+ shrl $1,%eax
+ addl $0x40000000,%eax
+ movl $0xaaaaaaaa,%ecx
+ mull %ecx
+ shll %edx /* max result was 7fff... */
+ testl $0x80000000,%edx /* but min was 3fff... */
+ jnz sqrt_prelim_no_adjust
+
+ movl $0x80000000,%edx /* round up */
+
+sqrt_prelim_no_adjust:
+ movl %edx,%esi /* Our first guess */
+
+/* We have now computed (approx) (2 + x) / 3, which forms the basis
+ for a few iterations of Newton's method */
+
+ movl fsqrt_arg_2,%ecx /* ms word */
+
+/* From our initial estimate, three iterations are enough to get us
+// to 30 bits or so. This will then allow two iterations at better
+// precision to complete the process.
+
+// Compute (g + n/g)/2 at each iteration (g is the guess). */
+ shrl %ecx /* Doing this first will prevent a divide */
+ /* overflow later. */
+
+ movl %ecx,%edx /* msw of the arg / 2 */
+ divl %esi /* current estimate */
+ shrl %esi /* divide by 2 */
+ addl %eax,%esi /* the new estimate */
+
+ movl %ecx,%edx
+ divl %esi
+ shrl %esi
+ addl %eax,%esi
+
+ movl %ecx,%edx
+ divl %esi
+ shrl %esi
+ addl %eax,%esi
+
+/* Now that an estimate accurate to about 30 bits has been obtained (in %esi),
+// we improve it to 60 bits or so.
+
+// The strategy from now on is to compute new estimates from
+// guess := guess + (n - guess^2) / (2 * guess) */
+
+/* First, find the square of the guess */
+ movl %esi,%eax
+ mull %esi
+/* guess^2 now in %edx:%eax */
+
+ movl fsqrt_arg_1,%ecx
+ subl %ecx,%eax
+ movl fsqrt_arg_2,%ecx /* ms word of normalized n */
+ sbbl %ecx,%edx
+ jnc sqrt_stage_2_positive
+/* subtraction gives a negative result
+// negate the result before division */
+ notl %edx
+ notl %eax
+ addl $1,%eax
+ adcl $0,%edx
+
+ divl %esi
+ movl %eax,%ecx
+
+ movl %edx,%eax
+ divl %esi
+ jmp sqrt_stage_2_finish
+
+sqrt_stage_2_positive:
+ divl %esi
+ movl %eax,%ecx
+
+ movl %edx,%eax
+ divl %esi
+
+ notl %ecx
+ notl %eax
+ addl $1,%eax
+ adcl $0,%ecx
+
+sqrt_stage_2_finish:
+ sarl $1,%ecx /* divide by 2 */
+ rcrl $1,%eax
+
+ /* Form the new estimate in %esi:%edi */
+ movl %eax,%edi
+ addl %ecx,%esi
+
+ jnz sqrt_stage_2_done /* result should be [1..2) */
+
+#ifdef PARANOID
+/* It should be possible to get here only if the arg is ffff....ffff*/
+ cmp $0xffffffff,fsqrt_arg_1
+ jnz sqrt_stage_2_error
+#endif PARANOID
+
+/* The best rounded result.*/
+ xorl %eax,%eax
+ decl %eax
+ movl %eax,%edi
+ movl %eax,%esi
+ movl $0x7fffffff,%eax
+ jmp sqrt_round_result
+
+#ifdef PARANOID
+sqrt_stage_2_error:
+ pushl EX_INTERNAL|0x213
+ call EXCEPTION
+#endif PARANOID
+
+sqrt_stage_2_done:
+
+/* Now the square root has been computed to better than 60 bits */
+
+/* Find the square of the guess*/
+ movl %edi,%eax /* ls word of guess*/
+ mull %edi
+ movl %edx,accum_1
+
+ movl %esi,%eax
+ mull %esi
+ movl %edx,accum_3
+ movl %eax,accum_2
+
+ movl %edi,%eax
+ mull %esi
+ addl %eax,accum_1
+ adcl %edx,accum_2
+ adcl $0,accum_3
+
+/* movl %esi,%eax*/
+/* mull %edi*/
+ addl %eax,accum_1
+ adcl %edx,accum_2
+ adcl $0,accum_3
+
+/* guess^2 now in accum_3:accum_2:accum_1*/
+
+ movl fsqrt_arg_0,%eax /* get normalized n*/
+ subl %eax,accum_1
+ movl fsqrt_arg_1,%eax
+ sbbl %eax,accum_2
+ movl fsqrt_arg_2,%eax /* ms word of normalized n*/
+ sbbl %eax,accum_3
+ jnc sqrt_stage_3_positive
+
+/* subtraction gives a negative result*/
+/* negate the result before division */
+ notl accum_1
+ notl accum_2
+ notl accum_3
+ addl $1,accum_1
+ adcl $0,accum_2
+
+#ifdef PARANOID
+ adcl $0,accum_3 /* This must be zero */
+ jz sqrt_stage_3_no_error
+
+sqrt_stage_3_error:
+ pushl EX_INTERNAL|0x207
+ call EXCEPTION
+
+sqrt_stage_3_no_error:
+#endif PARANOID
+
+ movl accum_2,%edx
+ movl accum_1,%eax
+ divl %esi
+ movl %eax,%ecx
+
+ movl %edx,%eax
+ divl %esi
+
+ sarl $1,%ecx / divide by 2*/
+ rcrl $1,%eax
+
+ /* prepare to round the result*/
+
+ addl %ecx,%edi
+ adcl $0,%esi
+
+ jmp sqrt_stage_3_finished
+
+sqrt_stage_3_positive:
+ movl accum_2,%edx
+ movl accum_1,%eax
+ divl %esi
+ movl %eax,%ecx
+
+ movl %edx,%eax
+ divl %esi
+
+ sarl $1,%ecx /* divide by 2*/
+ rcrl $1,%eax
+
+ /* prepare to round the result*/
+
+ notl %eax /* Negate the correction term*/
+ notl %ecx
+ addl $1,%eax
+ adcl $0,%ecx /* carry here ==> correction == 0*/
+ adcl $0xffffffff,%esi
+
+ addl %ecx,%edi
+ adcl $0,%esi
+
+sqrt_stage_3_finished:
+
+/* The result in %esi:%edi:%esi should be good to about 90 bits here,
+// and the rounding information here does not have sufficient accuracy
+// in a few rare cases. */
+ cmpl $0xffffffe0,%eax
+ ja sqrt_near_exact_x
+
+ cmpl $0x00000020,%eax
+ jb sqrt_near_exact
+
+ cmpl $0x7fffffe0,%eax
+ jb sqrt_round_result
+
+ cmpl $0x80000020,%eax
+ jb sqrt_get_more_precision
+
+sqrt_round_result:
+/* Set up for rounding operations*/
+ movl %eax,%edx
+ movl %esi,%eax
+ movl %edi,%ebx
+ movl PARAM1,%edi
+ movl EXP_BIAS,EXP(%edi) /* Result is in [1.0 .. 2.0)*/
+ movl PARAM2,%ecx
+ jmp FPU_round_sqrt
+
+
+sqrt_near_exact_x:
+/* First, the estimate must be rounded up.*/
+ addl $1,%edi
+ adcl $0,%esi
+
+sqrt_near_exact:
+/* This is an easy case because x^1/2 is monotonic.
+// We need just find the square of our estimate, compare it
+// with the argument, and deduce whether our estimate is
+// above, below, or exact. We use the fact that the estimate
+// is known to be accurate to about 90 bits. */
+ movl %edi,%eax /* ls word of guess*/
+ mull %edi
+ movl %edx,%ebx /* 2nd ls word of square*/
+ movl %eax,%ecx /* ls word of square*/
+
+ movl %edi,%eax
+ mull %esi
+ addl %eax,%ebx
+ addl %eax,%ebx
+
+#ifdef PARANOID
+ cmp $0xffffffb0,%ebx
+ jb sqrt_near_exact_ok
+
+ cmp $0x00000050,%ebx
+ ja sqrt_near_exact_ok
+
+ pushl EX_INTERNAL|0x214
+ call EXCEPTION
+
+sqrt_near_exact_ok:
+#endif PARANOID
+
+ or %ebx,%ebx
+ js sqrt_near_exact_small
+
+ jnz sqrt_near_exact_large
+
+ or %ebx,%edx
+ jnz sqrt_near_exact_large
+
+/* Our estimate is exactly the right answer*/
+ xorl %eax,%eax
+ jmp sqrt_round_result
+
+sqrt_near_exact_small:
+/* Our estimate is too small*/
+ movl $0x000000ff,%eax
+ jmp sqrt_round_result
+
+sqrt_near_exact_large:
+/* Our estimate is too large, we need to decrement it*/
+ subl $1,%edi
+ sbbl $0,%esi
+ movl $0xffffff00,%eax
+ jmp sqrt_round_result
+
+
+sqrt_get_more_precision:
+/* This case is almost the same as the above, except we start*/
+/* with an extra bit of precision in the estimate.*/
+ stc /* The extra bit.*/
+ rcll $1,%edi /* Shift the estimate left one bit*/
+ rcll $1,%esi
+
+ movl %edi,%eax /* ls word of guess*/
+ mull %edi
+ movl %edx,%ebx /* 2nd ls word of square*/
+ movl %eax,%ecx /* ls word of square*/
+
+ movl %edi,%eax
+ mull %esi
+ addl %eax,%ebx
+ addl %eax,%ebx
+
+/* Put our estimate back to its original value*/
+ stc /* The ms bit.*/
+ rcrl $1,%esi /* Shift the estimate left one bit*/
+ rcrl $1,%edi
+
+#ifdef PARANOID
+ cmp $0xffffff60,%ebx
+ jb sqrt_more_prec_ok
+
+ cmp $0x000000a0,%ebx
+ ja sqrt_more_prec_ok
+
+ pushl EX_INTERNAL|0x215
+ call EXCEPTION
+
+sqrt_more_prec_ok:
+#endif PARANOID
+
+ or %ebx,%ebx
+ js sqrt_more_prec_small
+
+ jnz sqrt_more_prec_large
+
+ or %ebx,%ecx
+ jnz sqrt_more_prec_large
+
+/* Our estimate is exactly the right answer*/
+ movl $0x80000000,%eax
+ jmp sqrt_round_result
+
+sqrt_more_prec_small:
+/* Our estimate is too small*/
+ movl $0x800000ff,%eax
+ jmp sqrt_round_result
+
+sqrt_more_prec_large:
+/* Our estimate is too large*/
+ movl $0x7fffff00,%eax
+ jmp sqrt_round_result
diff --git a/sys/i386/boot/Makefile b/sys/i386/boot/Makefile
index 3f402426ee49..3c7418f7ddda 100644
--- a/sys/i386/boot/Makefile
+++ b/sys/i386/boot/Makefile
@@ -20,7 +20,7 @@
# the rights to redistribute these changes.
#
# from: Mach, Revision 2.2 92/04/04 11:33:46 rpd
-# $Id: Makefile,v 1.5 1993/12/11 20:35:15 ats Exp $
+# $Id: Makefile,v 1.10 1994/06/20 04:32:40 jkh Exp $
#
wd0:
@@ -32,7 +32,10 @@ wd0:
NOPROG= noprog
NOMAN= noman
-CFLAGS = -O -DDO_BAD144 -I${.CURDIR}
+# tunable loopcount parameter, waiting for keypress
+BOOTWAIT?= 2400
+
+CFLAGS = -O2 -DDO_BAD144 -DBOOTWAIT=${BOOTWAIT} -I${.CURDIR}
LIBS= -lc
INC= -I${.CURDIR}/../..
@@ -61,31 +64,31 @@ biosboot: boot
bootbios: boot
dd if=boot of=bootbios skip=1
-/usr/mdec/bootsd: bootbios
- cp bootbios /usr/mdec/bootsd
+${DESTDIR}/usr/mdec/bootsd: bootbios
+ cp bootbios ${DESTDIR}/usr/mdec/bootsd
-/usr/mdec/sdboot: biosboot
- cp biosboot /usr/mdec/sdboot
+${DESTDIR}/usr/mdec/sdboot: biosboot
+ cp biosboot ${DESTDIR}/usr/mdec/sdboot
-/usr/mdec/bootwd: /usr/mdec/bootsd
- rm -f /usr/mdec/bootwd
- ln /usr/mdec/bootsd /usr/mdec/bootwd
+${DESTDIR}/usr/mdec/bootwd: ${DESTDIR}/usr/mdec/bootsd
+ rm -f ${DESTDIR}/usr/mdec/bootwd
+ ln ${DESTDIR}/usr/mdec/bootsd ${DESTDIR}/usr/mdec/bootwd
-/usr/mdec/wdboot: /usr/mdec/sdboot
- rm -f /usr/mdec/wdboot
- ln /usr/mdec/sdboot /usr/mdec/wdboot
+${DESTDIR}/usr/mdec/wdboot: ${DESTDIR}/usr/mdec/sdboot
+ rm -f ${DESTDIR}/usr/mdec/wdboot
+ ln ${DESTDIR}/usr/mdec/sdboot ${DESTDIR}/usr/mdec/wdboot
-/usr/mdec/bootfd: /usr/mdec/bootsd
- rm -f /usr/mdec/bootfd
- ln /usr/mdec/bootsd /usr/mdec/bootfd
+${DESTDIR}/usr/mdec/bootfd: ${DESTDIR}/usr/mdec/bootsd
+ rm -f ${DESTDIR}/usr/mdec/bootfd
+ ln ${DESTDIR}/usr/mdec/bootsd ${DESTDIR}/usr/mdec/bootfd
-/usr/mdec/fdboot: /usr/mdec/sdboot
- rm -f /usr/mdec/fdboot
- ln /usr/mdec/sdboot /usr/mdec/fdboot
+${DESTDIR}/usr/mdec/fdboot: ${DESTDIR}/usr/mdec/sdboot
+ rm -f ${DESTDIR}/usr/mdec/fdboot
+ ln ${DESTDIR}/usr/mdec/sdboot ${DESTDIR}/usr/mdec/fdboot
-sd: /usr/mdec/bootsd /usr/mdec/sdboot
-wd: /usr/mdec/bootwd /usr/mdec/wdboot
-fd: /usr/mdec/bootfd /usr/mdec/fdboot
+sd: ${DESTDIR}/usr/mdec/bootsd ${DESTDIR}/usr/mdec/sdboot
+wd: ${DESTDIR}/usr/mdec/bootwd ${DESTDIR}/usr/mdec/wdboot
+fd: ${DESTDIR}/usr/mdec/bootfd ${DESTDIR}/usr/mdec/fdboot
all: biosboot bootbios
diff --git a/sys/i386/boot/biosboot b/sys/i386/boot/biosboot
new file mode 100644
index 000000000000..9c572c5d2422
--- /dev/null
+++ b/sys/i386/boot/biosboot
Binary files differ
diff --git a/sys/i386/boot/boot b/sys/i386/boot/boot
new file mode 100644
index 000000000000..bba109001d81
--- /dev/null
+++ b/sys/i386/boot/boot
Binary files differ
diff --git a/sys/i386/boot/boot.c b/sys/i386/boot/boot.c
index 19de113b0c51..ad3c7b2ee258 100644
--- a/sys/i386/boot/boot.c
+++ b/sys/i386/boot/boot.c
@@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, [92/04/03 16:51:14 rvb]
- * $Id: boot.c,v 1.9.2.1 1994/05/01 05:14:49 rgrimes Exp $
+ * $Id: boot.c,v 1.14 1994/06/16 03:53:27 adam Exp $
*/
@@ -60,8 +60,7 @@ struct exec head;
int argv[10], esym;
char *name;
char *names[] = {
- "/386bsd", "/o386bsd", "/386bsd.old",
- "/vmunix", "/ovmunix", "/vmunix.old"
+ "/386bsd", "/o386bsd", "/386bsd.old"
};
#define NUMNAMES (sizeof(names)/sizeof(char *))
@@ -76,7 +75,7 @@ int drive;
ouraddr,
argv[7] = memsize(0),
argv[8] = memsize(1),
- "$Revision: 1.9.2.1 $");
+ "$Revision: 1.14 $");
printf("use hd(1,a)/386bsd to boot sd0 when wd0 is also installed\n");
gateA20();
loadstart:
@@ -138,13 +137,12 @@ loadprog(howto)
{
if((addr + head.a_text + head.a_data) > ouraddr)
{
- printf("kernel will not fit below loader\n");
+ printf("kernel overlaps loader\n");
return;
}
if((addr + head.a_text + head.a_data + head.a_bss) > 0xa0000)
{
- printf("kernel too big, won't fit in 640K with bss\n");
- printf("Only hope is to link the kernel for > 1MB\n");
+ printf("bss exceeds 640k limit\n");
return;
}
}
diff --git a/sys/i386/boot/boot.sym b/sys/i386/boot/boot.sym
new file mode 100755
index 000000000000..8249abc812dc
--- /dev/null
+++ b/sys/i386/boot/boot.sym
Binary files differ
diff --git a/sys/i386/boot/boot2.S b/sys/i386/boot/boot2.S
index 9270d4de0f3c..c49bde8d377e 100644
--- a/sys/i386/boot/boot2.S
+++ b/sys/i386/boot/boot2.S
@@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:35:26 rpd
- * $Id: boot2.S,v 1.3 1993/11/13 04:43:25 rgrimes Exp $
+ * $Id: boot2.S,v 1.4 1994/06/22 05:52:25 jkh Exp $
*/
#include "asm.h"
@@ -128,14 +128,22 @@ ENTRY(boot2)
mov %ax, %es
/* fix up IDT entries for bdb */
- subl $2, %ebx
+ data32
+ subl $2, %ebx /* calculate EA to check it */
+ jb 1f /* give up if it would trap */
+ addr32
movl %es: (%ebx), %eax /* actually movw to %ax */
addr32
movl %eax, EXT(Idt)+8*DEBUG_VECTOR /* actually movw %ax */
+1:
+ data32
subl $2, %ecx
+ jb 1f
+ addr32
movl %es: (%ecx), %eax /* actually movw to %ax */
addr32
movl %eax, EXT(Idt)+8*BREAKPOINT_VECTOR /* actually movw %ax */
+1:
/* finished with groping in real mode segments */
pop %es
diff --git a/sys/i386/boot/bootbios b/sys/i386/boot/bootbios
new file mode 100644
index 000000000000..a0ed09db1e0c
--- /dev/null
+++ b/sys/i386/boot/bootbios
Binary files differ
diff --git a/sys/i386/boot/disk.c b/sys/i386/boot/disk.c
index 1c7712f10517..8db41bbb6f4b 100644
--- a/sys/i386/boot/disk.c
+++ b/sys/i386/boot/disk.c
@@ -24,7 +24,17 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:35:49 rpd
- * $Id: disk.c,v 1.4 1994/02/22 22:59:40 rgrimes Exp $
+ * $Id: disk.c,v 1.5 1994/05/16 03:06:00 ache Exp $
+ */
+
+/*
+ * 93/10/08 bde
+ * If there is no 386BSD partition, initialize the label sector with
+ * LABELSECTOR instead of with garbage.
+ *
+ * 93/08/22 bde
+ * Fixed reading of bad sector table. It is at the end of the 'c'
+ * partition, which is not always at the end of the disk.
*/
#include "boot.h"
@@ -80,10 +90,12 @@ devopen()
#else EMBEDDED_DISKLABEL
Bread(dosdev, 0);
dptr = (struct dos_partition *)(((char *)0)+DOSPARTOFF);
+ sector = LABELSECTOR;
for (i = 0; i < NDOSPART; i++, dptr++)
- if (dptr->dp_typ == DOSPTYP_386BSD)
+ if (dptr->dp_typ == DOSPTYP_386BSD) {
+ sector = dptr->dp_start + LABELSECTOR;
break;
- sector = dptr->dp_start + LABELSECTOR;
+ }
Bread(dosdev, sector++);
dl=((struct disklabel *)0);
disklabel = *dl; /* structure copy (maybe useful later)*/
@@ -113,10 +125,20 @@ devopen()
int dkbbnum;
struct dkbad *dkbptr;
- /* find the first readable bad144 sector */
- /* some of this code is copied from ufs/disk_subr.c */
+ /* find the first readable bad sector table */
+ /* some of this code is copied from ufs/ufs_disksubr.c */
+ /* including the bugs :-( */
/* read a bad sector table */
- dkbbnum = dl->d_secperunit - dl->d_nsectors;
+
+#define BAD144_PART 2 /* XXX scattered magic numbers */
+#define BSD_PART 0 /* XXX should be 2 but bad144.c uses 0 */
+ if (dl->d_partitions[BSD_PART].p_offset != 0)
+ dkbbnum = dl->d_partitions[BAD144_PART].p_offset
+ + dl->d_partitions[BAD144_PART].p_size;
+ else
+ dkbbnum = dl->d_secperunit;
+ dkbbnum -= dl->d_nsectors;
+
if (dl->d_secsize > DEV_BSIZE)
dkbbnum *= dl->d_secsize / DEV_BSIZE;
else
@@ -138,9 +160,9 @@ devopen()
i += 2;
} while (i < 10 && i < dl->d_nsectors);
if (!do_bad144)
- printf("Bad badsect table\n");
+ printf("Bad bad sector table\n");
else
- printf("Using bad144 bad sector at %d\n", dkbbnum+i);
+ printf("Using bad sector table at %d\n", dkbbnum+i);
}
#endif DO_BAD144
}
@@ -245,7 +267,12 @@ badsect(dosdev, sector)
goto no_remap;
}
/* otherwise find replacement sector */
- newsec = dl->d_secperunit - dl->d_nsectors - i -1;
+ if (dl->d_partitions[BSD_PART].p_offset != 0)
+ newsec = dl->d_partitions[BAD144_PART].p_offset
+ + dl->d_partitions[BAD144_PART].p_size;
+ else
+ newsec = dl->d_secperunit;
+ newsec -= dl->d_nsectors + i + 1;
return newsec;
}
#endif DO_BAD144
diff --git a/sys/i386/boot/io.c b/sys/i386/boot/io.c
index 7cb6d02ba93a..29fd128c9ce7 100644
--- a/sys/i386/boot/io.c
+++ b/sys/i386/boot/io.c
@@ -1,3 +1,4 @@
+
/*
* Mach Operating System
* Copyright (c) 1992, 1991 Carnegie Mellon University
@@ -24,7 +25,7 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:35:57 rpd
- * $Id: io.c,v 1.3 1993/10/16 19:11:36 rgrimes Exp $
+ * $Id: io.c,v 1.6 1994/06/16 03:53:29 adam Exp $
*/
#include <i386/include/pio.h>
@@ -38,10 +39,10 @@
#define KC_CMD_WIN 0xd0 /* read output port */
#define KC_CMD_WOUT 0xd1 /* write output port */
-#define KB_A20 0x9f /* enable A20,
+#define KB_A20 0xdf /* enable A20,
enable output buffer full interrupt
enable data line
- disable clock line */
+ enable clock line */
/*
* Gate A20 for high memory
@@ -137,13 +138,24 @@ getchar()
return(c);
}
+#if BOOTWAIT
+spinwait(i)
+int i;
+{
+ while (--i >= 0)
+ (void)inb(0x84);
+}
+#endif
+
gets(buf)
char *buf;
{
int i;
char *ptr=buf;
- for (i = 240000; i>0; i--)
+#if BOOTWAIT
+ for (i = BOOTWAIT; i>0; spinwait(10000),i--)
+#endif
if (ischar())
for (;;)
switch(*ptr = getchar() & 0xff) {
diff --git a/sys/i386/boot/start.S b/sys/i386/boot/start.S
index bdf387667780..44de86eb89f4 100644
--- a/sys/i386/boot/start.S
+++ b/sys/i386/boot/start.S
@@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:36:29 rpd
- * $Id: start.S,v 1.2 1993/10/16 19:11:38 rgrimes Exp $
+ * $Id: start.S,v 1.3 1994/06/13 19:27:52 jkh Exp $
*/
/*
@@ -99,6 +99,7 @@ start:
jae hd
fd:
+ mov $0x0, %dl
# reset the disk system
#ifdef DEBUG
data32
diff --git a/sys/i386/conf/ECLIPSE b/sys/i386/conf/ECLIPSE
new file mode 100644
index 000000000000..31eede546035
--- /dev/null
+++ b/sys/i386/conf/ECLIPSE
@@ -0,0 +1,66 @@
+#
+# GENERICAH -- Generic machine with WD/AHx family disks
+#
+# $Id: GENERICAH,v 1.36 1994/06/17 06:56:59 sean Exp $
+#
+
+machine "i386"
+cpu "I386_CPU"
+cpu "I486_CPU"
+cpu "I586_CPU"
+ident ECLIPSE
+timezone 8 dst
+maxusers 10
+maxfdescs 2048 #Max file descriptors per process
+options INET #InterNETworking
+options ISOFS #ISO File System
+options NFS #Network File System
+options PCFS #MSDOS File System
+options "COMPAT_43" #Compatible with BSD 4.3
+options "TCP_COMPAT_42" #TCP/IP compatible with 4.2
+options XSERVER #Xserver
+options UCONSOLE #X Console support
+options "FAT_CURSOR" #block cursor in syscons or pccons
+options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
+options "NCONS=4" #4 virtual consoles
+
+config "386bsd" root on sd0 swap on sd0 dumps on sd0
+
+controller isa0
+
+device pci0 at isa? bio irq 9 vector pciintr
+device ncr0
+
+controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
+disk fd0 at fdc0 drive 0
+
+controller scbus0
+
+device sd0
+device sd1
+
+device st0
+
+device cd0 #Only need one of these, the code dynamically grows
+
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
+
+device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
+device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr
+
+device lpt0 at isa? port? tty irq 7 vector lptintr
+
+device ix0 at isa? port 0x320 net irq 10 iomem 0xd0000 iosiz 32768 vector ixintr
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device log
+pseudo-device sl 1
+pseudo-device ppp 1
+pseudo-device pty 32
+pseudo-device speaker
+
+pseudo-device swappager
+pseudo-device vnodepager
+pseudo-device devpager
diff --git a/sys/i386/conf/GENERICAH b/sys/i386/conf/GENERICAH
index 4bba699be512..2c10cd45daa1 100644
--- a/sys/i386/conf/GENERICAH
+++ b/sys/i386/conf/GENERICAH
@@ -1,12 +1,13 @@
#
# GENERICAH -- Generic machine with WD/AHx family disks
#
-# $Id: GENERICAH,v 1.25.2.2 1994/04/12 16:37:30 csgr Exp $
+# $Id: GENERICAH,v 1.36 1994/06/17 06:56:59 sean Exp $
#
machine "i386"
cpu "I386_CPU"
cpu "I486_CPU"
+cpu "I586_CPU"
ident GENERICAH
timezone 8 dst
maxusers 10
@@ -22,14 +23,17 @@ options XSERVER #Xserver
options UCONSOLE #X Console support
options "FAT_CURSOR" #block cursor in syscons or pccons
#options GATEWAY #Host is a Gateway (forwards packets)
+options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
+options "NCONS=4" #4 virtual consoles
-config "386bsd" root on wd0 swap on wd0 and sd0 dumps on wd0
+config "386bsd" root on wd0 swap on wd0 and wd1 and sd0 and sd1 dumps on wd0
controller isa0
controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
disk fd0 at fdc0 drive 0
disk fd1 at fdc0 drive 1
+#tape ft0 at fdc0 drive 2
controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr
disk wd0 at wdc0 drive 0
@@ -41,6 +45,7 @@ disk wd3 at wdc1 drive 1
controller ahb0 at isa? bio irq 11 vector ahbintr
controller aha0 at isa? port "IO_AHA0" bio irq 11 drq 5 vector ahaintr
+controller sea0 at isa? bio irq 5 iomem 0xc8000 iosiz 0x2000 vector seaintr
controller scbus0
device sd0
@@ -57,7 +62,7 @@ device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr
device mcd0 at isa? port 0x300 bio irq 10 vector mcdintr
device mcd1 at isa? port 0x340 bio irq 11 vector mcdintr
-device pc0 at isa? port "IO_KBD" tty irq 1 vector pcrint
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
@@ -78,7 +83,7 @@ pseudo-device loop
pseudo-device ether
pseudo-device log
pseudo-device sl 2
-pseudo-device pty 12
+pseudo-device pty 16
pseudo-device speaker
pseudo-device swappager
diff --git a/sys/i386/conf/GENERICBT b/sys/i386/conf/GENERICBT
index 5311d76f7388..fae078940fa7 100644
--- a/sys/i386/conf/GENERICBT
+++ b/sys/i386/conf/GENERICBT
@@ -1,12 +1,13 @@
#
# GENERICBT -- Generic machine with WD/BTx family disks
#
-# $Id: GENERICBT,v 1.25.2.2 1994/04/12 16:37:32 csgr Exp $
+# $Id: GENERICBT,v 1.35 1994/06/08 00:30:32 phk Exp $
#
machine "i386"
cpu "I386_CPU"
cpu "I486_CPU"
+cpu "I586_CPU"
ident GENERICBT
timezone 8 dst
maxusers 10
@@ -22,14 +23,17 @@ options XSERVER #Xserver
options UCONSOLE #X Console support
options "FAT_CURSOR" #block cursor in syscons or pccons
#options GATEWAY #Host is a Gateway (forwards packets)
+options "NCONS=4" #4 virtual consoles
+options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
-config "386bsd" root on wd0 swap on wd0 and sd0 dumps on wd0
+config "386bsd" root on wd0 swap on wd0 and wd1 and sd0 and sd1 dumps on wd0
controller isa0
controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
disk fd0 at fdc0 drive 0
disk fd1 at fdc0 drive 1
+#tape ft0 at fdc0 drive 2
controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr
disk wd0 at wdc0 drive 0
@@ -57,7 +61,7 @@ device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr
device mcd0 at isa? port 0x300 bio irq 10 vector mcdintr
device mcd1 at isa? port 0x340 bio irq 11 vector mcdintr
-device pc0 at isa? port "IO_KBD" tty irq 1 vector pcrint
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
@@ -78,7 +82,7 @@ pseudo-device loop
pseudo-device ether
pseudo-device log
pseudo-device sl 2
-pseudo-device pty 12
+pseudo-device pty 16
pseudo-device speaker
pseudo-device swappager
diff --git a/sys/i386/conf/HAMSTER b/sys/i386/conf/HAMSTER
new file mode 100644
index 000000000000..a3da520cd05e
--- /dev/null
+++ b/sys/i386/conf/HAMSTER
@@ -0,0 +1,67 @@
+#
+# GENERICAH -- Generic machine with WD/AHx family disks
+#
+# $Id: GENERICAH,v 1.36 1994/06/17 06:56:59 sean Exp $
+#
+
+machine "i386"
+cpu "I386_CPU"
+cpu "I486_CPU"
+cpu "I586_CPU"
+ident GENERICAH
+timezone 8 dst
+maxusers 10
+maxfdescs 2048 #Max file descriptors per process
+options INET #InterNETworking
+options ISOFS #ISO File System
+options NFS #Network File System
+options PCFS #MSDOS File System
+options "COMPAT_43" #Compatible with BSD 4.3
+options "TCP_COMPAT_42" #TCP/IP compatible with 4.2
+options XSERVER #Xserver
+options UCONSOLE #X Console support
+options "FAT_CURSOR" #block cursor in syscons or pccons
+#options GATEWAY #Host is a Gateway (forwards packets)
+options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
+options "NCONS=8" #4 virtual consoles
+
+config "386bsd" root on sd0 swap on sd0 dumps on sd0
+
+controller isa0
+
+controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
+disk fd0 at fdc0 drive 0
+
+controller aha0 at isa? port "IO_AHA0" bio irq 11 drq 5 vector ahaintr
+controller scbus0
+
+device sd0
+device sd1
+device sd2
+device sd3
+
+device st0
+device st1
+
+device cd0 #Only need one of these, the code dynamically grows
+
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
+
+device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
+device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr
+
+device lpt0 at isa? port? tty irq 7 vector lptintr
+
+device ix0 at isa? port 0x300 net irq 10 iomem 0xd0000 iosiz 32768 vector ixintr
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device log
+pseudo-device sl 2
+pseudo-device pty 32
+pseudo-device speaker
+
+pseudo-device swappager
+pseudo-device vnodepager
+pseudo-device devpager
diff --git a/sys/i386/conf/LAPTOP b/sys/i386/conf/LAPTOP
new file mode 100644
index 000000000000..4c7ce3b2fbd7
--- /dev/null
+++ b/sys/i386/conf/LAPTOP
@@ -0,0 +1,68 @@
+#
+# LAPTOP -- Minimal machine with IDE drives.
+#
+# $Id: LAPTOP,v 1.3 1994/06/22 05:58:53 jkh Exp $
+#
+
+machine "i386"
+cpu "I386_CPU"
+cpu "I486_CPU"
+cpu "I586_CPU"
+ident LAPTOP
+timezone 8 dst
+maxusers 8
+maxfdescs 256 #Max file descriptors per process
+options INET #InterNETworking
+options NFS #Network File System
+options PCFS #MSDOS File System
+options "COMPAT_43" #Compatible with BSD 4.3
+options "TCP_COMPAT_42" #TCP/IP compatible with 4.2
+options XSERVER #Xserver
+options UCONSOLE #X Console support
+options "FAT_CURSOR" #block cursor in syscons or pccons
+options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
+options "NCONS=8" #8 virtual consoles
+options LAPTOP
+
+# Do not use in binary distributions; put here because most laptops lack 387
+# support, and LAPTOP is not one of the kernels we build by default.
+options GPL_MATH_EMULATE #Support for x87 emualtion via GPL'd emu
+
+# Most laptops have PS/2 style trackball mice.
+options ALLOW_CONFLICT_IOADDR #no IO addr conflict checks (PS/2 mice)
+
+config "386bsd" root on wd0 swap on wd0 and wd1 and sd0 and sd1 dumps on wd0
+
+controller isa0
+
+controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
+disk fd0 at fdc0 drive 0
+
+controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr
+disk wd0 at wdc0 drive 0
+
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
+
+device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
+device lpt0 at isa? port? tty irq 7 vector lptintr
+device psm0 at isa? port "IO_KBD" tty irq 12 vector psmintr
+
+# IBM/National PCMCIA ethernet cards
+device ze0 at isa? port 0x300 net irq 5 iomem 0xd8000 vector zeintr
+
+# The digital speaker driver (/dev/pcaudio). Might as well since we almost
+# certainly won't have a sound card!
+device pca0 at isa? tty
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device log
+pseudo-device sl 1
+pseudo-device ppp 1
+pseudo-device pty 16
+pseudo-device speaker
+
+pseudo-device swappager
+pseudo-device vnodepager
+pseudo-device devpager
diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT
index 129d2c5d6ea0..9235212a9920 100644
--- a/sys/i386/conf/LINT
+++ b/sys/i386/conf/LINT
@@ -4,38 +4,40 @@
#
# This kernel is NOT MEANT to be runnable!
#
-# $Id: LINT,v 1.53 1994/02/09 05:35:57 nate Exp $
+# $Id: LINT,v 1.79 1994/06/16 05:31:16 jkh Exp $
#
machine "i386"
cpu "I386_CPU"
cpu "I486_CPU"
+cpu "I586_CPU"
ident LINT
timezone 8 dst
maxusers 10
maxfdescs 2048 #Max file descriptors per process
options MATH_EMULATE #Support for x87 emulation
+# Do not use in binary distributions
+#options GPL_MATH_EMULATE #Support for x87 emualtion via
+ #new math emulator
+
config "386bsd" root on wd0 swap on wd0 and sd0 dumps on wd0
#
# options that appear as inline #ifdef's
#
-options "COM_BIDIR" #Bidirectional support in sys/isa/sio.c
options "COM_MULTIPORT" #Multiport support in sys/isa/sio.c
-options "FIFO_TRIGGER=FIFO_TRIGGER_1" #Use this fifo value in sio.c
options "COMPAT_43" #compatible with BSD 4.3
-options "SYMTAB_SPACE=104705" #This kernel needs LOTS of symtable
+options "SYMTAB_SPACE=119000" #This kernel needs LOTS of symtable
options GATEWAY #internetwork gateway
options KTRACE #kernel tracing
options "NCONS=8" #number of syscons virtual consoles
options "FAT_CURSOR" #block cursor in syscons or pccons
-options "STAR_SAVER" #syscons "stars" screen saver
-options "FADE_SAVER" #syscons "fade" screen saver
-options "SNAKE_SAVER" #syscons "snake" screen saver
-options "BLANK_SAVER" #syscons "blank" screen saver
+
+#options ALLOW_CONFLICT_IOADDR #no IO addr conflict checks (PS/2 mice)
+#options ALLOW_CONFLICT_IRQ #no IRQ conflict checks (mport serial)
options "TCP_COMPAT_42" #tcp/ip compatible with 4.2
# ^^^ NOT RECOMMENDED FOR NORMAL USE
@@ -53,13 +55,14 @@ options MACHVMCOMPAT #support for Mach-style vm calls
options IPBROADCASTECHO=1 #send reply to broadcast pings
options IPMASKAGENT=1 #send reply to icmp mask requests
options TPCONS #support X.25 network-layer service
+options USER_LDT #allow user-level control of i386 ldt
-options EXCLUDE_CHIP_MIDI # \ sound driver options
-options "EXCLUDE_MPU401" # \ exclude specified
-options EXCLUDE_GUS # / device or chip
-options EXCLUDE_SBPRO # / from driver
+# See /sys/i386/doc/sound.doc for information about EXCLUDE options for
+# the sound drivers.
-options USER_LDT #allow user-level control of i386 ldt
+# Multicast support.
+options MULTICAST # Multicast code
+options MROUTING # Multicast routing
#
# options that are in sys/conf/files
@@ -120,13 +123,15 @@ controller ahb0 at isa? bio irq 11 vector ahbintr
controller bt0 at isa? port "IO_BT0" bio irq 12 vector btintr
# driver for the Seagate ST01/ST02 card, not yet finished.
#controller sg0 at isa? bio irq 5 iomem 0xc8000 iosiz 0x2000 vector sgintr
-#dcfclk device-driver
+# driver for the Seagate ST01/ST02 or Future Domain 950 card, works
+controller sea0 at isa? bio irq 5 iomem 0xc8000 iosiz 0x2000 vector seaintr
controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
disk fd0 at fdc0 drive 0
disk fd1 at fdc0 drive 1
tape ft0 at fdc0 drive 2
+
# driver for the Western Digital and SMCC WD80xx cards, for the Novell
-# NE1000/200 card and the 3COM 3C503 card.
+# NE1000/2000 card and the 3COM 3C503 card.
device ed0 at isa? port 0x280 net irq 5 iomem 0xd8000 vector edintr
# driver for the AT&T Starlan card.
device ie0 at isa? port 0x360 net irq 7 iomem 0xd0000 vector ieintr
@@ -135,27 +140,38 @@ device is0 at isa? port 0x280 net irq 10 drq 7 vector isintr
#device ix0 at isa? port 0x320 net irq 10 iomem 0xd0000 iosiz 32768 vector ixintr
# driver for the Etherlink III ( 3C509 ) card, beta version.
device ep0 at isa? port 0x300 net irq 10 vector epintr
+#driver for the 3c501
+device el0 at isa? port 0x300 net irq 9 vector elintr
+# IBM/National PCMCIA ethernet cards
+device ze0 at isa? port 0x300 net irq 5 iomem 0xd8000 vector zeintr
+
#special cased above:
#controller isa0
-# interruptless parallel printer port driver
-device lpa0 at isa? port "IO_LPT1" tty
-device lpa1 at isa? port "IO_LPT2" tty
+
+# interruptless parallel printer port driver. NOW OBSOLETE, DON'T USE.
+#device lpa0 at isa? port "IO_LPT1" tty
+#device lpa1 at isa? port "IO_LPT2" tty
# interrupt driven parallel printer port driver
device lpt0 at isa? port "IO_LPT3" tty irq 7 vector lptintr
-# Driver for Mutsumi CD-ROM players
-device mcd0 at isa? port 0x300 bio irq 10 vector mcdint
+# Driver for Mitsumi CD-ROM players
+device mcd0 at isa? port 0x300 bio irq 10 vector mcdintr
# Driver for Logitech and ATI inport bus mice
device mse0 at isa? port 0x23c tty irq 5 vector mseintr
device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
-device pc0 at isa? port "IO_KBD" tty irq 1 vector pcrint
#only one of pc0 or sc0 allowed
-#device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+#device pc0 at isa? port "IO_KBD" tty irq 1 vector pcrint
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr
device sio2 at isa? port "IO_COM3" tty irq 5 vector siointr
device sio3 at isa? port "IO_COM4" tty irq 9 vector siointr
+#PS/2 mouse driver (must follow pc0 or sc0 if enabled). Also enable
+#ALLOW_CONFLICT_IOADDR option (see above) if you want to use this.
+#device psm0 at isa? port "IO_KBD" tty irq 12 vector psmintr
+
pseudo-device speaker
-#tw device-driver
+device tw0 at isa? port 0x278 tty irq 5 vector twintr
+
controller uha0 at isa? port "IO_UHA0" bio irq 14 drq 5 vector uhaintr
controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr
disk wd0 at wdc0 drive 0
@@ -166,14 +182,17 @@ disk wd3 at wdc1 drive 1
device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr
# Various sound card drivers.
-# See /sys/i386/doc/sound.doc for more information.
-device snd5 at isa? port 0x330 irq 6 drq 0 vector mpuintr
+# See /sys/doc/sound.doc for more information.
+device snd5 at isa? port 0x330 irq 6 vector mpuintr
device snd4 at isa? port 0x220 irq 15 drq 6 vector gusintr
-device snd3 at isa? port 0x388 irq 12 drq 3 vector pasintr
+device snd3 at isa? port 0x388 irq 10 drq 6 vector pasintr
device snd2 at isa? port 0x220 irq 7 drq 1 vector sbintr
-device snd1 at isa? port 0x388 irq 0 drq 0 vector sbintr
-#
-#
+device snd6 at isa? port 0x220 irq 7 drq 5 vector sbintr
+device snd7 at isa? port 0x300
+device snd1 at isa? port 0x388
+
+# The digital speaker driver (/dev/pcaudio).
+device pca0 at isa? tty
+
# options that have not been resolved yet
-#
pseudo-device log
diff --git a/sys/i386/conf/Makefile.i386 b/sys/i386/conf/Makefile.i386
index df5fcf18c66c..0ecf4c5e14e5 100644
--- a/sys/i386/conf/Makefile.i386
+++ b/sys/i386/conf/Makefile.i386
@@ -1,6 +1,6 @@
# Copyright 1990 W. Jolitz
# from: @(#)Makefile.i386 7.1 5/10/91
-# $Id: Makefile.i386,v 1.22 1994/02/17 06:51:15 rgrimes Exp $
+# $Id: Makefile.i386,v 1.27 1994/06/16 00:45:02 adam Exp $
#
# Makefile for FreeBSD
#
@@ -24,7 +24,15 @@ TOUCH= touch -f -c
LD= /usr/bin/ld
CC= cc
CPP= cpp
+.if defined(DEBUG)
+.if defined(NOSTRIP)
+STRIP= echo '(skipping) strip'
+.else
+STRIP= cp $@ $@.sym; strip
+.endif
+.else
STRIP= strip
+.endif
DBSYM= /usr/sbin/dbsym
S= ../..
@@ -51,11 +59,11 @@ NORMAL_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
NORMAL_S= ${CPP} -I. -DLOCORE ${COPTS} $< | ${AS} ${ASFLAGS} -o $*.o
DRIVER_C= ${CC} -c ${CFLAGS} ${PROF} $<
DRIVER_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
-SYSTEM_OBJS=locore.o exception.o swtch.o support.o ${OBJS} param.o \
+SYSTEM_OBJS=locore.o config.o exception.o swtch.o support.o ${OBJS} param.o \
ioconf.o conf.o machdep.o
SYSTEM_DEP=Makefile symbols.sort ${SYSTEM_OBJS}
SYSTEM_LD_HEAD= @echo loading $@; rm -f $@
-SYSTEM_LD= @${LD} -Bstatic -Z -T ${LOAD_ADDRESS} -o $@ -X vers.o ${SYSTEM_OBJS}
+SYSTEM_LD= @${LD} -Bstatic -Z -T ${LOAD_ADDRESS} -o $@ -X ${SYSTEM_OBJS} vers.o
SYSTEM_LD_TAIL= @echo rearranging symbols; symorder symbols.sort $@; \
${DBSYM} -fT ${LOAD_ADDRESS} $@; ${STRIP} -x $@; size $@; chmod 755 $@
@@ -90,7 +98,7 @@ symbols.sort: ${I386}/i386/symbols.raw
locore.o: assym.s ${I386}/i386/locore.s machine/trap.h machine/psl.h \
machine/pte.h ${I386}/isa/vector.s ${I386}/isa/icu.s \
- $S/sys/errno.h machine/specialreg.h ${I386}/isa/debug.h \
+ $S/sys/errno.h machine/specialreg.h \
${I386}/isa/icu.h ${I386}/isa/isa.h vector.h $S/net/netisr.h \
machine/asmacros.h
${CPP} -I. -DLOCORE ${COPTS} ${I386}/i386/locore.s | \
@@ -104,7 +112,7 @@ exception.o: assym.s ${I386}/i386/exception.s machine/trap.h \
${AS} ${ASFLAGS} -o exception.o
swtch.o: assym.s ${I386}/i386/swtch.s \
- $S/sys/errno.h ${I386}/isa/debug.h machine/asmacros.h
+ $S/sys/errno.h machine/asmacros.h
${CPP} -I. ${COPTS} ${I386}/i386/swtch.s | \
${AS} ${ASFLAGS} -o swtch.o
diff --git a/sys/i386/conf/SYSCONS b/sys/i386/conf/SYSCONS
deleted file mode 100644
index 2143ec61c60d..000000000000
--- a/sys/i386/conf/SYSCONS
+++ /dev/null
@@ -1,86 +0,0 @@
-#
-# SYSCONS -- Generic machine with WD/AHx family disks and syscons
-#
-# $Id: SYSCONS,v 1.18 1994/02/07 10:42:04 rgrimes Exp $
-#
-
-machine "i386"
-cpu "I386_CPU"
-cpu "I486_CPU"
-ident SYSCONS
-timezone 8 dst
-maxusers 10
-maxfdescs 2048 #Max file descriptors per process
-options MATH_EMULATE #Support for x87 emulation
-options INET #InterNETworking
-options ISOFS #ISO File System
-options NFS #Network File System
-options PCFS #MSDOS File System
-options "COMPAT_43" #Compatible with BSD 4.3
-options "TCP_COMPAT_42" #TCP/IP compatible with 4.2
-options XSERVER #Xserver
-options UCONSOLE #X Console support
-options "NCONS=8" #8 virtual consoles
-options "FAT_CURSOR" #block cursor in syscons
-options "STAR_SAVER" #syscons "stars" screen saver
-#options GATEWAY #Host is a Gateway (forwards packets)
-
-config "386bsd" root on wd0 swap on wd0 and sd0 dumps on wd0
-
-controller isa0
-
-controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
-disk fd0 at fdc0 drive 0
-disk fd1 at fdc0 drive 1
-
-controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr
-disk wd0 at wdc0 drive 0
-disk wd1 at wdc0 drive 1
-
-controller wdc1 at isa? port "IO_WD2" bio irq 15 vector wdintr
-disk wd2 at wdc1 drive 0
-disk wd3 at wdc1 drive 1
-
-controller ahb0 at isa? bio irq 11 vector ahbintr
-controller aha0 at isa? port "IO_AHA0" bio irq 11 drq 5 vector ahaintr
-controller scbus0
-
-device sd0
-device sd1
-device sd2
-device sd3
-
-device st0
-device st1
-
-device cd0 #Only need one of these, the code dynamically grows
-
-device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
-device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
-
-device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
-device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr
-device sio2 at isa? port "IO_COM3" tty irq 5 vector siointr
-device sio3 at isa? port "IO_COM4" tty irq 9 vector siointr
-
-device lpt0 at isa? port "IO_LPT3" tty irq 7 vector lptintr
-device lpa0 at isa? port "IO_LPT1" tty
-device lpa1 at isa? port "IO_LPT2" tty
-
-device ed0 at isa? port 0x280 net irq 5 iomem 0xd8000 vector edintr
-device ed1 at isa? port 0x300 net irq 5 iomem 0xd8000 vector edintr
-device ie0 at isa? port 0x360 net irq 7 iomem 0xd0000 vector ieintr
-device is0 at isa? port 0x280 net irq 10 drq 7 vector isintr
-
-device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr
-
-pseudo-device loop
-pseudo-device ether
-pseudo-device log
-pseudo-device sl 2
-pseudo-device pty 4
-pseudo-device speaker
-
-pseudo-device swappager
-pseudo-device vnodepager
-pseudo-device devpager
diff --git a/sys/i386/conf/TIME b/sys/i386/conf/TIME
new file mode 100644
index 000000000000..bc9c0d8e8752
--- /dev/null
+++ b/sys/i386/conf/TIME
@@ -0,0 +1,64 @@
+#
+# GENERICBT -- Generic machine with WD/BTx family disks
+#
+# $Id: GENERICBT,v 1.35 1994/06/08 00:30:32 phk Exp $
+#
+
+machine "i386"
+cpu "I386_CPU"
+cpu "I486_CPU"
+cpu "I586_CPU"
+ident TIME
+timezone 8 dst
+maxusers 10
+maxfdescs 1024 #Max file descriptors per process
+options INET #InterNETworking
+options ISOFS #ISO File System
+options NFS #Network File System
+options PCFS #MSDOS File System
+options "COMPAT_43" #Compatible with BSD 4.3
+options "TCP_COMPAT_42" #TCP/IP compatible with 4.2
+options XSERVER #Xserver
+options UCONSOLE #X Console support
+options "FAT_CURSOR" #block cursor in syscons or pccons
+options "NCONS=4" #4 virtual consoles
+options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
+
+config "386bsd" root on sd0 swap on sd0 dumps on sd0
+
+controller isa0
+
+controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
+disk fd0 at fdc0 drive 0
+
+controller bt0 at isa? port "IO_BT0" bio irq 11 vector btintr
+controller scbus0
+
+device sd0
+device sd1
+
+device st0
+
+device cd0 #Only need one of these, the code dynamically grows
+
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
+
+device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
+device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr
+
+device lpt0 at isa? port? tty irq 7 vector lptintr
+
+device ed0 at isa? port 0x360 net irq 10 iomem 0xd8000 iosiz 16384 vector edintr
+#device ix0 at isa? port 0x320 net irq 10 iomem 0xd8000 iosiz 32768 vector ixintr
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device log
+pseudo-device sl 2
+pseudo-device pty 32
+pseudo-device speaker
+
+pseudo-device swappager
+pseudo-device vnodepager
+pseudo-device devpager
diff --git a/sys/i386/conf/WCARCH b/sys/i386/conf/WCARCH
new file mode 100644
index 000000000000..f228ec5752d8
--- /dev/null
+++ b/sys/i386/conf/WCARCH
@@ -0,0 +1,67 @@
+#
+# GENERICBT -- Generic machine with WD/BTx family disks
+#
+# $Id: GENERICBT,v 1.35 1994/06/08 00:30:32 phk Exp $
+#
+
+machine "i386"
+cpu "I386_CPU"
+cpu "I486_CPU"
+cpu "I586_CPU"
+ident TIME
+timezone 8 dst
+maxusers 10
+maxfdescs 1024 #Max file descriptors per process
+options INET #InterNETworking
+options ISOFS #ISO File System
+options NFS #Network File System
+options PCFS #MSDOS File System
+options "COMPAT_43" #Compatible with BSD 4.3
+options "TCP_COMPAT_42" #TCP/IP compatible with 4.2
+options XSERVER #Xserver
+options UCONSOLE #X Console support
+options "FAT_CURSOR" #block cursor in syscons or pccons
+options "NCONS=4" #4 virtual consoles
+options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
+
+config "386bsd" root on sd0 swap on sd0 dumps on sd0
+
+controller isa0
+
+controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
+disk fd0 at fdc0 drive 0
+
+# driver for the Adaptec 154x SCSI cards.
+controller aha0 at isa? port "IO_AHA0" bio irq 11 drq 5 vector ahaintr
+
+#controller bt0 at isa? port "IO_BT0" bio irq 11 vector btintr
+#controller scbus0
+
+device sd0
+device sd1
+
+device st0
+
+device cd0 #Only need one of these, the code dynamically grows
+
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
+
+device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
+device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr
+
+device lpt0 at isa? port? tty irq 7 vector lptintr
+
+device ed0 at isa? port 0x360 net irq 10 iomem 0xd8000 iosiz 16384 vector edintr
+#device ix0 at isa? port 0x320 net irq 10 iomem 0xd8000 iosiz 32768 vector ixintr
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device log
+pseudo-device sl 2
+pseudo-device pty 32
+pseudo-device speaker
+
+pseudo-device swappager
+pseudo-device vnodepager
+pseudo-device devpager
diff --git a/sys/i386/conf/WCARCHIVE b/sys/i386/conf/WCARCHIVE
new file mode 100644
index 000000000000..0ce90784f3fd
--- /dev/null
+++ b/sys/i386/conf/WCARCHIVE
@@ -0,0 +1,73 @@
+#
+# GENERICAH -- Generic machine with WD/AHx family disks
+#
+# $Id: GENERICAH,v 1.36 1994/06/17 06:56:59 sean Exp $
+#
+
+machine "i386"
+cpu "I386_CPU"
+cpu "I486_CPU"
+cpu "I586_CPU"
+ident WCARCHIVE
+timezone 8 dst
+maxusers 40
+maxfdescs 1024 #Max file descriptors per process
+options INET #InterNETworking
+options ISOFS #ISO File System
+options NFS #Network File System
+options PCFS #MSDOS File System
+options "COMPAT_43" #Compatible with BSD 4.3
+options "TCP_COMPAT_42" #TCP/IP compatible with 4.2
+options XSERVER #Xserver
+options UCONSOLE #X Console support
+options "FAT_CURSOR" #block cursor in syscons or pccons
+options GATEWAY #Host is a Gateway (forwards packets)
+options "SCSI_DELAY=10" #Be pessimistic about Joe SCSI device
+options "NCONS=4" #4 virtual consoles
+options "NMBCLUSTERS=1024" #Needed space for many ftp connections
+
+config "386bsd" root on sd0 swap on sd0 and sd1 and sd2 dumps on sd0
+
+controller isa0
+
+controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
+disk fd0 at fdc0 drive 0
+
+controller ahb0 at isa? bio irq 11 vector ahbintr
+controller ahb1 at isa? bio irq 12 vector ahbintr
+
+#controller aha0 at isa? port "IO_AHA0" bio irq 11 drq 5 vector ahaintr
+#controller aha1 at isa? port 0x230 bio irq 12 drq 6 vector ahaintr
+
+controller scbus0
+controller scbus1
+
+device sd0
+device sd1
+device sd2
+device sd3
+device sd4
+device sd5
+device sd6
+device sd7
+
+device cd0 #Only need one of these, the code dynamically grows
+
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
+
+device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
+
+device lpt0 at isa? port? tty irq 7 vector lptintr
+
+device ed0 at isa? port 0x280 net irq 5 iomem 0xd8000 flags 0x4 vector edintr
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device log
+pseudo-device pty 32
+pseudo-device speaker
+
+pseudo-device swappager
+pseudo-device vnodepager
+pseudo-device devpager
diff --git a/sys/i386/conf/devices.i386 b/sys/i386/conf/devices.i386
index c388159afee3..3abc0605aac1 100644
--- a/sys/i386/conf/devices.i386
+++ b/sys/i386/conf/devices.i386
@@ -1,6 +1,6 @@
# This file tells what major numbers the various possible swap devices have.
#
-# $Id: devices.i386,v 1.5 1994/01/04 20:09:28 nate Exp $
+# $Id: devices.i386,v 1.6 1994/03/21 20:48:49 ats Exp $
#
wd 0
dk 1
@@ -10,3 +10,4 @@ sd 4
st 5
cd 6
mcd 7
+scd 8
diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386
index 1b84847c7713..92a79684af05 100644
--- a/sys/i386/conf/files.i386
+++ b/sys/i386/conf/files.i386
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.25 1994/02/07 04:27:59 alm Exp $
+# $Id: files.i386,v 1.39 1994/06/16 05:31:20 jkh Exp $
#
i386/i386/autoconf.c standard device-driver
i386/i386/cons.c standard
@@ -17,53 +17,61 @@ i386/i386/pmap.c standard
i386/i386/sys_machdep.c standard
i386/i386/trap.c standard
i386/i386/vm_machdep.c standard
+i386/i386/random.s optional multicast
i386/isa/aha1542.c optional aha device-driver
i386/isa/aha1742.c optional ahb device-driver
i386/isa/bt742a.c optional bt device-driver
i386/isa/clock.c standard
i386/isa/com.c optional com device-driver
-i386/isa/dcfclk.c optional dcfclk device-driver
i386/isa/fd.c optional fd device-driver
i386/isa/ft.c optional ft device-driver
i386/isa/if_ed.c optional ed device-driver
+i386/isa/if_el.c optional el device-driver
i386/isa/if_ep.c optional ep device-driver
i386/isa/if_ie.c optional ie device-driver
i386/isa/if_is.c optional is device-driver
i386/isa/if_ix.c optional ix device-driver
i386/isa/isa.c optional isa device-driver
-i386/isa/lpa.c optional lpa device-driver
i386/isa/lpt.c optional lpt device-driver
i386/isa/mcd.c optional mcd device-driver
i386/isa/mse.c optional mse device-driver
i386/isa/npx.c optional npx device-driver
i386/isa/syscons.c optional sc device-driver
i386/isa/pccons.c optional pc device-driver
+i386/isa/pcaudio.c optional pca device-driver
i386/isa/psm.c optional psm device-driver
i386/isa/sb.c optional sb device-driver
+i386/isa/scd.c optional scd device-driver
+i386/isa/seagate.c optional sea device-driver
i386/isa/sg.c optional sg device-driver
i386/isa/sio.c optional sio device-driver
-i386/isa/sound/adlib_card.c optional snd device-driver
-i386/isa/sound/audio.c optional snd device-driver
-i386/isa/sound/dev_table.c optional snd device-driver
-i386/isa/sound/dmabuf.c optional snd device-driver
-i386/isa/sound/dsp.c optional snd device-driver
-i386/isa/sound/gus_card.c optional snd device-driver
-i386/isa/sound/gus_midi.c optional snd device-driver
-i386/isa/sound/gus_vol.c optional snd device-driver
-i386/isa/sound/gus_wave.c optional snd device-driver
-i386/isa/sound/midi.c optional snd device-driver
-i386/isa/sound/midibuf.c optional snd device-driver
-i386/isa/sound/mpu401.c optional snd device-driver
-i386/isa/sound/opl3.c optional snd device-driver
-i386/isa/sound/pas2_card.c optional snd device-driver
-i386/isa/sound/pas2_midi.c optional snd device-driver
-i386/isa/sound/pas2_mixer.c optional snd device-driver
-i386/isa/sound/pas2_pcm.c optional snd device-driver
-i386/isa/sound/patmgr.c optional snd device-driver
-i386/isa/sound/pro_midi.c optional snd device-driver
-i386/isa/sound/sb_card.c optional snd device-driver
-i386/isa/sound/sb_dsp.c optional snd device-driver
-i386/isa/sound/sequencer.c optional snd device-driver
+i386/isa/sound/adlib_card.c optional snd device-driver
+i386/isa/sound/audio.c optional snd device-driver
+i386/isa/sound/dev_table.c optional snd device-driver
+i386/isa/sound/dmabuf.c optional snd device-driver
+i386/isa/sound/gus_card.c optional snd device-driver
+i386/isa/sound/gus_midi.c optional snd device-driver
+i386/isa/sound/gus_vol.c optional snd device-driver
+i386/isa/sound/gus_wave.c optional snd device-driver
+i386/isa/sound/ics2101.c optional snd device-driver
+i386/isa/sound/midi.c optional snd device-driver
+i386/isa/sound/midibuf.c optional snd device-driver
+i386/isa/sound/mpu401.c optional snd device-driver
+i386/isa/sound/opl3.c optional snd device-driver
+i386/isa/sound/pas2_card.c optional snd device-driver
+i386/isa/sound/pas2_midi.c optional snd device-driver
+i386/isa/sound/pas2_mixer.c optional snd device-driver
+i386/isa/sound/pas2_pcm.c optional snd device-driver
+i386/isa/sound/patmgr.c optional snd device-driver
+i386/isa/sound/pro_midi.c optional snd device-driver
+i386/isa/sound/sb16_dsp.c optional snd device-driver
+i386/isa/sound/sb16_midi.c optional snd device-driver
+i386/isa/sound/sb_card.c optional snd device-driver
+i386/isa/sound/sb_dsp.c optional snd device-driver
+i386/isa/sound/sb_midi.c optional snd device-driver
+i386/isa/sound/sb_mixer.c optional snd device-driver
+i386/isa/sound/sequencer.c optional snd device-driver
+i386/isa/sound/sound_switch.c optional snd device-driver
i386/isa/sound/soundcard.c optional snd device-driver
i386/isa/spkr.c optional speaker
i386/isa/tw.c optional tw device-driver
@@ -76,3 +84,39 @@ i386/isa/pcvt/pcvt_out.c optional vt device-driver
i386/isa/pcvt/pcvt_kbd.c optional vt device-driver
i386/isa/pcvt/pcvt_vtf.c optional vt device-driver
i386/isa/pcvt/pcvt_ext.c optional vt device-driver
+i386/isa/if_ze.c optional ze device-driver
+gnu/fpemul/div_small.s optional gpl_math_emulate
+gnu/fpemul/errors.c optional gpl_math_emulate
+gnu/fpemul/fpu_arith.c optional gpl_math_emulate
+gnu/fpemul/fpu_aux.c optional gpl_math_emulate
+gnu/fpemul/fpu_entry.c optional gpl_math_emulate
+gnu/fpemul/fpu_etc.c optional gpl_math_emulate
+gnu/fpemul/fpu_trig.c optional gpl_math_emulate
+gnu/fpemul/get_address.c optional gpl_math_emulate
+gnu/fpemul/load_store.c optional gpl_math_emulate
+gnu/fpemul/poly_2xm1.c optional gpl_math_emulate
+gnu/fpemul/poly_atan.c optional gpl_math_emulate
+gnu/fpemul/poly_div.s optional gpl_math_emulate
+gnu/fpemul/poly_l2.c optional gpl_math_emulate
+gnu/fpemul/poly_mul64.s optional gpl_math_emulate
+gnu/fpemul/poly_sin.c optional gpl_math_emulate
+gnu/fpemul/poly_tan.c optional gpl_math_emulate
+gnu/fpemul/polynomial.s optional gpl_math_emulate
+gnu/fpemul/reg_add_sub.c optional gpl_math_emulate
+gnu/fpemul/reg_compare.c optional gpl_math_emulate
+gnu/fpemul/reg_constant.c optional gpl_math_emulate
+gnu/fpemul/reg_div.s optional gpl_math_emulate
+gnu/fpemul/reg_ld_str.c optional gpl_math_emulate
+gnu/fpemul/reg_mul.c optional gpl_math_emulate
+gnu/fpemul/reg_norm.s optional gpl_math_emulate
+gnu/fpemul/reg_round.s optional gpl_math_emulate
+gnu/fpemul/reg_u_add.s optional gpl_math_emulate
+gnu/fpemul/reg_u_div.s optional gpl_math_emulate
+gnu/fpemul/reg_u_mul.s optional gpl_math_emulate
+gnu/fpemul/reg_u_sub.s optional gpl_math_emulate
+gnu/fpemul/wm_shrx.s optional gpl_math_emulate
+gnu/fpemul/wm_sqrt.s optional gpl_math_emulate
+i386/pci/ncr.c optional ncr device-driver
+i386/pci/pci.c optional pci device-driver
+i386/pci/pcibios.c optional pci device-driver
+i386/pci/pci_config.c optional pci device-driver
diff --git a/sys/i386/doc/sound.doc b/sys/i386/doc/sound.doc
deleted file mode 100644
index 7f5b9da64e6d..000000000000
--- a/sys/i386/doc/sound.doc
+++ /dev/null
@@ -1,38 +0,0 @@
-To enable sound card support, you need to add one or more of the following
-lines to your kernel configuration file:
-
-device snd5 at isa? port 0x330 irq 6 drq 0 vector mpuintr
-device snd4 at isa? port 0x220 irq 15 drq 6 vector gusintr
-device snd3 at isa? port 0x388 irq 12 drq 3 vector pasintr
-device snd2 at isa? port 0x220 irq 7 drq 1 vector sbintr
-device snd1 at isa? port 0x388 irq 0 drq 0 vector sbintr
-
- Unit numbers are:
- 1 for Yamaha FM synth
- 2 for SB/SB Pro DSP
- 3 for PAS PCM and Midi
- 4 for GUS
- 5 for MPU-401
-
- If you have ProAudioSpectrum, uncomment units 3 and 2.
- If you have SoundBlaster, uncomment 2 and 1.
- If you have GravisUltrasound, uncomment 4
- If you have MPU-401, uncomment 5
-
-NOTE: The MPU-401 driver may or may not work, and is unfortunately
-unverifiable since no one I know has one. If you can test this,
-please let me know! Also note that you will have to change these
-settings if your soundcard is set for a non-standard address or IRQ.
-Please check your documentation (or verify with any provided DOS utilities
-that may have come with your card) and set the IRQ or address fields
-accordingly.
-
-
-Also: Some systems with the OPTI chipset will require you to #define
-BROKEN_BUS_CLOCK in /sys/i386/sound/pas2_card.c. Symptoms are that
-you will hear a lot of clicking and popping sounds, like a geiger counter,
-coming out of the PAS even when is not playing anything.
-
-
-
- - Jordan Hubbard (jkh@freefall.cdrom.com)
diff --git a/sys/i386/i386/autoconf.c b/sys/i386/i386/autoconf.c
index 7584c02b353e..5b571a04432c 100644
--- a/sys/i386/i386/autoconf.c
+++ b/sys/i386/i386/autoconf.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
- * $Id: autoconf.c,v 1.8.2.1 1994/03/23 23:45:08 rgrimes Exp $
+ * $Id: autoconf.c,v 1.11 1994/03/21 15:02:47 ache Exp $
*/
/*
@@ -79,6 +79,11 @@ configure()
isa_configure();
#endif
+#include "pci.h"
+#if NPCI > 0
+ pci_configure();
+#endif
+
#if GENERICxxx && !defined(DISKLESS)
if ((boothowto & RB_ASKNAME) == 0)
setroot();
diff --git a/sys/i386/i386/conf.c b/sys/i386/i386/conf.c
index b1ed3063a3b1..8e0bf2673c3a 100644
--- a/sys/i386/i386/conf.c
+++ b/sys/i386/i386/conf.c
@@ -41,7 +41,7 @@
* SUCH DAMAGE.
*
* from: @(#)conf.c 5.8 (Berkeley) 5/12/91
- * $Id: conf.c,v 1.20.2.1 1994/05/04 07:45:12 rgrimes Exp $
+ * $Id: conf.c,v 1.28 1994/05/30 03:35:53 ache Exp $
*/
#include "param.h"
@@ -213,6 +213,7 @@ struct bdevsw bdevsw[] =
cddump, cdsize, 0 },
{ mcdopen, mcdclose, mcdstrategy, mcdioctl, /*7*/
mcddump, mcdsize, 0 },
+ { 0, } /* block major 8 is reserved for local use */
/*
* If you need a bdev major number, please contact the FreeBSD team
* by sending mail to "FreeBSD-hackers@freefall.cdrom.com".
@@ -236,7 +237,7 @@ d_close_t pcclose;
d_rdwr_t pcread, pcwrite;
d_ioctl_t pcioctl;
d_mmap_t pcmmap;
-extern struct tty pccons;
+extern struct tty *pccons;
/* controlling TTY */
d_open_t cttyopen;
@@ -262,7 +263,7 @@ d_close_t ptcclose;
d_rdwr_t ptcread, ptcwrite;
d_select_t ptcselect;
d_ioctl_t ptyioctl;
-extern struct tty pt_tty[];
+extern struct tty *pt_tty[];
#else
#define ptsopen (d_open_t *)enxio
#define ptsclose (d_close_t *)enxio
@@ -285,9 +286,8 @@ d_close_t comclose;
d_rdwr_t comread;
d_rdwr_t comwrite;
d_ioctl_t comioctl;
-d_select_t comselect;
#define comreset (d_reset_t *)enxio
-extern struct tty com_tty[];
+extern struct tty *com_tty[];
#else
#define comopen (d_open_t *)enxio
#define comclose (d_close_t *)enxio
@@ -295,7 +295,6 @@ extern struct tty com_tty[];
#define comwrite (d_rdwr_t *)enxio
#define comioctl (d_ioctl_t *)enxio
#define comreset (d_reset_t *)enxio
-#define comselect (d_select_t *)enxio
#define com_tty NULL
#endif
@@ -401,33 +400,15 @@ d_ioctl_t bpfioctl;
#define bpfioctl (d_ioctl_t *)enxio
#endif
-#include "dcfclk.h"
-#if NDCFCLK > 0
-d_open_t dcfclkopen;
-d_close_t dcfclkclose;
-d_rdwr_t dcfclkread;
-d_ioctl_t dcfclkioctl;
-d_select_t dcfclkselect;
-#else
-#define dcfclkopen (d_open_t *)enxio
-#define dcfclkclose (d_close_t *)enxio
-#define dcfclkread (d_rdwr_t *)enxio
-#define dcfclkioctl (d_ioctl_t *)enxio
-#define dcfclkselect (d_select_t *)enxio
-#endif
-
-#include "lpa.h"
-#if NLPA > 0
-d_open_t lpaopen;
-d_close_t lpaclose;
-d_rdwr_t lpawrite;
-d_ioctl_t lpaioctl;
-#else
+/*
+ * lpa has been removed from the tree,
+ * but the major dev no for it still remains.
+ * (lpt now provides all the functionality which lpa used to.)
+ */
#define lpaopen (d_open_t *)enxio
#define lpaclose (d_close_t *)enxio
#define lpawrite (d_rdwr_t *)enxio
#define lpaioctl (d_ioctl_t *)enxio
-#endif
#include "speaker.h"
#if NSPEAKER > 0
@@ -442,6 +423,21 @@ d_ioctl_t spkrioctl;
#define spkrioctl (d_ioctl_t *)enxio
#endif
+#include "pca.h"
+#if NPCA > 0
+d_open_t pcaopen;
+d_close_t pcaclose;
+d_rdwr_t pcawrite;
+d_ioctl_t pcaioctl;
+d_select_t pcaselect;
+#else
+#define pcaopen (d_open_t *)enxio
+#define pcaclose (d_close_t *)enxio
+#define pcawrite (d_rdwr_t *)enxio
+#define pcaioctl (d_ioctl_t *)enxio
+#define pcaselect (d_select_t *)enxio
+#endif
+
#include "mse.h"
#if NMSE > 0
d_open_t mseopen;
@@ -464,7 +460,7 @@ d_ioctl_t sioioctl;
d_select_t sioselect;
d_stop_t siostop;
#define sioreset (d_reset_t *)enxio
-extern struct tty sio_tty[];
+extern struct tty *sio_tty[];
#else
#define sioopen (d_open_t *)enxio
#define sioclose (d_close_t *)enxio
@@ -544,7 +540,7 @@ struct cdevsw cdevsw[] =
logselect, nommap, NULL },
{ comopen, comclose, comread, comwrite, /*8*/
comioctl, nostop, comreset, com_tty, /* com */
- comselect, nommap, NULL },
+ ttselect, nommap, NULL },
{ Fdopen, fdclose, rawread, rawwrite, /*9*/
fdioctl, nostop, nullreset, NULL, /* Fd (!=fd) */
seltrue, nommap, fdstrategy },
@@ -590,9 +586,9 @@ struct cdevsw cdevsw[] =
{ bpfopen, bpfclose, bpfread, bpfwrite, /*23*/
bpfioctl, nostop, nullreset, NULL, /* bpf */
bpfselect, nommap, NULL },
- { dcfclkopen, dcfclkclose, dcfclkread, nowrite, /*24*/
- dcfclkioctl, nostop, nullreset, NULL, /* dcfclk */
- dcfclkselect, nommap, NULL },
+ { pcaopen, pcaclose, noread, pcawrite, /*24*/
+ pcaioctl, nostop, nullreset, NULL, /* pcaudio */
+ pcaselect, nommap, NULL },
{ lpaopen, lpaclose, noread, lpawrite, /*25*/
lpaioctl, nullstop, nullreset, NULL, /* lpa */
seltrue, nommap, NULL },
@@ -614,6 +610,7 @@ struct cdevsw cdevsw[] =
{ ukopen, ukclose, noread, nowrite, /*31*/
ukioctl, nostop, nullreset, NULL, /* unknown */
seltrue, nommap, NULL }, /* scsi */
+ { 0, } /* character device 32 is reserved for local use */
/*
* If you need a cdev major number, please contact the FreeBSD team
* by sending mail to `freebsd-hackers@freefall.cdrom.com'.
diff --git a/sys/i386/i386/db_interface.c b/sys/i386/i386/db_interface.c
index 7e68844e4ade..aeeedbecdac1 100644
--- a/sys/i386/i386/db_interface.c
+++ b/sys/i386/i386/db_interface.c
@@ -23,7 +23,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: db_interface.c,v 1.5 1993/12/19 00:50:00 wollman Exp $
+ * $Id: db_interface.c,v 1.7 1994/06/22 05:52:28 jkh Exp $
*/
/*
@@ -178,8 +178,6 @@ db_read_bytes(addr, size, data)
db_nofault = 0;
}
-struct pte *pmap_pte(pmap_t, vm_offset_t);
-
/*
* Write bytes to kernel address space for debugger.
*/
@@ -234,9 +232,24 @@ db_write_bytes(addr, size, data)
}
}
+/*
+ * XXX move this to machdep.c and allow it to be called iff any debugger is
+ * installed.
+ * XXX msg is not printed.
+ */
void
Debugger (msg)
const char *msg;
{
- asm ("int $3");
+ static volatile u_char in_Debugger;
+
+ if (!in_Debugger) {
+ in_Debugger = 1;
+#ifdef __GNUC__
+ asm("int $3");
+#else
+ int3();
+#endif
+ in_Debugger = 0;
+ }
}
diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s
index aa2e3d940fd1..f247c0a233af 100644
--- a/sys/i386/i386/exception.s
+++ b/sys/i386/i386/exception.s
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: exception.s,v 1.2 1994/01/03 07:55:20 davidg Exp $
+ * $Id: exception.s,v 1.3 1994/04/02 07:00:23 davidg Exp $
*/
#include "npx.h" /* NNPX */
@@ -39,7 +39,9 @@
#include "errno.h" /* error return codes */
-#include "i386/isa/debug.h" /* BDE debugging macros */
+#include "machine/spl.h" /* SWI_AST_MASK ... */
+
+#include "machine/psl.h" /* PSL_I */
#include "machine/trap.h" /* trap codes */
#include "syscall.h" /* syscall numbers */
@@ -57,31 +59,49 @@
/*****************************************************************************/
/*
* Trap and fault vector routines
- *
+ */
+#define IDTVEC(name) ALIGN_TEXT ; .globl _X/**/name ; _X/**/name:
+#define TRAP(a) pushl $(a) ; jmp _alltraps
+
+/*
* XXX - debugger traps are now interrupt gates so at least bdb doesn't lose
* control. The sti's give the standard losing behaviour for ddb and kgdb.
*/
-#define IDTVEC(name) ALIGN_TEXT; .globl _X/**/name; _X/**/name:
-#define TRAP(a) pushl $(a) ; jmp alltraps
+#ifdef BDE_DEBUGGER
+#define BDBTRAP(name) \
+ ss ; \
+ cmpb $0,_bdb_exists ; \
+ je 1f ; \
+ testb $SEL_RPL_MASK,4(%esp) ; \
+ jne 1f ; \
+ ss ; \
+ .globl bdb_/**/name/**/_ljmp ; \
+bdb_/**/name/**/_ljmp: ; \
+ ljmp $0,$0 ; \
+1:
+#else
+#define BDBTRAP(name)
+#endif
+
#ifdef KGDB
-# define BPTTRAP(a) sti; pushl $(a) ; jmp bpttraps
+# define BPTTRAP(a) testl $PSL_I,4+8(%esp) ; je 1f ; sti ; 1: ; \
+ pushl $(a) ; jmp _bpttraps
#else
-# define BPTTRAP(a) sti; TRAP(a)
+# define BPTTRAP(a) testl $PSL_I,4+8(%esp) ; je 1f ; sti ; 1: ; TRAP(a)
#endif
+MCOUNT_LABEL(user)
+MCOUNT_LABEL(btrap)
+
IDTVEC(div)
pushl $0; TRAP(T_DIVIDE)
IDTVEC(dbg)
-#if defined(BDE_DEBUGGER) && defined(BDBTRAP)
BDBTRAP(dbg)
-#endif
pushl $0; BPTTRAP(T_TRCTRAP)
IDTVEC(nmi)
pushl $0; TRAP(T_NMI)
IDTVEC(bpt)
-#if defined(BDE_DEBUGGER) && defined(BDBTRAP)
BDBTRAP(bpt)
-#endif
pushl $0; BPTTRAP(T_BPTFLT)
IDTVEC(ofl)
pushl $0; TRAP(T_OFLOW)
@@ -114,22 +134,24 @@ IDTVEC(fpu)
* error. It would be better to handle npx interrupts as traps but
* this is difficult for nested interrupts.
*/
- pushl $0 /* dummy error code */
- pushl $T_ASTFLT
+ pushl $0 /* dumby error code */
+ pushl $0 /* dumby trap type */
pushal
- nop /* silly, the bug is for popal and it only
- * bites when the next instruction has a
- * complicated address mode */
pushl %ds
pushl %es /* now the stack frame is a trap frame */
movl $KDSEL,%eax
movl %ax,%ds
movl %ax,%es
- pushl _cpl
+ FAKE_MCOUNT(12*4(%esp))
+ movl _cpl,%eax
+ pushl %eax
pushl $0 /* dummy unit to finish building intr frame */
incl _cnt+V_TRAP
+ orl $SWI_AST_MASK,%eax
+ movl %eax,_cpl
call _npxintr
- jmp doreti
+ MEXITCOUNT
+ jmp _doreti
#else /* NNPX > 0 */
pushl $0; TRAP(T_ARITHTRAP)
#endif /* NNPX > 0 */
@@ -166,25 +188,37 @@ IDTVEC(rsvd14)
pushl $0; TRAP(31)
SUPERALIGN_TEXT
-alltraps:
+_alltraps:
pushal
- nop
pushl %ds
pushl %es
movl $KDSEL,%eax
movl %ax,%ds
movl %ax,%es
+ FAKE_MCOUNT(12*4(%esp))
calltrap:
+ FAKE_MCOUNT(_btrap) /* init "from" _btrap -> calltrap */
incl _cnt+V_TRAP
+ orl $SWI_AST_MASK,_cpl
call _trap
/*
- * Return through doreti to handle ASTs. Have to change trap frame
+ * There was no place to save the cpl so we have to recover it
+ * indirectly. For traps from user mode it was 0, and for traps
+ * from kernel mode Oring SWI_AST_MASK into it didn't change it.
+ */
+ subl %eax,%eax
+ testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
+ jne 1f
+ movl _cpl,%eax
+1:
+ /*
+ * Return via _doreti to handle ASTs. Have to change trap frame
* to interrupt frame.
*/
- movl $T_ASTFLT,TF_TRAPNO(%esp) /* new trap type (err code not used) */
- pushl _cpl
- pushl $0 /* dummy unit */
- jmp doreti
+ pushl %eax
+ subl $4,%esp
+ MEXITCOUNT
+ jmp _doreti
#ifdef KGDB
/*
@@ -192,17 +226,18 @@ calltrap:
* to the regular trap code.
*/
SUPERALIGN_TEXT
-bpttraps:
+_bpttraps:
pushal
- nop
pushl %ds
pushl %es
movl $KDSEL,%eax
movl %ax,%ds
movl %ax,%es
+ FAKE_MCOUNT(12*4(%esp))
testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp) /* non-kernel mode? */
jne calltrap /* yes */
call _kgdb_trap_glue
+ MEXITCOUNT
jmp calltrap
#endif
@@ -214,7 +249,6 @@ IDTVEC(syscall)
pushfl /* Room for tf_err */
pushfl /* Room for tf_trapno */
pushal
- nop
pushl %ds
pushl %es
movl $KDSEL,%eax /* switch to kernel segments */
@@ -222,51 +256,17 @@ IDTVEC(syscall)
movl %ax,%es
movl TF_ERR(%esp),%eax /* copy eflags from tf_err to fs_eflags */
movl %eax,TF_EFLAGS(%esp)
- movl $0,TF_ERR(%esp) /* zero tf_err */
+ FAKE_MCOUNT(12*4(%esp))
incl _cnt+V_SYSCALL
+ movl $SWI_AST_MASK,_cpl
call _syscall
/*
- * Return through doreti to handle ASTs.
+ * Return via _doreti to handle ASTs.
*/
- movl $T_ASTFLT,TF_TRAPNO(%esp) /* new trap type (err code not used) */
- pushl _cpl
- pushl $0
- jmp doreti
-
-#ifdef SHOW_A_LOT
-/*
- * 'show_bits' was too big when defined as a macro. The line length for some
- * enclosing macro was too big for gas. Perhaps the code would have blown
- * the cache anyway.
- */
- ALIGN_TEXT
-show_bits:
- pushl %eax
- SHOW_BIT(0)
- SHOW_BIT(1)
- SHOW_BIT(2)
- SHOW_BIT(3)
- SHOW_BIT(4)
- SHOW_BIT(5)
- SHOW_BIT(6)
- SHOW_BIT(7)
- SHOW_BIT(8)
- SHOW_BIT(9)
- SHOW_BIT(10)
- SHOW_BIT(11)
- SHOW_BIT(12)
- SHOW_BIT(13)
- SHOW_BIT(14)
- SHOW_BIT(15)
- popl %eax
- ret
-
- .data
-bit_colors:
- .byte GREEN,RED,0,0
- .text
-
-#endif /* SHOW_A_LOT */
+ pushl $0 /* cpl to restore */
+ subl $4,%esp
+ MEXITCOUNT
+ jmp _doreti
/*
* include generated interrupt vectors and ISA intr code
diff --git a/sys/i386/i386/in_cksum.c b/sys/i386/i386/in_cksum.c
index 0dec1d67056d..0b3d3e5d9637 100644
--- a/sys/i386/i386/in_cksum.c
+++ b/sys/i386/i386/in_cksum.c
@@ -32,7 +32,7 @@
*
* from tahoe: in_cksum.c 1.2 86/01/05
* from: @(#)in_cksum.c 1.3 (Berkeley) 1/19/91
- * $Id: in_cksum.c,v 1.4 1993/12/19 00:50:02 wollman Exp $
+ * $Id: in_cksum.c,v 1.5 1994/03/07 11:47:30 davidg Exp $
*/
#include "param.h"
@@ -56,9 +56,10 @@
* Thanks to gcc we don't have to guess
* which registers contain sum & w.
*/
-#define CLC asm("clc")
-#define ADD(n) asm("adcl " #n "(%2), %0": "=r"(sum): "0"(sum), "r"(w))
-#define MOP asm("adcl $0, %0": "=r"(sum): "0"(sum))
+#define ADD(n) asm("addl " #n "(%2), %0" : "=r" (sum) : "0" (sum), "r" (w))
+#define ADDC(n) asm("adcl " #n "(%2), %0" : "=r" (sum) : "0" (sum), "r" (w))
+#define LOAD(n) asm volatile("movb " #n "(%1), %0" : "=r" (junk) : "r" (w))
+#define MOP asm("adcl $0, %0" : "=r" (sum) : "0" (sum))
int
in_cksum(m, len)
@@ -114,28 +115,90 @@ in_cksum(m, len)
}
}
/*
+ * Advance to a 486 cache line boundary.
+ */
+ if (4 & (int) w && mlen >= 4) {
+ ADD(0);
+ MOP;
+ w += 2;
+ mlen -= 4;
+ }
+ if (8 & (int) w && mlen >= 8) {
+ ADD(0);
+ ADDC(4);
+ MOP;
+ w += 4;
+ mlen -= 8;
+ }
+ /*
* Do as much of the checksum as possible 32 bits at at time.
* In fact, this loop is unrolled to make overhead from
* branches &c small.
*/
+ mlen -= 1;
while ((mlen -= 32) >= 0) {
+ u_char junk;
/*
- * Clear the carry flag, add with carry 16 words
- * and fold-in last carry by adding a 0 with carry.
+ * Add with carry 16 words and fold in the last
+ * carry by adding a 0 with carry.
+ *
+ * The early ADD(16) and the LOAD(32) are to load
+ * the next 2 cache lines in advance on 486's. The
+ * 486 has a penalty of 2 clock cycles for loading
+ * a cache line, plus whatever time the external
+ * memory takes to load the first word(s) addressed.
+ * These penalties are unavoidable. Subsequent
+ * accesses to a cache line being loaded (and to
+ * other external memory?) are delayed until the
+ * whole load finishes. These penalties are mostly
+ * avoided by not accessing external memory for
+ * 8 cycles after the ADD(16) and 12 cycles after
+ * the LOAD(32). The loop terminates when mlen
+ * is initially 33 (not 32) to guaranteed that
+ * the LOAD(32) is within bounds.
*/
- CLC;
- ADD(0); ADD(4); ADD(8); ADD(12);
- ADD(16); ADD(20); ADD(24); ADD(28);
- MOP; w += 16;
+ ADD(16);
+ ADDC(0);
+ ADDC(4);
+ ADDC(8);
+ ADDC(12);
+ LOAD(32);
+ ADDC(20);
+ ADDC(24);
+ ADDC(28);
+ MOP;
+ w += 16;
+ }
+ mlen += 32 + 1;
+ if (mlen >= 32) {
+ ADD(16);
+ ADDC(0);
+ ADDC(4);
+ ADDC(8);
+ ADDC(12);
+ ADDC(20);
+ ADDC(24);
+ ADDC(28);
+ MOP;
+ w += 16;
+ mlen -= 32;
}
- mlen += 32;
- while ((mlen -= 8) >= 0) {
- CLC;
- ADD(0); ADD(4);
+ if (mlen >= 16) {
+ ADD(0);
+ ADDC(4);
+ ADDC(8);
+ ADDC(12);
+ MOP;
+ w += 8;
+ mlen -= 16;
+ }
+ if (mlen >= 8) {
+ ADD(0);
+ ADDC(4);
MOP;
w += 4;
+ mlen -= 8;
}
- mlen += 8;
if (mlen == 0 && byte_swapped == 0)
continue; /* worth 1% maybe ?? */
REDUCE;
@@ -172,4 +235,3 @@ in_cksum(m, len)
REDUCE;
return (~sum & 0xffff);
}
-
diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s
index 57ee6a93832d..d0317103d43e 100644
--- a/sys/i386/i386/locore.s
+++ b/sys/i386/i386/locore.s
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)locore.s 7.3 (Berkeley) 5/13/91
- * $Id: locore.s,v 1.15 1994/02/01 04:08:54 davidg Exp $
+ * $Id: locore.s,v 1.20 1994/06/14 17:49:42 davidg Exp $
*/
/*
@@ -51,7 +51,6 @@
#include "machine/pte.h" /* page table entry definitions */
#include "errno.h" /* error return codes */
#include "machine/specialreg.h" /* x86 special registers */
-#include "i386/isa/debug.h" /* BDE debugging macros */
#include "machine/cputypes.h" /* x86 cpu type definitions */
#include "syscall.h" /* system call numbers */
#include "machine/asmacros.h" /* miscellaneous asm macros */
@@ -102,8 +101,10 @@ _esym: .long 0 /* ptr to end of syms */
.globl _boothowto,_bootdev,_curpcb
- .globl _cpu,_cold,_atdevbase
+ .globl _cpu,_cold,_atdevbase,_cpu_vendor,_cpu_id
_cpu: .long 0 /* are we 386, 386sx, or 486 */
+_cpu_id: .long 0
+_cpu_vendor: .space 17
_cold: .long 1 /* cold till we are not */
_atdevbase: .long 0 /* location of start of iomem in virtual */
_atdevphys: .long 0 /* location of device mapping ptes (phys) */
@@ -123,7 +124,7 @@ _proc0paddr: .long 0 /* address of proc 0 address space */
#ifdef BDE_DEBUGGER
.globl _bdb_exists /* flag to indicate BDE debugger is available */
-_bde_exists: .long 0
+_bdb_exists: .long 0
#endif
.globl tmpstk
@@ -140,10 +141,10 @@ tmpstk:
* btext: beginning of text section.
* Also the entry point (jumped to directly from the boot blocks).
*/
-ENTRY(btext)
+NON_GPROF_ENTRY(btext)
movw $0x1234,0x472 /* warm boot */
jmp 1f
- .space 0x500 /* skip over warm boot shit */
+ .org 0x500 /* space for BIOS variables */
/*
* pass parameters on stack (howto, bootdev, unit, cyloffset, esym)
@@ -151,7 +152,8 @@ ENTRY(btext)
* ( if we want to hold onto /boot, it's physical %esp up to _end)
*/
- 1: movl 4(%esp),%eax
+ 1:
+ movl 4(%esp),%eax
movl %eax,_boothowto-KERNBASE
movl 8(%esp),%eax
movl %eax,_bootdev-KERNBASE
@@ -164,30 +166,76 @@ ENTRY(btext)
movl _nfs_diskless_size-KERNBASE,%ecx
movl 20(%esp),%esi
movl $(_nfs_diskless-KERNBASE),%edi
+ cld
rep
movsb
#endif
- /* find out our CPU type. */
- pushfl
- popl %eax
- movl %eax,%ecx
- xorl $0x40000,%eax
- pushl %eax
- popfl
- pushfl
- popl %eax
- xorl %ecx,%eax
- shrl $18,%eax
- andl $1,%eax
- push %ecx
- popfl
-
- cmpl $0,%eax
- jne 1f
- movl $CPU_386,_cpu-KERNBASE
+ /* don't trust what the BIOS gives for eflags */
+ pushl $PSL_MBO
+ popfl
+
+ /* Find out our CPU type. */
+
+ /* Try to toggle alignment check flag; does not exist on 386. */
+ pushfl
+ popl %eax
+ movl %eax,%ecx
+ orl $PSL_AC,%eax
+ pushl %eax
+ popfl
+ pushfl
+ popl %eax
+ xorl %ecx,%eax
+ andl $PSL_AC,%eax
+ pushl %ecx
+ popfl
+
+ testl %eax,%eax
+ jnz 1f
+ movl $CPU_386,_cpu-KERNBASE
+ jmp 2f
+
+1: /* Try to toggle identification flag; does not exist on early 486s. */
+ pushfl
+ popl %eax
+ movl %eax,%ecx
+ xorl $PSL_ID,%eax
+ pushl %eax
+ popfl
+ pushfl
+ popl %eax
+ xorl %ecx,%eax
+ andl $PSL_ID,%eax
+ pushl %ecx
+ popfl
+
+ testl %eax,%eax
+ jnz 1f
+ movl $CPU_486,_cpu-KERNBASE
+ jmp 2f
+
+1: /* Use the `cpuid' instruction. */
+ xorl %eax,%eax
+ .byte 0x0f,0xa2 # cpuid 0
+ movl %ebx,_cpu_vendor-KERNBASE # store vendor string
+ movl %edx,_cpu_vendor+4-KERNBASE
+ movl %ecx,_cpu_vendor+8-KERNBASE
+ movb $0,_cpu_vendor+12-KERNBASE
+
+ movl $1,%eax
+ .byte 0x0f,0xa2 # cpuid 1
+ movl %eax,_cpu_id-KERNBASE # store cpu_id
+ rorl $8,%eax # extract family type
+ andl $15,%eax
+ cmpl $5,%eax
+ jae 1f
+
+ /* less than Pentium; must be 486 */
+ movl $CPU_486,_cpu-KERNBASE
jmp 2f
-1: movl $CPU_486,_cpu-KERNBASE
+
+1: movl $CPU_586,_cpu-KERNBASE
2:
/*
@@ -217,7 +265,7 @@ ENTRY(btext)
movl $_end-KERNBASE,%ecx
addl $NBPG-1,%ecx /* page align up */
andl $~(NBPG-1),%ecx
- movl %ecx,%esi /* esi=start of tables */
+ movl %ecx,%esi /* esi = start of free memory */
movl %ecx,_KERNend-KERNBASE /* save end of kernel */
/* clear bss */
@@ -296,7 +344,7 @@ ENTRY(btext)
shrl $PGSHIFT,%ecx
orl $PG_V|PG_KW,%eax /* valid, kernel read/write */
fillkpt
-#endif
+#endif /* KGDB || BDE_DEBUGGER */
/* now initialize the page dir, upages, p0stack PT, and page tables */
@@ -309,7 +357,7 @@ ENTRY(btext)
addl %esi,%ebx /* address of page directory */
addl $((1+UPAGES+1)*NBPG),%ebx /* offset to kernel page tables */
fillkpt
-
+
/* map I/O memory map */
movl _KPTphys-KERNBASE,%ebx /* base of kernel page tables */
@@ -368,6 +416,7 @@ ENTRY(btext)
movl $_gdt-KERNBASE,%edi
movl %edi,2(%esp)
movl $8*18/4,%ecx
+ cld
rep /* copy gdt */
movsl
movl $_gdt-KERNBASE,-8+2(%edi) /* adjust gdt self-ptr */
@@ -389,6 +438,7 @@ ENTRY(btext)
movl $_idt-KERNBASE,%edi
movl %edi,6+2(%esp)
movl $8*4/4,%ecx
+ cld
rep /* copy idt */
movsl
@@ -397,7 +447,7 @@ ENTRY(btext)
addl $2*6,%esp
popal
-#endif
+#endif /* BDE_DEBUGGER */
/* load base of page directory and enable mapping */
movl %esi,%eax /* phys address of ptd in proc 0 */
@@ -436,7 +486,7 @@ begin: /* now running relocated at KERNBASE where the system is linked to run */
movl $_gdt+8*9,%eax /* adjust slots 9-17 */
movl $9,%ecx
reloc_gdt:
- movb $0xfe,7(%eax) /* top byte of base addresses, was 0, */
+ movb $KERNBASE>>24,7(%eax) /* top byte of base addresses, was 0, */
addl $8,%eax /* now KERNBASE>>24 */
loop reloc_gdt
@@ -444,7 +494,7 @@ reloc_gdt:
je 1f
int $3
1:
-#endif
+#endif /* BDE_DEBUGGER */
/*
* Skip over the page tables and the kernel stack
@@ -494,7 +544,7 @@ lretmsg1:
.asciz "lret: toinit\n"
-#define LCALL(x,y) .byte 0x9a ; .long y; .word x
+#define LCALL(x,y) .byte 0x9a ; .long y ; .word x
/*
* Icode is copied out to process 1 and executed in user mode:
* execve("/sbin/init", argv, envp); exit(0);
@@ -551,4 +601,3 @@ NON_GPROF_ENTRY(sigcode)
.globl _szsigcode
_szsigcode:
.long _szsigcode-_sigcode
-
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 3e0a368b4b44..05546058fbd0 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -35,13 +35,12 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.36.2.5 1994/04/18 04:56:56 rgrimes Exp $
+ * $Id: machdep.c,v 1.47 1994/06/17 13:32:07 davidg Exp $
*/
#include "npx.h"
#include "isa.h"
-#include <stddef.h>
#include "param.h"
#include "systm.h"
#include "signalvar.h"
@@ -58,7 +57,6 @@
#include "malloc.h"
#include "mbuf.h"
#include "msgbuf.h"
-#include "net/netisr.h"
#ifdef SYSVSHM
#include "sys/shm.h"
@@ -96,6 +94,8 @@ static void initcpu(void);
static int test_page(int *, int);
extern int grow(struct proc *,int);
+const char machine[] = "PC-Class";
+const char *cpu_model;
#ifndef PANIC_REBOOT_WAIT_TIME
#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */
@@ -115,22 +115,22 @@ int bufpages = BUFPAGES;
#else
int bufpages = 0;
#endif
+#ifdef BOUNCEPAGES
+int bouncepages = BOUNCEPAGES;
+#else
+int bouncepages = 0;
+#endif
extern int freebufspace;
+extern char *bouncememory;
int _udatasel, _ucodesel;
/*
* Machine-dependent startup code
*/
-int boothowto = 0, Maxmem = 0, maxmem = 0, badpages = 0, physmem = 0;
+int boothowto = 0, Maxmem = 0, badpages = 0, physmem = 0;
long dumplo;
extern int bootdev;
-#ifdef SMALL
-extern int forcemaxmem;
-#endif
-#if defined(GENERICAH) || defined(GENERICBT)
-int generic_hack = 1;
-#endif
int biosmem;
vm_offset_t phys_avail[6];
@@ -141,6 +141,8 @@ int cpu_class;
void dumpsys __P((void));
+#define offsetof(type, member) ((size_t)(&((type *)0)->member))
+
void
cpu_startup()
{
@@ -255,6 +257,7 @@ again:
panic("startup: no room for tables");
goto again;
}
+
/*
* End of second pass, addresses have been assigned
*/
@@ -295,6 +298,22 @@ again:
printf("using %d buffers containing %d bytes of memory\n",
nbuf, bufpages * CLBYTES);
+#ifndef NOBOUNCE
+ /*
+ * If there is more than 16MB of memory, allocate some bounce buffers
+ */
+ if (Maxmem > 4096) {
+ if (bouncepages == 0)
+ bouncepages = 96; /* largest physio size + extra */
+ bouncememory = (char *)kmem_alloc(kernel_map, bouncepages * PAGE_SIZE);
+ }
+
+ /*
+ * init bounce buffers
+ */
+ vm_bounce_init();
+#endif
+
/*
* Set up CPU-specific registers, cache, etc.
*/
@@ -324,10 +343,13 @@ struct cpu_nameclass i386_cpus[] = {
static void
identifycpu()
{
+ extern unsigned long cpu_id;
+ extern char cpu_vendor[];
printf("CPU: ");
if (cpu >= 0 && cpu < (sizeof i386_cpus/sizeof(struct cpu_nameclass))) {
printf("%s", i386_cpus[cpu].cpu_name);
cpu_class = i386_cpus[cpu].cpu_class;
+ cpu_model = i386_cpus[cpu].cpu_name;
} else {
printf("unknown cpu type %d\n", cpu);
panic("startup: bad cpu id");
@@ -350,6 +372,10 @@ identifycpu()
printf("unknown"); /* will panic below... */
}
printf("-class CPU)");
+ if(cpu_id)
+ printf(" Id = 0x%x",cpu_id);
+ if(*cpu_vendor)
+ printf(" Origin = \"%s\"",cpu_vendor);
printf("\n"); /* cpu speed would be