summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/luna88k/conf/GENERIC5
-rw-r--r--sys/arch/luna88k/conf/Makefile.luna88k11
-rw-r--r--sys/arch/luna88k/conf/RAMDISK5
-rw-r--r--sys/arch/luna88k/conf/files.luna88k9
-rw-r--r--sys/arch/luna88k/luna88k/cmmu.c78
-rw-r--r--sys/arch/luna88k/luna88k/genassym.cf144
-rw-r--r--sys/arch/luna88k/luna88k/locore_asm_routines.S1621
-rw-r--r--sys/arch/luna88k/luna88k/m88100_fp.S2516
-rw-r--r--sys/arch/luna88k/luna88k/process.S332
-rw-r--r--sys/arch/luna88k/luna88k/process_machdep.c149
-rw-r--r--sys/arch/luna88k/luna88k/vectors_88100.S89
-rw-r--r--sys/arch/m88k/conf/files.m88k13
-rw-r--r--sys/arch/m88k/m88k/cmmu.c (renamed from sys/arch/mvme88k/mvme88k/cmmu.c)2
-rw-r--r--sys/arch/m88k/m88k/genassym.cf (renamed from sys/arch/mvme88k/mvme88k/genassym.cf)4
-rw-r--r--sys/arch/m88k/m88k/m88100_fp.S (renamed from sys/arch/mvme88k/mvme88k/m88100_fp.S)2
-rw-r--r--sys/arch/m88k/m88k/m88110_fp.S (renamed from sys/arch/mvme88k/mvme88k/m88110_fp.S)2
-rw-r--r--sys/arch/m88k/m88k/m88110_mmu.S (renamed from sys/arch/mvme88k/mvme88k/m88110_mmu.S)2
-rw-r--r--sys/arch/m88k/m88k/process.S (renamed from sys/arch/mvme88k/mvme88k/process.S)2
-rw-r--r--sys/arch/m88k/m88k/process_machdep.c (renamed from sys/arch/mvme88k/mvme88k/process_machdep.c)2
-rw-r--r--sys/arch/m88k/m88k/subr.S (renamed from sys/arch/mvme88k/mvme88k/locore_asm_routines.S)2
-rw-r--r--sys/arch/m88k/m88k/trap.c (renamed from sys/arch/luna88k/luna88k/trap.c)2
-rw-r--r--sys/arch/m88k/m88k/vectors_88100.S (renamed from sys/arch/mvme88k/mvme88k/vectors_88100.S)2
-rw-r--r--sys/arch/m88k/m88k/vectors_88110.S (renamed from sys/arch/mvme88k/mvme88k/vectors_88110.S)2
-rw-r--r--sys/arch/mvme88k/conf/GENERIC15
-rw-r--r--sys/arch/mvme88k/conf/M18710
-rw-r--r--sys/arch/mvme88k/conf/M18812
-rw-r--r--sys/arch/mvme88k/conf/M19714
-rw-r--r--sys/arch/mvme88k/conf/Makefile.mvme88k16
-rw-r--r--sys/arch/mvme88k/conf/RAMDISK13
-rw-r--r--sys/arch/mvme88k/conf/files.mvme88k16
-rw-r--r--sys/arch/mvme88k/mvme88k/trap.c1797
31 files changed, 80 insertions, 6809 deletions
diff --git a/sys/arch/luna88k/conf/GENERIC b/sys/arch/luna88k/conf/GENERIC
index 6be78a4d132..d0baea0be60 100644
--- a/sys/arch/luna88k/conf/GENERIC
+++ b/sys/arch/luna88k/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.2 2004/04/26 12:34:02 miod Exp $
+# $OpenBSD: GENERIC,v 1.3 2004/04/29 14:33:24 miod Exp $
machine luna88k m88k
@@ -8,6 +8,9 @@ option "NCPUS=1" # number of CPUs supported (max 4)
#option DEBUG # print debugging statements
#option EH_DEBUG # debugging code for exception handlers
+# Processor type
+option M88100 # 88100 support; mandatory
+
# Define this if your processor has the xxx.usr bug (mask C82N)
option ERRATA__XXX_USR
diff --git a/sys/arch/luna88k/conf/Makefile.luna88k b/sys/arch/luna88k/conf/Makefile.luna88k
index 9c67c8fca69..992cc4979e7 100644
--- a/sys/arch/luna88k/conf/Makefile.luna88k
+++ b/sys/arch/luna88k/conf/Makefile.luna88k
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.luna88k,v 1.1 2004/04/21 15:23:47 aoyama Exp $
+# $OpenBSD: Makefile.luna88k,v 1.2 2004/04/29 14:33:24 miod Exp $
#
# Makefile for OpenBSD
#
@@ -32,6 +32,7 @@ STRIP?= strip
S!= cd ../../../..; pwd
.endif
LUNA88K= $S/arch/luna88k
+M88K= $S/arch/m88k
INCLUDES= -nostdinc -I. -I$S/arch -I$S
CPPFLAGS= ${INCLUDES} ${IDENT} ${PARAM} -D_KERNEL -Dluna88k -Dm88k
@@ -52,10 +53,6 @@ HOSTCC?= ${CC}
HOSTED_CPPFLAGS?=${CPPFLAGS:S/^-nostdinc$//}
HOSTED_CFLAGS?= ${CFLAGS}
-### CPU configuration
-
-CPPFLAGS+= -DM88100
-
### find out what to use for libkern
.include "$S/lib/libkern/Makefile.inc"
.ifndef PROF
@@ -119,9 +116,9 @@ LINKFLAGS+= -x
%LOAD
-assym.h: $S/kern/genassym.sh ${LUNA88K}/luna88k/genassym.cf Makefile
+assym.h: $S/kern/genassym.sh ${M88K}/m88k/genassym.cf Makefile
sh $S/kern/genassym.sh ${CC} ${CFLAGS} ${CPPFLAGS} \
- ${PARAM} < ${LUNA88K}/luna88k/genassym.cf > assym.h.tmp && \
+ ${PARAM} < ${M88K}/m88k/genassym.cf > assym.h.tmp && \
mv -f assym.h.tmp assym.h
param.c: $S/conf/param.c
diff --git a/sys/arch/luna88k/conf/RAMDISK b/sys/arch/luna88k/conf/RAMDISK
index d579558fd61..e066edb7d52 100644
--- a/sys/arch/luna88k/conf/RAMDISK
+++ b/sys/arch/luna88k/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.2 2004/04/26 12:34:02 miod Exp $
+# $OpenBSD: RAMDISK,v 1.3 2004/04/29 14:33:24 miod Exp $
machine luna88k m88k
@@ -8,6 +8,9 @@ option RAMDISK_HOOKS
option "NCPUS=1" # number of CPUs supported (max 4)
+# Processor type
+option M88100 # 88100 support; mandatory
+
# Define this if your processor has the xxx.usr bug (mask C82N)
option ERRATA__XXX_USR
diff --git a/sys/arch/luna88k/conf/files.luna88k b/sys/arch/luna88k/conf/files.luna88k
index b60d9268090..3b2c8d3547b 100644
--- a/sys/arch/luna88k/conf/files.luna88k
+++ b/sys/arch/luna88k/conf/files.luna88k
@@ -1,4 +1,4 @@
-# $OpenBSD: files.luna88k,v 1.1 2004/04/21 15:23:47 aoyama Exp $
+# $OpenBSD: files.luna88k,v 1.2 2004/04/29 14:33:24 miod Exp $
#
maxpartitions 16
@@ -76,23 +76,16 @@ file arch/luna88k/luna88k/clock.c
file arch/luna88k/luna88k/autoconf.c
file arch/luna88k/luna88k/conf.c
-file arch/luna88k/luna88k/cmmu.c
file arch/luna88k/luna88k/m8820x.c
file arch/luna88k/luna88k/disksubr.c
#file arch/luna88k/luna88k/dkbad.c
file arch/luna88k/luna88k/eh.S
file arch/luna88k/luna88k/isr.c
-file arch/luna88k/luna88k/locore_asm_routines.S
file arch/luna88k/luna88k/locore_c_routines.c
-file arch/luna88k/luna88k/m88100_fp.S
file arch/luna88k/luna88k/machdep.c
file arch/luna88k/luna88k/mem.c
file arch/luna88k/luna88k/pmap.c
file arch/luna88k/luna88k/pmap_table.c
-file arch/luna88k/luna88k/process.S
-file arch/luna88k/luna88k/process_machdep.c
-file arch/luna88k/luna88k/trap.c
-file arch/luna88k/luna88k/vectors_88100.S
file arch/luna88k/luna88k/vm_machdep.c
file arch/luna88k/ddb/db_disasm.c ddb
file arch/luna88k/ddb/db_interface.c ddb
diff --git a/sys/arch/luna88k/luna88k/cmmu.c b/sys/arch/luna88k/luna88k/cmmu.c
deleted file mode 100644
index 375a8241e99..00000000000
--- a/sys/arch/luna88k/luna88k/cmmu.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* $OpenBSD: cmmu.c,v 1.1 2004/04/21 15:23:58 aoyama Exp $ */
-/*
- * Copyright (c) 1998 Steve Murphree, Jr.
- * Copyright (c) 1996 Nivas Madhur
- * All rights reserved.
- *
- * 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 reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Nivas Madhur.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
- *
- */
-/*
- * Mach Operating System
- * Copyright (c) 1993-1991 Carnegie Mellon University
- * Copyright (c) 1991 OMRON Corporation
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/simplelock.h>
-#include <machine/cmmu.h>
-#include <machine/cpu_number.h>
-
-/*
- * This lock protects the cmmu SAR and SCR's; other ports
- * can be accessed without locking it.
- *
- * May be used from "db_interface.c".
- */
-struct simplelock cmmu_cpu_lock;
-
-unsigned cpu_sets[MAX_CPUS];
-unsigned master_cpu = 0;
-int max_cpus, max_cmmus;
-
-struct cmmu_p *cmmu;
diff --git a/sys/arch/luna88k/luna88k/genassym.cf b/sys/arch/luna88k/luna88k/genassym.cf
deleted file mode 100644
index dfe4af42192..00000000000
--- a/sys/arch/luna88k/luna88k/genassym.cf
+++ /dev/null
@@ -1,144 +0,0 @@
-# $OpenBSD: genassym.cf,v 1.1 2004/04/21 15:24:00 aoyama Exp $
-#
-# Copyright (c) 1982, 1990 The Regents of the University of California.
-# All rights reserved.
-#
-# 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 reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# 3. Neither the name of the University nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
-#
-# @(#)genassym.c 7.8 (Berkeley) 5/7/91
-# $Id: genassym.cf,v 1.1 2004/04/21 15:24:00 aoyama Exp $
-#
-
-include <sys/param.h>
-include <sys/buf.h>
-include <sys/time.h>
-include <sys/proc.h>
-include <sys/mbuf.h>
-include <sys/msgbuf.h>
-include <machine/cpu.h>
-include <machine/trap.h>
-include <machine/psl.h>
-include <machine/vmparam.h>
-include <sys/syscall.h>
-include <sys/user.h>
-
-# proc fields and values
-struct proc
-member p_forw
-member p_back
-member p_addr
-member p_stat
-member p_wchan
-
-export SRUN
-
-# general constants
-export UPAGES
-define USIZE USPACE
-
-# pcb fields
-struct pcb
-member pcb_onfault
-member PCB_USER_STATE user_state
-
-# system calls
-export SYS_exit
-export SYS_sigreturn
-
-# trapframe element indexes
-define EF_R0 offsetof(struct trapframe, tf_r[0]) / sizeof(int)
-define EF_FPSR offsetof(struct trapframe, tf_fpsr) / sizeof(int)
-define EF_FPCR offsetof(struct trapframe, tf_fpcr) / sizeof(int)
-define EF_EPSR offsetof(struct trapframe, tf_epsr) / sizeof(int)
-define EF_SXIP offsetof(struct trapframe, tf_sxip) / sizeof(int)
-define EF_SFIP offsetof(struct trapframe, tf_sfip) / sizeof(int)
-define EF_SNIP offsetof(struct trapframe, tf_snip) / sizeof(int)
-define EF_SSBR offsetof(struct trapframe, tf_ssbr) / sizeof(int)
-define EF_DMT0 offsetof(struct trapframe, tf_dmt0) / sizeof(int)
-define EF_DMD0 offsetof(struct trapframe, tf_dmd0) / sizeof(int)
-define EF_DMA0 offsetof(struct trapframe, tf_dma0) / sizeof(int)
-define EF_DMT1 offsetof(struct trapframe, tf_dmt1) / sizeof(int)
-define EF_DMD1 offsetof(struct trapframe, tf_dmd1) / sizeof(int)
-define EF_DMA1 offsetof(struct trapframe, tf_dma1) / sizeof(int)
-define EF_DMT2 offsetof(struct trapframe, tf_dmt2) / sizeof(int)
-define EF_DMD2 offsetof(struct trapframe, tf_dmd2) / sizeof(int)
-define EF_DMA2 offsetof(struct trapframe, tf_dma2) / sizeof(int)
-define EF_FPECR offsetof(struct trapframe, tf_fpecr) / sizeof(int)
-define EF_FPHS1 offsetof(struct trapframe, tf_fphs1) / sizeof(int)
-define EF_FPLS1 offsetof(struct trapframe, tf_fpls1) / sizeof(int)
-define EF_FPHS2 offsetof(struct trapframe, tf_fphs2) / sizeof(int)
-define EF_FPLS2 offsetof(struct trapframe, tf_fpls2) / sizeof(int)
-define EF_FPPT offsetof(struct trapframe, tf_fppt) / sizeof(int)
-define EF_FPRH offsetof(struct trapframe, tf_fprh) / sizeof(int)
-define EF_FPRL offsetof(struct trapframe, tf_fprl) / sizeof(int)
-define EF_FPIT offsetof(struct trapframe, tf_fpit) / sizeof(int)
-define EF_VECTOR offsetof(struct trapframe, tf_vector) / sizeof(int)
-define EF_MASK offsetof(struct trapframe, tf_mask) / sizeof(int)
-define EF_MODE offsetof(struct trapframe, tf_mode) / sizeof(int)
-define EF_RET offsetof(struct trapframe, tf_scratch1) / sizeof(int)
-define EF_IPFSR offsetof(struct trapframe, tf_ipfsr) / sizeof(int)
-define EF_DPFSR offsetof(struct trapframe, tf_dpfsr) / sizeof(int)
-define EF_CPU offsetof(struct trapframe, tf_cpu) / sizeof(int)
-
-# m88110 trapframe element indexes
-define EF_EXIP offsetof(struct trapframe, tf_exip) / sizeof(int)
-define EF_ENIP offsetof(struct trapframe, tf_enip) / sizeof(int)
-define EF_DSR offsetof(struct trapframe, tf_dsr) / sizeof(int)
-define EF_DLAR offsetof(struct trapframe, tf_dlar) / sizeof(int)
-define EF_DPAR offsetof(struct trapframe, tf_dpar) / sizeof(int)
-define EF_ISR offsetof(struct trapframe, tf_isr) / sizeof(int)
-define EF_ILAR offsetof(struct trapframe, tf_ilar) / sizeof(int)
-define EF_IPAR offsetof(struct trapframe, tf_ipar) / sizeof(int)
-define EF_ISAP offsetof(struct trapframe, tf_isap) / sizeof(int)
-define EF_DSAP offsetof(struct trapframe, tf_dsap) / sizeof(int)
-define EF_IUAP offsetof(struct trapframe, tf_iuap) / sizeof(int)
-define EF_DUAP offsetof(struct trapframe, tf_duap) / sizeof(int)
-
-define SIZEOF_EF sizeof(struct trapframe)
-
-# more (machine-dependent) pcb fields
-struct m88100_pcb
-member pcb_pc
-member pcb_ipl
-member pcb_r14
-member pcb_r15
-member pcb_r16
-member pcb_r17
-member pcb_r18
-member pcb_r19
-member pcb_r20
-member pcb_r21
-member pcb_r22
-member pcb_r23
-member pcb_r24
-member pcb_r25
-member pcb_r26
-member pcb_r27
-member pcb_r28
-member pcb_r29
-member pcb_r30
-member pcb_sp
-member pcb_fcr62
-member pcb_fcr63
diff --git a/sys/arch/luna88k/luna88k/locore_asm_routines.S b/sys/arch/luna88k/luna88k/locore_asm_routines.S
deleted file mode 100644
index d8b52dce159..00000000000
--- a/sys/arch/luna88k/luna88k/locore_asm_routines.S
+++ /dev/null
@@ -1,1621 +0,0 @@
-/* $OpenBSD: locore_asm_routines.S,v 1.1 2004/04/21 15:24:01 aoyama Exp $ */
-/*
- * Mach Operating System
- * Copyright (c) 1993-1992 Carnegie Mellon University
- * Copyright (c) 1991 OMRON Corporation
- * Copyright (c) 1996 Nivas Madhur
- * Copyright (c) 1998 Steve Murphree, Jr.
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-#include "assym.h"
-
-#include <sys/errno.h>
-
-#include <machine/asm.h>
-#include <machine/board.h>
-#include <machine/cpu_number.h>
-#include <machine/trap.h>
-
-/*****************************************************************************
- * DO_LOAD_ADDRESS
- *
- * unsigned int do_load_word(address, supervisor_mode)
- * vaddr_t address; \\ in r2
- * boolean_t supervisor_mode; \\ in r3
- *
- * Return the word at ADDRESS (from user space if SUPERVISOR_MODE is zero,
- * supervisor space if non-zero).
- *
- */
-
-ENTRY(do_load_word) /* do_load_word(address, supervisor) */
- bcnd ne0,r3,1f
-#ifdef ERRATA__XXX_USR
- NOP
- ld.usr r2,r2,r0
- NOP
- NOP
- NOP
-#else
- ld.usr r2,r2,r0
-#endif
- br 2f
-1: ld r2,r2,r0
-2: jmp r1
-
-ENTRY(do_load_half) /* do_load_half(address, supervisor) */
- bcnd ne0,r3,1f
-#ifdef ERRATA__XXX_USR
- NOP
- ld.h.usr r2,r2,r0
- NOP
- NOP
- NOP
-#else
- ld.h.usr r2,r2,r0
-#endif
- br 2f
-1: ld.h r2,r2,r0
-2: jmp r1
-
-ENTRY(do_load_byte) /* do_load_byte(address, supervisor) */
- bcnd ne0,r3,1f
-#ifdef ERRATA__XXX_USR
- NOP
- ld.b.usr r2,r2,r0
- NOP
- NOP
- NOP
-#else
- ld.b.usr r2,r2,r0
-#endif
- br 2f
-1: ld.b r2,r2,r0
-2: jmp r1
-
-ENTRY(do_store_word) /* do_store_word(address, data, supervisor) */
- bcnd ne0,r4,1f
-#ifdef ERRATA__XXX_USR
- NOP
- st.usr r3,r2,r0
- NOP
- NOP
- NOP
-#else
- st.usr r3,r2,r0
-#endif
- br 2f
-1: st r3,r2,r0
-2: jmp r1
-
-ENTRY(do_store_half) /* do_store_half(address, data, supervisor) */
- bcnd ne0,r4,1f
-#ifdef ERRATA__XXX_USR
- NOP
- st.h.usr r3,r2,r0
- NOP
- NOP
- NOP
-#else
- st.h.usr r3,r2,r0
-#endif
- br 2f
-1: st.h r3,r2,r0
-2: jmp r1
-
-ENTRY(do_store_byte) /* do_store_byte(address, data, supervisor) */
- bcnd ne0,r4,1f
-#ifdef ERRATA__XXX_USR
- NOP
- st.b.usr r3,r2,r0
- NOP
- NOP
- NOP
-#else
- st.b.usr r3,r2,r0
-#endif
- br 2f
-1: st.b r3,r2,r0
-2: jmp r1
-
-ENTRY(do_xmem_word) /* do_xmem_word(address, data, supervisor) */
- bcnd ne0,r4,1f
-#ifdef ERRATA__XXX_USR
- NOP
- xmem.usr r3,r2,r0
- NOP
- NOP
- NOP
-#else
- xmem.usr r3,r2,r0
-#endif
- br 2f
-1: xmem r3,r2,r0
-2: jmp r1
-
-ENTRY(do_xmem_byte) /* do_xmem_byte(address, data, supervisor) */
- bcnd ne0,r4,1f
-#ifdef ERRATA__XXX_USR
- NOP
- xmem.bu.usr r3,r2,r0
- NOP
- NOP
- NOP
-#else
- xmem.bu.usr r3,r2,r0
-#endif
- br 2f
-1: xmem.bu r3,r2,r0
-2: jmp r1
-
-/*
- * Copy specified amount of data from user space into the kernel
- * copyin(from, to, len)
- * r2 == from (user source address)
- * r3 == to (kernel destination address)
- * r4 == length
- * (r1=return addr)
- */
-
-#define SRC r2
-#define DEST r3
-#define LEN r4
-
-ENTRY(copyin)
- /* set up fault handler */
- or.u r5, r0, hi16(_C_LABEL(curpcb))
- ld r6, r5, lo16(_C_LABEL(curpcb))
- or.u r5, r0, hi16(_ASM_LABEL(Lciflt))
- or r5, r5, lo16(_ASM_LABEL(Lciflt))
- st r5, r6, PCB_ONFAULT /* pcb_onfault = Lciflt */
-
-#if 0
- bcnd ne0, LEN, 1f /* XXX optimize len = 0 case */
- or r2, r0, 0
- br _ASM_LABEL(Lcidone)
-1: bcnd lt0, LEN, _ASM_LABEL(Lciflt) /* EFAULT if len < 0 */
-#endif
-
- /* If it's a small length (less than 8), then do byte-by-byte */
- cmp r9, LEN, 8
- bb1 lt, r9, _ASM_LABEL(copyin_byte_only)
-
- /* If they're not aligned similarly, use byte only... */
- xor r9, SRC, DEST
- mask r8, r9, 0x3
- bcnd ne0, r8, _ASM_LABEL(copyin_byte_only)
-
- /*
- * At this point, we don't know if they're word aligned or not,
- * but we know that what needs to be done to one to align
- * it is what's needed for the other.
- */
- bb1 0, SRC, _ASM_LABEL(copyin_left_align_to_halfword)
-ASLOCAL(copyin_left_aligned_to_halfword)
- bb1 1, SRC, _ASM_LABEL(copyin_left_align_to_word)
-ASLOCAL(copyin_left_aligned_to_word)
- bb1 0, LEN, _ASM_LABEL(copyin_right_align_to_halfword)
-ASLOCAL(copyin_right_aligned_to_halfword)
- bb1 1, LEN, _ASM_LABEL(copyin_right_align_to_word)
-ASLOCAL(copyin_right_aligned_to_word)
-
- /* At this point, both SRC and DEST are aligned to a word */
- /* boundry, and LEN is an even multiple of 4. */
- bb1.n 2, LEN, _ASM_LABEL(copyin_right_align_to_doubleword)
- or r7, r0, 4
-
-ASLOCAL(copyin_right_aligned_to_doubleword)
-#ifdef ERRATA__XXX_USR
- NOP
- ld.usr r5, SRC, r0
- NOP
- NOP
- NOP
- ld.usr r6, SRC, r7
- NOP
- NOP
- NOP
-#else
- ld.usr r5, SRC, r0
- ld.usr r6, SRC, r7
-#endif
- subu LEN, LEN, 8
- st r5, DEST, r0
- addu SRC, SRC, 8
- st r6, DEST, r7
- bcnd.n ne0, LEN, _ASM_LABEL(copyin_right_aligned_to_doubleword)
- addu DEST, DEST, 8
- br.n _ASM_LABEL(Lcidone)
- or r2, r0, r0 /* successful return */
-
- /***************************************************/
-
-ASLOCAL(copyin_left_align_to_halfword)
-#ifdef ERRATA__XXX_USR
- NOP
- ld.b.usr r5, SRC, r0
- NOP
- NOP
- NOP
-#else
- ld.b.usr r5, SRC, r0
-#endif
- subu LEN, LEN, 1
- st.b r5, DEST, r0
- addu SRC, SRC, 1
- br.n _ASM_LABEL(copyin_left_aligned_to_halfword)
- addu DEST, DEST, 1
-
-ASLOCAL(copyin_left_align_to_word)
-#ifdef ERRATA__XXX_USR
- NOP
- ld.h.usr r5, SRC, r0
- NOP
- NOP
- NOP
-#else
- ld.h.usr r5, SRC, r0
-#endif
- subu LEN, LEN, 2
- st.h r5, DEST, r0
- addu SRC, SRC, 2
- br.n _ASM_LABEL(copyin_left_aligned_to_word)
- addu DEST, DEST, 2
-
-ASLOCAL(copyin_right_align_to_halfword)
- subu LEN, LEN, 1
-#ifdef ERRATA__XXX_USR
- NOP
- ld.b.usr r5, SRC, LEN
- NOP
- NOP
- NOP
-#else
- ld.b.usr r5, SRC, LEN
-#endif
- br.n _ASM_LABEL(copyin_right_aligned_to_halfword)
- st.b r5, DEST, LEN
-
-ASLOCAL(copyin_right_align_to_word)
- subu LEN, LEN, 2
-#ifdef ERRATA__XXX_USR
- NOP
- ld.h.usr r5, SRC, LEN
- NOP
- NOP
- NOP
-#else
- ld.h.usr r5, SRC, LEN
-#endif
- br.n _ASM_LABEL(copyin_right_aligned_to_word)
- st.h r5, DEST, LEN
-
-ASLOCAL(copyin_right_align_to_doubleword)
- subu LEN, LEN, 4
-#ifdef ERRATA__XXX_USR
- NOP
- ld.usr r5, SRC, LEN
- NOP
- NOP
- NOP
-#else
- ld.usr r5, SRC, LEN
-#endif
- bcnd.n ne0, LEN, _ASM_LABEL(copyin_right_aligned_to_doubleword)
- st r5, DEST, LEN
- br.n _ASM_LABEL(Lcidone)
- or r2, r0, r0 /* successful return */
-
-ASLOCAL(copyin_byte_only)
- bcnd eq0, LEN, 2f
-1:
- subu LEN, LEN, 1
-#ifdef ERRATA__XXX_USR
- NOP
- ld.b.usr r5, SRC, LEN
- NOP
- NOP
- NOP
-#else
- ld.b.usr r5, SRC, LEN
-#endif
- bcnd.n ne0, LEN, 1b
- st.b r5, DEST, LEN
-2:
- br.n _ASM_LABEL(Lcidone)
- or r2, r0, r0 /* successful return */
-
-ASLOCAL(Lcidone)
- or.u r5,r0,hi16(_C_LABEL(curpcb))
- ld r6,r5,lo16(_C_LABEL(curpcb))
- jmp.n r1
- st r0,r6,PCB_ONFAULT
-
-ASLOCAL(Lciflt)
- br.n _ASM_LABEL(Lcidone)
- or r2, r0, EFAULT /* return fault */
-
-#undef SRC
-#undef DEST
-#undef LEN
-/*######################################################################*/
-/*######################################################################*/
-
-/*
- * Copy a null terminated string from the user space to the kernel
- * address space.
- *
- * copyinstr(from, to, maxlen, &lencopied)
- * r2 == from
- * r3 == to
- * r4 == maxlen
- * r5 == len actually transferred (includes the terminating NULL!!!)
- * r6 & r7 - used as temporaries
- */
-#define SRC r2
-#define DEST r3
-#define CNT r4
-#define LEN r5
-
-ENTRY(copyinstr)
-
- /* setup fault handler */
- or.u r6, r0, hi16(_C_LABEL(curpcb))
- ld r7, r6, lo16(_C_LABEL(curpcb))
- or.u r6, r0, hi16(_ASM_LABEL(Lcisflt))
- or r6, r6, lo16(_ASM_LABEL(Lcisflt))
- st r6, r7, PCB_ONFAULT
- or r6, r0, 0
- bcnd lt0, CNT, _ASM_LABEL(Lcisflt)
- bcnd eq0, CNT, _ASM_LABEL(Lcistoolong)
-1:
-#ifdef ERRATA__XXX_USR
- NOP
- ld.bu.usr r7, SRC, r6
- NOP
- NOP
- NOP
-#else
- ld.bu.usr r7, SRC, r6
-#endif
- st.b r7, DEST, r6
- bcnd.n eq0, r7, 2f /* all done */
- addu r6, r6, 1
- cmp r7, r6, CNT
- bb1 lt, r7, 1b
-
-ASLOCAL(Lcistoolong)
- or r2, r0, ENAMETOOLONG /* overflow */
-
-ASLOCAL(Lcisnull)
- bcnd eq0,r6, _ASM_LABEL(Lcisdone) /* do not attempt to clear last byte */
- /* if we did not write to the string */
- subu r6, r6, 1
- st.b r0, DEST, r6 /* clear last byte */
- br.n _ASM_LABEL(Lcisdone)
- addu r6, r6, 1
-2: /* all done */
- or r2, r0, 0
-
-ASLOCAL(Lcisdone)
- bcnd eq0, LEN, 3f
- st r6, r0, LEN
-3:
- or.u r5,r0,hi16(_C_LABEL(curpcb))
- ld r6,r5,lo16(_C_LABEL(curpcb))
- jmp.n r1
- st r0,r6,PCB_ONFAULT /* clear the handler */
-
-ASLOCAL(Lcisflt)
- br.n _ASM_LABEL(Lcisnull)
- or r2, r0, EFAULT /* return fault */
-
-#undef SRC
-#undef DEST
-#undef CNT
-#undef LEN
-
-/*
- * Copy specified amount of data from kernel to the user space
- * Copyout(from, to, len)
- * r2 == from (kernel source address)
- * r3 == to (user destination address)
- * r4 == length
- */
-
-#define SRC r2
-#define DEST r3
-#define LEN r4
-
-ENTRY(copyout)
- /* setup fault handler */
- or.u r5, r0, hi16(_C_LABEL(curpcb))
- ld r6, r5, lo16(_C_LABEL(curpcb))
- or.u r5, r0, hi16(_ASM_LABEL(Lcoflt))
- or r5, r5, lo16(_ASM_LABEL(Lcoflt))
- st r5, r6, PCB_ONFAULT /* pcb_onfault = Lcoflt */
-#if 0
- bcnd ne0, LEN, 1f /* XXX optimize len = 0 case */
- or r2, r0, 0
- br _ASM_LABEL(Lcodone)
-1: bcnd lt0, LEN, _ASM_LABEL(Lcoflt) /* EFAULT if len < 0 */
-#endif
- /* If it's a small length (less than 8), then do byte-by-byte */
- cmp r9, LEN, 8
- bb1 lt, r9, _ASM_LABEL(copyout_byte_only)
-
- /* If they're not aligned similarly, use byte only... */
- xor r9, SRC, DEST
- mask r8, r9, 0x3
- bcnd ne0, r8, _ASM_LABEL(copyout_byte_only)
-
- /*
- * At this point, we don't know if they're word aligned or not,
- * but we know that what needs to be done to one to align
- * it is what's needed for the other.
- */
- bb1 0, SRC, _ASM_LABEL(copyout_left_align_to_halfword)
-ASLOCAL(copyout_left_aligned_to_halfword)
- bb1 1, SRC, _ASM_LABEL(copyout_left_align_to_word)
-ASLOCAL(copyout_left_aligned_to_word)
- bb1 0, LEN, _ASM_LABEL(copyout_right_align_to_halfword)
-ASLOCAL(copyout_right_aligned_to_halfword)
- bb1 1, LEN, _ASM_LABEL(copyout_right_align_to_word)
-ASLOCAL(copyout_right_aligned_to_word)
-
- /*
- * At this point, both SRC and DEST are aligned to a word
- * boundry, and LEN is an even multiple of 4.
- */
- bb1.n 2, LEN, _ASM_LABEL(copyout_right_align_to_doubleword)
- or r7, r0, 4
-
-ASLOCAL(copyout_right_aligned_to_doubleword)
- ld r5, SRC, r0
- ld r6, SRC, r7
- subu LEN, LEN, 8
-#ifdef ERRATA__XXX_USR
- NOP
- st.usr r5, DEST, r0
- NOP
- NOP
- NOP
-#else
- st.usr r5, DEST, r0
-#endif
- addu SRC, SRC, 8
-#ifdef ERRATA__XXX_USR
- NOP
- st.usr r6, DEST, r7
- NOP
- NOP
- NOP
-#else
- st.usr r6, DEST, r7
-#endif
- bcnd.n ne0, LEN, _ASM_LABEL(copyout_right_aligned_to_doubleword)
- addu DEST, DEST, 8
- or r2, r0, r0 /* successful return */
- br _ASM_LABEL(Lcodone)
-
- /***************************************************/
-ASLOCAL(copyout_left_align_to_halfword)
- ld.b r5, SRC, r0
- subu LEN, LEN, 1
-#ifdef ERRATA__XXX_USR
- NOP
- st.b.usr r5, DEST, r0
- NOP
- NOP
- NOP
-#else
- st.b.usr r5, DEST, r0
-#endif
- addu SRC, SRC, 1
- br.n _ASM_LABEL(copyout_left_aligned_to_halfword)
- addu DEST, DEST, 1
-
-ASLOCAL(copyout_left_align_to_word)
- ld.h r5, SRC, r0
- subu LEN, LEN, 2
-#ifdef ERRATA__XXX_USR
- NOP
- st.h.usr r5, DEST, r0
- NOP
- NOP
- NOP
-#else
- st.h.usr r5, DEST, r0
-#endif
- addu SRC, SRC, 2
- br.n _ASM_LABEL(copyout_left_aligned_to_word)
- addu DEST, DEST, 2
-
-ASLOCAL(copyout_right_align_to_halfword)
- subu LEN, LEN, 1
- ld.b r5, SRC, LEN
-#ifdef ERRATA__XXX_USR
- NOP
- st.b.usr r5, DEST, LEN
- NOP
- NOP
- NOP
- br _ASM_LABEL(copyout_right_aligned_to_halfword)
-#else
- br.n _ASM_LABEL(copyout_right_aligned_to_halfword)
- st.b.usr r5, DEST, LEN
-#endif
-
-ASLOCAL(copyout_right_align_to_word)
- subu LEN, LEN, 2
- ld.h r5, SRC, LEN
-#ifdef ERRATA__XXX_USR
- NOP
- st.h.usr r5, DEST, LEN
- NOP
- NOP
- NOP
- br _ASM_LABEL(copyout_right_aligned_to_word)
-#else
- br.n _ASM_LABEL(copyout_right_aligned_to_word)
- st.h.usr r5, DEST, LEN
-#endif
-
-ASLOCAL(copyout_right_align_to_doubleword)
- subu LEN, LEN, 4
- ld r5, SRC, LEN
-#ifdef ERRATA__XXX_USR
- NOP
- st.usr r5, DEST, LEN
- NOP
- NOP
- NOP
- bcnd ne0, LEN, _ASM_LABEL(copyout_right_aligned_to_doubleword)
-#else
- bcnd.n ne0, LEN, _ASM_LABEL(copyout_right_aligned_to_doubleword)
- st.usr r5, DEST, LEN
-#endif
- br.n _ASM_LABEL(Lcodone)
- or r2, r0, r0 /* successful return */
-
-ASLOCAL(copyout_byte_only)
- bcnd eq0, LEN, 2f
-1:
- subu LEN, LEN, 1
- ld.b r5, SRC, LEN
-#ifdef ERRATA__XXX_USR
- NOP
- st.b.usr r5, DEST, LEN
- NOP
- NOP
- NOP
- bcnd ne0, LEN, 1b
-#else
- bcnd.n ne0, LEN, 1b
- st.b.usr r5, DEST, LEN
-#endif
-
-2:
- br.n _ASM_LABEL(Lcodone)
- or r2, r0, r0 /* successful return */
-
-ASLOCAL(Lcodone)
- or.u r5,r0,hi16(_C_LABEL(curpcb))
- ld r6,r5,lo16(_C_LABEL(curpcb))
- jmp.n r1
- st r0,r6,PCB_ONFAULT /* clear the handler */
-
-ASLOCAL(Lcoflt)
- br.n _ASM_LABEL(Lcodone)
- or r2, r0, EFAULT /* return fault */
-
-#undef SRC
-#undef DEST
-#undef LEN
-
-/*
- * Copy a null terminated string from the kernel space to the user
- * address space.
- *
- * copyoutstr(from, to, maxlen, &lencopied)
- * r2 == from
- * r3 == to
- * r4 == maxlen that can be copied
- * r5 == len actually copied (including the terminating NULL!!!)
- */
-
-#define SRC r2
-#define DEST r3
-#define CNT r4
-#define LEN r5
-
-ENTRY(copyoutstr)
- /* setup fault handler */
- or.u r6, r0, hi16(_C_LABEL(curpcb))
- ld r7, r6, lo16(_C_LABEL(curpcb))
- or.u r6, r0, hi16(_ASM_LABEL(Lcosflt))
- or r6, r6, lo16(_ASM_LABEL(Lcosflt))
- st r6, r7, PCB_ONFAULT
- bcnd lt0, CNT, _ASM_LABEL(Lcosflt)
- bcnd eq0, CNT, _ASM_LABEL(Lcosdone)
- or r6, r0, 0
-1:
- ld.bu r7, SRC, r6
-#ifdef ERRATA__XXX_USR
- NOP
- st.b.usr r7, DEST, r6
- NOP
- NOP
- NOP
-#else
- st.b.usr r7, DEST, r6
-#endif
- bcnd.n eq0, r7, 2f /* all done */
- addu r6, r6, 1
- cmp r7, r6, CNT
- bb1 lt, r7, 1b
- br.n _ASM_LABEL(Lcosdone)
- or r2, r0, ENAMETOOLONG
-2:
- br.n _ASM_LABEL(Lcosdone)
- or r2, r0, 0
-
-ASLOCAL(Lcosflt)
- br.n _ASM_LABEL(Lcosdone)
- or r2, r0, EFAULT
-
-ASLOCAL(Lcosdone)
- bcnd eq0, LEN, 3f
- st r6, r0, LEN
-3: or.u r5,r0,hi16(_C_LABEL(curpcb))
- ld r6,r5,lo16(_C_LABEL(curpcb))
- jmp.n r1
- st r0,r6,PCB_ONFAULT /* clear the handler */
-
-#undef SRC
-#undef DEST
-#undef CNT
-#undef LEN
-
-/*######################################################################*/
-
-/*
- * kcopy(const void *src, void *dst, size_t len);
- *
- * Copy len bytes from src to dst, aborting if we encounter a page fault.
- */
-ENTRY(kcopy)
- or.u r5, r0, hi16(_C_LABEL(curpcb))
- ld r6, r5, lo16(_C_LABEL(curpcb))
- or.u r5, r0, hi16(_ASM_LABEL(kcopy_fault))
- or r5, r5, lo16(_ASM_LABEL(kcopy_fault))
- st r5, r6, PCB_ONFAULT /* pcb_onfault = kcopy_fault */
- bcnd le0,r4,_ASM_LABEL(kcopy_out) /* nothing to do if <= 0 */
-/*
- * check position of source and destination data
- */
- cmp r9,r2,r3 /* compare source address to destination */
- bb1 eq,r9,_ASM_LABEL(kcopy_out) /* nothing to do if equal */
- bb1 lo,r9,_ASM_LABEL(kcopy_revers)e /* reverse copy if src < dest */
-/*
- * source address is greater than destination address, copy forward
- */
- cmp r9,r4,16 /* see if we have at least 16 bytes */
- bb1 lt,r9,_ASM_LABEL(kf_byte_copy) /* copy bytes for small length */
-/*
- * determine copy strategy based on alignment of source and destination
- */
- mask r6,r2,3 /* get 2 low order bits of source address */
- mask r7,r3,3 /* get 2 low order bits of destintation addr */
- mak r6,r6,0<4> /* convert source bits to table offset */
- mak r7,r7,0<2> /* convert destination bits to table offset */
- or.u r12,r0,hi16(_ASM_LABEL(kf_strat))
- or r12,r12,lo16(_ASM_LABEL(kf_strat))
- addu r6,r6,r7 /* compute final table offset for strategy */
- ld r12,r12,r6 /* load the strategy routine */
- jmp r12 /* branch to strategy routine */
-
-/*
- * Copy three bytes from src to destination then copy words
- */
-ASLOCAL(kf_3byte_word_copy)
- ld.bu r6,r2,0 /* load byte from source */
- ld.bu r7,r2,1 /* load byte from source */
- ld.bu r8,r2,2 /* load byte from source */
- st.b r6,r3,0 /* store byte to destination */
- st.b r7,r3,1 /* store byte to destination */
- st.b r8,r3,2 /* store byte to destination */
- addu r2,r2,3 /* increment source pointer */
- addu r3,r3,3 /* increment destination pointer */
- br.n _ASM_LABEL(kf_word_copy) /* copy full words */
- subu r4,r4,3 /* decrement length */
-
-/*
- * Copy 1 halfword from src to destination then copy words
- */
-ASLOCAL(kf_1half_word_copy)
- ld.hu r6,r2,0 /* load half-word from source */
- st.h r6,r3,0 /* store half-word to destination */
- addu r2,r2,2 /* increment source pointer */
- addu r3,r3,2 /* increment destination pointer */
- br.n _ASM_LABEL(kf_word_copy) /* copy full words */
- subu r4,r4,2 /* decrement remaining length */
-
-/*
- * Copy 1 byte from src to destination then copy words
- */
-ASLOCAL(kf_1byte_word_copy)
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- addu r2,r2,1 /* increment source pointer */
- addu r3,r3,1 /* increment destination pointer */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to word copy */
-/*
- * Copy as many full words as possible, 4 words per loop
- */
-ASLOCAL(kf_word_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,_ASM_LABEL(kf_byte_copy) /* not enough left, copy bytes */
- ld r6,r2,0 /* load first word */
- ld r7,r2,4 /* load second word */
- ld r8,r2,8 /* load third word */
- ld r9,r2,12 /* load fourth word */
- st r6,r3,0 /* store first word */
- st r7,r3,4 /* store second word */
- st r8,r3,8 /* store third word */
- st r9,r3,12 /* store fourth word */
- addu r2,r2,16 /* increment source pointer */
- addu r3,r3,16 /* increment destination pointer */
- br.n _ASM_LABEL(kf_word_copy) /* copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-ASLOCAL(kf_1byte_half_copy)
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- addu r2,r2,1 /* increment source pointer */
- addu r3,r3,1 /* increment destination pointer */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to half copy */
-
-ASLOCAL(kf_half_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,_ASM_LABEL(kf_byte_copy) /* not enough left, copy bytes */
- ld.hu r6,r2,0 /* load first half-word */
- ld.hu r7,r2,2 /* load second half-word */
- ld.hu r8,r2,4 /* load third half-word */
- ld.hu r9,r2,6 /* load fourth half-word */
- ld.hu r10,r2,8 /* load fifth half-word */
- ld.hu r11,r2,10 /* load sixth half-word */
- ld.hu r12,r2,12 /* load seventh half-word */
- ld.hu r13,r2,14 /* load eighth half-word */
- st.h r6,r3,0 /* store first half-word */
- st.h r7,r3,2 /* store second half-word */
- st.h r8,r3,4 /* store third half-word */
- st.h r9,r3,6 /* store fourth half-word */
- st.h r10,r3,8 /* store fifth half-word */
- st.h r11,r3,10 /* store sixth half-word */
- st.h r12,r3,12 /* store seventh half-word */
- st.h r13,r3,14 /* store eighth half-word */
- addu r2,r2,16 /* increment source pointer */
- addu r3,r3,16 /* increment destination pointer */
- br.n _ASM_LABEL(kf_half_copy) /* copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-ASLOCAL(kf_byte_copy)
- bcnd eq0,r4,_ASM_LABEL(kcopy_out) /* branch if nothing left to copy */
- ld.bu r6,r2,0 /* load byte from source */
- st.b r6,r3,0 /* store byte in destination */
- addu r2,r2,1 /* increment source pointer */
- addu r3,r3,1 /* increment destination pointer */
- br.n _ASM_LABEL(kf_byte_copy) /* branch for next byte */
- subu r4,r4,1 /* decrement remaining length */
-
-/*
- * source address is less than destination address, copy in reverse
- */
-ASLOCAL(kcopy_reverse)
-/*
- * start copy pointers at end of data
- */
- addu r2,r2,r4 /* start source at end of data */
- addu r3,r3,r4 /* start destination at end of data */
-/*
- * check for short data
- */
- cmp r9,r4,16 /* see if we have at least 16 bytes */
- bb1 lt,r9,_ASM_LABEL(kr_byte_copy) /* copy bytes for small data length */
-/*
- * determine copy strategy based on alignment of source and destination
- */
- mask r6,r2,3 /* get 2 low order bits of source address */
- mask r7,r3,3 /* get 2 low order bits of destintation addr */
- mak r6,r6,0<4> /* convert source bits to table offset */
- mak r7,r7,0<2> /* convert destination bits to table offset */
- or.u r12,r0,hi16(_ASM_LABEL(kr_strat))
- or r12,r12,lo16(_ASM_LABEL(kr_strat))
- addu r6,r6,r7 /* compute final table offset for strategy */
- ld r12,r12,r6 /* load the strategy routine */
- jmp r12 /* branch to strategy routine */
-
-/*
- * Copy three bytes from src to destination then copy words
- */
-ASLOCAL(kr_3byte_word_copy)
- subu r2,r2,3 /* decrement source pointer */
- subu r3,r3,3 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load byte from source */
- ld.bu r7,r2,1 /* load byte from source */
- ld.bu r8,r2,2 /* load byte from source */
- st.b r6,r3,0 /* store byte to destination */
- st.b r7,r3,1 /* store byte to destination */
- st.b r8,r3,2 /* store byte to destination */
- br.n _ASM_LABEL(kr_word_copy) /* copy full words */
- subu r4,r4,3 /* decrement length */
-
-/*
- * Copy 1 halfword from src to destination then copy words
- */
-ASLOCAL(kr_1half_word_copy)
- subu r2,r2,2 /* decrement source pointer */
- subu r3,r3,2 /* decrement destination pointer */
- ld.hu r6,r2,0 /* load half-word from source */
- st.h r6,r3,0 /* store half-word to destination */
- br.n _ASM_LABEL(kr_word_copy) /* copy full words */
- subu r4,r4,2 /* decrement remaining length */
-
-/*
- * Copy 1 byte from src to destination then copy words
- */
-ASLOCAL(kr_1byte_word_copy)
- subu r2,r2,1 /* decrement source pointer */
- subu r3,r3,1 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to word copy */
-/*
- * Copy as many full words as possible, 4 words per loop
- */
-ASLOCAL(kr_word_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,_ASM_LABEL(kr_byte_copy) /* not enough left, copy bytes */
- subu r2,r2,16 /* decrement source pointer */
- subu r3,r3,16 /* decrement destination pointer */
- ld r6,r2,0 /* load first word */
- ld r7,r2,4 /* load second word */
- ld r8,r2,8 /* load third word */
- ld r9,r2,12 /* load fourth word */
- st r6,r3,0 /* store first word */
- st r7,r3,4 /* store second word */
- st r8,r3,8 /* store third word */
- st r9,r3,12 /* store fourth word */
- br.n _ASM_LABEL(kr_word_copy) /* copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-ASLOCAL(kr_1byte_half_copy)
- subu r2,r2,1 /* decrement source pointer */
- subu r3,r3,1 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to half copy */
-
-ASLOCAL(kr_half_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,_ASM_LABEL(kr_byte_copy) /* not enough left, copy bytes */
- subu r2,r2,16 /* decrement source pointer */
- subu r3,r3,16 /* decrement destination pointer */
- ld.hu r6,r2,0 /* load first half-word */
- ld.hu r7,r2,2 /* load second half-word */
- ld.hu r8,r2,4 /* load third half-word */
- ld.hu r9,r2,6 /* load fourth half-word */
- ld.hu r10,r2,8 /* load fifth half-word */
- ld.hu r11,r2,10 /* load sixth half-word */
- ld.hu r12,r2,12 /* load seventh half-word */
- ld.hu r13,r2,14 /* load eighth half-word */
- st.h r6,r3,0 /* store first half-word */
- st.h r7,r3,2 /* store second half-word */
- st.h r8,r3,4 /* store third half-word */
- st.h r9,r3,6 /* store fourth half-word */
- st.h r10,r3,8 /* store fifth half-word */
- st.h r11,r3,10 /* store sixth half-word */
- st.h r12,r3,12 /* store seventh half-word */
- st.h r13,r3,14 /* store eighth half-word */
- br.n _ASM_LABEL(kr_half_copy) /* copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-ASLOCAL(kr_byte_copy)
- bcnd eq0,r4,_ASM_LABEL(kcopy_out) /* branch if nothing left to copy */
- subu r2,r2,1 /* decrement source pointer */
- subu r3,r3,1 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load byte from source */
- st.b r6,r3,0 /* store byte in destination */
- br.n _ASM_LABEL(kr_byte_copy) /* branch for next byte */
- subu r4,r4,1 /* decrement remaining length */
-
-ASLOCAL(kcopy_out)
- or r2, r0, 0 /* return success */
-ASLOCAL(kcopy_out_fault)
- or.u r5,r0,hi16(_C_LABEL(curpcb))
- ld r6,r5,lo16(_C_LABEL(curpcb))
- st r0,r6,PCB_ONFAULT /* clear the handler */
- jmp r1 /* all done, return to caller */
-
-ASLOCAL(kcopy_fault)
- or r2, r0, EFAULT /* return fault */
- br _ASM_LABEL(kcopy_out_fault)
-
- data
- align 4
-ASLOCAL(kf_strat)
- word _ASM_LABEL(kf_word_copy)
- word _ASM_LABEL(kf_byte_copy)
- word _ASM_LABEL(kf_half_copy)
- word _ASM_LABEL(kf_byte_copy)
- word _ASM_LABEL(kf_byte_copy)
- word _ASM_LABEL(kf_3byte_word_copy)
- word _ASM_LABEL(kf_byte_copy)
- word _ASM_LABEL(kf_1byte_half_copy)
- word _ASM_LABEL(kf_half_copy)
- word _ASM_LABEL(kf_byte_copy)
- word _ASM_LABEL(kf_1half_word_copy)
- word _ASM_LABEL(kf_byte_copy)
- word _ASM_LABEL(kf_byte_copy)
- word _ASM_LABEL(kf_1byte_half_copy)
- word _ASM_LABEL(kf_byte_copy)
- word _ASM_LABEL(kf_1byte_word_copy)
-
-ASLOCAL(kr_strat)
- word _ASM_LABEL(kr_word_copy)
- word _ASM_LABEL(kr_byte_copy)
- word _ASM_LABEL(kr_half_copy)
- word _ASM_LABEL(kr_byte_copy)
- word _ASM_LABEL(kr_byte_copy)
- word _ASM_LABEL(kr_1byte_word_copy)
- word _ASM_LABEL(kr_byte_copy)
- word _ASM_LABEL(kr_1byte_half_copy)
- word _ASM_LABEL(kr_half_copy)
- word _ASM_LABEL(kr_byte_copy)
- word _ASM_LABEL(kr_1half_word_copy)
- word _ASM_LABEL(kr_byte_copy)
- word _ASM_LABEL(kr_byte_copy)
- word _ASM_LABEL(kr_1byte_half_copy)
- word _ASM_LABEL(kr_byte_copy)
- word _ASM_LABEL(kr_3byte_word_copy)
-
-/*
- * Gcc 2 generates calls to memcpy for bcopies of unknown size. memcpy can
- * simply be implemented as ovbcopy but the src (r2, r3) and dst args need to
- * be switched.
- */
-/*
- * void memcpy(dest, source, count)
- *
- */
-ENTRY(memcpy)
- or r5, r0, r2 /* dst -> tmp */
- or r2, r0, r3 /* src -> 1st arg */
- br.n _C_LABEL(ovbcopy)
- or r3, r0, r5 /* dst -> 2nd arg */
-
-/*
- * void bcopy(source, destination, count)
- *
- * copy count bytes of data from source to destination
- * Don Harper (don@omron.co.jp), Omron Corporation.
- *
- */
-
-ENTRY(bcopy)
-ENTRY(ovbcopy)
- bcnd le0,r4,_ASM_LABEL(bcopy_out) /* nothing to do if <= 0 */
-/*
- * check position of source and destination data
- */
- cmp r9,r2,r3 /* compare source address to destination */
- bb1 eq,r9,_ASM_LABEL(bcopy_out) /* nothing to do if equal */
- bb1 lo,r9,_ASM_LABEL(bcopy_reverse) /* reverse copy if src < dest */
-/*
- * source address is greater than destination address, copy forward
- */
- cmp r9,r4,16 /* see if we have at least 16 bytes */
- bb1 lt,r9,_ASM_LABEL(f_byte_copy) /* copy bytes for small data length */
-/*
- * determine copy strategy based on alignment of source and destination
- */
- mask r6,r2,3 /* get 2 low order bits of source address */
- mask r7,r3,3 /* get 2 low order bits of destintation addr */
- mak r6,r6,0<4> /* convert source bits to table offset */
- mak r7,r7,0<2> /* convert destination bits to table offset */
- or.u r12,r0,hi16(_ASM_LABEL(f_strat))
- or r12,r12,lo16(_ASM_LABEL(f_strat))
- addu r6,r6,r7 /* compute final table offset for strategy */
- ld r12,r12,r6 /* load the strategy routine */
- jmp r12 /* branch to strategy routine */
-
-
-/*
- * Copy three bytes from src to destination then copy words
- */
-ASLOCAL(f_3byte_word_copy)
- ld.bu r6,r2,0 /* load byte from source */
- ld.bu r7,r2,1 /* load byte from source */
- ld.bu r8,r2,2 /* load byte from source */
- st.b r6,r3,0 /* store byte to destination */
- st.b r7,r3,1 /* store byte to destination */
- st.b r8,r3,2 /* store byte to destination */
- addu r2,r2,3 /* increment source pointer */
- addu r3,r3,3 /* increment destination pointer */
- br.n _ASM_LABEL(f_word_copy) /* copy full words */
- subu r4,r4,3 /* decrement length */
-
-/*
- * Copy 1 halfword from src to destination then copy words
- */
-ASLOCAL(f_1half_word_copy)
- ld.hu r6,r2,0 /* load half-word from source */
- st.h r6,r3,0 /* store half-word to destination */
- addu r2,r2,2 /* increment source pointer */
- addu r3,r3,2 /* increment destination pointer */
- br.n _ASM_LABEL(f_word_copy) /* copy full words */
- subu r4,r4,2 /* decrement remaining length */
-
-/*
- * Copy 1 byte from src to destination then copy words
- */
-ASLOCAL(f_1byte_word_copy)
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- addu r2,r2,1 /* increment source pointer */
- addu r3,r3,1 /* increment destination pointer */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to word copy */
-/*
- * Copy as many full words as possible, 4 words per loop
- */
-ASLOCAL(f_word_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,_ASM_LABEL(f_byte_copy) /* not enough left, copy bytes */
- ld r6,r2,0 /* load first word */
- ld r7,r2,4 /* load second word */
- ld r8,r2,8 /* load third word */
- ld r9,r2,12 /* load fourth word */
- st r6,r3,0 /* store first word */
- st r7,r3,4 /* store second word */
- st r8,r3,8 /* store third word */
- st r9,r3,12 /* store fourth word */
- addu r2,r2,16 /* increment source pointer */
- addu r3,r3,16 /* increment destination pointer */
- br.n _ASM_LABEL(f_word_copy) /* branch to copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-ASLOCAL(f_1byte_half_copy)
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- addu r2,r2,1 /* increment source pointer */
- addu r3,r3,1 /* increment destination pointer */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to half copy */
-
-ASLOCAL(f_half_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,_ASM_LABEL(f_byte_copy) /* not enough left, copy bytes */
- ld.hu r6,r2,0 /* load first half-word */
- ld.hu r7,r2,2 /* load second half-word */
- ld.hu r8,r2,4 /* load third half-word */
- ld.hu r9,r2,6 /* load fourth half-word */
- ld.hu r10,r2,8 /* load fifth half-word */
- ld.hu r11,r2,10 /* load sixth half-word */
- ld.hu r12,r2,12 /* load seventh half-word */
- ld.hu r13,r2,14 /* load eighth half-word */
- st.h r6,r3,0 /* store first half-word */
- st.h r7,r3,2 /* store second half-word */
- st.h r8,r3,4 /* store third half-word */
- st.h r9,r3,6 /* store fourth half-word */
- st.h r10,r3,8 /* store fifth half-word */
- st.h r11,r3,10 /* store sixth half-word */
- st.h r12,r3,12 /* store seventh half-word */
- st.h r13,r3,14 /* store eighth half-word */
- addu r2,r2,16 /* increment source pointer */
- addu r3,r3,16 /* increment destination pointer */
- br.n _ASM_LABEL(f_half_copy) /* branch to copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-ASLOCAL(f_byte_copy)
- bcnd eq0,r4,_ASM_LABEL(bcopy_out) /* branch if nothing left to copy */
- ld.bu r6,r2,0 /* load byte from source */
- st.b r6,r3,0 /* store byte in destination */
- addu r2,r2,1 /* increment source pointer */
- addu r3,r3,1 /* increment destination pointer */
- br.n _ASM_LABEL(f_byte_copy) /* branch for next byte */
- subu r4,r4,1 /* decrement remaining length */
-
-/*
- * source address is less than destination address, copy in reverse
- */
-ASLOCAL(bcopy_reverse)
-/*
- * start copy pointers at end of data
- */
- addu r2,r2,r4 /* start source at end of data */
- addu r3,r3,r4 /* start destination at end of data */
-/*
- * check for short data
- */
- cmp r9,r4,16 /* see if we have at least 16 bytes */
- bb1 lt,r9,_ASM_LABEL(r_byte_copy) /* copy bytes for small data length */
-/*
- * determine copy strategy based on alignment of source and destination
- */
- mask r6,r2,3 /* get 2 low order bits of source address */
- mask r7,r3,3 /* get 2 low order bits of destintation addr */
- mak r6,r6,0<4> /* convert source bits to table offset */
- mak r7,r7,0<2> /* convert destination bits to table offset */
- or.u r12,r0,hi16(_ASM_LABEL(r_strat))
- or r12,r12,lo16(_ASM_LABEL(r_strat))
- addu r6,r6,r7 /* compute final table offset for strategy */
- ld r12,r12,r6 /* load the strategy routine */
- jmp r12 /* branch to strategy routine */
-
-/*
- * Copy three bytes from src to destination then copy words
- */
-ASLOCAL(r_3byte_word_copy)
- subu r2,r2,3 /* decrement source pointer */
- subu r3,r3,3 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load byte from source */
- ld.bu r7,r2,1 /* load byte from source */
- ld.bu r8,r2,2 /* load byte from source */
- st.b r6,r3,0 /* store byte to destination */
- st.b r7,r3,1 /* store byte to destination */
- st.b r8,r3,2 /* store byte to destination */
- br.n _ASM_LABEL(r_word_copy) /* copy full words */
- subu r4,r4,3 /* decrement length */
-
-/*
- * Copy 1 halfword from src to destination then copy words
- */
-ASLOCAL(r_1half_word_copy)
- subu r2,r2,2 /* decrement source pointer */
- subu r3,r3,2 /* decrement destination pointer */
- ld.hu r6,r2,0 /* load half-word from source */
- st.h r6,r3,0 /* store half-word to destination */
- br.n _ASM_LABEL(r_word_copy) /* copy full words */
- subu r4,r4,2 /* decrement remaining length */
-
-/*
- * Copy 1 byte from src to destination then copy words
- */
-ASLOCAL(r_1byte_word_copy)
- subu r2,r2,1 /* decrement source pointer */
- subu r3,r3,1 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to word copy */
-/*
- * Copy as many full words as possible, 4 words per loop
- */
-ASLOCAL(r_word_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,_ASM_LABEL(r_byte_copy) /* not enough left, copy bytes */
- subu r2,r2,16 /* decrement source pointer */
- subu r3,r3,16 /* decrement destination pointer */
- ld r6,r2,0 /* load first word */
- ld r7,r2,4 /* load second word */
- ld r8,r2,8 /* load third word */
- ld r9,r2,12 /* load fourth word */
- st r6,r3,0 /* store first word */
- st r7,r3,4 /* store second word */
- st r8,r3,8 /* store third word */
- st r9,r3,12 /* store fourth word */
- br.n _ASM_LABEL(r_word_copy) /* branch to copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-ASLOCAL(r_1byte_half_copy)
- subu r2,r2,1 /* decrement source pointer */
- subu r3,r3,1 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to half copy */
-
-ASLOCAL(r_half_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,_ASM_LABEL(r_byte_copy) /* not enough left, copy bytes */
- subu r2,r2,16 /* decrement source pointer */
- subu r3,r3,16 /* decrement destination pointer */
- ld.hu r6,r2,0 /* load first half-word */
- ld.hu r7,r2,2 /* load second half-word */
- ld.hu r8,r2,4 /* load third half-word */
- ld.hu r9,r2,6 /* load fourth half-word */
- ld.hu r10,r2,8 /* load fifth half-word */
- ld.hu r11,r2,10 /* load sixth half-word */
- ld.hu r12,r2,12 /* load seventh half-word */
- ld.hu r13,r2,14 /* load eighth half-word */
- st.h r6,r3,0 /* store first half-word */
- st.h r7,r3,2 /* store second half-word */
- st.h r8,r3,4 /* store third half-word */
- st.h r9,r3,6 /* store fourth half-word */
- st.h r10,r3,8 /* store fifth half-word */
- st.h r11,r3,10 /* store sixth half-word */
- st.h r12,r3,12 /* store seventh half-word */
- st.h r13,r3,14 /* store eighth half-word */
- br.n _ASM_LABEL(r_half_copy) /* branch to copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-ASLOCAL(r_byte_copy)
- bcnd eq0,r4,_ASM_LABEL(bcopy_out) /* branch if nothing left to copy */
- subu r2,r2,1 /* decrement source pointer */
- subu r3,r3,1 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load byte from source */
- st.b r6,r3,0 /* store byte in destination */
- br.n _ASM_LABEL(r_byte_copy) /* branch for next byte */
- subu r4,r4,1 /* decrement remaining length */
-
-ASLOCAL(bcopy_out)
- jmp r1 /* all done, return to caller */
-
- data
- align 4
-ASLOCAL(f_strat)
- word _ASM_LABEL(f_word_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_half_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_3byte_word_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_1byte_half_copy)
- word _ASM_LABEL(f_half_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_1half_word_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_1byte_half_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_1byte_word_copy)
-
-ASLOCAL(r_strat)
- word _ASM_LABEL(r_word_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_half_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_1byte_word_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_1byte_half_copy)
- word _ASM_LABEL(r_half_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_1half_word_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_1byte_half_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_3byte_word_copy)
-
- text
-
-/*######################################################################*/
-
-/*
- * April 1990, Omron Corporation
- * jfriedl@nff.ncl.omron.co.jp
- *
- * void bzero(destination, length)
- *
- * Clear (set to zero) LENGTH bytes of memory starting at DESTINATION.
- * Note that there is no return value.
- *
- * This is fast. Really fast. Especially for long lengths.
- */
-#define R_dest r2
-#define R_len r3
-
-#define R_bytes r4
-#define R_mark_address r5
-#define R_addr r6 /* R_addr && R_temp SHARE */
-#define R_temp r6 /* R_addr && R_temp SHARE */
-
-ENTRY(bzero)
- /*
- * If the destination is not word aligned, we'll word align
- * it first to make things easier.
- *
- * We'll check to see first if bit #0 is set and then bit #1
- * (of the destination address). If either are set, it's
- * not word aligned.
- */
- bb1 0, R_dest, _ASM_LABEL(not_initially_word_aligned)
- bb1 1, R_dest, _ASM_LABEL(not_initially_word_aligned)
-
-ASLOCAL(now_word_aligned)
- /*
- * before we get into the main loop, grab the
- * address of the label "mark" below.
- */
- or.u R_mark_address, r0, hi16(_ASM_LABEL(mark))
- or R_mark_address, R_mark_address, lo16(_ASM_LABEL(mark))
-
-ASLOCAL(top_of_main_loop)
-#define MAX_AT_ONE_TIME 128
- /*
- * Now we find out how many words we can zero-fill in a row.
- * We do this by doing something like:
- *
- * bytes &= 0xfffffffc;
- * if (bytes > MAX_AT_ONE_TIME)
- * bytes = MAX_AT_ONE_TIME;
- */
-
- /*
- * Clear lower two bits of length to give us the number of bytes
- * ALIGNED TO THE WORD LENGTH remaining to move.
- */
- clr R_bytes, R_len, 2<0>
-
- /* if we're done clearing WORDS, jump out */
- bcnd eq0, R_bytes, _ASM_LABEL(done_doing_words)
-
- /* if the number of bytes > MAX_AT_ONE_TIME, do only the max */
- cmp R_temp, R_bytes, MAX_AT_ONE_TIME
- bb1 lt, R_temp, 1f
-
- /*
- * Since we're doing the max, we know exactly where we're
- * jumping (the first one in the list!), so we can jump
- * right there. However, we've still got to adjust
- * the length, so we'll jump to where we ajust the length
- * which just happens to fall through to the first store zero
- * in the list.
- *
- * Note, however, that we're jumping to an instruction that
- * would be in the delay slot for the jump in front of it,
- * so if you change things here, WATCH OUT.
- */
- br.n do_max
- or R_bytes, r0, MAX_AT_ONE_TIME
-
-1:
- /*
- * Now we have the number of bytes to zero during this iteration,
- * (which, as it happens, is the last iteration if we're here).
- * We'll calculate the proper place to jump and then jump there,
- * after adjusting the length. NOTE that there is a label between
- * the "jmp.n" and the "subu" below... the "subu" is NOT always
- * executed in the delay slot of the "jmp.n".
- */
- subu R_addr, R_mark_address, R_bytes
-
- /* and go there (after adjusting the length via ".n") */
- jmp.n R_addr
-ASLOCAL(do_max)
- subu R_len, R_len, R_bytes /* NOTE: this is in the delay slot! */
-
- st r0, R_dest, 0x7c /* 128 */
- st r0, R_dest, 0x78 /* 124 */
- st r0, R_dest, 0x74 /* 120 */
- st r0, R_dest, 0x70 /* 116 */
- st r0, R_dest, 0x6c /* 112 */
- st r0, R_dest, 0x68 /* 108 */
- st r0, R_dest, 0x64 /* 104 */
- st r0, R_dest, 0x60 /* 100 */
- st r0, R_dest, 0x5c /* 96 */
- st r0, R_dest, 0x58 /* 92 */
- st r0, R_dest, 0x54 /* 88 */
- st r0, R_dest, 0x50 /* 84 */
- st r0, R_dest, 0x4c /* 80 */
- st r0, R_dest, 0x48 /* 76 */
- st r0, R_dest, 0x44 /* 72 */
- st r0, R_dest, 0x40 /* 68 */
- st r0, R_dest, 0x3c /* 64 */
- st r0, R_dest, 0x38 /* 60 */
- st r0, R_dest, 0x34 /* 56 */
- st r0, R_dest, 0x30 /* 52 */
- st r0, R_dest, 0x2c /* 44 */
- st r0, R_dest, 0x28 /* 40 */
- st r0, R_dest, 0x24 /* 36 */
- st r0, R_dest, 0x20 /* 32 */
- st r0, R_dest, 0x1c /* 28 */
- st r0, R_dest, 0x18 /* 24 */
- st r0, R_dest, 0x14 /* 20 */
- st r0, R_dest, 0x10 /* 16 */
- st r0, R_dest, 0x0c /* 12 */
- st r0, R_dest, 0x08 /* 8 */
- st r0, R_dest, 0x04 /* 4 */
- st r0, R_dest, 0x00 /* 0 */
-
-ASLOCAL(mark)
- br.n _ASM_LABEL(top_of_main_loop)
- addu R_dest, R_dest, R_bytes /* bump up the dest address */
-
-ASLOCAL(done_doing_words)
- bcnd ne0, R_len, 1f
- jmp r1
-
-1:
- subu R_len, R_len, 1
- bcnd.n ne0, R_len, 1b
- st.b r0, R_dest, R_len
-1:
- jmp r1
-
-ASLOCAL(not_initially_word_aligned)
- /*
- * Bzero to word-align the address (at least if the length allows it).
- */
- bcnd eq0, R_len, 1b
- st.b r0, R_dest, 0
- addu R_dest, R_dest, 1
- mask R_temp, R_dest, 0x3
- bcnd.n eq0, R_temp, _ASM_LABEL(now_word_aligned)
- subu R_len, R_len, 1
- br _ASM_LABEL(not_initially_word_aligned)
-
-#undef R_dest
-#undef R_len
-#undef R_bytes
-#undef R_mark_address
-#undef R_addr
-#undef R_temp
-#undef MAX_AT_ONE_TIME
-
-/*
- * non-local goto
- * int setjmp(label_t *);
- * void longjmp(label_t*);
- */
-ENTRY(setjmp)
- st r1,r2,0
- st r14,r2,4
- st r15,r2,2*4
- st r16,r2,3*4
- st r17,r2,4*4
- st r18,r2,5*4
- st r19,r2,6*4
- st r20,r2,7*4
- st r21,r2,8*4
- st r22,r2,9*4
- st r23,r2,10*4
- st r24,r2,11*4
- st r25,r2,12*4
- st r26,r2,13*4
- st r27,r2,14*4
- st r28,r2,15*4
- st r29,r2,16*4
- st r30,r2,17*4
- st r31,r2,18*4
- jmp.n r1
- or r2,r0,r0
-
-ENTRY(longjmp)
- ld r1,r2,0
- ld r14,r2,4
- ld r15,r2,2*4
- ld r16,r2,3*4
- ld r17,r2,4*4
- ld r18,r2,5*4
- ld r19,r2,6*4
- ld r20,r2,7*4
- ld r21,r2,8*4
- ld r22,r2,9*4
- ld r23,r2,10*4
- ld r24,r2,11*4
- ld r25,r2,12*4
- ld r26,r2,13*4
- ld r27,r2,14*4
- ld r28,r2,15*4
- ld r29,r2,16*4
- ld r30,r2,17*4
- ld r31,r2,18*4
- jmp.n r1
- or r2,r0,1
-
-ENTRY(read_processor_identification_register)
- jmp.n r1
- ldcr r2, PID
-
-GLOBAL(guarded_access_start)
-ENTRY(guarded_access)
- cmp r9,r3,4
- bb1 eq,r9,@L145
- cmp r9,r3,2
- bb1 eq,r9,@L144
- cmp r9,r3,1
- bb1 eq,r9,@L143
- br _C_LABEL(guarded_access_bad)
-@L143:
- ld.b r9,r0,r2
- tb1 0, r0, 0
- st.b r9,r0,r4
- br @L142
-@L144:
- ld.h r9,r0,r2
- tb1 0, r0, 0
- st.h r9,r0,r4
- br @L142
-@L145:
- ld r9,r0,r2
- tb1 0, r0, 0
- st r9,r0,r4
- br @L142
-
-GLOBAL(guarded_access_bad)
- jmp.n r1
- or r2,r0,EFAULT
-
-@L142:
- jmp.n r1
- or r2,r0,0
-
-GLOBAL(guarded_access_end)
-
-/*
- * void set_cpu_number(unsigned number);
- *
- * Sets the kernel cpu number for this cpu to the given value.
- *
- * Input:
- * r1 return address
- * r2 the number (should be 0, 1, 2, or 3).
- *
- * Other registers used:
- * r3 temp
- * r4 original PSR
- * r5 temporary new PSR
- */
-ENTRY(set_cpu_number)
-#ifdef DEBUG
- /* make sure the CPU number is valid */
- clr r3, r2, FLAG_CPU_FIELD_WIDTH<0>
- bcnd ne0, r3, 1f /* bad cpu number */
-#endif
-
- /* going to change a control register -- disable interrupts */
- ldcr r4, PSR
- set r5, r4, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r5, PSR
- FLUSH_PIPELINE
-
- /* put in the cpu number */
- ldcr r3, SR1 /* get the flags */
- clr r3, r3, FLAG_CPU_FIELD_WIDTH<0> /* clean the slate */
- or r3, r3, r2 /* add the cpu number */
- stcr r3, SR1 /* put back */
-
- /* put back the PSR to what it was before and return */
- stcr r4, PSR
- FLUSH_PIPELINE
- jmp r1
-
-#ifdef DEBUG
-1: /* bad cpu number*/
- or.u r2, r0, hi16(9f)
- bsr.n _C_LABEL(panic)
- or r2, r2, lo16(9f)
-
- data
-9: string "set_cpu_number: bad CPU number %x\0"
-#endif
diff --git a/sys/arch/luna88k/luna88k/m88100_fp.S b/sys/arch/luna88k/luna88k/m88100_fp.S
deleted file mode 100644
index c3959e4879f..00000000000
--- a/sys/arch/luna88k/luna88k/m88100_fp.S
+++ /dev/null
@@ -1,2516 +0,0 @@
-/* $OpenBSD: m88100_fp.S,v 1.1 2004/04/21 15:24:02 aoyama Exp $ */
-/*
- * Mach Operating System
- * Copyright (c) 1991 Carnegie Mellon University
- * Copyright (c) 1991 OMRON Corporation
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-/* Floating point trouble routines */
-#include "assym.h"
-#include <machine/trap.h>
-#include <machine/asm.h>
-
-#define destsize 10
-
-/* Floating-Point Status Register bits */
-#define inexact 0
-#define overflow 1
-#define underflow 2
-#define divzero 3
-#define oper 4
-
-#define sign 31
-#define s1size 9
-#define s2size 7
-#define dsize 5
-
-#define FADDop 0x05
-#define FSUBop 0x06
-#define FCMPop 0x07
-#define FMULop 0x00
-#define FDIVop 0x0e
-#define FSQRTop 0x0f
-#define INTop 0x09
-#define NINTop 0x0a
-#define TRNCop 0x0b
-
-#define s1nan 7
-#define s2nan 6
-#define s1inf 5
-#define s2inf 4
-#define s1zero 3
-#define s2zero 2
-#define sigbit 19
-
-#define modehi 30
-#define modelo 29
-#define rndhi 15
-#define rndlo 14
-#define efunf 7
-#define efovf 6
-#define efinx 5
-
-ASENTRY(m88100_Xfp_precise)
- or r29, r3, r0 /* r29 is now the E.F. */
- subu r31, r31, 40
- st r1, r31, 32
- st r29, r31, 36
-
- ld r2, r29, EF_FPSR * 4
- ld r3, r29, EF_FPCR * 4
- ld r4, r29, EF_FPECR * 4
- ld r5, r29, EF_FPHS1 * 4
- ld r6, r29, EF_FPLS1 * 4
- ld r7, r29, EF_FPHS2 * 4
- ld r8, r29, EF_FPLS2 * 4
- ld r9, r29, EF_FPPT * 4
-
-
- /*
- * Load into r1 the return address for the 0 handlers. Looking at
- * FPECR, branch to the appropriate 0 handler. However, if none of the
- * 0 bits are enabled, then a floating point instruction was issued
- * with the floating point unit disabled. This will cause an
- * unimplemented opcode 0.
- */
-
- or.u r1,r0,hi16(wrapup) /* load return address of function */
- or r1,r1,lo16(wrapup)
-
- bb0 6,r4, 3f /* branch to FPunimp if bit set */
- br FPuimp
-3:
- bb0 7,r4, 4f /* branch to FPintover if bit set */
- br FPintover
-4:
-#if 0
- bb0 5,r4, 5f /* branch to FPpriviol if bit set */
- br FPpriviol
-#endif
-5:
- bb0 4,r4, 6f /* branch to FPresoper if bit set */
- br FPresoper
-6:
- bb0 3,r4, 7f /* branch to FPdivzero if bit set */
- br FPdivzero
-7:
- or.u r4, r4, 0xffff
-
-ASLOCAL(FPuimp)
- subu r31,r31,40 /* allocate stack */
- st r1,r31,36 /* save return address */
- st r3,r31,32 /* save exception frame */
- or r2,r0,T_FPEPFLT /* load trap type */
- or r3, r29, r0
- bsr _C_LABEL(m88100_trap)
- ld r1,r31,36 /* recover return address */
- addu r31,r31,40 /* deallocate stack */
- jmp r1
-
- /*
- * To write back the results to the user registers, disable exceptions
- * and the floating point unit. Write FPSR and FPCR and load the SNIP
- * and SFIP.
- * r5 will contain the upper word of the result
- * r6 will contain the lower word of the result
- */
-
-ASLOCAL(wrapup)
- tb1 0,r0,0 /* make sure all floating point operations */
- /* have finished */
- ldcr r10, cr1 /* load the PSR */
-#if 0
- set r10, r10, 1<PSR_FPU_DISABLE_BIT>
-#endif
- set r10, r10, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r10, cr1
-
- ld r1, r31, 32
- ld r29, r31, 36
- addu r31, r31, 40
-
- fstcr r2, FPSR /* write revised value of FPSR */
- fstcr r3, FPCR /* write revised value of FPCR */
-
- /* result writeback routine */
- addu r3, r29, EF_R0 * 4
- extu r2, r9, 5<0> /* get 5 bits of destination register */
- bb0 5, r9, writesingle /* branch if destination is single */
-
-/* writedouble here */
- st r5, r3 [r2] /* write high word */
- add r2, r2, 1 /* for double, the low word is the */
- /* unspecified register */
- clr r2, r2, 27<5> /* perform equivalent of mod 32 */
-ASLOCAL(writesingle)
- st r6, r3 [r2] /* write low word into memory */
- jmp r1
-
-/*
- * Check if the numerator is zero. If the numerator is zero, then handle
- * this instruction as you would a 0/0 invalid operation.
- */
-
-ASLOCAL(FPdivzero)
- st r1,r31,0 /* save return address */
- bb1 s1size,r9,1f /* branch if numerator double */
-/* single number */
- clr r10,r5,1<sign> /* clear sign bit */
- extu r11,r6,3<29> /* grab upper bits of lower word */
- or r10,r10,r11 /* combine ones of mantissa */
- bcnd eq0,r10,resoper /* numerator is zero, handle reserved operand */
- br setbit /* set divzero bit */
-1:
-/* double number */
- clr r10,r5,1<sign> /* clear sign bit */
- or r10,r10,r6 /* or high and low words */
- bcnd ne0,r10,setbit /* set divzero bit */
-
-/*
- * The numerator is zero, so handle the invalid operation by setting the
- * invalid operation bit and branching to the user handler if there is one
- * or writing a quiet NaN to the destination.
- */
-
-ASLOCAL(resoper)
- set r2,r2,1<oper>
-#ifdef HANDLER
- bb0 oper,r3,noreshand /* branch to execute default handling */
- /* for reserved operands */
- bsr _handler /* branch to user handler */
- br FP_div_return
-#endif
-
-noreshand:
- set r5,r0,0<0> /* put a NaN in high word */
- set r6,r0,0<0> /* put a NaN in low word */
- br FP_div_return
- /* writing to a word which may be ignored */
- /* is just as quick as checking the precision */
- /* of the destination */
-
-/*
- * The operation is divide by zero, so set the divide by zero bit in the
- * FPSR. If the user handler is set, then go to the user handler, else
- * go to the default mode.
- */
-
-setbit:
- set r2,r2,1<divzero>
-#ifdef HANDLER
- bb0 divzero,r3,default /* go to default routine if no hdlr */
- bsr _handler /* execute handler routine */
- br FP_div_return
-#endif
-
-/*
- * Considering the sign of the numerator and zero, write a correctly
- * signed infinity of the proper precision into the destination.
- */
-
-default:
- bb1 dsize,r9,FPzero_double /* branch to handle double result */
-FPzero_single:
- clr r10,r5,31<0> /* clear all of S1HI except sign bit */
- xor r10,r7,r10 /* xor the sign bits of the operands */
- or.u r6,r0,0x7f80 /* load single precision infinity */
- br.n FP_div_return
- or r6,r6,r10 /* load correctly signed infinity */
-
-FPzero_double:
- clr r10,r5,31<0> /* clear all of S1HI except sign bit */
- xor r10,r7,r10 /* xor the sign bits of the operands */
- or.u r5,r0,0x7ff0 /* load double precision infinity */
- or r5,r5,r10 /* load correctly signed infinity */
- or r6,r0,r0 /* clear lower word of double */
-
-FP_div_return:
- ld r1,r31,0 /* load return address */
- jmp r1
-
-/*
- * Both NINT and TRNC require a certain rounding mode, so check which
- * instruction caused the integer conversion overflow. Use a substitute
- * FPCR in r1, and modify the rounding mode if the instruction is NINT
- * or TRNC.
- */
-ASLOCAL(FPintover)
- extu r10,r9,5<11> /* extract opcode */
- cmp r11,r10,INTop /* see if instruction is INT */
- st r1,r31,0 /* save return address */
- bb1.n eq,r11,checksize /* instruction is INT, do not modify */
- /* rounding mode */
- or r1,r0,r3 /* load FPCR into r1 */
- cmp r11,r10,NINTop /* see if instruction is NINT */
- bb1 eq,r11,NINT /* instruction is NINT */
-TRNC:
- clr r1,r1,2<rndlo> /* clear rounding mode bits, */
- /* instruction is TRNC */
- br.n checksize /* branch to check size */
- set r1,r1,1<rndlo> /* make rounding mode round towards */
- /* zero */
-NINT:
- clr r1,r1,2<rndlo> /* make rounding mode round to */
- /* nearest */
-
-/* See whether the source is single or double precision. */
-
-checksize:
- bb1 s2size,r9,checkdoub /* S2 is double, branch to see if */
- /* there is a false alarm */
-
-/*
- * An integer has more bits than the mantissa of a single precision floating
- * point number, so to check for false alarms (i.e. valid conversion), simply
- * check the exponents. False alarms are detected for 2**30 to (2**30) - 1
- * and -2**30 to -2**31. Only seven bits need to be looked at since an
- * exception will not occur for the other half of the numbering system.
- * To speed up the processing, first check to see if the exponent is 32 or
- * greater.
- *
- * This code was originally written for the exponent in the control
- * register to have the most significant bit (8 - single, 11 - double)
- * flipped and sign extended. For precise exceptions, however, the most
- * significant bit is only sign extended. Therefore, the code was chopped
- * up so that it would work for positive values of real exponent which were
- * only sign extended.
- */
-
-checksing:
- extu r10,r7,7<20> /* internal representation for single */
- /* precision is IEEE 8 bits sign extended */
- /* to 11 bits; for real exp. = 30, the */
- /* above instruction gives a result exp. */
- /* that has the MSB flipped and sign */
- /* extended like in the IMPCR */
- cmp r11,r10,31 /* compare to 32,but exp. off by 1 */
- /* these 2 instructions to speed up valid */
- /* execution of valid cases */
- bb1 ge,r11,overflw /* valid case, perform overflow routine */
- bb1 sign,r7,checksingn /* source operand is negative */
-
-/*
- * If the number is positve and the exponent is greater than 30, than it is
- * overflow.
- */
-checksingp:
- cmp r10,r10,29 /* compare to 30, but exp. off by 1 */
- bb1 gt,r10,overflw /* no false alarm, its overflow */
- br conversionsp /* finish single precision conversion */
-
-/*
- * If the number is negative, and the exponent is 30, or 31 with a mantissa
- * of 0, then it is a false alarm.
- */
-checksingn:
- cmp r11,r10,30 /* compare to 31,but exp. off by 1 */
- bb1 lt,r11,conversionsn /* exp. less than 31, so convert */
- extu r10,r8,3<29> /* get upper three bits of lower */
- /* mantissa */
- mak r12,r7,20<3> /* get upper 20 bits of mantissa */
- or r10,r10,r12 /* form complete mantissa */
- bcnd eq0,r10,conversionsn /* complete conversion if mantissa */
- /* is 0 */
- br overflw /* no false alarm, its overflow */
-
-/*
- * False alarms are detected for 2**30 to (2**30) - 1 and -2**30 to -2**31.
- * Only seven bits need to be looked at since an exception will not occur
- * for the other half of the numbering system.
- * To speed up the processing, first check to see if the exponent is 32 or
- * greater. Since there are more mantissa bits than integer bits, rounding
- * could cause overflow. (2**31) - 1 needs to be checked so that it does
- * not round to 2**31, and -2**31 needs to be checked in case it rounds to
- * -((2**31) + 1).
- */
-checkdoub:
- extu r10,r7,10<20> /* internal representation for double */
- /* precision is the same IEEE 11 bits */
- /* for real exp. = 30, the */
- /* above instruction gives a result exp. */
- /* that has the MSB flipped and sign */
- /* extended like in the IMPCR */
- cmp r11,r10,31 /* compare to 32,but exp. off by 1 */
- /* these 2 instructions to speed up valid */
- /* execution of valid cases */
- bb1 ge,r11,overflw /* valid case, perform overflow routine */
- bb1 sign,r7,checkdoubn /* source operand is negative */
-
-/*
- * If the exponent is not 31, then the floating point number will be rounded
- * before the conversion is done. A branch table is set up with bits 4 and 3
- * being the rounding mode, and bits 2, 1, and 0 are the guard, round, and
- * sticky bits.
- */
-checkdoubp:
- cmp r11,r10,30 /* compare to 31, but exponent off by 1 */
- bb1 eq,r11,overflw /* no false alarm, its overflow */
- extu r12,r8,1<22> /* get LSB for integer with exp. = 30 */
- mak r12,r12,1<2> /* start to set up field for branch table */
- extu r11,r8,1<21> /* get guard bit */
- mak r11,r11,1<1> /* set up field for branch table */
- or r12,r11,r12 /* set up field for branch table */
- extu r11,r8,21<0> /* get bits for sticky bit */
- bcnd eq0,r11,nostickyp /* do not set sticky */
- set r12,r12,1<0> /* set sticky bit */
-nostickyp:
- rot r11,r1,0<rndlo> /* shift rounding mode to 2 LSB''s */
- mak r11,r11,2<3> /* set up field, clear other bits */
- or r12,r11,r12 /* set up field for branch table */
- lda r12,r0[r12] /* scale r12 */
- or.u r12,r12,hi16(ptable) /* load pointer into table */
- addu r12,r12,lo16(ptable)
- jmp r12
-
-ptable:
- br conversiondp
- br conversiondp
- br conversiondp
- br paddone
- br conversiondp
- br conversiondp
- br paddone
- br paddone
- br conversiondp
- br conversiondp
- br conversiondp
- br conversiondp
- br conversiondp
- br conversiondp
- br conversiondp
- br conversiondp
- br conversiondp
- br conversiondp
- br conversiondp
- br conversiondp
- br conversiondp
- br conversiondp
- br conversiondp
- br conversiondp
- br conversiondp
- br paddone
- br paddone
- br paddone
- br conversiondp
- br paddone
- br paddone
- br paddone
-
-/*
- * Add one to the bit of the mantissa which corresponds to the LSB of an
- * integer. If the mantissa overflows, then there is a valid integer
- * overflow conversion; otherwise, the mantissa can be converted to the
- * integer.
- */
-paddone:
- or r10,r0,r0 /* clear r10 */
- set r10,r10,1<22> /* set LSB bit to 1 for adding */
- addu.co r8,r8,r10 /* add the 1 obtained from rounding */
- clr r11,r7,12<20> /* clear exponent and sign */
- addu.ci r11,r0,r11 /* add carry */
- bb1 20,r11,overflw /* overflow to 2**31, abort the rest */
- br.n conversiondp /* since the exp. was 30, and the exp. */
- /* did not round up to 31, the largest */
- /* number that S2 could become is 2**31-1 */
- or r7,r0,r11 /* store r11 into r7 for conversion */
-
-/*
- * Now check for negative double precision sources. If the exponent is 30,
- * then convert the false alarm. If the exponent is 31, then check the
- * mantissa bits which correspond to integer bits. If any of them are a one,
- * then there is overflow. If they are zero, then check the guard, round,
- * and sticky bits.
- * Round toward zero and positive will not cause a roundup, but round toward
- * nearest and negative may, so perform those roundings. If there is no
- * overflow, then convert and return.
- */
-checkdoubn:
- cmp r11,r10,29 /* compare to 30, but exp. off by 1 */
- bb1 eq,r11,conversiondn /* false alarm if exp. = 30 */
- extu r10,r8,11<21> /* check upper bits of lower mantissa */
- bcnd ne0,r10,overflw /* one of the bits is a 1, so oflow */
- extu r10,r7,20<0> /* check upper bits of upper mantissa */
- bcnd ne0,r10,overflw /* one of the bits is a 1, so oflow */
- bb0 rndlo,r1,possround /* rounding mode is either round near */
- /* or round negative, which may cause */
- /* a round */
- br.n FPintov_return /* round positive, which will not */
- /* cause a round */
- set r6,r0,1<sign>
-possround:
- extu r12,r8,1<20> /* get guard bit */
- extu r11,r8,20<0> /* get bits for sticky bit */
- bcnd.n eq0,r11,nostickyn /* do not set sticky */
- mak r12,r12,1<1> /* set up field for branch table */
- set r12,r12,1<0> /* set sticky bit */
-nostickyn:
- bb1 rndhi,r1,negative /* rounding mode is negative */
-nearest:
- cmp r12,r12,3 /* are both guard and sticky set */
- bb1 eq,r12,overflw /* both guard and sticky are set, */
- /* so signal overflow */
- or r6,r0,r0 /* clear destination register r6 */
- br.n FPintov_return
- set r6,r6,1<sign> /* set the sign bit and take care of */
- /* this special case */
-negative:
- bcnd ne0,r12,overflw /* -2**31 will be rounded to */
- /* -(2**31+1), so signal overflow */
- or r6,r0,r0 /* clear destination register r6 */
- br.n FPintov_return
- set r6,r6,1<sign> /* set the sign bit and take care of */
- /* this special case */
-
- /*
- * Since the exp. was 30, and there was no round-up, the largest
- * number that S2 could have been was 2**31 - 1
- */
-
-
- /* Convert the single precision positive floating point number. */
-
-conversionsp:
- extu r6,r8,3<29> /* extract lower bits of integer */
- mak r6,r6,3<7> /* shift left to correct place in integer */
- mak r10,r7,20<10> /* shift left upper bits of integer */
- or r6,r6,r10 /* form most of integer */
- br.n FPintov_return
- set r6,r6,1<30> /* set hidden one */
-
- /* Convert the single precision negative floating point number. */
-
-conversionsn:
- bb1 eq,r11,exp31s /* use old r11 to see if exp. is 31 */
- extu r6,r8,3<29> /* extract lower bits of mantissa */
- mak r6,r6,3<7> /* shift left to correct place in integer */
- mak r10,r7,20<10> /* shift left upper bits of integer */
- or r6,r6,r10 /* form most of integer */
- set r6,r6,1<30> /* set hidden one */
- or.c r6,r0,r6 /* negate result */
- br.n FPintov_return
- addu r6,r6,1 /* add 1 to get 2''s complement */
-exp31s:
- or r6,r0,r0 /* clear r6 */
- br.n FPintov_return
- set r6,r6,1<sign> /* set sign bit */
-
- /* Convert the double precision positive floating point number. */
-
-conversiondp:
- extu r6,r8,10<22> /* extract lower bits of integer */
- mak r10,r7,20<10> /* shift left upper bits of integer */
- or r6,r6,r10 /* form most of integer */
- br.n FPintov_return
- set r6,r6,1<30> /* set hidden one */
-
- /*
- * Convert the double precision negative floating point number.
- * The number, whose exponent is 30, must be rounded before converting.
- * Bits 4 and 3 are the rounding mode, and bits 2, 1, and 0 are the
- * guard, round, and sticky bits for the branch table.
- */
-
-conversiondn:
- extu r12,r8,1<22> /* get LSB for integer with exp. = 30 */
- mak r12,r12,1<2> /* start to set up field for branch table */
- extu r11,r8,1<21> /* get guard bit */
- mak r11,r11,1<1> /* set up field for branch table */
- or r12,r11,r12 /* set up field for branch table */
- extu r11,r8,21<0> /* get bits for sticky bit */
- bcnd eq0,r11,nostkyn /* do not set sticky */
- set r12,r12,1<0> /* set sticky bit */
-nostkyn:
- rot r11,r1,0<rndlo> /* shift rounding mode to 2 LSB''s */
- mak r11,r11,2<3> /* set up field, clear other bits */
- or r12,r11,r12 /* set up field for branch table */
- lda r12,r0[r12] /* scale r12 */
- or.u r12,r12,hi16(ntable) /* load pointer into table */
- addu r12,r12,lo16(ntable)
- jmp r12
-
-ntable:
- br nnoaddone
- br nnoaddone
- br nnoaddone
- br naddone
- br nnoaddone
- br nnoaddone
- br naddone
- br naddone
- br nnoaddone
- br nnoaddone
- br nnoaddone
- br nnoaddone
- br nnoaddone
- br nnoaddone
- br nnoaddone
- br nnoaddone
- br nnoaddone
- br naddone
- br naddone
- br naddone
- br nnoaddone
- br naddone
- br naddone
- br naddone
- br nnoaddone
- br nnoaddone
- br nnoaddone
- br nnoaddone
- br nnoaddone
- br nnoaddone
- br nnoaddone
- br nnoaddone
-
-/*
- * Add one to the mantissa, and check to see if it overflows to -2**31.
- * The conversion is done in nnoaddone.
- */
-
-naddone:
- or r10,r0,r0 /* clear r10 */
- set r10,r10,1<22> /* set LSB bit to 1 for adding */
- add.co r8,r8,r10 /* add the 1 obtained from rounding */
- clr r7,r7,12<20> /* clear exponent and sign */
- add.ci r7,r0,r7 /* add carry */
- bb1 20,r7,maxneg /* rounded to -2**31,handle separately */
- /* the exponent was originally 30 */
-nnoaddone:
- extu r6,r8,11<22> /* extract lower bits of integer */
- mak r10,r7,20<10> /* shift left upper bits of integer */
- or r6,r6,r10 /* form most of integer */
- set r6,r6,1<30> /* set hidden one */
- or.c r6,r0,r6 /* negate integer */
- br.n FPintov_return
- addu r6,r6,1 /* add 1 to get 2''s complement */
-
-maxneg:
- or r6,r0,r0 /* clear integer */
- br.n FPintov_return
- set r6,r6,1<sign> /* set sign bit */
-
- /*
- * For valid overflows, check to see if the integer overflow user
- * handler is set. If it is set, then go to user handler, else write
- * the correctly signed largest integer.
- */
-
-overflw:
- set r2,r2,1<oper>
-#ifdef HANDLER
- bb0 oper,r3,nohandler /* do not go to user handler routine */
- bsr _handler /* go to user handler routine */
- br FPintov_return
-nohandler:
-#endif
- bb0.n sign,r7,FPintov_return /* if positive then return */
- set r6,r6,31<0> /* set result to largest positive int */
- or.c r6,r0,r6 /* negate r6, giving largest negative */
- /* integer */
-
-FPintov_return:
- ld r1,r31,0 /* load return address from memory */
- jmp r1
-
-/*
- * Some instructions only have the S2 operations, so clear S1HI and S1LO
- * for those instructions so that the previous contents of S1HI and S1LO
- * do not influence this instruction.
- */
-
-ASLOCAL(FPresoper)
- st r1, r31, 0
- extu r10,r9,5<11> /* extract opcode */
-#if 0
- cmp r11,r10,FSQRTop /* compare to FSQRT */
- bb1 eq,r11,S1clear /* clear S1 if instruction only had S2 operand */
-#endif
- cmp r11,r10,INTop /* compare to INT */
- bb1 eq,r11,S1clear /* clear S1 if instruction only had S2 operand */
- cmp r11,r10,NINTop /* compare to NINT */
- bb1 eq,r11,S1clear /* clear S1 if instruction only had S2 operand */
- cmp r11,r10,TRNCop /* compare to TRNC */
- bb0 eq,r11,opercheck /* check for reserved operands */
-
-ASLOCAL(S1clear)
- or r5,r0,r0 /* clear any NaN''s, denorms, or infinities */
- or r6,r0,r0 /* that may be left in S1HI,S1LO from a */
- /* previous instruction */
-
-/*
- * r12 contains the following flags:
- * bit 9 -- s1sign
- * bit 8 -- s2sign
- * bit 7 -- s1nan
- * bit 6 -- s2nan
- * bit 5 -- s1inf
- * bit 4 -- s2inf
- * bit 3 -- s1zero
- * bit 2 -- s2zero
- * bit 1 -- s1denorm
- * bit 0 -- s2denorm
- */
-
-/*
- * Using code for both single and double precision, check if S1 is either
- * a NaN or infinity and set the appropriate flags in r12. Then check if
- * S2 is a NaN or infinity. If it is a NaN, then branch to the NaN routine.
- */
-
-ASLOCAL(opercheck)
- extu r10,r5,11<20> /* internal representation for double */
- bb1.n s1size,r9,S1NaNdoub /* S1 is double precision */
- or r12,r0,r0 /* clear operand flag register */
-ASLOCAL(S1NaNsing)
- xor r10,r10,0x0080 /* internal representation for single */
- ext r10,r10,8<0> /* precision is IEEE 8 bits sign extended */
- /* to 11 bits; for real exp. > 0, the */
- /* above instructions gives a result exp. */
- /* that has the MSB flipped and sign */
- /* extended like in the IMPCR */
- cmp r11,r10,127 /* Is exponent equal to IEEE 255 (here 127) */
- bb1 ne,r11,S2NaN /* source 1 is not a NaN or infinity */
- mak r10,r5,20<0> /* load r10 with upper bits of S1 mantissa */
- extu r11,r6,3<29> /* get 3 upper bits of lower word */
- or r11,r10,r11 /* combine any existing 1 */
- bcnd eq0,r11,noS1NaNs /* since r11 can only hold 0 or a */
- /* > 0 number, branch to noS1NaN when eq0 */
- br.n S2NaN /* see if S2 has a NaN */
- set r12,r12,1<s1nan> /* indicate that S1 has a NaN */
-ASLOCAL(noS1NaNs)
- br.n S2NaN /* check contents of S2 */
- set r12,r0,1<s1inf> /* indicate that S1 has an infinity */
-
-ASLOCAL(S1NaNdoub)
- xor r10,r10,0x0400 /* precision is the same IEEE 11 bits */
- /* The above instructions gives a result exp. */
- /* that has the MSB flipped and sign */
- /* extended like in the IMPCR */
- cmp r11,r10,1023 /* Is exp. equal to IEEE 2047 (internal 1023) */
- bb1 ne,r11,S2NaN /* source 1 is not a NaN or infinity */
- mak r10,r5,20<0> /* load r10 with upper bits of S1 mantissa */
- or r11,r6,r10 /* combine existing 1''s of mantissa */
- bcnd eq0,r11,noS1NaNd /* since r11 can only hold 0 or a > 0 */
- /* number, branch to noS1NaN when eq0 */
- br.n S2NaN /* see if S2 has a NaN */
- set r12,r12,1<s1nan> /* indicate that S1 has a NaN */
-ASLOCAL(noS1NaNd)
- set r12,r0,1<s1inf> /* indicate that S1 has an infinity */
-
-ASLOCAL(S2NaN)
- bb1.n s2size,r9,S2NaNdoub /* S1 is double precision */
- extu r10,r7,11<20> /* internal representation for double */
-ASLOCAL(S2NaNsing)
- xor r10,r10,0x0080 /* internal representation for single */
- ext r10,r10,8<0> /* precision is IEEE 8 bits sign extended */
- /* to 11 bits; for real exp. > 0, the */
- /* above instruction gives a result exp. */
- /* that has the MSB flipped and sign */
- /* extended like in the IMPCR */
- cmp r11,r10,127 /* Is exponent equal to IEEE 255 (here 127) */
- bb1 ne,r11,inf /* source 2 is not a NaN or infinity */
- mak r10,r7,20<0> /* load r10 with upper bits of S1 mantissa */
- extu r11,r8,3<29> /* get 3 upper bits of lower word */
- or r11,r10,r11 /* combine any existing 1''s */
- bcnd eq0,r11,noS2NaNs /* since r11 can only hold 0 or a > 0 */
- /* number, branch to noS2NaNs when eq0 */
- br.n _ASM_LABEL(NaN) /* branch to NaN routine */
- set r12,r12,1<s2nan> /* indicate that s2 has a NaN */
-ASLOCAL(noS2NaNs)
- bb0 s1nan,r12, 1f /* branch to NaN if S1 is a NaN */
- br _ASM_LABEL(NaN)
-1:
- br.n _ASM_LABEL(infinity) /* If S1 had a NaN we would have */
- /* already branched, and S2 does not have a */
- /* NaN, but it does have an infinity, so */
- /* branch to handle the finity */
- set r12,r12,1<s2inf> /* indicate that S2 has an infinity */
-
-ASLOCAL(S2NaNdoub)
- xor r10,r10,0x0400 /* precision is the same IEEE 11 bits */
- /* The above instruction gives a result exp. */
- /* that has the MSB flipped and sign */
- /* extended like in the IMPCR */
- cmp r11,r10,1023 /* Is exp. equal to IEEE 2047 (internal 1023) */
- bb1 ne,r11,inf /* source 2 is not a NaN or infinity */
- mak r10,r7,20<0> /* load r10 with upper bits of S2 mantissa */
- or r11,r8,r10 /* combine existing 1''s of mantissa */
- bcnd eq0,r11,noS2NaNd /* since r11 can only hold 0 or a > 0 */
- /* number, branch to noS2NaNd when eq0 */
- br.n _ASM_LABEL(NaN) /* branch to NaN routine */
- set r12,r12,1<s2nan> /* indicate that s2 has a NaN */
-ASLOCAL(noS2NaNd)
- bb0 s1nan,r12,1f /* branch to NaN if S1 is a NaN */
- br _ASM_LABEL(NaN)
-1:
- br.n _ASM_LABEL(infinity) /* If S1 had a NaN we would have */
- /* already branched, and S2 does not have a */
- /* NaN, but it does have an infinity, so */
- /* branch to handle the finity */
- set r12,r12,1<s2inf> /* indicate that S2 has an infinity */
-
-/*
- * If S2 was a NaN, the routine would have already branched to NaN. If S1
- * is a NaN, then branch to NaN. If S1 is not a NaN and S2 is infinity, then
- * we would have already branched to infinity. If S1 is infinity, then branch.
- * If the routine still has not branched, then branch to denorm, the only
- * reserved operand left.
- */
-
-ASLOCAL(inf)
- bb0 s1nan,r12,1f /* branch if S1 has a NaN and S2 does not */
- br _ASM_LABEL(NaN)
-1:
- bb0 s1inf,r12,2f /* Neither S1 or S2 has a NaN, and we would */
- /* have branched already if S2 had an */
- /* infinity, so branch if S1 is infinity */
- br _ASM_LABEL(infinity)
-2:
- br _ASM_LABEL(denorm) /* branch to denorm, the only */
- /* remaining alternative */
-
-/*
- * First check for an underflow user handler. If there is not one, then
- * branch to the routine to make a denormalized number. Before branching
- * to the underflow user handler, add 192 to a single precision exponent
- * and 1536 to a double precision exponent.
- */
-
-ASLOCAL(FPunderflow)
- st r1,r31,0 /* save return address */
- set r2,r2,1<underflow>
- set r2,r2,1<inexact>
-#ifdef HANDLER
- bb0 efunf,r12,FPU_denorm /* jump to default procedure */
- bb1 destsize,r12,doubleprec /* double precision destination */
-singleprec:
- or.u r6,r0,0x0c00 /* load exponent adjust 192 */
- br.n callundhand /* branch to call handler for user handler */
- add r12,r6,r12 /* adjust single precision exponent */
-doubleprec:
- or.u r6,r0,0x6000 /* load exponent adjust 1536 */
- add r12,r6,r12 /* adjust double precision exponent */
-callundhand:
- bsr _handler /* call handler for user handler */
- br Ureturn
-#endif
-
-/*
- * Now the floating point number, which has an exponent smaller than what
- * IEEE allows, must be denormalized. Denormalization is done by calculating
- * the difference between a denormalized exponent and an underflow exponent
- * and shifting the mantissa by that amount. A one may need to be subtracted
- * from the LSB if a one was added during rounding.
- * r9 is used to contain the guard, round, sticky, and an inaccuracy bit in
- * case some bits were shifted off the mantissa during denormalization.
- * r9 will contain:
- * bit 4 -- new addone if one added during rounding after denormalization
- * bit 3 -- inaccuracy flag caused by denormalization or pre-denormalization
- * inexactness
- * bit 2 -- guard bit of result
- * bit 1 -- round bit of result
- * bit 0 -- sticky bit of result
- */
-
-FPU_denorm:
- bb1.n destsize,r12,Udouble /* denorm for double */
- extu r9,r10,3<26> /* load r9 with grs */
-Usingle:
- mak r5,r10,21<3> /* extract high 21 bits of mantissa */
- extu r6,r11,3<29> /* extract low 3 bits of mantissa */
- or r11,r5,r6 /* form 24 bits of mantissa */
-
-/* See if the addone bit is set and unround if it is. */
- bb0.n 25,r10,nounrounds /* do not unround if addone bit clear */
- extu r6,r12,12<20> /* extract signed exponent from IMPCR */
-unrounds:
- subu r11,r11,1 /* subtract 1 from mantissa */
-
-/*
- * If the hidden bit is cleared after subtracting the one, then the one added
- * during the rounding must have propagated through the mantissa. The exponent
- * will need to be decremented.
- */
- bb1 23,r11,nounrounds /* if hidden bit is set,then exponent */
- /* does not need to be decremented */
-decexps:
- sub r6,r6,1 /* decrement exponent 1 */
- set r11,r11,1<23> /* set the hidden bit */
-
-/*
- * For both single and double precision, there are cases where it is easier
- * and quicker to make a special case. Examples of this are if the shift
- * amount is only 1 or 2, or all the mantissa is shifted off, or all the
- * mantissa is shifted off and it is still shifting, or, in the case of
- * doubles, if the shift amount is around the boundary of MANTLO and MANTHI.
- */
-
-nounrounds:
- or r8,r0,lo16(0x00000f81) /* load r8 with -127 in decimal */
- /* for lowest 12 bits */
- sub r7,r8,r6 /* find difference between two exponents, */
- /* this amount is the shift amount */
- cmp r6,r7,3 /* check to see if r7 contains 3 or more */
- bb1 ge,r6,threesing /* br to code that handles shifts of >=3 */
- cmp r6,r7,2 /* check to see if r7 contains 2 */
- bb1 eq,r6,twosing /* br to code that handles shifts of 2 */
-one:
- rot r9,r9,0<1> /* rotate roundoff register once, this places */
- /* guard in round and round in sticky */
- bb0 31,r9,nosticky1s /* do not or round and sticky if sticky is */
- /* 0, this lost bit will be cleared later */
- set r9,r9,1<0> /* or round and sticky */
-nosticky1s:
- bb0 0,r11,guardclr1s /* do not set guard bit if LSB = 0 */
- set r9,r9,1<2> /* set guard bit */
-guardclr1s:
- extu r11,r11,31<1> /* shift mantissa right 1 */
- br.n round /* round result */
- mak r9,r9,3<0> /* clear bits lost during rotation */
-
-twosing:
- rot r9,r9,0<2> /* rotate roundff register twice, this places */
- /* guard in sticky */
- bb0 30,r9,nosticky2s /* do not or guard and sticky if stick is 0 */
- /* this lost bit will be cleared later */
- br.n noround2s /* skip or old guard and old round if old */
- /* sticky set */
- set r9,r9,1<0> /* or guard and sticky */
-nosticky2s:
- bb0 31,r9,noround2s /* do not or guard and round if round is 0 */
- /* this lost bit will be cleared later */
- set r9,r9,1<0> /* or guard and round */
-noround2s:
- bb0 0,r11,roundclr2s /* do not set round bit if LSB = 0 */
- set r9,r9,1<1> /* set round bit */
-roundclr2s:
- bb0 1,r11,guardclr2s /* do not set guard bit if LSB + 1 = 0 */
- set r9,r9,1<2> /* set guard bit */
-guardclr2s:
- extu r11,r11,30<2> /* shift mantissa right 2 */
- br.n round /* round result */
- mak r9,r9,3<0> /* clear bits lost during rotation */
-
-threesing:
- bb1 0,r9,noguard3s /* check sticky initially */
- /* sticky is set, forget most of the oring */
-nosticky3s:
- bb0 1,r9,noround3s /* check round initially, do not set sticky */
- br.n noguard3s /* forget most of the rest of oring */
- set r9,r9,1<0> /* if round is clear,set sticky if round set */
-noround3s:
- bb0.n 2,r9,noguard3s /* check guard initially, do not set sticky */
- clr r9,r9,2<1> /* clear the original guard and round for when */
- /* you get to round section */
- set r9,r9,1<0> /* if guard is clear,set sticky if guard set */
-noguard3s:
- cmp r6,r7,23 /* check if # of shifts is <=23 */
- bb1 gt,r6,s24 /* branch to see if shifts = 24 */
- sub r6,r7,2 /* get number of bits to check for sticky */
- mak r6,r6,5<5> /* shift width into width field */
- mak r8,r11,r6 /* mask off shifted bits -2 */
- ff1 r8,r8 /* see if r8 has any ones */
- bb1 5,r8,nostky23 /* do not set sticky if no ones found */
- set r9,r9,1<0> /* set sticky bit */
-nostky23:
- or r8,r0,34 /* start code to get new mantissa plus two */
- /* extra bits for new round and new guard */
- /* bits */
- subu r8,r8,r7
- mak r8,r8,5<5> /* shift field width into second five bits */
- extu r6,r6,5<5> /* shift previous shifted -2 into offset field */
- or r6,r6,r8 /* complete field */
- extu r11,r11,r6 /* form new mantissa with two extra bits */
-
- bb0 0,r11,nornd3s /* do not set new round bit */
- set r9,r9,1<1> /* set new round bit */
-nornd3s:
- bb0 1,r11,nogrd3s /* do not set new guard bit */
- set r9,r9,1<2> /* set new guard bit */
-nogrd3s:
- br.n round /* round mantissa */
- extu r11,r11,30<2> /* shift off remaining two bits */
-
-s24:
- cmp r6,r7,24 /* check to see if # of shifts is 24 */
- bb1 gt,r6,s25 /* branch to see if shifts = 25 */
- bb1 0,r9,nostky24 /* skip checking if old sticky set */
- extu r8,r11,22<0> /* prepare to check bits that will be shifted */
- /* into the sticky */
- ff1 r8,r8 /* see if there are any 1''s */
- bb1 5,r8,nostky24 /* do not set sticky if no ones found */
- set r9,r9,1<0> /* set sticky bit */
-nostky24:
- bb0 22,r11,nornd24 /* do not set new round bit */
- set r9,r9,1<1> /* set new round bit */
-nornd24:
- set r9,r9,1<2> /* set new guard bit,this is hidden bit */
- br.n round /* round mantissa */
- or r11,r0,r0 /* clear r11, all of mantissa shifted off */
-
-s25:
- cmp r6,r7,25 /* check to see if # of shifts is 25 */
- bb1 gt,r6,s26 /* branch to execute for shifts => 26 */
- bb1 0,r9,nostky25 /* skip checking if old sticky set */
- extu r8,r11,23<0> /* prepare to check bits that will be shifted */
- /* into the sticky */
- ff1 r8,r8 /* see if there are any 1''s */
- bb1 5,r8,nostky25 /* do not set sticky if no ones found */
- set r9,r9,1<0> /* set sticky bit */
-nostky25:
- set r9,r9,1<1> /* set new round bit,this is hidden bit */
- clr r9,r9,1<2> /* clear guard bit since nothing shifted in */
- br.n round /* round and assemble result */
- or r11,r0,r0 /* clear r11, all of mantissa shifted off */
-
-s26:
- set r9,r9,1<0> /* set sticky bit,this contains hidden bit */
- clr r9,r9,2<1> /* clear guard and round bits since nothing */
- /* shifted in */
- br.n round /* round and assemble result */
- or r11,r0,r0 /* clear mantissa */
-
-Udouble:
- mak r5,r10,21<0> /* extract upper bits of mantissa */
- bb0.n 25,r10,nounroundd /* do not unround if addone bit clear */
- extu r6,r12,12<20> /* extract signed exponenet from IMPCR */
-unroundd:
- or r8,r0,1
- subu.co r11,r11,r8 /* subtract 1 from mantissa */
- subu.ci r5,r5,r0 /* subtract borrow from upper word */
- bb1 20,r5,nounroundd /* if hidden bit is set, then exponent does */
- /* not need to be decremented */
-decexpd:
- sub r6,r6,1 /* decrement exponent 1 */
- set r5,r5,1<20> /* set the hidden bit */
-
-nounroundd:
- or r8,r0,lo16(0x00000c01) /* load r8 with -1023 in decimal */
- /* for lowest 12 bits */
- sub r7,r8,r6 /* find difference between two exponents, */
- /* this amount is the shift amount */
- cmp r6,r7,3 /* check to see if r7 contains 3 or more */
- bb1 ge,r6,threedoub /* br to code that handles shifts of >=3 */
- cmp r6,r7,2 /* check to see if r7 contains 2 */
- bb1 eq,r6,twodoub /* br to code that handles shifts of 2 */
-
-onedoub:
- rot r9,r9,0<1> /* rotate roundoff register once, this places */
- /* guard in round and round in sticky */
- bb0 31,r9,nosticky1d/* do not or round and sticky if sticky is 0 */
- /* this lost bit will be cleared later */
- set r9,r9,1<0> /* or old round and old sticky into new sticky */
-nosticky1d:
- bb0 0,r11,guardclr1d /* do not set new guard bit if old LSB = 0 */
- set r9,r9,1<2> /* set new guard bit */
-guardclr1d:
- extu r11,r11,31<1> /* shift lower mantissa over 1 */
- mak r6,r5,1<31> /* shift off low bit of high mantissa */
- or r11,r6,r11 /* load high bit onto lower mantissa */
- extu r5,r5,20<1> /* shift right once upper 20 bits of mantissa */
- br.n round /* round mantissa and assemble result */
- mak r9,r9,3<0> /* clear bits lost during rotation */
-
-twodoub:
- rot r9,r9,0<2> /* rotate roundoff register twice, this places */
- /* old guard into sticky */
- bb0 30,r9,nosticky2d /* do not or old guard and old sticky if */
- /* old sticky is 0 */
- br.n noround2d /* skip or of old guard and old round if old */
- /* sticky set */
- set r9,r9,1<0> /* or old guard and old sticky into new sticky */
-nosticky2d:
- bb0 31,r9,noround2d /* do not or old guard and old round if */
- /* old round is 0 */
- set r9,r9,1<0> /* or old guard and old round into new sticky */
-noround2d:
- bb0 0,r11,roundclr2d /* do not set round bit if old LSB = 0 */
- set r9,r9,1<1> /* set new round bit */
-roundclr2d:
- bb0 1,r11,guardclr2d /* do not set guard bit if old LSB + 1 = 0 */
- set r9,r9,1<2> /* set new guard bit */
-guardclr2d:
- extu r11,r11,30<2> /* shift lower mantissa over 2 */
- mak r6,r5,2<30> /* shift off low bits of high mantissa */
- or r11,r6,r11 /* load high bit onto lower mantissa */
- extu r5,r5,19<2> /* shift right twice upper 19 bits of mantissa */
- br.n round /* round mantissa and assemble result */
- mak r9,r9,3<0> /* clear bits lost during rotation */
-
-threedoub:
- bb1 0,r9,noguard3d /* checky sticky initially */
- /* sticky is set, forget most of rest of oring */
-nosticky3d:
- bb0 1,r9,noround3d /* check old round, do not set sticky if */
- /* old round is clear, set otherwise */
- br.n noguard3d /* sticky is set, forget most of rest of oring */
- set r9,r9,1<0> /* set sticky if old round is set */
-noround3d:
- bb0 2,r9,noguard3d /* check old guard, do not set sticky if 0 */
- clr r9,r9,2<1> /* clear the original guard and round for when */
- /* you get to round section */
- set r9,r9,1<0> /* set sticky if old guard is set */
-noguard3d:
- cmp r6,r7,32 /* do I need to work with a 1 or 2 word mant. */
- /* when forming sticky, round and guard */
- bb1 gt,r6,d33 /* jump to code that handles 2 word mantissas */
- sub r6,r7,2 /* get number of bits to check for sticky */
- mak r6,r6,5<5> /* shift width into width field */
- mak r8,r11,r6 /* mask off shifted bits -2 */
- ff1 r8,r8 /* see if r8 has any ones */
- bb1 5,r8,nostky32 /* do not set sticky if no ones found */
- set r9,r9,1<0> /* set sticky bit */
-nostky32:
- or r8,r0,34 /* start code to get new mantissa plus two */
- /* extra bits for new round and new guard bits, */
- /* the upper word bits will be shifted after */
- /* the round and guard bits are handled */
- subu r8,r8,r7
- mak r8,r8,5<5> /* shift field width into second five bits */
- extu r6,r6,5<5> /* shift previous shifted -2 into offset field */
- or r6,r6,r8 /* complete bit field */
- extu r11,r11,r6 /* partially form new low mantissa with 2 more */
- /* bits */
- bb0 0,r11,nornd32d /* do not set new round bit */
- set r9,r9,1<1> /* set new round bit */
-nornd32d:
- bb0 1,r11,nogrd32d /* do not set new guard bit */
- set r9,r9,1<2> /* set new guard bit */
-nogrd32d:
- extu r11,r11,30<2> /* shift off remaining two bits */
- mak r6,r7,5<5> /* shift field width into second 5 bits, if the */
- /* width is 32, then these bits will be 0 */
- or r8,r0,32 /* load word length into r8 */
- sub r8,r8,r7 /* form offset for high bits moved to low word */
- or r6,r6,r8 /* form complete bit field */
- mak r6,r5,r6 /* get shifted bits of high word */
- or r11,r6,r11 /* form new low word of mantissa */
- bcnd ne0,r8,regular33 /* do not adjust for special case of r8 */
- br.n round /* containing zeros, which would cause */
- or r5,r0,r0 /* all of the bits to be extracted under */
- /* the regular method */
-regular33:
- mak r6,r7,5<0> /* place lower 5 bits of shift into r6 */
- mak r8,r8,5<5> /* shift r8 into width field */
- or r6,r6,r8 /* form field for shifting of upper bits */
- br.n round /* round and assemble result */
- extu r5,r5,r6 /* form new high word mantissa */
-
-d33:
- cmp r6,r7,33 /* is the number of bits to be shifted is 33? */
- bb1 gt,r6,d34 /* check to see if # of bits is 34 */
- bb1 0,r9,nostky33 /* skip checking if old sticky set */
- mak r6,r11,31<0> /* check bits that will be shifted into sticky */
- ff1 r8,r8 /* check for ones */
- bb1 5,r8,nostky33 /* do not set sticky if there are no ones */
- set r9,r9,1<0> /* set new sticky bit */
-nostky33:
- bb0 31,r11,nornd33 /* do not set round if bit is not a 1 */
- set r9,r9,1<1> /* set new round bit */
-nornd33:
- bb0 0,r5,nogrd33 /* do not set guard bit if bit is not a 1 */
- set r9,r9,1<2> /* set new guard bit */
-nogrd33:
- extu r11,r5,31<1> /* shift high bits into low word */
- br.n round /* round and assemble result */
- or r5,r0,r0 /* clear high word */
-
-d34:
- cmp r6,r7,34 /* is the number of bits to be shifted 34? */
- bb1 gt,r6,d35 /* check to see if # of bits is >= 35 */
- bb1 0,r9,nostky34 /* skip checking if old sticky set */
- ff1 r8,r11 /* check bits that will be shifted into sticky */
- bb1 5,r8,nostky34 /* do not set sticky if there are no ones */
- set r9,r9,1<0> /* set new sticky bit */
-nostky34:
- bb0 0,r5,nornd34 /* do not set round if bit is not a 1 */
- set r9,r9,1<1> /* set new round bit */
-nornd34:
- bb0 1,r5,nogrd34 /* do not set guard bit if bit is not a 1 */
- set r9,r9,1<2> /* set new guard bit */
-nogrd34:
- extu r11,r5,30<2> /* shift high bits into low word */
- br.n round /* round and assemble result */
- or r5,r0,r0 /* clear high word */
-
-d35:
- cmp r6,r7,52 /* see if # of shifts is 35 <= X <= 52 */
- bb1 gt,r6,d53 /* check to see if # of shifts is 52 */
- bb1.n 0,r9,nostky35 /* skip checking if old sticky set */
- sub r7,r7,34 /* subtract 32 from # of shifts so that opera- */
- /* tions can be done on the upper word, and */
- /* then subtract two more checking guard and */
- /* sticky bits */
- ff1 r8,r11 /* see if lower word has a bit for sticky */
- bb1 5,r8,stkycheck35 /* see if upper word has any sticky bits */
- br.n nostky35 /* quit checking for sticky */
- set r9,r9,1<0> /* set sticky bit */
-stkycheck35:
- mak r6,r7,5<5> /* place width into width field */
- mak r8,r5,r6 /* mask off shifted bits - 2 */
- ff1 r8,r8 /* see if r8 has any ones */
- bb1 5,r8,nostky35 /* do not set sticky if no ones found */
- set r9,r9,1<0> /* set sticky bit */
-nostky35:
- or r8,r0,32 /* look at what does not get shifted off plus */
- /* round and sticky, remember that the r7 value */
- /* was adjusted so that it did not include */
- /* new round or new sticky in shifted off bits */
- subu r8,r8,r7 /* complement width */
- mak r8,r8,5<5> /* shift width into width field */
- or r8,r7,r8 /* add offset field */
- extu r11,r5,r8 /* extract upper bits into low word */
- bb0 0,r11,nornd35 /* do not set new round bit */
- set r9,r9,1<1> /* set new round bit */
-nornd35:
- bb0 1,r11,nogrd35 /* do not set new guard bit */
- set r9,r9,1<2> /* set new guard bit */
-nogrd35:
- extu r11,r11,30<2> /* shift off remaining guard and round bits */
- br.n round /* round and assemble result */
- or r5,r0,r0 /* clear high word */
-
-d53:
- cmp r6,r7,53 /* check to see if # of shifts is 53 */
- bb1 gt,r6,d54 /* branch to see if shifts = 54 */
- bb1 0,r9,nostky53 /* skip checking if old sticky set */
- ff1 r8,r11 /* see if lower word has a bit for sticky */
- bb1 5,r8,stkycheck53 /* see if upper word has any sticky bits */
- br.n nostky53 /* quit checking for sticky */
- set r9,r9,1<0> /* set sticky bit */
-stkycheck53:
- mak r6,r5,19<0> /* check bits that are shifted into sticky */
- ff1 r8,r6 /* see if r6 has any ones */
- bb1 5,r8,nostky53 /* do not set sticky if no ones found */
- set r9,r9,1<0> /* set sticky bit */
-nostky53:
- bb0 19,r5,nornd53 /* do not set new round bit */
- set r9,r9,1<1> /* set new round bit */
-nornd53:
- set r9,r9,1<2> /* set new guard bit,this is hidden bit */
- or r5,r0,r0 /* clear high word */
- br.n round /* round and assemble result */
- or r11,r0,r0 /* clear low word */
-
-d54:
- cmp r6,r7,54 /* check to see if # of shifts is 54 */
- bb1 gt,r6,d55 /* branch to execute for shifts =>55 */
- bb1 0,r9,nostky54 /* skip checking if old sticky set */
- ff1 r8,r11 /* see if lower word has a bit for sticky */
- bb1 5,r8,stkycheck54 /* see if upper word has any sticky bits */
- br.n nostky54 /* quit checking for sticky */
- set r9,r9,1<0> /* set sticky bit */
-stkycheck54:
- mak r6,r5,20<0> /* check bits that are shifted into sticky */
- ff1 r8,r6 /* see if r6 has any ones */
- bb1 5,r8,nostky54 /* do not set sticky if no ones found */
- set r9,r9,1<0> /* set sticky bit */
-nostky54:
- set r9,r9,1<1> /* set new round bit,this is hidden bit */
- clr r9,r9,1<2> /* clear guard bit since nothing shifted in */
- or r5,r0,r0 /* clear high word */
- br.n round /* round and assemble result */
- or r11,r0,r0 /* clear low word */
-
-d55:
- set r9,r9,1<0> /* set new sticky bit,this contains hidden bit */
- clr r9,r9,2<1> /* clear guard and round bits since nothing */
- /* shifted in */
- or r5,r0,r0 /* clear high word */
- or r11,r0,r0 /* clear low word */
-
-
-/* The first item that the rounding code does is see if either guard, round, */
-/* or sticky is set. If all are clear, then there is no denormalization loss */
-/* and no need to round, then branch to assemble answer. */
-/* For rounding, a branch table is set up. The left two most bits are the */
-/* rounding mode. The third bit is either the LSB of the mantissa or the */
-/* sign bit, depending on the rounding mode. The three LSB''s are the guard, */
-/* round and sticky bits. */
-
-round:
- ff1 r8,r9 /* see if there is denormalization loss */
- bb1 5,r8,assemble /* no denormalization loss or inexactness */
- extu r6,r10,2<modelo> /* extract rounding mode */
- bb1.n modehi,r10,signext /* use sign bit instead of LSB */
- mak r6,r6,2<4> /* shift over rounding mode */
- extu r7,r11,1<0> /* extract LSB */
- br.n grs /* skip sign extraction */
- mak r7,r7,1<3> /* shift over LSB */
-signext:
- extu r7,r10,1<31> /* extract sign bit */
- mak r7,r7,1<3> /* shift sign bit over */
-grs:
- or r6,r6,r7
- or r6,r6,r9 /* or in guard, round, and sticky */
- or.u r1,r0,hi16(roundtable) /* form address of branch table */
- or r1,r1,lo16(roundtable)
- lda r6,r1[r6] /* scale offset into branch table */
- jmp.n r6 /* jump to branch table */
- set r9,r9,1<3> /* set inexact flag in r9 */
-
-roundtable:
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br addone
- br addone
- br addone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br addone
- br addone
- br addone
- br addone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br addone
- br addone
- br addone
- br addone
- br addone
- br addone
- br addone
- br noaddone
- br addone
- br addone
- br addone
- br addone
- br addone
- br addone
- br addone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
- br noaddone
-
-/* Round by adding a one to the LSB of the mantissa. */
-addone:
- or r6,r0,1 /* load a 1 into r6 so that add.co can be used */
- add.co r11,r11,r6 /* add a one to the lower word of result */
- bb0.n destsize,r12,noaddone /* single result,forget carry */
- set r9,r9,1<4> /* indicate that a 1 has been added */
- add.ci r5,r5,r0 /* propagate carry into high word */
-
-
-/* Branch to inexact user handler if there is one. */
-
-noaddone:
- set r2,r2,1<inexact>
- set r2,r2,1<underflow>
-#ifdef HANDLER
- bb1 efinx,r12,modformdef /* branch to modify form for user */
- /* handler */
-#endif
-
-
-/* Assemble the result of the denormalization routine for writeback to the */
-/* destination register. The exponent of a denormalized number is zero, */
-/* so simply assemble the sign and the new mantissa. */
-
-assemble:
- bb1 destsize,r12,doubassem /* assemble double result */
- bb0 sign,r10,exassems /* exit assemble if sign is zero */
- set r11,r11,1<sign> /* make result negative */
-exassems:
- br Ureturn
-
-doubassem:
- bb0.n sign,r10,signclr /* do not set sign in r10 */
- or r10,r5,r0 /* load high word from r5 into r10 */
- set r10,r10,1<sign> /* high word with sign loaded */
-signclr:
- br Ureturn
-
-
-/* modfordef modifies the result of denormalization to the input format of */
-/* the inexact user handler. This input format is the same format that */
-/* MANTHI, MANTLO, and IMPCR were initially loaded with. */
-
-#ifdef HANDLER
-modformdef:
- clr r12,r12,12<20> /* clear result exponent,IMPCR complete */
- clr r10,r10,4<25> /* clear old guard,round,sticky,and addone */
- mak r5,r9,3<26> /* make grs field */
- bb0.n 4,r9,newaddone /* do not set new addone in MANTHI */
- or r10,r5,r10 /* or in new grs field */
- set r10,r10,1<25> /* set new addone */
-newaddone:
- bb1.n destsize,r12,moddefd /* branch to handle double precision */
- clr r10,r10,21<0> /* clear upper bits of old mantissa */
-moddefs:
- extu r5,r11,20<3> /* extract upper bits */
- or r10,r5,r10 /* MANTHI complete */
- bsr.n _handler /* execute user handler for inexact */
- rot r11,r11,0<3> /* MANTLO complete */
- br Ureturn
-moddefd:
- bsr.n _handler /* execute user handler for inexact */
- or r10,r5,r10 /* MANTHI complete,r5 should be set to OR */
-#endif
-
-/* Return to fpui. */
-
-Ureturn:
- ld r1,r31,0 /* load return address */
- jmp r1
-
-/*
- * FPoverflow
- */
-/* If the overflow user handler bit is not set, then the inexact bit in the */
-/* FPSR is set, and the inexact user handler bit is checked. If it is set, */
-/* then the inexact user handler is executed, else the default routine for */
-/* overflow is executed. */
-
-ASLOCAL(FPoverflow)
- st r1,r31,0 /* save return address */
- set r2,r2,1<overflow>
- set r2,r2,1<inexact>
-#ifdef HANDLER
- bb1 efovf,r12,hand /* go to user handler if bit set for overflow */
- bb0 efinx,r12,nohandler/* if userhandler for inexact not set,then */
- /* round result */
- br callhandler /* branch to user handler for inexact */
-
-/* Before the overflow user handler is executed, the exponent is modified */
-/* by subtracting 192 for single precision and 1536 for double precision. */
-
-hand:
- bb1 10,r12,doubleprec /* double precision result */
-singleprec:
- or.u r5,r0,0x0c00 /* load exponent adjust */
- br.n callhandler /* prepare to call user handler */
- subu r12,r12,r5 /* adjust single precision exponent */
-doubleprec:
- or.u r5,r0,0x6000 /* load exponent adjust */
- subu r12,r12,r5 /* adjust double precision exponent */
-callhandler:
- bsr _handler /* branch to common handler routine */
- br return
-#endif
-
-/* Determine which rounding mode to use for the default procedure. */
-
-nohandler:
- bb1 modehi,r10,signed /* mode is either round toward pos. or neg. */
- bb0 modelo,r10,OFnearest /* rounding mode is round nearest */
- br OFzero /* rounding mode is round zero */
-signed:
- bb0 modelo,r10,OFnegative /* rounding mode is round negative */
- br positive /* rounding mode is round positive */
-
-
-/* In the round toward nearest mode, positive values are rounded to */
-/* positive infinity and negative values are loaded toward negative infinity. */
-/* The value for single or double precision is loaded from a data table. */
-
-OFnearest:
- bb1.n destsize,r12,neardouble /* branch to neardouble of */
- /* double result */
- mask.u r5,r10,0x8000 /* mask off sign bit from MANTHI */
- or.u r11,r0,hi16(0x7f800000) /* load single infinity constant */
- or r11,r11,lo16(0x7f800000)
- br.n return /* return with result */
- or r11,r5,r11 /* adjust sign */
-neardouble:
- or r11,r0,r0 /* load lower word of infinity */
- or.u r10,r0,hi16(0x7ff00000) /* load upper word of infinity */
- or r10,r10,lo16(0x7ff00000)
- br.n return /* return with result */
- or r10,r5,r10 /* adjust sign */
-
-
-/* In the round toward zero mode, positive values are rounded to the largest */
-/* postive finite number and negative values are rounded toward the largest */
-/* negative finite number. */
-/* The value for single or double precision is loaded from a data table. */
-
-OFzero:
- bb1.n destsize,r12,zerodouble /* branch to zerodouble of */
- /* double result */
- mask.u r5,r10,0x8000 /* mask off sign bit from MANTHI */
- or.u r11,r0,hi16(0x7f7fffff) /* load single finite number constant */
- or r11,r11,lo16(0x7f7fffff)
- br.n return /* return with result */
- or r11,r5,r11 /* adjust sign */
-zerodouble:
- set r11,r0,0<0> /* load lower word of finite number */
- or.u r10,r0,hi16(0x7fefffff) /* load upper word of finite number */
- or r10,r10,lo16(0x7fefffff)
- br.n return /* return with result */
- or r10,r5,r10 /* adjust sign */
-
-
-/* In the round toward positve mode, positive values are rounded to */
-/* postive infinity and negative values are loaded toward the largest */
-/* negative finite number. */
-/* The value for single or double precision is loaded from a data table. */
-
-positive:
- bb1 destsize,r12,posdouble /* branch to section for double result */
-possingle:
- bb1 sign,r10,possingleneg /* branch to section for negatives */
-possinglepos:
- or.u r11,r0,hi16(0x7f800000) /* load single infinity constant */
- br.n return /* return with result */
- or r11,r11,lo16(0x7f800000)
-possingleneg:
- or.u r11,r0,hi16(0x7f7fffff) /* load single finite number constant */
- or r11,r11,lo16(0x7f7fffff)
- br.n return /* return with result */
- set r11,r11,1<sign> /* set sign for negative */
-posdouble:
- bb1 sign,r10,posdoubleneg /* branch to negative double results */
-posdoublepos:
- or r11,r0,r0 /* load lower word of double infinity */
- or.u r10,r0,hi16(0x7ff00000) /* load upper word of infinity */
- br.n return /* return with result */
- or r10,r10,lo16(0x7ff00000)
-posdoubleneg:
- set r11,r0,0<0> /* load lower word of finite number */
- or.u r10,r0,hi16(0x7fefffff) /* load upper word of finite number */
- or r10,r10,lo16(0x7fefffff)
- br.n return /* return with result */
- set r10,r10,1<sign> /* set sign for negative */
-
-
-/* In the round toward negative mode, positive values are rounded to the largest */
-/* postive finite number and negative values are rounded to negative infinity. */
-/* The value for single or double precision is loaded from a data table. */
-
-OFnegative:
- bb1 destsize,r12,negdouble /* branch to section for double result */
-negsingle:
- bb1 sign,r10,negsingleneg /* branch to section for negatives */
-negsinglepos:
- or.u r11,r0,hi16(0x7f7fffff) /* load single finite number constant */
- br.n return /* return with result */
- or r11,r11,lo16(0x7f7fffff)
-negsingleneg:
- or.u r11,r0,hi16(0x7f800000) /* load single infinity constant */
- or r11,r11,lo16(0x7f800000)
- br.n return /* return with result */
- set r11,r11,1<sign> /* set sign for negative */
-negdouble:
- bb1 sign,r10,negdoubleneg /* branch to negative double results */
-negdoublepos:
- set r11,r0,0<0> /* load lower word of finite number */
- or.u r10,r0,hi16(0x7fefffff) /* load upper word of finite number */
- br.n return /* return with result */
- or r10,r10,lo16(0x7fefffff)
-negdoubleneg:
- or r11,r0,r0 /* load lower word of double infinity */
- or.u r10,r0,hi16(0x7ff00000) /* load upper word of infinity */
- or r10,r10,lo16(0x7ff00000)
- set r10,r10,1<sign> /* set sign for negative */
-
-return:
- ld r1,r31,0 /* ld return address */
- jmp r1
-
- data
-
-
-/* If either S1 or S2 is a signalling NaN, then set the invalid operation */
-/* bit of the FPSR. If the invalid operation user handler flag is set and */
-/* then NaN is signalling, then branch to the handler routine to go to the */
-/* user handler. */
-/* If S1 is the only NaN or one of two NaN''s, then write */
-/* a quiet S1 to the result. A signalling NaN must be made quiet before */
-/* it can be written, but a signalling S2 is not modified in this routine */
-/* if S1 is a NaN. */
- text
-ASLOCAL(NaN)
- bb0.n s1nan,r12,S2sigcheck /* S1 is not a NaN */
- st r1,r31,0 /* save return address */
- bb1 sigbit,r5,S2sigcheck /* S1 is not a signaling NaN */
- set r2,r2,1<oper>
-#ifdef HANDLER
- bb0 oper,r3,S1nohandler /* branch if no user handler */
- bsr _handler /* branch to handler */
- br FPnan_return
-ASLOCAL(S1nohandler)
-#endif
- br.n S1write /* FPSR bit already set, S1 is made quiet, */
- /* and since we always write S1 if it is a */
- /* NaN, write S1 and skip rest of routine */
- set r5,r5,1<sigbit> /* make S1 a quiet NaN */
-
-ASLOCAL(S2sigcheck)
- bb0 s2nan,r12,S1write /* S2 is not a NaN */
- bb1 sigbit,r7,S1write /* S2 is not a signaling NaN */
- set r2,r2,1<oper>
-#ifdef HANDLER
- bb0 oper,r3,S2nohandler /* branch if no user handler */
- bsr _handler /* branch to handler */
- br FPnan_return
-#endif
-
-ASLOCAL(S2nohandler)
- set r7,r7,1<sigbit> /* make S2 a quiet NaN */
-
-
-/* Write a single or double precision quiet NaN unless the opeation is FCMP. */
-/* If the operation is FCMP, then set the not comparable bit in the result. */
-
-ASLOCAL(S1write)
- bb0 s1nan,r12,S2write /* do not write S1 if it is not a NaN */
- extu r10,r9,5<11> /* extract opcode */
- cmp r11,r10,FCMPop /* compare to FCMP */
- bb1 ne,r11,S1noFCMP /* operation is not FCMP */
- set r6,r0,1<nc> /* set the not comparable bit */
- br.n FPnan_return
- set r6,r6,1<ne> /* set the not equal bit */
-ASLOCAL(S1noFCMP)
- bb1.n dsize,r9,wrdoubS1 /* double destination */
- set r5,r5,11<20> /* set all exponent bits to 1 */
-/* The single result will be formed the same way whether S1 is a single or double */
-ASLOCAL(wrsingS1)
- mak r10,r5,28<3> /* wipe out extra exponent bits */
- extu r11,r6,3<29> /* get lower three bits of mantissa */
- or r10,r10,r11 /* combine all of result except sign */
- clr r6,r5,31<0> /* clear all but sign */
- br.n FPnan_return
- or r6,r6,r10 /* form result */
-
-ASLOCAL(wrdoubS1)
- set r6,r6,29<0> /* set extra bits of lower word */
- br FPnan_return /* no modification necessary for writing */
- /* double to double, so return */
-
-ASLOCAL(S2write)
- extu r10,r9,5<11> /* extract opcode */
- cmp r11,r10,FCMPop /* compare to FCMP */
- bb1.n ne,r11,S2noFCMP /* operation is not FCMP */
- set r7,r7,11<20> /* set all exponent bits to 1 */
- set r6,r0,1<nc> /* set the not comparable bit */
- br.n FPnan_return
- set r6,r6,1<ne> /* set the not equal bit */
-ASLOCAL(S2noFCMP)
- bb1.n dsize,r9,wrdoubS2 /* double destination */
- set r5,r5,11<20> /* set all exponent bits to 1 */
-/* The single result will be formed the same way whether S1 is a single or double */
-ASLOCAL(wrsingS2)
- mak r10,r7,28<3> /* wipe out extra exponent bits */
- extu r11,r8,3<29> /* get lower three bits of mantissa */
- or r10,r10,r11 /* combine all of result except sign */
- clr r6,r7,31<0> /* clear all but sign */
- br.n FPnan_return
- or r6,r6,r10 /* form result */
-
-ASLOCAL(wrdoubS2)
- set r6,r8,29<0> /* set extra bits of lower word */
-
-/* Return from this subroutine with the result. */
-
-ASLOCAL(FPnan_return)
- /* no modification necessary for writing */
- /* double to double, so return */
- ld r1,r31, 0 /* retrieve return address */
- jmp r1
-
- data
-
-/*
- * infinity
- */
-
-/* Extract the opcode, compare to a constant, and branch to the code */
-/* for the instruction. */
-
-ASLOCAL(infinity)
- extu r10,r9,5<11> /* extract opcode */
- cmp r11,r10,FADDop /* compare to FADD */
- bb1.n eq,r11,FADD /* operation is FADD */
- st r1,r31,0 /* save return address */
- cmp r11,r10,FSUBop /* compare to FSUB */
- bb1 eq,r11,FSUB /* operation is FSUB */
- cmp r11,r10,FCMPop /* compare to FCMP */
- bb1 eq,r11,FCMP /* operation is FCMP */
- cmp r11,r10,FMULop /* compare to FMUL */
- bb1 eq,r11,FMUL /* operation is FMUL */
- cmp r11,r10,FDIVop /* compare to FDIV */
- bb1 eq,r11,FDIV /* operation is FDIV */
-#if 0
- cmp r11,r10,FSQRTop /* compare to FSQRT */
- bb1 eq,r11,FSQRT /* operation is FSQRT */
-#endif
- cmp r11,r10,INTop /* compare to INT */
- bb1 eq,r11,FP_inf_overflw /* operation is INT */
- cmp r11,r10,NINTop /* compare to NINT */
- bb1 eq,r11,FP_inf_overflw /* operation is NINT */
- cmp r11,r10,TRNCop /* compare to TRNC */
- bb1 eq,r11,FP_inf_overflw /* operation is TRNC */
-
-
-/* Adding infinities of opposite signs will cause an exception, */
-/* but all other operands will result in a correctly signed infinity. */
-
-FADD:
- bb0 s1inf,r12,addS2write /* branch if S1 not infinity */
- bb0 s2inf,r12,addS1write /* S2 is not inf., so branch to write S1 */
- bb1 sign,r5,addS1neg /* handle case of S1 negative */
-addS1pos:
- bb1 sign,r7,excpt /* adding infinities of different */
- /* signs causes an exception */
- br poswrinf /* branch to write positive infinity */
-addS1neg:
- bb0 sign,r7,excpt /* adding infinities of different */
- /* signs causes an exception */
- br negwrinf /* branch to write negative infinity */
-addS1write:
- bb0 sign,r5,poswrinf /* branch to write positive infinity */
- br negwrinf /* branch to write negative infinity */
-addS2write:
- bb0 sign,r7,poswrinf /* branch to write positive infinity */
- br negwrinf /* branch to write negative infinity */
-
-
-/* Subtracting infinities of the same sign will cause an exception, */
-/* but all other operands will result in a correctly signed infinity. */
-
-FSUB:
- bb0 s1inf,r12,subS2write /* branch if S1 not infinity */
- bb0 s2inf,r12,subS1write /* S2 is not inf., so branch to write S1 */
- bb1 sign,r5,subS1neg /* handle case of S1 negative */
-subS1pos:
- bb0 sign,r7,excpt /* subtracting infinities of the same */
- /* sign causes an exception */
- br poswrinf /* branch to write positive infinity */
-subS1neg:
- bb1 sign,r7,excpt /* subtracting infinities of the same */
- /* sign causes an exception */
- br negwrinf /* branch to write negative infinity */
-subS1write:
- bb0 sign,r5,poswrinf /* branch to write positive infinity */
- br negwrinf /* branch to write negative infinity */
-subS2write:
- bb1 sign,r7,poswrinf /* branch to write positive infinity */
- br negwrinf /* branch to write negative infinity */
-
-
-/* Compare the operands, at least one of which is infinity, and set the */
-/* correct bits in the destination register. */
-
-FCMP:
- bb0.n s1inf,r12,FCMPS1f /* branch for finite S1 */
- set r4,r0,1<cp> /* since neither S1 or S2 is a NaN, */
- /* set cp */
-FCMPS1i:
- bb1 sign,r5,FCMPS1ni /* branch to negative S1i */
-FCMPS1pi:
- bb0 s2inf,r12,FCMPS1piS2f /* branch to finite S2 with S1pi */
-FCMPS1piS2i:
- bb1 sign,r7,FCMPS1piS2ni /* branch to negative S2i with S1pi */
-FCMPS1piS2pi:
- set r4,r4,1<eq> /* set eq bit */
- set r4,r4,1<le> /* set le bit */
- set r4,r4,1<ge> /* set ge bit */
- set r4,r4,1<ib> /* set ib bit */
- br.n move
- set r4,r4,1<ob> /* set ob bit */
-FCMPS1piS2ni:
- set r4,r4,1<ne> /* set ne bit */
- set r4,r4,1<gt> /* set gt bit */
- br.n move
- set r4,r4,1<ge> /* set ge bit */
-FCMPS1piS2f:
- set r4,r4,1<ne> /* set ne bit */
- set r4,r4,1<gt> /* set gt bit */
- bsr.n _ASM_LABEL(zero) /* see if any of the operands are zero */
- set r4,r4,1<ge> /* set ge bit */
- bb0 s2zero,r12,FCMPS1piS2nz /* check for negative if s2 not zero */
- set r4,r4,1<ou> /* set ou bit */
- br.n move
- set r4,r4,1<ob> /* set ob bit */
-FCMPS1piS2nz:
- bb1 sign,r7,move /* return if s2 is negative */
-FCMPS1piS2pf:
- set r4,r4,1<ou> /* set ou bit */
- br.n move
- set r4,r4,1<ob> /* set ob bit */
-FCMPS1ni:
- bb0 s2inf,r12,FCMPS1niS2f /* branch to finite S2 with S1ni */
-FCMPS1niS2i:
- bb1 sign,r7,FCMPS1niS2ni /* branch to negative S2i with S1ni */
-FCMPS1niS2pi:
- set r4,r4,1<ne> /* set eq bit */
- set r4,r4,1<le> /* set le bit */
- set r4,r4,1<lt> /* set lt bit */
- set r4,r4,1<ou> /* set ou bit */
- br.n move
- set r4,r4,1<ob> /* set ob bit */
-FCMPS1niS2ni:
- set r4,r4,1<eq> /* set eq bit */
- set r4,r4,1<le> /* set le bit */
- br.n move
- set r4,r4,1<ge> /* set ge bit */
-FCMPS1niS2f:
- set r4,r4,1<ne> /* set eq bit */
- set r4,r4,1<le> /* set le bit */
- bsr.n _ASM_LABEL(zero) /* see if any of the operands are zero */
- set r4,r4,1<lt> /* set lt bit */
- bb0 s2zero,r12,FCMPS1niS2nz /* branch if s2 is not zero */
- set r4,r4,1<ou> /* set ou bit */
- br.n move
- set r4,r4,1<ob> /* set ob bit */
-FCMPS1niS2nz:
- bb1 sign,r7,move /* return if s2 is negative */
- set r4,r4,1<ou> /* set ou bit */
- br.n move
- set r4,r4,1<ob> /* set ob bit */
-FCMPS1f:
- bb1 sign,r5,FCMPS1nf /* branch to negative S1f */
-FCMPS1pf:
- bb1.n sign,r7,FCMPS1pfS2ni /* branch to negative S2i with S1pf */
- set r4,r4,1<ne> /* set ne bit */
-FCMPS1pfS2pi:
- set r4,r4,1<le> /* set le bit */
- set r4,r4,1<lt> /* set lt bit */
- bsr.n _ASM_LABEL(zero)
- set r4,r4,1<ib> /* set ib bit */
- bb0 s1zero,r12,FCMPS1pfS2pinozero
-FCMPS1pfS2pizero:
- br.n move
- set r4,r4,1<ob> /* set ob bit */
-FCMPS1pfS2pinozero:
- br.n move
- set r4,r4,1<in> /* set in bit */
-FCMPS1pfS2ni:
- set r4,r4,1<gt> /* set gt bit */
- br.n move
- set r4,r4,1<ge> /* set ge bit */
-FCMPS1nf:
- bb1.n sign,r7,FCMPS1nfS2ni /* branch to negative S2i with S1nf */
- set r4,r4,1<ne> /* set ne bit */
- set r4,r4,1<le> /* set gt bit */
- set r4,r4,1<lt> /* set ge bit */
- bsr.n _ASM_LABEL(zero) /* see which of the operands are zero */
- set r4,r4,1<ob> /* set ob bit */
- bb0 s1zero,r12,FCMPS1nfS2pinozero /* no ls and lo */
-FCMPS1nfS2pizero:
- br.n move
- set r4,r4,1<ib> /* set ib bit */
-FCMPS1nfS2pinozero:
- br.n move
- set r4,r4,1<ou> /* set ou bit */
-FCMPS1nfS2ni:
- set r4,r4,1<gt> /* set gt bit */
- set r4,r4,1<ge> /* set ge bit */
-
-move:
- br.n inf_return
- or r6,r0,r4 /* transfer answer to r6 */
-
-
-/* Multiplying infinity and zero causes an exception, but all other */
-/* operations produce a correctly signed infinity. */
-
-FMUL:
- bsr _ASM_LABEL(zero) /* see if any of the operands are zero */
- bb1 s1zero,r12,excpt /* infinity X 0 causes an exception */
- bb1 s2zero,r12,excpt /* infinity X 0 causes an exception */
- bb1 sign,r5,FMULS1neg /* handle negative cases of S1 */
- bb0 sign,r7,poswrinf /* + X + = + */
- br negwrinf /* + X - = - */
-FMULS1neg:
- bb1 sign,r7,poswrinf /* - X - = + */
- br negwrinf /* - X + = - */
-
-
-/* Dividing infinity by infinity causes an exception, but dividing */
-/* infinity by a finite yields a correctly signed infinity, and */
-/* dividing a finite by an infinity produces a correctly signed zero. */
-
-FDIV:
- bb1 s1inf,r12,FDIVS1inf /* handle case of S1 being infinity */
- bb1 sign,r5,FDIVS1nf /* handle cases of S1 being neg. non-inf. */
- bb1 sign,r7,FDIVS1pfS2mi /* handle case of negative S2 */
-FDIVS1pfS2pi:
- br poswrzero /* +f / +inf = +0 */
-FDIVS1pfS2mi:
- br negwrzero /* +f / -inf = -0 */
-FDIVS1nf:
- bb1 sign,r7,FDIVS1nfS2mi /* handle case of negative S2 */
-FDIVS1nfS2pi:
- br negwrzero /* -f / +inf = -0 */
-FDIVS1nfS2mi:
- br poswrzero /* -f / -inf = +0 */
-FDIVS1inf:
- bb1 s2inf,r12,excpt /* inf / inf = exception */
- bb1 sign,r5,FDIVS1mi /* handle cases of S1 being neg. inf. */
- bb1 sign,r7,FDIVS1piS2nf /* handle case of negative S2 */
-FDIVS1piS2pf:
- br poswrinf /* +inf / +f = +inf */
-FDIVS1piS2nf:
- br negwrinf /* +inf / -f = -inf */
-FDIVS1mi:
- bb1 sign,r7,FDIVS1miS2nf /* handle case of negative S2 */
-FDIVS1miS2pf:
- br negwrinf /* -inf / +f = -inf */
-FDIVS1miS2nf:
- br poswrinf /* -inf / -f = +inf */
-
-
-/* The square root of positive infinity is positive infinity, */
-/* but the square root of negative infinity is a NaN */
-
-#if 0
-FSQRT:
- bb0 sign,r7,poswrinf /* write sqrt(inf) = inf */
- br excpt /* write sqrt(-inf) = NaN */
-#endif
-
-excpt:
- set r2,r2,1<oper>
-#ifdef HANDLER
- bb0 oper,r3,nohandler /* branch if no user handler */
- bsr _handler /* branch to interface with user handler */
- br inf_return
-nohandler:
-#endif
- set r5,r0,0<0> /* write NaN into r5 */
- br.n inf_return
- set r6,r0,0<0> /* write NaN into r6, writing NaN''s into */
- /* both of these registers is quicker than */
- /* checking for single or double precision */
-
-
-/* Write positive infinity of the correct precision */
-
-poswrinf:
- bb1 dsize,r9,poswrinfd /* branch to write double precision inf. */
- br.n inf_return
- or.u r6,r0,0x7f80 /* load r6 with single precision pos inf. */
-poswrinfd:
- or.u r5,r0,0x7ff0 /* load double precision pos inf. */
- br.n inf_return
- or r6,r0,r0
-
-
-/* Write negative infinity of the correct precision */
-
-negwrinf:
- bb1 dsize,r9,negwrinfd /* branch to write double precision inf. */
- br.n inf_return
- or.u r6,r0,0xff80 /* load r6 with single precision pos inf. */
-negwrinfd:
- or.u r5,r0,0xfff0 /* load double precision pos inf. */
- br.n inf_return
- or r6,r0,r0
-
-
-/* Write a positive zero disregarding precision. */
-
-poswrzero:
- or r5,r0,r0 /* write to both high word and low word now */
- br.n inf_return /* it does not matter that both are written */
- or r6,r0,r0
-
-
-/* Write a negative zero of the correct precision. */
-
-negwrzero:
- or r6,r0,r0 /* clear low word */
- bb1 dsize,r9,negwrzerod /* branch to write double precision zero */
- br.n inf_return
- set r6,r6,1<31> /* set sign bit */
-negwrzerod:
- or r5,r0,r0 /* clear high word */
- br.n inf_return
- set r5,r5,1<31> /* set sign bit */
-
-FP_inf_overflw:
- set r2,r2,1<oper>
- set r2,r2,1<overflow>
- set r2,r2,1<inexact>
-#ifdef HANDLER
- bb0 oper,r3,nohandlero /* do not go to user handler routine */
- bsr _handler /* go to user handler routine */
- br inf_return
-#endif
-
-nohandlero:
- bb0.n sign,r7,inf_return /* if positive then return */
-
- set r6,r6,31<0> /* set result to largest positive integer */
- or.c r6,r0,r6 /* negate r6,giving largest negative int. */
-
-inf_return:
- ld r1,r31,0 /* load return address */
- jmp r1
-
- data
-
-#define FADD denorm_FADD
-#define FSUB denorm_FSUB
-#define FCMP denorm_FCMP
-#define FMUL denorm_FMUL
-#define FDIV denorm_FDIV
-#define NINT denorm_NINT
-#define TRNC denorm_TRNC
-#define return denorm_return
-
-/*
- * denorm
- */
-
-/* Check to see if either S1 or S2 is a denormalized number. First */
-/* extract the exponent to see if it is zero, and then check to see if */
-/* the mantissa is not zero. If the number is denormalized, then set the */
-/* 1 or 0 bit 10 r12. */
-
-ASLOCAL(denorm)
- st r1,r31,0 /* save return address */
-dnmcheckS1:
- extu r10,r5,11<20> /* extract exponent */
- bcnd ne0,r10,dnmsetS2 /* S1 is not a denorm, so S2 must be */
- bb1.n 9,r9,dnmcheckS1d /* S1 is double precision */
- mak r10,r5,20<3> /* mak field with only mantissa bits */
- /* into final result */
-dnmcheckS1s:
- extu r11,r6,3<29> /* get three low bits of mantissa */
- or r10,r10,r11 /* assemble all of the mantissa bits */
- bcnd eq0,r10,dnmsetS2 /* S1 is not a denorm, so S2 must be */
- br dnmsetS1 /* S1 is a denorm */
-
-dnmcheckS1d:
- or r10,r6,r10 /* or all of mantissa bits */
- bcnd eq0,r10,dnmsetS2 /* S1 is not a denorm, so S2 must be */
-dnmsetS1:
- set r12,r12,1<1> /* S1 is a denorm */
-
-dnmcheckS2:
- extu r10,r7,11<20> /* extract exponent */
- bcnd ne0,r10,S1form /* S2 is not a denorm */
- bb1.n 7,r9,dnmcheckS2d /* S2 is double precision */
- mak r10,r7,20<3> /* mak field with only mantissa bits */
-dnmcheckS2s:
- extu r11,r8,3<29> /* get three low bits of mantissa */
- or r10,r10,r11 /* assemble all of the mantissa bits */
- bcnd eq0,r10,S1form /* S2 is not a denorm */
- br dnmsetS2 /* S1 is a denorm */
-dnmcheckS2d:
- or r10,r8,r10 /* or all or mantissa bits */
- bcnd eq0,r10,S1form /* S2 is not a denorm */
-dnmsetS2:
- set r12,r12,1<0> /* S2 is a denorm */
-
-
-/* Since the operations are going to be reperformed with modified denorms, */
-/* the operands which were initially single precision need to be modified */
-/* back to single precision. */
-
-S1form:
- bb1 9,r9,S2form /* S1 is double precision, so do not */
- /* modify S1 into single format */
- mak r11,r5,28<3> /* over final exponent and mantissa */
- /* eliminating extra 3 bits of exponent */
- extu r6,r6,3<29> /* get low 3 bits of mantissa */
- or r11,r6,r11 /* form complete mantissa and exponent */
- extu r10,r5,1<31> /* get the 31 bit */
- mak r10,r10,1<31> /* place 31 bit 10 correct position */
- or r6,r10,r11 /* or 31, exponent, and all of mantissa */
-
-S2form:
- bb1 7,r9,checkop /* S2 is double precision, so do not */
- /* modify S2 into single format */
- mak r11,r7,28<3> /* over final exponent and mantissa */
- /* eliminating extra 3 bits of exponent */
- extu r8,r8,3<29> /* get low 3 bits of mantissa */
- or r11,r8,r11 /* form complete mantissa and exponent */
- extu r10,r7,1<31> /* get the 31 bit */
- mak r10,r10,1<31> /* place 31 bit 10 correct position */
- or r8,r10,r11 /* or 31, exponent, and all of mantissa */
-
-
-/* Extract the opcode, compare to a constant, and branch to the code that */
-/* deals with that opcode. */
-
-checkop:
- extu r10,r9,5<11> /* extract opcode */
- cmp r11,r10,0x05 /* compare to FADD */
- bb1 2,r11,FADD /* operation is FADD */
- cmp r11,r10,0x06 /* compare to FSUB */
- bb1 2,r11,FSUB /* operation is FSUB */
- cmp r11,r10,0x07 /* compare to FCMP */
- bb1 2,r11,FCMP /* operation is FCMP */
- cmp r11,r10,0x00 /* compare to FMUL */
- bb1 2,r11,FMUL /* operation is FMUL */
- cmp r11,r10,0x0e /* compare to FDIV */
- bb1 2,r11,FDIV /* operation is FDIV */
-#if 0
- cmp r11,r10,0x0f /* compare to FSQRT */
- bb1 2,r11,FSQRT /* operation is FSQRT */
-#endif
- cmp r11,r10,0x09 /* compare to INT */
- bb1 2,r11,INT /* operation is INT */
- cmp r11,r10,0x0a /* compare to NINT */
- bb1 2,r11,NINT /* operation is NINT */
- cmp r11,r10,0x0b /* compare to TRNC */
- bb1 2,r11,TRNC /* operation is TRNC */
-
-
-/* For all the following operations, the denormalized number is set to */
-/* zero and the operation is reperformed the correct destination and source */
-/* sizes. */
-
-FADD:
- bb0 1,r12,FADDS2dnm /* S1 is not denorm, so S2 must be */
- or r5,r0,r0 /* set S1 to zero */
- or r6,r0,r0
-FADDS2chk:
- bb0 0,r12,FADDcalc /* S2 is not a denorm */
-FADDS2dnm:
- or r7,r0,r0 /* set S2 to zero */
- or r8,r0,r0
-FADDcalc:
- bb1 5,r9,FADDdD /* branch for double precision destination */
-FADDsD:
- bb1 9,r9,FADDsDdS1 /* branch for double precision S1 */
-FADDsDsS1:
- bb1 7,r9,FADDsDsS1dS2 /* branch for double precision S2 */
-FADDsDsS1sS2:
- br.n return
- fadd.sss r6,r6,r8 /* add the two sources and place result 10 S1 */
-FADDsDsS1dS2:
- br.n return
- fadd.ssd r6,r6,r7 /* add the two sources and place result 10 S1 */
-FADDsDdS1:
- bb1 7,r9,FADDsDdS1dS2 /* branch for double precision S2 */
-FADDsDdS1sS2:
- br.n return
- fadd.sds r6,r5,r8 /* add the two sources and place result 10 S1 */
-FADDsDdS1dS2:
- br.n return
- fadd.sdd r6,r5,r7 /* add the two sources and place result 10 S1 */
-FADDdD:
- bb1 9,r9,FADDdDdS1 /* branch for double precision S1 */
-FADDdDsS1:
- bb1 7,r9,FADDdDsS1dS2 /* branch for double precision S2 */
-FADDdDsS1sS2:
- br.n return
- fadd.dss r5,r6,r8 /* add the two sources and place result 10 S1 */
-FADDdDsS1dS2:
- br.n return
- fadd.dsd r5,r6,r7 /* add the two sources and place result 10 S1 */
-FADDdDdS1:
- bb1 7,r9,FADDdDdS1dS2 /* branch for double precision S2 */
-FADDdDdS1sS2:
- br.n return
- fadd.dds r5,r5,r8 /* add the two sources and place result 10 S1 */
-FADDdDdS1dS2:
- br.n return
- fadd.ddd r5,r5,r7 /* add the two sources and place result 10 S1 */
-
-FSUB:
- bb0 1,r12,FSUBS2dnm /* S1 is not denorm, so S2 must be */
- or r5,r0,r0 /* set S1 to zero */
- or r6,r0,r0
-FSUBS2chk:
- bb0 0,r12,FSUBcalc /* S2 is not a denorm */
-FSUBS2dnm:
- or r7,r0,r0 /* set S2 to zero */
- or r8,r0,r0
-FSUBcalc:
- bb1 5,r9,FSUBdD /* branch for double precision destination */
-FSUBsD:
- bb1 9,r9,FSUBsDdS1 /* branch for double precision S1 */
-FSUBsDsS1:
- bb1 7,r9,FSUBsDsS1dS2 /* branch for double precision S2 */
-FSUBsDsS1sS2:
- br.n return
- fsub.sss r6,r6,r8 /* add the two sources and place result 10 S1 */
-FSUBsDsS1dS2:
- br.n return
- fsub.ssd r6,r6,r7 /* add the two sources and place result 10 S1 */
-FSUBsDdS1:
- bb1 7,r9,FSUBsDdS1dS2 /* branch for double precision S2 */
-FSUBsDdS1sS2:
- br.n return
- fsub.sds r6,r5,r8 /* add the two sources and place result 10 S1 */
-FSUBsDdS1dS2:
- br.n return
- fsub.sdd r6,r5,r7 /* add the two sources and place result 10 S1 */
-FSUBdD:
- bb1 9,r9,FSUBdDdS1 /* branch for double precision S1 */
-FSUBdDsS1:
- bb1 7,r9,FSUBdDsS1dS2 /* branch for double precision S2 */
-FSUBdDsS1sS2:
- br.n return
- fsub.dss r5,r6,r8 /* add the two sources and place result 10 S1 */
-FSUBdDsS1dS2:
- br.n return
- fsub.dsd r5,r6,r7 /* add the two sources and place result 10 S1 */
-FSUBdDdS1:
- bb1 7,r9,FSUBdDdS1dS2 /* branch for double precision S2 */
-FSUBdDdS1sS2:
- br.n return
- fsub.dds r5,r5,r8 /* add the two sources and place result 10 S1 */
-FSUBdDdS1dS2:
- br.n return
- fsub.ddd r5,r5,r7 /* add the two sources and place result 10 S1 */
-
-FCMP:
- bb0 1,r12,FCMPS2dnm /* S1 is not denorm, so S2 must be */
- or r5,r0,r0 /* set S1 to zero */
- or r6,r0,r0
-FCMPS2chk:
- bb0 0,r12,FCMPcalc /* S2 is not a denorm */
-FCMPS2dnm:
- or r7,r0,r0 /* set S2 to zero */
- or r8,r0,r0
-FCMPcalc:
- bb1 9,r9,FCMPdS1 /* branch for double precision S1 */
-FCMPsS1:
- bb1 7,r9,FCMPsS1dS2 /* branch for double precision S2 */
-FCMPsS1sS2:
- br.n return
- fcmp.sss r6,r6,r8 /* add the two sources and place result 10 S1 */
-FCMPsS1dS2:
- br.n return
- fcmp.ssd r6,r6,r7 /* add the two sources and place result 10 S1 */
-FCMPdS1:
- bb1 7,r9,FCMPdS1dS2 /* branch for double precision S2 */
-FCMPdS1sS2:
- br.n return
- fcmp.sds r6,r5,r8 /* add the two sources and place result 10 S1 */
-FCMPdS1dS2:
- br.n return
- fcmp.sdd r6,r5,r7 /* add the two sources and place result 10 S1 */
-
-FMUL:
- bb0 1,r12,FMULS2dnm /* S1 is not denorm, so S2 must be */
- or r5,r0,r0 /* set S1 to zero */
- or r6,r0,r0
-FMULS2chk:
- bb0 0,r12,FMULcalc /* S2 is not a denorm */
-FMULS2dnm:
- or r7,r0,r0 /* set S2 to zero */
- or r8,r0,r0
-FMULcalc:
- bb1 5,r9,FMULdD /* branch for double precision destination */
-FMULsD:
- bb1 9,r9,FMULsDdS1 /* branch for double precision S1 */
-FMULsDsS1:
- bb1 7,r9,FMULsDsS1dS2 /* branch for double precision S2 */
-FMULsDsS1sS2:
- br.n return
- fmul.sss r6,r6,r8 /* add the two sources and place result 10 S1 */
-FMULsDsS1dS2:
- br.n return
- fmul.ssd r6,r6,r7 /* add the two sources and place result 10 S1 */
-FMULsDdS1:
- bb1 7,r9,FMULsDdS1dS2 /* branch for double precision S2 */
-FMULsDdS1sS2:
- br.n return
- fmul.sds r6,r5,r8 /* add the two sources and place result 10 S1 */
-FMULsDdS1dS2:
- br.n return
- fmul.sdd r6,r5,r7 /* add the two sources and place result 10 S1 */
-FMULdD:
- bb1 9,r9,FMULdDdS1 /* branch for double precision S1 */
-FMULdDsS1:
- bb1 7,r9,FMULdDsS1dS2 /* branch for double precision S2 */
-FMULdDsS1sS2:
- br.n return
- fmul.dss r5,r6,r8 /* add the two sources and place result 10 S1 */
-FMULdDsS1dS2:
- br.n return
- fmul.dsd r5,r6,r7 /* add the two sources and place result 10 S1 */
-FMULdDdS1:
- bb1 7,r9,FMULdDdS1dS2 /* branch for double precision S2 */
-FMULdDdS1sS2:
- br.n return
- fmul.dds r5,r5,r8 /* add the two sources and place result 10 S1 */
-FMULdDdS1dS2:
- br.n return
- fmul.ddd r5,r5,r7 /* add the two sources and place result 10 S1 */
-
-FDIV:
- bb0 1,r12,FDIVS2dnm /* S1 is not denorm, so S2 must be */
- or r5,r0,r0 /* set S1 to zero */
- or r6,r0,r0
-FDIVS2chk:
- bb0 0,r12,FDIVcalc /* S2 is not a denorm */
-FDIVS2dnm:
- or r7,r0,r0 /* set S2 to zero */
- or r8,r0,r0
-FDIVcalc:
- bb1 5,r9,FDIVdD /* branch for double precision destination */
-FDIVsD:
- bb1 9,r9,FDIVsDdS1 /* branch for double precision S1 */
-FDIVsDsS1:
- bb1 7,r9,FDIVsDsS1dS2 /* branch for double precision S2 */
-FDIVsDsS1sS2:
- fdiv.sss r6,r6,r8 /* add the two sources and place result 10 S1 */
- br return
-FDIVsDsS1dS2:
- fdiv.ssd r6,r6,r7 /* add the two sources and place result 10 S1 */
- br return
-FDIVsDdS1:
- bb1 7,r9,FDIVsDdS1dS2 /* branch for double precision S2 */
-FDIVsDdS1sS2:
- fdiv.sds r6,r5,r8 /* add the two sources and place result 10 S1 */
- br return
-FDIVsDdS1dS2:
- fdiv.sdd r6,r5,r7 /* add the two sources and place result 10 S1 */
- br return
-FDIVdD:
- bb1 9,r9,FDIVdDdS1 /* branch for double precision S1 */
-FDIVdDsS1:
- bb1 7,r9,FDIVdDsS1dS2 /* branch for double precision S2 */
-FDIVdDsS1sS2:
- fdiv.dss r5,r6,r8 /* add the two sources and place result 10 S1 */
- br return
-FDIVdDsS1dS2:
- fdiv.dsd r5,r6,r7 /* add the two sources and place result 10 S1 */
- br return
-FDIVdDdS1:
- bb1 7,r9,FDIVdDdS1dS2 /* branch for double precision S2 */
-FDIVdDdS1sS2:
- fdiv.dds r5,r5,r8 /* add the two sources and place result 10 S1 */
- br return
-FDIVdDdS1dS2:
- fdiv.ddd r5,r5,r7 /* add the two sources and place result 10 S1 */
- br return
-
-#if 0
-FSQRT:
- or r7,r0,r0 /* set S2 to zero */
- or r8,r0,r0
-FSQRTcalc:
- bb1 5,r9,FSQRTdD /* branch for double precision destination */
-FSQRTsD:
- bb1 7,r9,FSQRTsDdS2 /* branch for double precision S2 */
-FSQRTsDsS2:
- br.n return
- fsqrt.ss r6,r8 /* add the two sources and place result 10 S1 */
-FSQRTsDdS2:
- br.n return
- fsqrt.sd r6,r7 /* add the two sources and place result 10 S1 */
-FSQRTdD:
- bb1 7,r9,FSQRTdDdS2 /* branch for double precision S2 */
-FSQRTdDsS2:
- br.n return
- fsqrt.ds r5,r8 /* add the two sources and place result 10 S1 */
-FSQRTdDdS2:
- br.n return
- fsqrt.dd r5,r7 /* add the two sources and place result 10 S1 */
-#endif
-
-INT:
- or r7,r0,r0 /* set S2 to zero */
- or r8,r0,r0
-INTcalc:
- bb1 7,r9,INTdS2 /* branch for double precision S2 */
-INTsS2:
- br.n return
- int.ss r6,r8 /* add the two sources and place result 10 S1 */
-INTdS2:
- br.n return
- int.sd r6,r7 /* add the two sources and place result 10 S1 */
-
-NINT:
- or r7,r0,r0 /* set S2 to zero */
- or r8,r0,r0
-NINTcalc:
- bb1 7,r9,NINTdS2 /* branch for double precision S2 */
-NINTsS2:
- br.n return
- nint.ss r6,r8 /* add the two sources and place result 10 S1 */
-NINTdS2:
- br.n return
- nint.sd r6,r7 /* add the two sources and place result 10 S1 */
-
-TRNC:
- or r7,r0,r0 /* set S2 to zero */
- or r8,r0,r0
-TRNCcalc:
- bb1 7,r9,TRNCdS2 /* branch for double precision S2 */
-TRNCsS2:
- br.n return
- trnc.ss r6,r8 /* add the two sources and place result 10 S1 */
-TRNCdS2:
- trnc.sd r6,r7 /* add the two sources and place result 10 S1 */
-
-
-/* Return to the routine that detected the reserved operand. */
-
-return:
- ld r1,r31,0 /* load return address */
- jmp r1
-
- data
-
-
-/* S1 and/or S2 is an infinity, and the other operand may be a zero. */
-/* Knowing which operands are infinity, check the remaining operands for zeros. */
-
-ASLOCAL(zero)
- bb0 s1inf,r12,S1noinf /* see if S1 is zero */
- bb0 s2inf,r12,S2noinf /* see if S2 is zero */
- jmp r1
-
-/* See if S1 is zero. Whether or not S1 is a zero, being in this routine */
-/* implies that S2 is infinity, so return to subroutine infinity after */
-/* completing this code. Set the s1zero flag in r12 if S1 is zero. */
-
-S1noinf:
- bb1 s1size,r9,S1noinfd /* work with double precision operand */
-S1noinfs:
- or r10,r0,r5 /* load high word into r10 */
- clr r10,r10,1<sign> /* clear the sign bit */
- extu r11,r6,3<29> /* extract lower 3 bits of mantissa */
- or r10,r10,r11 /* or these 3 bits with high word */
- bcnd ne0,r10,operation /* do not set zero flag */
- jmp.n r1 /* since this operand was not */
- /* infinity, S2 must have been, */
- /* so return */
- set r12,r12,1<s1zero> /* set zeroflag */
-S1noinfd:
- clr r10,r5,1<sign> /* clear the sign bit */
- or r10,r6,r10 /* or high and low word */
- bcnd ne0,r10,operation /* do not set zero flag */
- jmp.n r1 /* since this operand was not */
- /* infinity, S2 must have been, */
- /* so return */
- set r12,r12,1<s1zero> /* set zeroflag */
-
-
-/* Check S2 for zero. If it is zero, then set the s2zero flag in r12. */
-
-S2noinf:
- bb1 s2size,r9,S2noinfd /* work with double precision operand */
-S2noinfs:
- or r10,r0,r7 /* load high word into r10 */
- clr r10,r10,1<sign> /* clear the sign bit */
- extu r11,r8,3<29> /* extract lower 3 bits of mantissa */
- or r10,r10,r11 /* or these 3 bits with high word */
- bcnd ne0,r10,operation /* do not set zero flag */
- jmp.n r1 /* since this operand was not */
- /* infinity, S1 must have been, */
- /* so return */
- set r12,r12,1<s2zero> /* set zeroflag */
-S2noinfd:
- clr r10,r7,1<sign> /* clear the sign bit */
- or r10,r8,r10 /* or high and low word */
- bcnd ne0,r10,operation /* do not set zero flag */
- set r12,r12,1<s2zero> /* set zeroflag */
- /* since this operand was not */
- /* infinity, S1 must have been, */
- /* so return */
-operation:
- jmp r1
-
-ASENTRY(Xfp_imprecise)
-/* input: r3 is the exception frame */
- or r29, r3, r0 /* r29 is now the E.F. */
- subu r31, r31, 40
- st r1, r31, 32
- st r29, r31, 36
-
- ld r2 , r29, EF_FPSR * 4
- ld r3 , r29, EF_FPCR * 4
- ld r4 , r29, EF_FPECR * 4
- ld r10, r29, EF_FPRH * 4
- ld r11, r29, EF_FPRL * 4
- ld r12, r29, EF_FPIT * 4
-
-/* Load into r1 the return address for the exception handlers. Looking */
-/* at FPECR, branch to the appropriate exception handler. */
-
- or.u r1,r0,hi16(fpui_wrapup)/* load return address of functions */
- or r1,r1,lo16(fpui_wrapup)
-
- bb0 2,r4,2f /* branch to FPunderflow if bit set */
- br _ASM_LABEL(FPunderflow)
-2:
- bb0 1,r4,3f /* branch to FPoverflow if bit set */
- br _ASM_LABEL(FPoverflow)
-3:
- /* XXX handle inexact!!! */
-#ifdef HANDLER
- br _handler /* branch to handler since bit will */
- /* be set for inexact */
-#endif
-
-fpui_wrapup:
- tb1 0,r0,0 /* make sure all floating point operations */
- /* have finished */
- ldcr r4, cr1 /* load the PSR */
-#if 0
- set r4, r4, 1<PSR_FPU_DISABLE_BIT>
-#endif
- set r4, r4, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r4, cr1
- ld r1, r31, 32
- ld r29,r31, 36
- addu r31, r31, 40
-
- fstcr r2, FPSR /* write revised value of FPSR */
- fstcr r3, FPCR /* write revised value of FPCR */
-
- /* write back the results */
- extu r2, r12, 5<0>
- addu r3, r29, EF_R0*4
- bb0 destsize, r12, Iwritesingle
- st r10, r3 [r2]
- addu r2, r2, 1
- clr r2, r2, 27<5>
-Iwritesingle:
- st r11, r3 [r2]
- jmp r1
diff --git a/sys/arch/luna88k/luna88k/process.S b/sys/arch/luna88k/luna88k/process.S
deleted file mode 100644
index 5ffa2bf65e1..00000000000
--- a/sys/arch/luna88k/luna88k/process.S
+++ /dev/null
@@ -1,332 +0,0 @@
-/* $OpenBSD: process.S,v 1.1 2004/04/21 15:24:13 aoyama Exp $ */
-/*
- * Copyright (c) 1996 Nivas Madhur
- * All rights reserved.
- *
- * 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 reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Nivas Madhur.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
- *
- */
-
-#include "assym.h"
-#include <machine/asm.h>
-#include <machine/psl.h>
-#include <machine/intr.h>
-
- data
- align 4
-ASLOCAL(swchanpanic)
- string "switch wchan %x\0"
- align 4
-ASLOCAL(swsrunpanic)
- string "switch SRUN %x\0"
-#ifdef DEBUG
- align 4
-ASLOCAL(boguspsr)
- string "Invalid PSR in idle loop 0x%x\n\0"
-#endif
-
- text
- align 8
-ASLOCAL(Lswchanpanic)
- or.u r2, r0, hi16(_ASM_LABEL(swchanpanic))
- or r2, r2, lo16(_ASM_LABEL(swchanpanic))
- bsr.n _C_LABEL(panic)
- or r3, r0, r9
-
-ASLOCAL(Lswsrunpanic)
- or.u r2, r0, hi16(_ASM_LABEL(swsrunpanic))
- or r2, r2, lo16(_ASM_LABEL(swsrunpanic))
- bsr.n _C_LABEL(panic)
- or r3, r0, r9
-
-/*
- * At exit of a process, do a cpu_switch for the last time.
- * The mapping of the pcb at p->p_addr has already been deleted,
- * and the memory for the pcb+stack has been freed.
- * The ipl is high enough to prevent the memory from being reallocated.
- * switch_exit(proc * p)
- */
-
-ENTRY(switch_exit)
- /*
- * Change pcb to idle u. area, i.e., set r31 to top of stack
- * and set curpcb to point to _idle_u. r2 contains proc *p.
- */
- or.u r30, r0, hi16(_C_LABEL(idle_u))
- or r30, r30,lo16(_C_LABEL(idle_u))
- addu r31, r30, USIZE /* now on idle_u stack */
- or.u r10, r0, hi16(_C_LABEL(curpcb))
- st r30, r10,lo16(_C_LABEL(curpcb)) /* curpcb = &idle_u */
- or.u r10, r0, hi16(_C_LABEL(curproc))
- st r0, r10, lo16(_C_LABEL(curproc)) /* curproc = NULL */
-
- /* Schedule the vmspace and stack to be freed. */
- bsr.n _C_LABEL(exit2)
- subu r31, r31, 48 /* allocate stack */
- addu r31, r31, 48 /* restore stack */
- bsr _C_LABEL(cpu_switch) /* goto final switch */
-
-/*
- * cpu_switch()
- * XXX - Arg 1 is a proc pointer (curproc) but this doesn't use it.
- * XXX - how about using stack for saving spl and last proc?
- * XXX rewrite this whole mess in C nivas
- */
-ENTRY(cpu_switch)
-
- /*
- * Save state of previous process in its pcb.
- */
- or.u r2, r0, hi16(_C_LABEL(curpcb))
- ld r2, r2, lo16(_C_LABEL(curpcb))
- st r1, r2, PCB_PC /* save return address */
- bsr _ASM_LABEL(__savectx)
- /* note that we don't need to recover r1 at this point */
-
- or.u r11, r0, hi16(_C_LABEL(curproc))
- ld r2, r11, lo16(_C_LABEL(curproc))
- bcnd eq0, r2, 1f
-
- bsr.n _C_LABEL(pmap_deactivate)
- subu r31, r31,48
- addu r31, r31,48
- or.u r11, r0, hi16(_C_LABEL(curproc))
-
-1:
- st r0, r11, lo16(_C_LABEL(curproc)) /* curproc = NULL */
-
-ASLOCAL(Lidleloop)
-
- /*
- * Find the highest-priority queue that isn't empty,
- * then take the first proc from that queue.
- */
-
- or.u r7, r0, hi16(_C_LABEL(whichqs))
- ld r7, r7, lo16(_C_LABEL(whichqs))
-
- bcnd ne0, r7, _ASM_LABEL(Ldoneloop)
-
-ASLOCAL(Lloopchk) /* if whichqs is zero, keep checking */
- bsr.n _C_LABEL(setipl) /* unmask all ints... */
- or r2, r0, IPL_NONE
-
- ldcr r2, PSR
- bb0 PSR_INTERRUPT_DISABLE_BIT, r2, 1f
-#ifdef DEBUG
- or r3, r2, r0
- or.u r2, r0, hi16(_ASM_LABEL(boguspsr))
- bsr.n _C_LABEL(printf)
- or r2, r2, lo16(_ASM_LABEL(boguspsr))
- ldcr r2, PSR
-#endif
- clr r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT> /* ...and enable them */
- stcr r2, PSR
- FLUSH_PIPELINE
-1:
- br _ASM_LABEL(Lidleloop)
-
-ASLOCAL(Ldoneloop)
-
- bsr.n _C_LABEL(setipl) /* disable ints */
- or r2, r0, IPL_HIGH
-
- or.u r7, r0, hi16(_C_LABEL(whichqs)) /* reload whichqs */
- ld r7, r7, lo16(_C_LABEL(whichqs))
-
- bcnd eq0, r7, _ASM_LABEL(Lloopchk) /* keep spinning for whichqs to be != 0 */
-
- xor r6, r6, r6 /* set r6 to 0 */
-1: bb1 0, r7, 2f /* if rightmost bit set, done */
- extu r7, r7, 0<1> /* else, right shift whichqs, */
- br.n 1b /* increment r6, and repeat */
- addu r6, r6, 1
-2:
- or.u r7, r0, hi16(_qs)
- or r7, r7, lo16(_qs)
-
- /*
- * Need to make
- * p->p_forw->p_back = p->p_back and
- * p->p_back->p_forw = p->p_forw where
- * p is q->p_forw.
- * Remember that q->p_forw == p and p->p_back == q.
- */
-
- lda.d r8, r7[r6] /* r8 = &qs[ff1(whichqs)] */
- ld r9, r8, P_FORW /* r8 is q, r9 is p */
-
- ld r12, r9, P_FORW /* r12 = p->p_forw */
- st r8, r12, P_BACK /* p->p_forw->p_back = q (p->p_back) */
- st r12, r8, P_FORW /* q->p_forw = p->p_forw */
- lda.d r8, r7[r6] /* reload r8 with qs[ff1(whichqs)] */
- ld r12, r8, P_FORW /* q->p_forw */
- cmp r12, r12, r8 /* q == q->p_forw; anyone left on queue? */
- bb1 ne, r12, 3f /* yes, skip clearing bit in whichqs */
-
- or r12, r0, 1 /* r12 is 1 now */
-1: bcnd eq0, r6, 2f
- mak r12, r12, 0<1> /* shift left by 1 */
- br.n 1b
- subu r6, r6, 1 /* keep doing this while r6 != 0 */
-2:
- /*
- * NOTE: we could have just used "mak r12, r12, r6" instead of the
- * loop above. But that will break if NQS is made > 32. I can use
- * preprocessor to do the right thing, but that means I have to
- * include sys/proc.h in this file. XXX nivas
- */
- or.u r7, r0, hi16(_C_LABEL(whichqs))
- ld r8, r7, lo16(_C_LABEL(whichqs))
- and.c r8, r8, r12 /* whichqs &= ~the bit */
- st r8, r7, lo16(_C_LABEL(whichqs))
-3:
- ld r2, r9, P_WCHAN
- bcnd ne0, r2, _ASM_LABEL(Lswchanpanic)
- ld.b r2, r9, P_STAT
- cmp r2, r2, SRUN
- bb1 ne, r2, _ASM_LABEL(Lswsrunpanic)
-
- or.u r11, r0, hi16(_C_LABEL(want_resched))
- st r0, r11, lo16(_C_LABEL(want_resched)) /* clear want_resched */
-
- or.u r11, r0, hi16(_C_LABEL(curproc))
- st r9, r11,lo16(_C_LABEL(curproc)) /* curproc = p */
-
- /* r9 is curproc */
- st r0, r9, P_BACK /* p->p_back = 0 */
- ld r3, r9, P_ADDR
- or.u r10, r0, hi16(_C_LABEL(curpcb))
- st r3, r10, lo16(_C_LABEL(curpcb)) /* curpcb = p->p_addr */
-
- /* pmap_activate() the process' pmap */
- or r2, r0, r9 /* r2 = p */
- or r14, r0, r9 /* save p in r14 */
- bsr.n _C_LABEL(pmap_activate)
- subu r31, r31,48
- addu r31, r31,48
- or r9, r0, r14 /* restore p saved in r14 */
-
- or.u r31, r0, hi16(_ASM_LABEL(intstack_end))
- or r31,r31, lo16(_ASM_LABEL(intstack_end))
- subu r31, r31,48
- bsr.n _C_LABEL(load_u_area)
- or r2, r0, r9
- addu r31, r31,48
-
- or.u r10, r0, hi16(_C_LABEL(curpcb))
- ld r10, r10, lo16(_C_LABEL(curpcb))
- /* XXX Is this correct/necessary? */
- st r10, r14, P_ADDR /* p->p_addr = curpcb; restore p_addr */
-
- /* restore from the current context */
- ld r2, r10, PCB_FCR62
- ld r3, r10, PCB_FCR63
- fstcr r2, fcr62
- fstcr r3, fcr63
- ld r1, r10, PCB_PC
- ld r14,r10, PCB_R14
- ld r15,r10, PCB_R15
- ld r16,r10, PCB_R16
- ld r17,r10, PCB_R17
- ld r18,r10, PCB_R18
- ld r19,r10, PCB_R19
- ld r20,r10, PCB_R20
- ld r21,r10, PCB_R21
- ld r22,r10, PCB_R22
- ld r23,r10, PCB_R23
- ld r24,r10, PCB_R24
- ld r25,r10, PCB_R25
- ld r26,r10, PCB_R26
- ld r27,r10, PCB_R27
- ld r28,r10, PCB_R28
- ld r29,r10, PCB_R29
- ld r30,r10, PCB_R30 /* restore frame pointer & stack */
- ld r31,r10, PCB_SP
-
-/* XXX
- * Should we postpone restoring stack till after ipl is restored?
- * The stack access could fault
- */
- subu r31,r31,48
- st r1, r31,36 /* save r1 on stack */
- bsr.n _C_LABEL(setipl)
- ld r2, r10, PCB_IPL /* restore interrupt mask */
- ld r1, r31,36 /* restore r1 from stack */
- addu r31,r31,48
- jmp.n r1
- or r2, r0, 1 /* return 1 (for alternate returns) */
-
-/*
- * savectx(pcb)
- * Update pcb, saving current processor state.
- */
-ENTRY(savectx)
- /*
- * Save preserved general register set.
- */
- st r1, r2, PCB_PC /* save return address */
-ASENTRY(__savectx)
- st r14, r2, PCB_R14
- st r15, r2, PCB_R15
- st r16, r2, PCB_R16
- st r17, r2, PCB_R17
- st r18, r2, PCB_R18
- st r19, r2, PCB_R19
- st r20, r2, PCB_R20
- st r21, r2, PCB_R21
- st r22, r2, PCB_R22
- st r23, r2, PCB_R23
- st r24, r2, PCB_R24
- st r25, r2, PCB_R25
- st r26, r2, PCB_R26
- st r27, r2, PCB_R27
- st r28, r2, PCB_R28
- st r29, r2, PCB_R29
- st r30, r2, PCB_R30 /* save frame pointer & stack pointer */
- st r31, r2, PCB_SP
-
- /*
- * Get the current spl.
- * We need to save r1 on the stack because we don't know if we were
- * called as savectx or __savectx.
- */
- subu r31, r31, 40 /* allocate stack for r1 and args */
- st r1, r31, 32
- bsr.n _C_LABEL(getipl) /* get the current interrupt mask */
- or r14, r0, r2
- st r2, r14, PCB_IPL /* save interrupt mask */
- ld r1, r31, 32 /* recover return address */
- addu r31, r31, 40 /* put stack pointer back */
-
- /*
- * Save FP state.
- */
- fldcr r2, fcr62
- fldcr r3, fcr63
- st r2, r14, PCB_FCR62
- jmp.n r1
- st r3, r14, PCB_FCR63
diff --git a/sys/arch/luna88k/luna88k/process_machdep.c b/sys/arch/luna88k/luna88k/process_machdep.c
deleted file mode 100644
index 27bf49b45ed..00000000000
--- a/sys/arch/luna88k/luna88k/process_machdep.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/* $OpenBSD: process_machdep.c,v 1.1 2004/04/21 15:24:14 aoyama Exp $ */
-
-/*
- * Copyright (c) 1993 The Regents of the University of California.
- * Copyright (c) 1993 Jan-Simon Pendry
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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 reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
- *
- * from: Id: procfs_i386.c,v 4.1 1993/12/17 10:47:45 jsp Rel
- */
-
-/*
- * This file may seem a bit stylized, but that so that it's easier to port.
- * Functions to be implemented here are:
- *
- * process_read_regs(proc, regs)
- * Get the current user-visible register set from the process
- * and copy it into the regs structure (<machine/reg.h>).
- * The process is stopped at the time read_regs is called.
- *
- * process_write_regs(proc, regs)
- * Update the current register set from the passed in regs
- * structure. Take care to avoid clobbering special CPU
- * registers or privileged bits in the PSL.
- * The process is stopped at the time write_regs is called.
- *
- * process_sstep(proc)
- * Arrange for the process to trap after executing a single instruction.
- *
- * process_set_pc(proc)
- * Set the process's program counter.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/vnode.h>
-#include <machine/psl.h>
-#include <machine/reg.h>
-#include <machine/trap.h>
-#if 0
-#include <machine/frame.h>
-#endif
-#include <sys/ptrace.h>
-
-int
-process_read_regs(p, regs)
- struct proc *p;
- struct reg *regs;
-{
- bcopy((caddr_t)USER_REGS(p), (caddr_t)regs, sizeof(struct reg));
- return (0);
-}
-
-int
-process_read_fpregs(p, regs)
- struct proc *p;
- struct fpreg *regs;
-{
-#if 0
- extern struct fpstate initfpstate;
- struct fpstate *statep = &initfpstate;
-
- /* NOTE: struct fpreg == struct fpstate */
- if (p->p_md.md_fpstate)
- statep = p->p_md.md_fpstate;
- bcopy(statep, regs, sizeof(struct fpreg));
-#endif
- return 0;
-}
-
-#ifdef PTRACE
-
-int
-process_write_regs(p, regs)
- struct proc *p;
- struct reg *regs;
-{
- bcopy((caddr_t)regs, (caddr_t)USER_REGS(p), sizeof(struct reg));
- return (0);
-}
-
-int
-process_sstep(p, sstep)
- struct proc *p;
- int sstep;
-{
- if (sstep)
- cpu_singlestep(p);
- return (0);
-}
-
-int
-process_set_pc(p, addr)
- struct proc *p;
- caddr_t addr;
-{
- struct reg *regs;
-
- regs = USER_REGS(p);
- regs->sxip = (u_int)addr;
- regs->snip = (u_int)addr + 4;
- return (0);
-}
-
-int
-process_write_fpregs(p, regs)
- struct proc *p;
- struct fpreg *regs;
-{
-#if 0
- if (p->p_md.md_fpstate == NULL)
- return EINVAL;
-
- bcopy(regs, p->p_md.md_fpstate, sizeof(struct fpreg));
-#endif
- return 0;
-}
-
-#endif /* PTRACE */
diff --git a/sys/arch/luna88k/luna88k/vectors_88100.S b/sys/arch/luna88k/luna88k/vectors_88100.S
deleted file mode 100644
index e9e5a66734e..00000000000
--- a/sys/arch/luna88k/luna88k/vectors_88100.S
+++ /dev/null
@@ -1,89 +0,0 @@
-/* $OpenBSD: vectors_88100.S,v 1.1 2004/04/21 15:24:14 aoyama Exp $ */
-/*
- * Mach Operating System
- * Copyright (c) 1991, 1992 Carnegie Mellon University
- * Copyright (c) 1991 OMRON Corporation
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-#include <machine/asm.h>
-
-#define UNDEFINED16 \
- word UNKNOWN_HANDLER; word UNKNOWN_HANDLER; \
- word UNKNOWN_HANDLER; word UNKNOWN_HANDLER; \
- word UNKNOWN_HANDLER; word UNKNOWN_HANDLER; \
- word UNKNOWN_HANDLER; word UNKNOWN_HANDLER; \
- word UNKNOWN_HANDLER; word UNKNOWN_HANDLER; \
- word UNKNOWN_HANDLER; word UNKNOWN_HANDLER; \
- word UNKNOWN_HANDLER; word UNKNOWN_HANDLER; \
- word UNKNOWN_HANDLER; word UNKNOWN_HANDLER;
-
- data
- .align 4096 /* VBR points to page aligned list */
-GLOBAL(vector_list)
- VECTOR(reset_handler) /* 00 */
- VECTOR(interrupt_handler) /* 01 */
- VECTOR(instruction_access_handler) /* 02 */
- VECTOR(data_exception_handler) /* 03 */
- VECTOR(misaligned_handler) /* 04 */
- VECTOR(unimplemented_handler) /* 05 */
- VECTOR(privilege_handler) /* 06 */
- VECTOR(bounds_handler) /* 07 */
- VECTOR(divide_handler) /* 08 */
- VECTOR(overflow_handler) /* 09 */
- VECTOR(error_handler) /* 0a */
- word UNKNOWN_HANDLER /* 0b */
- word UNKNOWN_HANDLER /* 0c */
- word UNKNOWN_HANDLER /* 0d */
- word UNKNOWN_HANDLER /* 0e */
- word UNKNOWN_HANDLER /* 0f */
- UNDEFINED16 /* 1x */
- UNDEFINED16 /* 2x */
- UNDEFINED16 /* 3x */
- UNDEFINED16 /* 4x */
- UNDEFINED16 /* 5x */
- UNDEFINED16 /* 6x */
- word UNKNOWN_HANDLER /* 70 */
- word UNKNOWN_HANDLER /* 71 */
- VECTOR(fp_precise_handler) /* 72 */
- VECTOR(fp_imprecise_handler) /* 73 */
- VECTOR(unimplemented_handler) /* 74 */
- word UNKNOWN_HANDLER /* 75 */
- VECTOR(unimplemented_handler) /* 76 */
- word UNKNOWN_HANDLER /* 77 */
- VECTOR(unimplemented_handler) /* 78 */
- word UNKNOWN_HANDLER /* 79 */
- VECTOR(unimplemented_handler) /* 7a */
- word UNKNOWN_HANDLER /* 7b */
- VECTOR(unimplemented_handler) /* 7c */
- word UNKNOWN_HANDLER /* 7d */
- VECTOR(unimplemented_handler) /* 7e */
- word UNKNOWN_HANDLER /* 7f */
- VECTOR(syscall_handler) /* 80 */
- VECTOR(syscall_handler) /* 81 */
- VECTOR(break) /* 82 */
- VECTOR(trace) /* 83 */
- VECTOR(entry) /* 84 */
-GLOBAL(vector_list_end)
- word END_OF_VECTOR_LIST
-
diff --git a/sys/arch/m88k/conf/files.m88k b/sys/arch/m88k/conf/files.m88k
index 93b8183e615..b6e9706cf15 100644
--- a/sys/arch/m88k/conf/files.m88k
+++ b/sys/arch/m88k/conf/files.m88k
@@ -1 +1,12 @@
-# $OpenBSD: files.m88k,v 1.1 2004/04/26 12:34:05 miod Exp $
+# $OpenBSD: files.m88k,v 1.2 2004/04/29 14:33:27 miod Exp $
+
+file arch/m88k/m88k/cmmu.c
+file arch/m88k/m88k/m88100_fp.S m88100
+file arch/m88k/m88k/m88110_fp.S m88110
+file arch/m88k/m88k/m88110_mmu.S m88110
+file arch/m88k/m88k/process.S
+file arch/m88k/m88k/process_machdep.c
+file arch/m88k/m88k/subr.S
+file arch/m88k/m88k/trap.c
+file arch/m88k/m88k/vectors_88100.S m88100
+file arch/m88k/m88k/vectors_88110.S m88110
diff --git a/sys/arch/mvme88k/mvme88k/cmmu.c b/sys/arch/m88k/m88k/cmmu.c
index 6a2f26cef66..b82898ca979 100644
--- a/sys/arch/mvme88k/mvme88k/cmmu.c
+++ b/sys/arch/m88k/m88k/cmmu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmmu.c,v 1.27 2004/01/20 14:35:54 miod Exp $ */
+/* $OpenBSD: cmmu.c,v 1.1 2004/04/29 14:33:27 miod Exp $ */
/*
* Copyright (c) 1998 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
diff --git a/sys/arch/mvme88k/mvme88k/genassym.cf b/sys/arch/m88k/m88k/genassym.cf
index efb3f5e8a50..9c7329013c3 100644
--- a/sys/arch/mvme88k/mvme88k/genassym.cf
+++ b/sys/arch/m88k/m88k/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.10 2004/01/12 07:46:17 miod Exp $
+# $OpenBSD: genassym.cf,v 1.1 2004/04/29 14:33:27 miod Exp $
#
# Copyright (c) 1982, 1990 The Regents of the University of California.
# All rights reserved.
@@ -28,7 +28,7 @@
# SUCH DAMAGE.
#
# @(#)genassym.c 7.8 (Berkeley) 5/7/91
-# $Id: genassym.cf,v 1.10 2004/01/12 07:46:17 miod Exp $
+# $Id: genassym.cf,v 1.1 2004/04/29 14:33:27 miod Exp $
#
include <sys/param.h>
diff --git a/sys/arch/mvme88k/mvme88k/m88100_fp.S b/sys/arch/m88k/m88k/m88100_fp.S
index c1b11ca7947..5d32f10887c 100644
--- a/sys/arch/mvme88k/mvme88k/m88100_fp.S
+++ b/sys/arch/m88k/m88k/m88100_fp.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: m88100_fp.S,v 1.21 2004/01/16 00:13:43 miod Exp $ */
+/* $OpenBSD: m88100_fp.S,v 1.1 2004/04/29 14:33:27 miod Exp $ */
/*
* Mach Operating System
* Copyright (c) 1991 Carnegie Mellon University
diff --git a/sys/arch/mvme88k/mvme88k/m88110_fp.S b/sys/arch/m88k/m88k/m88110_fp.S
index 91ed4c2f44d..254a14894aa 100644
--- a/sys/arch/mvme88k/mvme88k/m88110_fp.S
+++ b/sys/arch/m88k/m88k/m88110_fp.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: m88110_fp.S,v 1.11 2003/08/12 19:33:27 miod Exp $ */
+/* $OpenBSD: m88110_fp.S,v 1.1 2004/04/29 14:33:27 miod Exp $ */
/*
* Copyright (c) 1999 Steve Murphree, Jr.
* All rights reserved.
diff --git a/sys/arch/mvme88k/mvme88k/m88110_mmu.S b/sys/arch/m88k/m88k/m88110_mmu.S
index ab5b6cf90f6..1daff42ed48 100644
--- a/sys/arch/mvme88k/mvme88k/m88110_mmu.S
+++ b/sys/arch/m88k/m88k/m88110_mmu.S
@@ -1,4 +1,4 @@
-# $OpenBSD: m88110_mmu.S,v 1.9 2003/08/20 20:33:47 miod Exp $
+# $OpenBSD: m88110_mmu.S,v 1.1 2004/04/29 14:33:27 miod Exp $
/*
* Copyright (c) 2000 Steve Murphree, Jr.
* All rights reserved.
diff --git a/sys/arch/mvme88k/mvme88k/process.S b/sys/arch/m88k/m88k/process.S
index 76984a44e08..9c460e544da 100644
--- a/sys/arch/mvme88k/mvme88k/process.S
+++ b/sys/arch/m88k/m88k/process.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: process.S,v 1.29 2004/01/17 22:35:41 miod Exp $ */
+/* $OpenBSD: process.S,v 1.1 2004/04/29 14:33:27 miod Exp $ */
/*
* Copyright (c) 1996 Nivas Madhur
* All rights reserved.
diff --git a/sys/arch/mvme88k/mvme88k/process_machdep.c b/sys/arch/m88k/m88k/process_machdep.c
index 1230bc39692..41071bf4c07 100644
--- a/sys/arch/mvme88k/mvme88k/process_machdep.c
+++ b/sys/arch/m88k/m88k/process_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: process_machdep.c,v 1.12 2004/01/12 21:33:15 miod Exp $ */
+/* $OpenBSD: process_machdep.c,v 1.1 2004/04/29 14:33:27 miod Exp $ */
/*
* Copyright (c) 1993 The Regents of the University of California.
diff --git a/sys/arch/mvme88k/mvme88k/locore_asm_routines.S b/sys/arch/m88k/m88k/subr.S
index 33ba3f9376c..bafc847981d 100644
--- a/sys/arch/mvme88k/mvme88k/locore_asm_routines.S
+++ b/sys/arch/m88k/m88k/subr.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore_asm_routines.S,v 1.28 2004/01/23 17:26:06 miod Exp $ */
+/* $OpenBSD: subr.S,v 1.1 2004/04/29 14:33:27 miod Exp $ */
/*
* Mach Operating System
* Copyright (c) 1993-1992 Carnegie Mellon University
diff --git a/sys/arch/luna88k/luna88k/trap.c b/sys/arch/m88k/m88k/trap.c
index d7bee6ad47b..1bd4e5b6fc2 100644
--- a/sys/arch/luna88k/luna88k/trap.c
+++ b/sys/arch/m88k/m88k/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.1 2004/04/21 15:24:14 aoyama Exp $ */
+/* $OpenBSD: trap.c,v 1.1 2004/04/29 14:33:27 miod Exp $ */
/*
* Copyright (c) 1998 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
diff --git a/sys/arch/mvme88k/mvme88k/vectors_88100.S b/sys/arch/m88k/m88k/vectors_88100.S
index d12e9fb7c0b..e3a77568f2e 100644
--- a/sys/arch/mvme88k/mvme88k/vectors_88100.S
+++ b/sys/arch/m88k/m88k/vectors_88100.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: vectors_88100.S,v 1.1 2003/01/14 03:20:16 miod Exp $ */
+/* $OpenBSD: vectors_88100.S,v 1.1 2004/04/29 14:33:27 miod Exp $ */
/*
* Mach Operating System
* Copyright (c) 1991, 1992 Carnegie Mellon University
diff --git a/sys/arch/mvme88k/mvme88k/vectors_88110.S b/sys/arch/m88k/m88k/vectors_88110.S
index ae07c247238..f0c70865f12 100644
--- a/sys/arch/mvme88k/mvme88k/vectors_88110.S
+++ b/sys/arch/m88k/m88k/vectors_88110.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: vectors_88110.S,v 1.1 2003/01/14 03:20:16 miod Exp $ */
+/* $OpenBSD: vectors_88110.S,v 1.1 2004/04/29 14:33:27 miod Exp $ */
/*
* Mach Operating System
* Copyright (c) 1991, 1992 Carnegie Mellon University
diff --git a/sys/arch/mvme88k/conf/GENERIC b/sys/arch/mvme88k/conf/GENERIC
index d1939c3e060..0ec3af450cf 100644
--- a/sys/arch/mvme88k/conf/GENERIC
+++ b/sys/arch/mvme88k/conf/GENERIC
@@ -1,15 +1,18 @@
-# $OpenBSD: GENERIC,v 1.41 2004/04/26 12:34:05 miod Exp $
+# $OpenBSD: GENERIC,v 1.42 2004/04/29 14:33:27 miod Exp $
machine mvme88k m88k
include "../../../conf/GENERIC"
-option MVME187 # support for 187
-option MVME188 # support for 188
-option MVME197 # support for 197
+# Processor type
+option M88100
+option M88110
+
+option MVME187 # support for 187 (requires M88100)
+option MVME188 # support for 188 (requires M88100)
+option MVME197 # support for 197 (requires M88110)
+
option "NCPUS=1" # number of CPUs supported (max 4)
-option BUGMAP # use the Bug ROM VME mappings
-#option DEBUG # print debugging statements
# Define this if your processor has the xxx.usr bug (mask C82N)
option ERRATA__XXX_USR
diff --git a/sys/arch/mvme88k/conf/M187 b/sys/arch/mvme88k/conf/M187
index f16c6f61910..037f444695a 100644
--- a/sys/arch/mvme88k/conf/M187
+++ b/sys/arch/mvme88k/conf/M187
@@ -1,13 +1,13 @@
-# $OpenBSD: M187,v 1.29 2004/04/26 12:34:05 miod Exp $
+# $OpenBSD: M187,v 1.30 2004/04/29 14:33:27 miod Exp $
machine mvme88k m88k
include "../../../conf/GENERIC"
-option MVME187 # support for 187
-option BUGMAP # use Bug Rom VME Mappings
-#option DEBUG # print debugging statements
-#option EH_DEBUG # debugging code for exception handlers
+# Processor type
+option M88100
+
+option MVME187 # support for 187 (requires M88100)
# Define this if your processor has the xxx.usr bug (mask C82N)
option ERRATA__XXX_USR
diff --git a/sys/arch/mvme88k/conf/M188 b/sys/arch/mvme88k/conf/M188
index 1fef0a26aaf..9ebc241e5e9 100644
--- a/sys/arch/mvme88k/conf/M188
+++ b/sys/arch/mvme88k/conf/M188
@@ -1,14 +1,16 @@
-# $OpenBSD: M188,v 1.22 2004/04/26 12:34:05 miod Exp $
+# $OpenBSD: M188,v 1.23 2004/04/29 14:33:27 miod Exp $
machine mvme88k m88k
include "../../../conf/GENERIC"
-option MVME188 # support for 188
+# Processor type
+option M88100
+option M88110
+
+option MVME188 # support for 188 (requires M88100)
+
option "NCPUS=1" # Number of cpus supported (max 4)
-option BUGMAP # use Bug Rom VME Mappings
-#option DEBUG # print debugging statements
-#option EH_DEBUG # debugging code for exception handlers
# Define this if your processor has the xxx.usr bug (mask C82N)
option ERRATA__XXX_USR
diff --git a/sys/arch/mvme88k/conf/M197 b/sys/arch/mvme88k/conf/M197
index 3b9fe1b6952..ae4f9f8ee71 100644
--- a/sys/arch/mvme88k/conf/M197
+++ b/sys/arch/mvme88k/conf/M197
@@ -1,17 +1,15 @@
-# $OpenBSD: M197,v 1.23 2004/04/26 12:34:05 miod Exp $
+# $OpenBSD: M197,v 1.24 2004/04/29 14:33:27 miod Exp $
machine mvme88k m88k
include "../../../conf/GENERIC"
-option MVME197 # support for 197
-option "NCPUS=1" # Number of cpus supported (max 4)
-option BUGMAP # use Bug Rom VME Mappings
-#option DEBUG # print debugging statements
-#option EH_DEBUG # debugging code for exception handlers
+# Processor type
+option M88110
+
+option MVME197 # support for 197 (requires M88110)
-# Define this if your processor has the xxx.usr bug (mask C82N)
-option ERRATA__XXX_USR
+option "NCPUS=1" # Number of cpus supported (max 4)
maxusers 64
diff --git a/sys/arch/mvme88k/conf/Makefile.mvme88k b/sys/arch/mvme88k/conf/Makefile.mvme88k
index f292482a6b6..080c03dd8fe 100644
--- a/sys/arch/mvme88k/conf/Makefile.mvme88k
+++ b/sys/arch/mvme88k/conf/Makefile.mvme88k
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.mvme88k,v 1.32 2004/04/05 19:17:25 miod Exp $
+# $OpenBSD: Makefile.mvme88k,v 1.33 2004/04/29 14:33:27 miod Exp $
#
# Makefile for OpenBSD
#
@@ -32,6 +32,7 @@ STRIP?= strip
S!= cd ../../../..; pwd
.endif
MVME88K= $S/arch/mvme88k
+M88K= $S/arch/m88k
INCLUDES= -nostdinc -I. -I$S/arch -I$S
CPPFLAGS= ${INCLUDES} ${IDENT} ${PARAM} -D_KERNEL -Dmvme88k -Dm88k
@@ -54,14 +55,7 @@ HOSTED_CFLAGS?= ${CFLAGS}
### CPU configuration
-.if (${IDENT:M-DMVME187} != "" || ${IDENT:M-DMVME188} != "")
-CPPFLAGS+= -DM88100
-.endif
-.if (${IDENT:M-DMVME197} != "")
-CPPFLAGS+= -DM88110
-.endif
-
-# syntaxic sugar for 187, which do not exist with multiple processors
+# syntaxic sugar for 187, which does not exist with multiple processors
.if (${IDENT:M-DMVME187} != "" && ${IDENT:M-DNCPUS} == "")
CPPFLAGS+= -DNCPUS=1
.endif
@@ -129,9 +123,9 @@ LINKFLAGS+= -x
%LOAD
-assym.h: $S/kern/genassym.sh ${MVME88K}/mvme88k/genassym.cf Makefile
+assym.h: $S/kern/genassym.sh ${M88K}/m88k/genassym.cf Makefile
sh $S/kern/genassym.sh ${CC} ${CFLAGS} ${CPPFLAGS} \
- ${PARAM} < ${MVME88K}/mvme88k/genassym.cf > assym.h.tmp && \
+ ${PARAM} < ${M88K}/m88k/genassym.cf > assym.h.tmp && \
mv -f assym.h.tmp assym.h
param.c: $S/conf/param.c
diff --git a/sys/arch/mvme88k/conf/RAMDISK b/sys/arch/mvme88k/conf/RAMDISK
index 29eb6dfab54..7fa300ed1dd 100644
--- a/sys/arch/mvme88k/conf/RAMDISK
+++ b/sys/arch/mvme88k/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.22 2004/04/26 12:34:05 miod Exp $
+# $OpenBSD: RAMDISK,v 1.23 2004/04/29 14:33:27 miod Exp $
machine mvme88k m88k
@@ -6,12 +6,15 @@ machine mvme88k m88k
option MINIROOTSIZE=4096
option RAMDISK_HOOKS
-option MVME187 # support for 187
-option MVME188 # support for 188
-option MVME197 # support for 197
+# Processor type
+option M88100
+option M88110
+
+option MVME187 # support for 187 (requires M88100)
+option MVME188 # support for 188 (requires M88100)
+option MVME197 # support for 197 (requires M88110)
option "NCPUS=1" # number of CPUs supported (max 4)
-option BUGMAP # use the Bug ROM VME mappings
# Define this if your processor has the xxx.usr bug (mask C82N)
option ERRATA__XXX_USR
diff --git a/sys/arch/mvme88k/conf/files.mvme88k b/sys/arch/mvme88k/conf/files.mvme88k
index 723cb448f29..00c51acde68 100644
--- a/sys/arch/mvme88k/conf/files.mvme88k
+++ b/sys/arch/mvme88k/conf/files.mvme88k
@@ -1,4 +1,4 @@
-# $OpenBSD: files.mvme88k,v 1.26 2004/04/24 19:51:44 miod Exp $
+# $OpenBSD: files.mvme88k,v 1.27 2004/04/29 14:33:27 miod Exp $
#
maxpartitions 16
@@ -77,26 +77,16 @@ file netns/ns_cksum.c ns
file arch/mvme88k/mvme88k/autoconf.c
file arch/mvme88k/mvme88k/conf.c
-file arch/mvme88k/mvme88k/cmmu.c
-file arch/mvme88k/mvme88k/m8820x.c mvme187 | mvme188
-file arch/mvme88k/mvme88k/m88110.c mvme197
+file arch/mvme88k/mvme88k/m8820x.c m88100
+file arch/mvme88k/mvme88k/m88110.c m88110
file arch/mvme88k/mvme88k/disksubr.c
file arch/mvme88k/mvme88k/dkbad.c
file arch/mvme88k/mvme88k/eh.S
-file arch/mvme88k/mvme88k/locore_asm_routines.S
file arch/mvme88k/mvme88k/locore_c_routines.c
-file arch/mvme88k/mvme88k/m88100_fp.S mvme187 | mvme188
-file arch/mvme88k/mvme88k/m88110_fp.S mvme197
-file arch/mvme88k/mvme88k/m88110_mmu.S mvme197
file arch/mvme88k/mvme88k/machdep.c
file arch/mvme88k/mvme88k/mem.c
file arch/mvme88k/mvme88k/pmap.c
file arch/mvme88k/mvme88k/pmap_table.c
-file arch/mvme88k/mvme88k/process.S
-file arch/mvme88k/mvme88k/process_machdep.c
-file arch/mvme88k/mvme88k/trap.c
-file arch/mvme88k/mvme88k/vectors_88100.S mvme187 | mvme188
-file arch/mvme88k/mvme88k/vectors_88110.S mvme197
file arch/mvme88k/mvme88k/vm_machdep.c
file arch/mvme88k/ddb/db_disasm.c ddb
file arch/mvme88k/ddb/db_interface.c ddb
diff --git a/sys/arch/mvme88k/mvme88k/trap.c b/sys/arch/mvme88k/mvme88k/trap.c
deleted file mode 100644
index e1d6f95faf0..00000000000
--- a/sys/arch/mvme88k/mvme88k/trap.c
+++ /dev/null
@@ -1,1797 +0,0 @@
-/* $OpenBSD: trap.c,v 1.72 2004/01/29 21:39:05 deraadt Exp $ */
-/*
- * Copyright (c) 1998 Steve Murphree, Jr.
- * Copyright (c) 1996 Nivas Madhur
- * All rights reserved.
- *
- * 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 reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Nivas Madhur.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
- *
- */
-/*
- * Mach Operating System
- * Copyright (c) 1991 Carnegie Mellon University
- * Copyright (c) 1991 OMRON Corporation
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/proc.h>
-#include <sys/signalvar.h>
-#include <sys/user.h>
-#include <sys/syscall.h>
-#include <sys/systm.h>
-#include <sys/ktrace.h>
-
-#include "systrace.h"
-#include <dev/systrace.h>
-
-#include <uvm/uvm_extern.h>
-
-#include <machine/asm_macro.h> /* enable/disable interrupts */
-#include <machine/cpu.h>
-#include <machine/locore.h>
-#ifdef M88100
-#include <machine/m88100.h> /* DMT_xxx */
-#include <machine/m8820x.h> /* CMMU_PFSR_xxx */
-#endif
-#ifdef M88110
-#include <machine/m88110.h>
-#endif
-#include <machine/pcb.h> /* FIP_E, etc. */
-#include <machine/psl.h> /* FIP_E, etc. */
-#include <machine/trap.h>
-
-#include <machine/db_machdep.h>
-#ifdef DDB
-#include <ddb/db_output.h> /* db_printf() */
-#endif /* DDB */
-#define SSBREAKPOINT (0xF000D1F8U) /* Single Step Breakpoint */
-
-#ifdef DDB
-#define DEBUG_MSG(x) db_printf x
-#else
-#define DEBUG_MSG(x)
-#endif /* DDB */
-
-#define USERMODE(PSR) (((PSR) & PSR_MODE) == 0)
-#define SYSTEMMODE(PSR) (((PSR) & PSR_MODE) != 0)
-
-/* sigh */
-extern int procfs_domem(struct proc *, struct proc *, void *, struct uio *);
-
-__dead void panictrap(int, struct trapframe *);
-__dead void error_fatal(struct trapframe *);
-
-extern void regdump(struct trapframe *f);
-
-const char *trap_type[] = {
- "Reset",
- "Interrupt Exception",
- "Instruction Access",
- "Data Access Exception",
- "Misaligned Access",
- "Unimplemented Opcode",
- "Privilege Violation"
- "Bounds Check Violation",
- "Illegal Integer Divide",
- "Integer Overflow",
- "Error Exception",
- "Non-Maskable Exception",
-};
-const int trap_types = sizeof trap_type / sizeof trap_type[0];
-
-const char *pbus_exception_type[] = {
- "Success (No Fault)",
- "unknown 1",
- "unknown 2",
- "Bus Error",
- "Segment Fault",
- "Page Fault",
- "Supervisor Violation",
- "Write Violation",
-};
-
-static inline void
-userret(struct proc *p, struct trapframe *frame, u_quad_t oticks)
-{
- int sig;
-
- /* take pending signals */
- while ((sig = CURSIG(p)) != 0)
- postsig(sig);
- p->p_priority = p->p_usrpri;
-
- if (want_resched) {
- /*
- * We're being preempted.
- */
- preempt(NULL);
- while ((sig = CURSIG(p)) != 0)
- postsig(sig);
- }
-
- /*
- * If profiling, charge recent system time to the trapped pc.
- */
- if (p->p_flag & P_PROFIL) {
- extern int psratio;
-
- addupc_task(p, frame->tf_sxip & XIP_ADDR,
- (int)(p->p_sticks - oticks) * psratio);
- }
- curpriority = p->p_priority;
-}
-
-__dead void
-panictrap(int type, struct trapframe *frame)
-{
-#ifdef DDB
- static int panicing = 0;
-
- if (panicing++ == 0) {
- switch (cputyp) {
-#ifdef M88100
- case CPU_88100:
- if (type == 2) {
- /* instruction exception */
- db_printf("\nInstr access fault (%s) v = %x, "
- "frame %p\n",
- pbus_exception_type[
- CMMU_PFSR_FAULT(frame->tf_ipfsr)],
- frame->tf_sxip & XIP_ADDR, frame);
- } else if (type == 3) {
- /* data access exception */
- db_printf("\nData access fault (%s) v = %x, "
- "frame %p\n",
- pbus_exception_type[
- CMMU_PFSR_FAULT(frame->tf_dpfsr)],
- frame->tf_sxip & XIP_ADDR, frame);
- } else
- db_printf("\nTrap type %d, v = %x, frame %p\n",
- type, frame->tf_sxip & XIP_ADDR, frame);
- break;
-#endif
-#ifdef M88110
- case CPU_88110:
- db_printf("\nTrap type %d, v = %x, frame %p\n",
- type, frame->tf_exip, frame);
- break;
-#endif
- }
- regdump(frame);
- }
-#endif
- if ((u_int)type < trap_types)
- panic(trap_type[type]);
- else
- panic("trap %d", type);
- /*NOTREACHED*/
-}
-
-#ifdef M88100
-void
-m88100_trap(unsigned type, struct trapframe *frame)
-{
- struct proc *p;
- u_quad_t sticks = 0;
- struct vm_map *map;
- vaddr_t va;
- vm_prot_t ftype;
- int fault_type, pbus_type;
- u_long fault_code;
- unsigned nss, fault_addr;
- struct vmspace *vm;
- union sigval sv;
- int result;
-#ifdef DDB
- int s;
-#endif
- int sig = 0;
-
- extern struct vm_map *kernel_map;
- extern caddr_t guarded_access_start;
- extern caddr_t guarded_access_end;
- extern caddr_t guarded_access_bad;
-
- uvmexp.traps++;
- if ((p = curproc) == NULL)
- p = &proc0;
-
- if (USERMODE(frame->tf_epsr)) {
- sticks = p->p_sticks;
- type += T_USER;
- p->p_md.md_tf = frame; /* for ptrace/signals */
- }
- fault_type = 0;
- fault_code = 0;
- fault_addr = frame->tf_sxip & XIP_ADDR;
-
- switch (type) {
- default:
- panictrap(frame->tf_vector, frame);
- break;
- /*NOTREACHED*/
-
-#if defined(DDB)
- case T_KDB_BREAK:
- s = splhigh();
- db_enable_interrupt();
- ddb_break_trap(T_KDB_BREAK, (db_regs_t*)frame);
- db_disable_interrupt();
- splx(s);
- return;
- case T_KDB_ENTRY:
- s = splhigh();
- db_enable_interrupt();
- ddb_entry_trap(T_KDB_ENTRY, (db_regs_t*)frame);
- db_disable_interrupt();
- splx(s);
- return;
-#endif /* DDB */
- case T_ILLFLT:
- DEBUG_MSG(("Unimplemented opcode!\n"));
- panictrap(frame->tf_vector, frame);
- break;
- case T_INT:
- case T_INT+T_USER:
- /* This function pointer is set in machdep.c
- It calls m188_ext_int or sbc_ext_int depending
- on the value of brdtyp - smurph */
- (*md.interrupt_func)(T_INT, frame);
- return;
-
- case T_MISALGNFLT:
- DEBUG_MSG(("kernel misaligned "
- "access exception @ 0x%08x\n", frame->tf_sxip));
- panictrap(frame->tf_vector, frame);
- break;
-
- case T_INSTFLT:
- /* kernel mode instruction access fault.
- * Should never, never happen for a non-paged kernel.
- */
-#ifdef TRAPDEBUG
- pbus_type = CMMU_PFSR_FAULT(frame->tf_ipfsr);
- printf("Kernel Instruction fault #%d (%s) v = 0x%x, frame 0x%x cpu %d\n",
- pbus_type, pbus_exception_type[pbus_type],
- fault_addr, frame, frame->tf_cpu);
-#endif
- panictrap(frame->tf_vector, frame);
- break;
-
- case T_DATAFLT:
- /* kernel mode data fault */
-
- /* data fault on the user address? */
- if ((frame->tf_dmt0 & DMT_DAS) == 0) {
- type = T_DATAFLT + T_USER;
- goto user_fault;
- }
-
- fault_addr = frame->tf_dma0;
- if (frame->tf_dmt0 & (DMT_WRITE|DMT_LOCKBAR)) {
- ftype = VM_PROT_READ|VM_PROT_WRITE;
- fault_code = VM_PROT_WRITE;
- } else {
- ftype = VM_PROT_READ;
- fault_code = VM_PROT_READ;
- }
-
- va = trunc_page((vaddr_t)fault_addr);
- if (va == 0) {
- panic("trap: bad kernel access at %x", fault_addr);
- }
-
- vm = p->p_vmspace;
- map = kernel_map;
-
- pbus_type = CMMU_PFSR_FAULT(frame->tf_dpfsr);
-#ifdef TRAPDEBUG
- printf("Kernel Data access fault #%d (%s) v = 0x%x, frame 0x%x cpu %d\n",
- pbus_type, pbus_exception_type[pbus_type],
- fault_addr, frame, frame->tf_cpu);
-#endif
-
- switch (pbus_type) {
- case CMMU_PFSR_BERROR:
- /*
- * If it is a guarded access, bus error is OK.
- */
- if ((frame->tf_sxip & XIP_ADDR) >=
- (unsigned)&guarded_access_start &&
- (frame->tf_sxip & XIP_ADDR) <=
- (unsigned)&guarded_access_end) {
- frame->tf_snip =
- ((unsigned)&guarded_access_bad ) | NIP_V;
- frame->tf_sfip =
- ((unsigned)&guarded_access_bad + 4) | FIP_V;
- frame->tf_sxip = 0;
- /* We sort of resolved the fault ourselves
- * because we know where it came from
- * [guarded_access()]. But we must still think
- * about the other possible transactions in
- * dmt1 & dmt2. Mark dmt0 so that
- * data_access_emulation skips it. XXX smurph
- */
- frame->tf_dmt0 |= DMT_SKIP;
- data_access_emulation((unsigned *)frame);
- frame->tf_dpfsr = 0;
- frame->tf_dmt0 = 0;
- return;
- }
- break;
- case CMMU_PFSR_SUCCESS:
- /*
- * The fault was resolved. Call data_access_emulation
- * to drain the data unit pipe line and reset dmt0
- * so that trap won't get called again.
- */
- data_access_emulation((unsigned *)frame);
- frame->tf_dpfsr = 0;
- frame->tf_dmt0 = 0;
- return;
- case CMMU_PFSR_SFAULT:
- case CMMU_PFSR_PFAULT:
- result = uvm_fault(map, va, VM_FAULT_INVALID, ftype);
- if (result == 0) {
- /*
- * We could resolve the fault. Call
- * data_access_emulation to drain the data
- * unit pipe line and reset dmt0 so that trap
- * won't get called again.
- */
- data_access_emulation((unsigned *)frame);
- frame->tf_dpfsr = 0;
- frame->tf_dmt0 = 0;
- return;
- }
- break;
- }
-#ifdef TRAPDEBUG
- printf("PBUS Fault %d (%s) va = 0x%x\n", pbus_type,
- pbus_exception_type[pbus_type], va);
-#endif
- panictrap(frame->tf_vector, frame);
- /* NOTREACHED */
- case T_INSTFLT+T_USER:
- /* User mode instruction access fault */
- /* FALLTHROUGH */
- case T_DATAFLT+T_USER:
-user_fault:
- if (type == T_INSTFLT + T_USER) {
- pbus_type = CMMU_PFSR_FAULT(frame->tf_ipfsr);
-#ifdef TRAPDEBUG
- printf("User Instruction fault #%d (%s) v = 0x%x, frame 0x%x cpu %d\n",
- pbus_type, pbus_exception_type[pbus_type],
- fault_addr, frame, frame->tf_cpu);
-#endif
- } else {
- fault_addr = frame->tf_dma0;
- pbus_type = CMMU_PFSR_FAULT(frame->tf_dpfsr);
-#ifdef TRAPDEBUG
- printf("User Data access fault #%d (%s) v = 0x%x, frame 0x%x cpu %d\n",
- pbus_type, pbus_exception_type[pbus_type],
- fault_addr, frame, frame->tf_cpu);
-#endif
- }
-
- if (frame->tf_dmt0 & (DMT_WRITE | DMT_LOCKBAR)) {
- ftype = VM_PROT_READ | VM_PROT_WRITE;
- fault_code = VM_PROT_WRITE;
- } else {
- ftype = VM_PROT_READ;
- fault_code = VM_PROT_READ;
- }
-
- va = trunc_page((vaddr_t)fault_addr);
-
- vm = p->p_vmspace;
- map = &vm->vm_map;
-
- /* Call uvm_fault() to resolve non-bus error faults */
- switch (pbus_type) {
- case CMMU_PFSR_SUCCESS:
- result = 0;
- break;
- case CMMU_PFSR_BERROR:
- result = EACCES;
- break;
- default:
- result = uvm_fault(map, va, VM_FAULT_INVALID, ftype);
- if (result == EACCES)
- result = EFAULT;
- break;
- }
-
- if ((caddr_t)va >= vm->vm_maxsaddr) {
- if (result == 0) {
- nss = btoc(USRSTACK - va);/* XXX check this */
- if (nss > vm->vm_ssize)
- vm->vm_ssize = nss;
- }
- }
-
- /*
- * This could be a fault caused in copyin*()
- * while accessing user space.
- */
- if (result != 0 && p->p_addr->u_pcb.pcb_onfault != NULL) {
- frame->tf_snip = p->p_addr->u_pcb.pcb_onfault | NIP_V;
- frame->tf_sfip = (p->p_addr->u_pcb.pcb_onfault + 4) | FIP_V;
- frame->tf_sxip = 0;
- /*
- * Continue as if the fault had been resolved, but
- * do not try to complete the faulting access.
- */
- frame->tf_dmt0 |= DMT_SKIP;
- result = 0;
- }
-
- if (result == 0) {
- if (type == T_DATAFLT+T_USER) {
- /*
- * We could resolve the fault. Call
- * data_access_emulation to drain the data unit
- * pipe line and reset dmt0 so that trap won't
- * get called again.
- */
- data_access_emulation((unsigned *)frame);
- frame->tf_dpfsr = 0;
- frame->tf_dmt0 = 0;
- } else {
- /*
- * back up SXIP, SNIP,
- * clearing the Error bit
- */
- frame->tf_sfip = frame->tf_snip & ~FIP_E;
- frame->tf_snip = frame->tf_sxip & ~NIP_E;
- frame->tf_ipfsr = 0;
- }
- } else {
- sig = result == EACCES ? SIGBUS : SIGSEGV;
- fault_type = result == EACCES ?
- BUS_ADRERR : SEGV_MAPERR;
- }
- break;
- case T_MISALGNFLT+T_USER:
- sig = SIGBUS;
- fault_type = BUS_ADRALN;
- break;
- case T_PRIVINFLT+T_USER:
- case T_ILLFLT+T_USER:
-#ifndef DDB
- case T_KDB_BREAK:
- case T_KDB_ENTRY:
-#endif
- case T_KDB_BREAK+T_USER:
- case T_KDB_ENTRY+T_USER:
- case T_KDB_TRACE:
- case T_KDB_TRACE+T_USER:
- sig = SIGILL;
- break;
- case T_BNDFLT+T_USER:
- sig = SIGFPE;
- break;
- case T_ZERODIV+T_USER:
- sig = SIGFPE;
- fault_type = FPE_INTDIV;
- break;
- case T_OVFFLT+T_USER:
- sig = SIGFPE;
- fault_type = FPE_INTOVF;
- break;
- case T_FPEPFLT+T_USER:
- case T_FPEIFLT+T_USER:
- sig = SIGFPE;
- break;
- case T_SIGSYS+T_USER:
- sig = SIGSYS;
- break;
- case T_SIGTRAP+T_USER:
- sig = SIGTRAP;
- fault_type = TRAP_TRACE;
- break;
- case T_STEPBPT+T_USER:
- /*
- * This trap is used by the kernel to support single-step
- * debugging (although any user could generate this trap
- * which should probably be handled differently). When a
- * process is continued by a debugger with the PT_STEP
- * function of ptrace (single step), the kernel inserts
- * one or two breakpoints in the user process so that only
- * one instruction (or two in the case of a delayed branch)
- * is executed. When this breakpoint is hit, we get the
- * T_STEPBPT trap.
- */
- {
- unsigned va;
- unsigned instr;
- struct uio uio;
- struct iovec iov;
- unsigned pc = PC_REGS(&frame->tf_regs);
-
- /* read break instruction */
- copyin((caddr_t)pc, &instr, sizeof(unsigned));
-#if 0
- printf("trap: %s (%d) breakpoint %x at %x: (adr %x ins %x)\n",
- p->p_comm, p->p_pid, instr, pc,
- p->p_md.md_ss_addr, p->p_md.md_ss_instr); /* XXX */
-#endif
- /* check and see if we got here by accident */
- if ((p->p_md.md_ss_addr != pc &&
- p->p_md.md_ss_taken_addr != pc) ||
- instr != SSBREAKPOINT) {
- sig = SIGTRAP;
- fault_type = TRAP_TRACE;
- break;
- }
- /* restore original instruction and clear BP */
- instr = p->p_md.md_ss_instr;
- va = p->p_md.md_ss_addr;
- if (va != 0) {
- iov.iov_base = (caddr_t)&instr;
- iov.iov_len = sizeof(int);
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_offset = (off_t)va;
- uio.uio_resid = sizeof(int);
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_rw = UIO_WRITE;
- uio.uio_procp = curproc;
- procfs_domem(p, p, NULL, &uio);
- }
-
- /* branch taken instruction */
- instr = p->p_md.md_ss_taken_instr;
- va = p->p_md.md_ss_taken_addr;
- if (instr != 0) {
- iov.iov_base = (caddr_t)&instr;
- iov.iov_len = sizeof(int);
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_offset = (off_t)va;
- uio.uio_resid = sizeof(int);
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_rw = UIO_WRITE;
- uio.uio_procp = curproc;
- procfs_domem(p, p, NULL, &uio);
- }
-#if 1
- frame->tf_sfip = frame->tf_snip; /* set up next FIP */
- frame->tf_snip = pc; /* set up next NIP */
- frame->tf_snip |= 2; /* set valid bit */
-#endif
- p->p_md.md_ss_addr = 0;
- p->p_md.md_ss_instr = 0;
- p->p_md.md_ss_taken_addr = 0;
- p->p_md.md_ss_taken_instr = 0;
- sig = SIGTRAP;
- fault_type = TRAP_BRKPT;
- }
- break;
-
- case T_USERBPT+T_USER:
- /*
- * This trap is meant to be used by debuggers to implement
- * breakpoint debugging. When we get this trap, we just
- * return a signal which gets caught by the debugger.
- */
- frame->tf_sfip = frame->tf_snip; /* set up the next FIP */
- frame->tf_snip = frame->tf_sxip; /* set up the next NIP */
- sig = SIGTRAP;
- fault_type = TRAP_BRKPT;
- break;
-
- case T_ASTFLT+T_USER:
- uvmexp.softs++;
- want_ast = 0;
- if (p->p_flag & P_OWEUPC) {
- p->p_flag &= ~P_OWEUPC;
- ADDUPROF(p);
- }
- break;
- }
-
- /*
- * If trap from supervisor mode, just return
- */
- if (type < T_USER)
- return;
-
- if (sig) {
- sv.sival_int = fault_addr;
- trapsignal(p, sig, fault_code, fault_type, sv);
- /*
- * don't want multiple faults - we are going to
- * deliver signal.
- */
- frame->tf_dmt0 = 0;
- frame->tf_ipfsr = frame->tf_dpfsr = 0;
- }
-
- userret(p, frame, sticks);
-}
-#endif /* m88100 */
-
-#ifdef M88110
-void
-m88110_trap(unsigned type, struct trapframe *frame)
-{
- struct proc *p;
- u_quad_t sticks = 0;
- struct vm_map *map;
- vaddr_t va;
- vm_prot_t ftype;
- int fault_type;
- u_long fault_code;
- unsigned nss, fault_addr;
- struct vmspace *vm;
- union sigval sv;
- int result;
-#ifdef DDB
- int s; /* IPL */
-#endif
- int sig = 0;
- pt_entry_t *pte;
-
- extern struct vm_map *kernel_map;
- extern unsigned guarded_access_start;
- extern unsigned guarded_access_end;
- extern unsigned guarded_access_bad;
- extern pt_entry_t *pmap_pte(pmap_t, vaddr_t);
-
- uvmexp.traps++;
- if ((p = curproc) == NULL)
- p = &proc0;
-
- if (USERMODE(frame->tf_epsr)) {
- sticks = p->p_sticks;
- type += T_USER;
- p->p_md.md_tf = frame; /* for ptrace/signals */
- }
- fault_type = 0;
- fault_code = 0;
- fault_addr = frame->tf_exip & XIP_ADDR;
-
- switch (type) {
- default:
- panictrap(frame->tf_vector, frame);
- break;
- /*NOTREACHED*/
-
- case T_197_READ+T_USER:
- case T_197_READ:
- DEBUG_MSG(("DMMU read miss: Hardware Table Searches should be enabled!\n"));
- panictrap(frame->tf_vector, frame);
- break;
- /*NOTREACHED*/
- case T_197_WRITE+T_USER:
- case T_197_WRITE:
- DEBUG_MSG(("DMMU write miss: Hardware Table Searches should be enabled!\n"));
- panictrap(frame->tf_vector, frame);
- break;
- /*NOTREACHED*/
- case T_197_INST+T_USER:
- case T_197_INST:
- DEBUG_MSG(("IMMU miss: Hardware Table Searches should be enabled!\n"));
- panictrap(frame->tf_vector, frame);
- break;
- /*NOTREACHED*/
-#ifdef DDB
- case T_KDB_TRACE:
- s = splhigh();
- db_enable_interrupt();
- ddb_break_trap(T_KDB_TRACE, (db_regs_t*)frame);
- db_disable_interrupt();
- splx(s);
- return;
- case T_KDB_BREAK:
- s = splhigh();
- db_enable_interrupt();
- ddb_break_trap(T_KDB_BREAK, (db_regs_t*)frame);
- db_disable_interrupt();
- splx(s);
- return;
- case T_KDB_ENTRY:
- s = splhigh();
- db_enable_interrupt();
- ddb_entry_trap(T_KDB_ENTRY, (db_regs_t*)frame);
- db_disable_interrupt();
- /* skip one instruction */
- if (frame->tf_exip & 1)
- frame->tf_exip = frame->tf_enip;
- else
- frame->tf_exip += 4;
- frame->tf_enip = 0;
- splx(s);
- return;
-#if 0
- case T_ILLFLT:
- s = splhigh();
- db_enable_interrupt();
- ddb_error_trap(type == T_ILLFLT ? "unimplemented opcode" :
- "error fault", (db_regs_t*)frame);
- db_disable_interrupt();
- splx(s);
- return;
-#endif /* 0 */
-#endif /* DDB */
- case T_ILLFLT:
- DEBUG_MSG(("Unimplemented opcode!\n"));
- panictrap(frame->tf_vector, frame);
- break;
- case T_NON_MASK:
- case T_NON_MASK+T_USER:
- /* This function pointer is set in machdep.c
- It calls m197_ext_int - smurph */
- (*md.interrupt_func)(T_NON_MASK, frame);
- return;
- case T_INT:
- case T_INT+T_USER:
- (*md.interrupt_func)(T_INT, frame);
- return;
- case T_MISALGNFLT:
- DEBUG_MSG(("kernel mode misaligned "
- "access exception @ 0x%08x\n", frame->tf_exip));
- panictrap(frame->tf_vector, frame);
- break;
- /*NOTREACHED*/
-
- case T_INSTFLT:
- /* kernel mode instruction access fault.
- * Should never, never happen for a non-paged kernel.
- */
-#ifdef TRAPDEBUG
- printf("Kernel Instruction fault exip %x isr %x ilar %x\n",
- frame->tf_exip, frame->tf_isr, frame->tf_ilar);
-#endif
- panictrap(frame->tf_vector, frame);
- break;
- /*NOTREACHED*/
-
- case T_DATAFLT:
- /* kernel mode data fault */
-
- /* data fault on the user address? */
- if ((frame->tf_dsr & CMMU_DSR_SU) == 0) {
- type = T_DATAFLT + T_USER;
- goto m88110_user_fault;
- }
-
-#ifdef TRAPDEBUG
- printf("Kernel Data access fault exip %x dsr %x dlar %x\n",
- frame->tf_exip, frame->tf_dsr, frame->tf_dlar);
-#endif
-
- fault_addr = frame->tf_dlar;
- if (frame->tf_dsr & CMMU_DSR_RW) {
- ftype = VM_PROT_READ;
- fault_code = VM_PROT_READ;
- } else {
- ftype = VM_PROT_READ|VM_PROT_WRITE;
- fault_code = VM_PROT_WRITE;
- }
-
- va = trunc_page((vaddr_t)fault_addr);
- if (va == 0) {
- panic("trap: bad kernel access at %x", fault_addr);
- }
-
- vm = p->p_vmspace;
- map = kernel_map;
-
- if (frame->tf_dsr & CMMU_DSR_BE) {
- /*
- * If it is a guarded access, bus error is OK.
- */
- if ((frame->tf_exip & XIP_ADDR) >=
- (unsigned)&guarded_access_start &&
- (frame->tf_exip & XIP_ADDR) <=
- (unsigned)&guarded_access_end) {
- frame->tf_exip = (unsigned)&guarded_access_bad;
- frame->tf_enip = 0;
- return;
- }
- }
- if (frame->tf_dsr & (CMMU_DSR_SI | CMMU_DSR_PI)) {
- frame->tf_dsr &= ~CMMU_DSR_WE; /* undefined */
- /*
- * On a segment or a page fault, call uvm_fault() to
- * resolve the fault.
- */
- result = uvm_fault(map, va, VM_FAULT_INVALID, ftype);
- if (result == 0)
- return;
- }
- if (frame->tf_dsr & CMMU_DSR_WE) { /* write fault */
- /*
- * This could be a write protection fault or an
- * exception to set the used and modified bits
- * in the pte. Basically, if we got a write error,
- * then we already have a pte entry that faulted
- * in from a previous seg fault or page fault.
- * Get the pte and check the status of the
- * modified and valid bits to determine if this
- * indeed a real write fault. XXX smurph
- */
- pte = pmap_pte(map->pmap, va);
- if (pte == PT_ENTRY_NULL)
- panic("NULL pte on write fault??");
- if (!(*pte & PG_M) && !(*pte & PG_RO)) {
- /* Set modified bit and try the write again. */
-#ifdef TRAPDEBUG
- printf("Corrected kernel write fault, map %x pte %x\n",
- map->pmap, *pte);
-#endif
- *pte |= PG_M;
- return;
-#if 1 /* shouldn't happen */
- } else {
- /* must be a real wp fault */
-#ifdef TRAPDEBUG
- printf("Uncorrected kernel write fault, map %x pte %x\n",
- map->pmap, *pte);
-#endif
- result = uvm_fault(map, va, VM_FAULT_INVALID, ftype);
- if (result == 0)
- return;
-#endif
- }
- }
- panictrap(frame->tf_vector, frame);
- /* NOTREACHED */
- case T_INSTFLT+T_USER:
- /* User mode instruction access fault */
- /* FALLTHROUGH */
- case T_DATAFLT+T_USER:
-m88110_user_fault:
- if (type == T_INSTFLT+T_USER) {
- ftype = VM_PROT_READ;
- fault_code = VM_PROT_READ;
-#ifdef TRAPDEBUG
- printf("User Instruction fault exip %x isr %x ilar %x\n",
- frame->tf_exip, frame->tf_isr, frame->tf_ilar);
-#endif
- } else {
- fault_addr = frame->tf_dlar;
- if (frame->tf_dsr & CMMU_DSR_RW) {
- ftype = VM_PROT_READ;
- fault_code = VM_PROT_READ;
- } else {
- ftype = VM_PROT_READ|VM_PROT_WRITE;
- fault_code = VM_PROT_WRITE;
- }
-#ifdef TRAPDEBUG
- printf("User Data access fault exip %x dsr %x dlar %x\n",
- frame->tf_exip, frame->tf_dsr, frame->tf_dlar);
-#endif
- }
-
- va = trunc_page((vaddr_t)fault_addr);
-
- vm = p->p_vmspace;
- map = &vm->vm_map;
-
- /*
- * Call uvm_fault() to resolve non-bus error faults
- * whenever possible.
- */
- if (type == T_DATAFLT+T_USER) {
- /* data faults */
- if (frame->tf_dsr & CMMU_DSR_BE) {
- /* bus error */
- result = EACCES;
- } else
- if (frame->tf_dsr & (CMMU_DSR_SI | CMMU_DSR_PI)) {
- /* segment or page fault */
- result = uvm_fault(map, va, VM_FAULT_INVALID, ftype);
- if (result == EACCES)
- result = EFAULT;
- } else
- if (frame->tf_dsr & (CMMU_DSR_CP | CMMU_DSR_WA)) {
- /* copyback or write allocate error */
- result = 0;
- } else
- if (frame->tf_dsr & CMMU_DSR_WE) {
- /* write fault */
- /* This could be a write protection fault or an
- * exception to set the used and modified bits
- * in the pte. Basically, if we got a write
- * error, then we already have a pte entry that
- * faulted in from a previous seg fault or page
- * fault.
- * Get the pte and check the status of the
- * modified and valid bits to determine if this
- * indeed a real write fault. XXX smurph
- */
- pte = pmap_pte(vm_map_pmap(map), va);
-#ifdef DEBUG
- if (pte == PT_ENTRY_NULL)
- panic("NULL pte on write fault??");
-#endif
- if (!(*pte & PG_M) && !(*pte & PG_RO)) {
- /*
- * Set modified bit and try the
- * write again.
- */
-#ifdef TRAPDEBUG
- printf("Corrected userland write fault, map %x pte %x\n",
- map->pmap, *pte);
-#endif
- *pte |= PG_M;
- /*
- * invalidate ATCs to force
- * table search
- */
- set_dcmd(CMMU_DCMD_INV_UATC);
- return;
- } else {
- /* must be a real wp fault */
-#ifdef TRAPDEBUG
- printf("Uncorrected userland write fault, map %x pte %x\n",
- map->pmap, *pte);
-#endif
- result = uvm_fault(map, va, VM_FAULT_INVALID, ftype);
- if (result == EACCES)
- result = EFAULT;
- }
- } else {
-#ifdef TRAPDEBUG
- printf("Unexpected Data access fault dsr %x\n",
- frame->tf_dsr);
-#endif
- panictrap(frame->tf_vector, frame);
- }
- } else {
- /* instruction faults */
- if (frame->tf_isr &
- (CMMU_ISR_BE | CMMU_ISR_SP | CMMU_ISR_TBE)) {
- /* bus error, supervisor protection */
- result = EACCES;
- } else
- if (frame->tf_isr & (CMMU_ISR_SI | CMMU_ISR_PI)) {
- /* segment or page fault */
- result = uvm_fault(map, va, VM_FAULT_INVALID, ftype);
- if (result == EACCES)
- result = EFAULT;
- } else {
-#ifdef TRAPDEBUG
- printf("Unexpected Instruction fault isr %x\n",
- frame->tf_isr);
-#endif
- panictrap(frame->tf_vector, frame);
- }
- }
-
- if ((caddr_t)va >= vm->vm_maxsaddr) {
- if (result == 0) {
- nss = btoc(USRSTACK - va);/* XXX check this */
- if (nss > vm->vm_ssize)
- vm->vm_ssize = nss;
- }
- }
-
- /*
- * This could be a fault caused in copyin*()
- * while accessing user space.
- */
- if (result != 0 && p->p_addr->u_pcb.pcb_onfault != NULL) {
- frame->tf_exip = p->p_addr->u_pcb.pcb_onfault;
- frame->tf_enip = 0;
- frame->tf_dsr = frame->tf_isr = 0;
- /*
- * Continue as if the fault had been resolved.
- */
- result = 0;
- }
-
- if (result != 0) {
- sig = result == EACCES ? SIGBUS : SIGSEGV;
- fault_type = result == EACCES ?
- BUS_ADRERR : SEGV_MAPERR;
- }
- break;
- case T_MISALGNFLT+T_USER:
- sig = SIGBUS;
- fault_type = BUS_ADRALN;
- break;
- case T_PRIVINFLT+T_USER:
- case T_ILLFLT+T_USER:
-#ifndef DDB
- case T_KDB_BREAK:
- case T_KDB_ENTRY:
- case T_KDB_TRACE:
-#endif
- case T_KDB_BREAK+T_USER:
- case T_KDB_ENTRY+T_USER:
- case T_KDB_TRACE+T_USER:
- sig = SIGILL;
- break;
- case T_BNDFLT+T_USER:
- sig = SIGFPE;
- break;
- case T_ZERODIV+T_USER:
- sig = SIGFPE;
- fault_type = FPE_INTDIV;
- break;
- case T_OVFFLT+T_USER:
- sig = SIGFPE;
- fault_type = FPE_INTOVF;
- break;
- case T_FPEPFLT+T_USER:
- case T_FPEIFLT+T_USER:
- sig = SIGFPE;
- break;
- case T_SIGSYS+T_USER:
- sig = SIGSYS;
- break;
- case T_SIGTRAP+T_USER:
- sig = SIGTRAP;
- fault_type = TRAP_TRACE;
- break;
- case T_STEPBPT+T_USER:
- /*
- * This trap is used by the kernel to support single-step
- * debugging (although any user could generate this trap
- * which should probably be handled differently). When a
- * process is continued by a debugger with the PT_STEP
- * function of ptrace (single step), the kernel inserts
- * one or two breakpoints in the user process so that only
- * one instruction (or two in the case of a delayed branch)
- * is executed. When this breakpoint is hit, we get the
- * T_STEPBPT trap.
- */
- {
- unsigned instr;
- struct uio uio;
- struct iovec iov;
- unsigned pc = PC_REGS(&frame->tf_regs);
-
- /* read break instruction */
- copyin((caddr_t)pc, &instr, sizeof(unsigned));
-#if 0
- printf("trap: %s (%d) breakpoint %x at %x: (adr %x ins %x)\n",
- p->p_comm, p->p_pid, instr, pc,
- p->p_md.md_ss_addr, p->p_md.md_ss_instr); /* XXX */
-#endif
- /* check and see if we got here by accident */
-#ifdef notyet
- if (p->p_md.md_ss_addr != pc || instr != SSBREAKPOINT) {
- sig = SIGTRAP;
- fault_type = TRAP_TRACE;
- break;
- }
-#endif
- /* restore original instruction and clear BP */
- /*sig = suiword((caddr_t)pc, p->p_md.md_ss_instr);*/
- instr = p->p_md.md_ss_instr;
- if (instr != 0) {
- iov.iov_base = (caddr_t)&instr;
- iov.iov_len = sizeof(int);
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_offset = (off_t)pc;
- uio.uio_resid = sizeof(int);
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_rw = UIO_WRITE;
- uio.uio_procp = curproc;
- }
-
- p->p_md.md_ss_addr = 0;
- sig = SIGTRAP;
- fault_type = TRAP_BRKPT;
- break;
- }
- case T_USERBPT+T_USER:
- /*
- * This trap is meant to be used by debuggers to implement
- * breakpoint debugging. When we get this trap, we just
- * return a signal which gets caught by the debugger.
- */
- sig = SIGTRAP;
- fault_type = TRAP_BRKPT;
- break;
-
- case T_ASTFLT+T_USER:
- uvmexp.softs++;
- want_ast = 0;
- if (p->p_flag & P_OWEUPC) {
- p->p_flag &= ~P_OWEUPC;
- ADDUPROF(p);
- }
- break;
- }
-
- /*
- * If trap from supervisor mode, just return
- */
- if (type < T_USER)
- return;
-
- if (sig) {
- sv.sival_int = fault_addr;
- trapsignal(p, sig, fault_code, fault_type, sv);
- /*
- * don't want multiple faults - we are going to
- * deliver signal.
- */
- frame->tf_dsr = frame->tf_isr = 0;
- }
-
- userret(p, frame, sticks);
-}
-#endif /* MVME197 */
-
-__dead void
-error_fatal(struct trapframe *frame)
-{
-#ifdef DDB
- switch (frame->tf_vector) {
- case 0:
- db_printf("\n[RESET EXCEPTION (Really Bad News[tm]) frame %8p]\n", frame);
- db_printf("This is usually caused by a branch to a NULL function pointer.\n");
- db_printf("e.g. jump to address 0. Use the debugger trace command to track it down.\n");
- break;
- default:
- db_printf("\n[ERROR EXCEPTION (Bad News[tm]) frame %p]\n", frame);
- db_printf("This is usually an exception within an exception. The trap\n");
- db_printf("frame shadow registers you are about to see are invalid.\n");
- db_printf("(read totally useless) But R1 to R31 might be interesting.\n");
- break;
- }
- regdump((struct trapframe*)frame);
-#endif /* DDB */
- panic("unrecoverable exception %d", frame->tf_vector);
-}
-
-#ifdef M88100
-void
-m88100_syscall(register_t code, struct trapframe *tf)
-{
- int i, nsys, nap;
- struct sysent *callp;
- struct proc *p;
- int error;
- register_t args[11], rval[2], *ap;
- u_quad_t sticks;
-#ifdef DIAGNOSTIC
- extern struct pcb *curpcb;
-#endif
-
- uvmexp.syscalls++;
-
- p = curproc;
-
- callp = p->p_emul->e_sysent;
- nsys = p->p_emul->e_nsysent;
-
-#ifdef DIAGNOSTIC
- if (USERMODE(tf->tf_epsr) == 0)
- panic("syscall");
- if (curpcb != &p->p_addr->u_pcb)
- panic("syscall curpcb/ppcb");
- if (tf != (struct trapframe *)&curpcb->user_state)
- panic("syscall trapframe");
-#endif
-
- sticks = p->p_sticks;
- p->p_md.md_tf = tf;
-
- /*
- * For 88k, all the arguments are passed in the registers (r2-r12)
- * For syscall (and __syscall), r2 (and r3) has the actual code.
- * __syscall takes a quad syscall number, so that other
- * arguments are at their natural alignments.
- */
- ap = &tf->tf_r[2];
- nap = 11; /* r2-r12 */
-
- switch (code) {
- case SYS_syscall:
- code = *ap++;
- nap--;
- break;
- case SYS___syscall:
- if (callp != sysent)
- break;
- code = ap[_QUAD_LOWWORD];
- ap += 2;
- nap -= 2;
- break;
- }
-
- /* Callp currently points to syscall, which returns ENOSYS. */
- if (code < 0 || code >= nsys)
- callp += p->p_emul->e_nosys;
- else {
- callp += code;
- i = callp->sy_argsize / sizeof(register_t);
- if (i > nap)
- panic("syscall nargs");
- /*
- * just copy them; syscall stub made sure all the
- * args are moved from user stack to registers.
- */
- bcopy((caddr_t)ap, (caddr_t)args, i * sizeof(register_t));
- }
-
-#ifdef SYSCALL_DEBUG
- scdebug_call(p, code, args);
-#endif
-#ifdef KTRACE
- if (KTRPOINT(p, KTR_SYSCALL))
- ktrsyscall(p, code, callp->sy_argsize, args);
-#endif
- rval[0] = 0;
- rval[1] = 0;
-#if NSYSTRACE > 0
- if (ISSET(p->p_flag, P_SYSTRACE))
- error = systrace_redirect(code, p, args, rval);
- else
-#endif
- error = (*callp->sy_call)(p, args, rval);
- /*
- * system call will look like:
- * ld r10, r31, 32; r10,r11,r12 might be garbage.
- * ld r11, r31, 36
- * ld r12, r31, 40
- * or r13, r0, <code>
- * tb0 0, r0, <128> <- sxip
- * br err <- snip
- * jmp r1 <- sfip
- * err: or.u r3, r0, hi16(errno)
- * st r2, r3, lo16(errno)
- * subu r2, r0, 1
- * jmp r1
- *
- * So, when we take syscall trap, sxip/snip/sfip will be as
- * shown above.
- * Given this,
- * 1. If the system call returned 0, need to skip nip.
- * nip = fip, fip += 4
- * (doesn't matter what fip + 4 will be but we will never
- * execute this since jmp r1 at nip will change the execution flow.)
- * 2. If the system call returned an errno > 0, plug the value
- * in r2, and leave nip and fip unchanged. This will have us
- * executing "br err" on return to user space.
- * 3. If the system call code returned ERESTART,
- * we need to rexecute the trap instruction. Back up the pipe
- * line.
- * fip = nip, nip = xip
- * 4. If the system call returned EJUSTRETURN, don't need to adjust
- * any pointers.
- */
-
- switch (error) {
- case 0:
- /*
- * If fork succeeded and we are the child, our stack
- * has moved and the pointer tf is no longer valid,
- * and p is wrong. Compute the new trapframe pointer.
- * (The trap frame invariably resides at the
- * tippity-top of the u. area.)
- */
- p = curproc;
- tf = (struct trapframe *)USER_REGS(p);
- tf->tf_r[2] = rval[0];
- tf->tf_r[3] = rval[1];
- tf->tf_epsr &= ~PSR_C;
- tf->tf_snip = tf->tf_sfip & ~NIP_E;
- tf->tf_sfip = tf->tf_snip + 4;
- break;
- case ERESTART:
- /*
- * If (error == ERESTART), back up the pipe line. This
- * will end up reexecuting the trap.
- */
- tf->tf_epsr &= ~PSR_C;
- tf->tf_sfip = tf->tf_snip & ~FIP_E;
- tf->tf_snip = tf->tf_sxip & ~NIP_E;
- break;
- case EJUSTRETURN:
- /* if (error == EJUSTRETURN), leave the ip's alone */
- tf->tf_epsr &= ~PSR_C;
- break;
- default:
- /* error != ERESTART && error != EJUSTRETURN*/
- if (p->p_emul->e_errno)
- error = p->p_emul->e_errno[error];
- tf->tf_r[2] = error;
- tf->tf_epsr |= PSR_C; /* fail */
- tf->tf_snip = tf->tf_snip & ~NIP_E;
- tf->tf_sfip = tf->tf_sfip & ~FIP_E;
- break;
- }
-#ifdef SYSCALL_DEBUG
- scdebug_ret(p, code, error, rval);
-#endif
- userret(p, tf, sticks);
-#ifdef KTRACE
- if (KTRPOINT(p, KTR_SYSRET))
- ktrsysret(p, code, error, rval[0]);
-#endif
-}
-#endif /* M88100 */
-
-#ifdef M88110
-/* Instruction pointers operate differently on mc88110 */
-void
-m88110_syscall(register_t code, struct trapframe *tf)
-{
- int i, nsys, nap;
- struct sysent *callp;
- struct proc *p;
- int error;
- register_t args[11], rval[2], *ap;
- u_quad_t sticks;
-#ifdef DIAGNOSTIC
- extern struct pcb *curpcb;
-#endif
-
- uvmexp.syscalls++;
-
- p = curproc;
-
- callp = p->p_emul->e_sysent;
- nsys = p->p_emul->e_nsysent;
-
-#ifdef DIAGNOSTIC
- if (USERMODE(tf->tf_epsr) == 0)
- panic("syscall");
- if (curpcb != &p->p_addr->u_pcb)
- panic("syscall curpcb/ppcb");
- if (tf != (struct trapframe *)&curpcb->user_state)
- panic("syscall trapframe");
-#endif
-
- sticks = p->p_sticks;
- p->p_md.md_tf = tf;
-
- /*
- * For 88k, all the arguments are passed in the registers (r2-r12)
- * For syscall (and __syscall), r2 (and r3) has the actual code.
- * __syscall takes a quad syscall number, so that other
- * arguments are at their natural alignments.
- */
- ap = &tf->tf_r[2];
- nap = 11; /* r2-r12 */
-
- switch (code) {
- case SYS_syscall:
- code = *ap++;
- nap--;
- break;
- case SYS___syscall:
- if (callp != sysent)
- break;
- code = ap[_QUAD_LOWWORD];
- ap += 2;
- nap -= 2;
- break;
- }
-
- /* Callp currently points to syscall, which returns ENOSYS. */
- if (code < 0 || code >= nsys)
- callp += p->p_emul->e_nosys;
- else {
- callp += code;
- i = callp->sy_argsize / sizeof(register_t);
- if (i > nap)
- panic("syscall nargs");
- /*
- * just copy them; syscall stub made sure all the
- * args are moved from user stack to registers.
- */
- bcopy((caddr_t)ap, (caddr_t)args, i * sizeof(register_t));
- }
-#ifdef SYSCALL_DEBUG
- scdebug_call(p, code, args);
-#endif
-#ifdef KTRACE
- if (KTRPOINT(p, KTR_SYSCALL))
- ktrsyscall(p, code, callp->sy_argsize, args);
-#endif
- rval[0] = 0;
- rval[1] = 0;
-#if NSYSTRACE > 0
- if (ISSET(p->p_flag, P_SYSTRACE))
- error = systrace_redirect(code, p, args, rval);
- else
-#endif
- error = (*callp->sy_call)(p, args, rval);
- /*
- * system call will look like:
- * ld r10, r31, 32; r10,r11,r12 might be garbage.
- * ld r11, r31, 36
- * ld r12, r31, 40
- * or r13, r0, <code>
- * tb0 0, r0, <128> <- exip
- * br err <- enip
- * jmp r1
- * err: or.u r3, r0, hi16(errno)
- * st r2, r3, lo16(errno)
- * subu r2, r0, 1
- * jmp r1
- *
- * So, when we take syscall trap, exip/enip will be as
- * shown above.
- * Given this,
- * 1. If the system call returned 0, need to jmp r1.
- * exip += 8
- * 2. If the system call returned an errno > 0, increment
- * exip += 4 and plug the value in r2. This will have us
- * executing "br err" on return to user space.
- * 3. If the system call code returned ERESTART,
- * we need to rexecute the trap instruction. leave exip as is.
- * 4. If the system call returned EJUSTRETURN, just return.
- * exip += 4
- */
-
- switch (error) {
- case 0:
- /*
- * If fork succeeded and we are the child, our stack
- * has moved and the pointer tf is no longer valid,
- * and p is wrong. Compute the new trapframe pointer.
- * (The trap frame invariably resides at the
- * tippity-top of the u. area.)
- */
- p = curproc;
- tf = (struct trapframe *)USER_REGS(p);
- tf->tf_r[2] = rval[0];
- tf->tf_r[3] = rval[1];
- tf->tf_epsr &= ~PSR_C;
- /* skip two instructions */
- if (tf->tf_exip & 1)
- tf->tf_exip = tf->tf_enip + 4;
- else
- tf->tf_exip += 4 + 4;
- tf->tf_enip = 0;
- break;
- case ERESTART:
- /*
- * Reexecute the trap.
- * exip is already at the trap instruction, so
- * there is nothing to do.
- */
- tf->tf_epsr &= ~PSR_C;
- break;
- case EJUSTRETURN:
- tf->tf_epsr &= ~PSR_C;
- /* skip one instruction */
- if (tf->tf_exip & 1)
- tf->tf_exip = tf->tf_enip;
- else
- tf->tf_exip += 4;
- tf->tf_enip = 0;
- break;
- default:
- if (p->p_emul->e_errno)
- error = p->p_emul->e_errno[error];
- tf->tf_r[2] = error;
- tf->tf_epsr |= PSR_C; /* fail */
- /* skip one instruction */
- if (tf->tf_exip & 1)
- tf->tf_exip = tf->tf_enip;
- else
- tf->tf_exip += 4;
- tf->tf_enip = 0;
- break;
- }
-
-#ifdef SYSCALL_DEBUG
- scdebug_ret(p, code, error, rval);
-#endif
- userret(p, tf, sticks);
-#ifdef KTRACE
- if (KTRPOINT(p, KTR_SYSRET))
- ktrsysret(p, code, error, rval[0]);
-#endif
-}
-#endif /* MVME197 */
-
-/*
- * Set up return-value registers as fork() libc stub expects,
- * and do normal return-to-user-mode stuff.
- */
-void
-child_return(arg)
- void *arg;
-{
- struct proc *p = arg;
- struct trapframe *tf;
-
- tf = (struct trapframe *)USER_REGS(p);
- tf->tf_r[2] = 0;
- tf->tf_r[3] = 0;
- tf->tf_epsr &= ~PSR_C;
- if (cputyp != CPU_88110) {
- tf->tf_snip = tf->tf_sfip & XIP_ADDR;
- tf->tf_sfip = tf->tf_snip + 4;
- } else {
- /* skip two instructions */
- if (tf->tf_exip & 1)
- tf->tf_exip = tf->tf_enip + 4;
- else
- tf->tf_exip += 4 + 4;
- tf->tf_enip = 0;
- }
-
- userret(p, tf, p->p_sticks);
-#ifdef KTRACE
- if (KTRPOINT(p, KTR_SYSRET))
- ktrsysret(p, SYS_fork, 0, 0);
-#endif
-}
-
-#ifdef PTRACE
-
-/*
- * User Single Step Debugging Support
- */
-
-#include <sys/ptrace.h>
-
-unsigned ss_get_value(struct proc *, unsigned, int);
-int ss_put_value(struct proc *, unsigned, unsigned, int);
-unsigned ss_branch_taken(unsigned, unsigned,
- unsigned (*func)(unsigned int, struct reg *), struct reg *);
-unsigned int ss_getreg_val(unsigned int, struct reg *);
-int ss_inst_branch(unsigned);
-int ss_inst_delayed(unsigned);
-unsigned ss_next_instr_address(struct proc *, unsigned, unsigned);
-
-unsigned
-ss_get_value(struct proc *p, unsigned addr, int size)
-{
- struct uio uio;
- struct iovec iov;
- unsigned value;
-
- iov.iov_base = (caddr_t)&value;
- iov.iov_len = size;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_offset = (off_t)addr;
- uio.uio_resid = size;
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_rw = UIO_READ;
- uio.uio_procp = curproc;
- procfs_domem(curproc, p, NULL, &uio);
- return value;
-}
-
-int
-ss_put_value(struct proc *p, unsigned addr, unsigned value, int size)
-{
- struct uio uio;
- struct iovec iov;
-
- iov.iov_base = (caddr_t)&value;
- iov.iov_len = size;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_offset = (off_t)addr;
- uio.uio_resid = size;
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_rw = UIO_WRITE;
- uio.uio_procp = curproc;
- return procfs_domem(curproc, p, NULL, &uio);
-}
-
-/*
- * ss_branch_taken(instruction, program counter, func, func_data)
- *
- * instruction will be a control flow instruction location at address pc.
- * Branch taken is supposed to return the address to which the instruction
- * would jump if the branch is taken. Func can be used to get the current
- * register values when invoked with a register number and func_data as
- * arguments.
- *
- * If the instruction is not a control flow instruction, panic.
- */
-unsigned
-ss_branch_taken(unsigned inst, unsigned pc,
- unsigned (*func)(unsigned int, struct reg *), struct reg *func_data)
-{
- /* check if br/bsr */
- if ((inst & 0xf0000000) == 0xc0000000) {
- /* signed 26 bit pc relative displacement, shift left two bits */
- inst = (inst & 0x03ffffff) << 2;
- /* check if sign extension is needed */
- if (inst & 0x08000000)
- inst |= 0xf0000000;
- return (pc + inst);
- }
-
- /* check if bb0/bb1/bcnd case */
- switch (inst & 0xf8000000) {
- case 0xd0000000: /* bb0 */
- case 0xd8000000: /* bb1 */
- case 0xe8000000: /* bcnd */
- /* signed 16 bit pc relative displacement, shift left two bits */
- inst = (inst & 0x0000ffff) << 2;
- /* check if sign extension is needed */
- if (inst & 0x00020000)
- inst |= 0xfffc0000;
- return (pc + inst);
- }
-
- /* check jmp/jsr case */
- /* check bits 5-31, skipping 10 & 11 */
- if ((inst & 0xfffff3e0) == 0xf400c000)
- return (*func)(inst & 0x1f, func_data); /* the register value */
-
- /* can't happen */
- return (0);
-}
-
-/*
- * ss_getreg_val - handed a register number and an exception frame.
- * Returns the value of the register in the specified
- * frame. Only makes sense for general registers.
- */
-unsigned int
-ss_getreg_val(unsigned int regno, struct reg *regs)
-{
- return (regno == 0 ? 0 : regs->r[regno]);
-}
-
-int
-ss_inst_branch(unsigned ins)
-{
- /* check high five bits */
-
- switch (ins >> (32 - 5)) {
- case 0x18: /* br */
- case 0x1a: /* bb0 */
- case 0x1b: /* bb1 */
- case 0x1d: /* bcnd */
- return TRUE;
- break;
- case 0x1e: /* could be jmp */
- if ((ins & 0xfffffbe0) == 0xf400c000)
- return TRUE;
- }
-
- return FALSE;
-}
-
-/* ss_inst_delayed - this instruction is followed by a delay slot. Could be
- br.n, bsr.n bb0.n, bb1.n, bcnd.n or jmp.n or jsr.n */
-
-int
-ss_inst_delayed(unsigned ins)
-{
- /* check the br, bsr, bb0, bb1, bcnd cases */
- switch ((ins & 0xfc000000) >> (32 - 6)) {
- case 0x31: /* br */
- case 0x33: /* bsr */
- case 0x35: /* bb0 */
- case 0x37: /* bb1 */
- case 0x3b: /* bcnd */
- return TRUE;
- }
-
- /* check the jmp, jsr cases */
- /* mask out bits 0-4, bit 11 */
- return ((ins & 0xfffff7e0) == 0xf400c400) ? TRUE : FALSE;
-}
-
-unsigned
-ss_next_instr_address(struct proc *p, unsigned pc, unsigned delay_slot)
-{
- if (delay_slot == 0)
- return (pc + 4);
- else {
- if (ss_inst_delayed(ss_get_value(p, pc, sizeof(int))))
- return (pc + 4);
- else
- return pc;
- }
-}
-
-int
-cpu_singlestep(p)
- struct proc *p;
-{
- struct reg *sstf = USER_REGS(p);
- unsigned pc, brpc;
- int bpinstr = SSBREAKPOINT;
- unsigned curinstr;
-
- pc = PC_REGS(sstf);
- /*
- * User was stopped at pc, e.g. the instruction
- * at pc was not executed.
- * Fetch what's at the current location.
- */
- curinstr = ss_get_value(p, pc, sizeof(int));
-
- /* compute next address after current location */
- if (curinstr != 0) {
- if (ss_inst_branch(curinstr) ||
- inst_call(curinstr) || inst_return(curinstr)) {
- brpc = ss_branch_taken(curinstr, pc, ss_getreg_val, sstf);
- if (brpc != pc) { /* self-branches are hopeless */
- p->p_md.md_ss_taken_addr = brpc;
- p->p_md.md_ss_taken_instr =
- ss_get_value(p, brpc, sizeof(int));
- /* Store breakpoint instruction at the
- "next" location now. */
- if (ss_put_value(p, brpc, bpinstr,
- sizeof(int)) != 0)
- return (EFAULT);
- }
- }
- pc = ss_next_instr_address(p, pc, 0);
- } else {
- pc = PC_REGS(sstf) + 4;
- }
-
- if (p->p_md.md_ss_addr != NULL) {
- return (EFAULT);
- }
-
- p->p_md.md_ss_addr = pc;
-
- /* Fetch what's at the "next" location. */
- p->p_md.md_ss_instr = ss_get_value(p, pc, sizeof(int));
-
- /* Store breakpoint instruction at the "next" location now. */
- if (ss_put_value(p, pc, bpinstr, sizeof(int)) != 0)
- return (EFAULT);
-
- return (0);
-}
-
-#endif /* PTRACE */
-
-#ifdef DIAGNOSTIC
-void
-splassert_check(int wantipl, const char *func)
-{
- int oldipl;
-
- /*
- * This will raise the spl if too low,
- * in a feeble attempt to reduce further damage.
- */
- oldipl = raiseipl(wantipl);
-
- if (oldipl < wantipl) {
- splassert_fail(wantipl, oldipl, func);
- }
-}
-#endif