Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 09 Jan 2026 20:13:35 +0000
From:      Ed Maste <emaste@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Cc:        Minsoo Choo <minsoochoo0122@proton.me>
Subject:   git: c5d4a124d093 - main - conf: remove powerpcspe
Message-ID:  <6961616f.8363.487560a9@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by emaste:

URL: https://cgit.FreeBSD.org/src/commit/?id=c5d4a124d093f11784833f25d1332a54465678fb

commit c5d4a124d093f11784833f25d1332a54465678fb
Author:     Minsoo Choo <minsoochoo0122@proton.me>
AuthorDate: 2025-12-03 04:06:10 +0000
Commit:     Ed Maste <emaste@FreeBSD.org>
CommitDate: 2026-01-09 20:11:22 +0000

    conf: remove powerpcspe
    
    Signed-off-by: Minsoo Choo <minsoochoo0122@proton.me>
    Reviewed by:    emaste
    Pull Request:   https://github.com/freebsd/freebsd-src/pull/1914
    (cherry picked from commit 4a5a1c17ac43356fae053524187bb16f8fc1ac70)
---
 sys/conf/files.powerpc       |  51 ++--
 sys/conf/ldscript.powerpcspe | 143 ---------
 sys/conf/options.powerpc     |   1 -
 sys/powerpc/booke/spe.c      | 685 -------------------------------------------
 4 files changed, 25 insertions(+), 855 deletions(-)

diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index 0deada385f31..7989f1c9bea4 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -75,7 +75,7 @@ crypto/openssl/powerpc64/sha512p8-ppc.S			optional	ossl powerpc64
 crypto/openssl/powerpc64/vpaes-ppc.S			optional	ossl powerpc64
 crypto/openssl/powerpc64/x25519-ppc64.S			optional	ossl powerpc64
 
-cddl/compat/opensolaris/kern/opensolaris_atomic.c			optional zfs powerpc | dtrace powerpc | zfs powerpcspe | dtrace powerpcspe compile-with "${ZFS_C}"
+cddl/compat/opensolaris/kern/opensolaris_atomic.c			optional zfs powerpc | dtrace powerpc compile-with "${ZFS_C}"
 cddl/dev/dtrace/powerpc/dtrace_asm.S		optional dtrace compile-with "${DTRACE_S}"
 cddl/dev/dtrace/powerpc/dtrace_subr.c		optional dtrace compile-with "${DTRACE_C}"
 cddl/dev/fbt/powerpc/fbt_isa.c			optional dtrace_fbt | dtraceall compile-with "${FBT_C}"
@@ -235,25 +235,25 @@ dev/tsec/if_tsec_fdt.c		optional	tsec
 dev/uart/uart_cpu_powerpc.c	optional	uart
 dev/usb/controller/ehci_fsl.c	optional	ehci mpc85xx
 dev/vt/hw/ofwfb/ofwfb.c		optional	vt aim
-kern/subr_atomic64.c		optional	powerpc | powerpcspe
+kern/subr_atomic64.c		optional	powerpc
 kern/subr_dummy_vdso_tc.c	standard
 kern/subr_sfbuf.c		standard
-libkern/ashldi3.c		optional	powerpc | powerpcspe
-libkern/ashrdi3.c		optional	powerpc | powerpcspe
+libkern/ashldi3.c		optional	powerpc
+libkern/ashrdi3.c		optional	powerpc
 libkern/bcopy.c			standard
-libkern/cmpdi2.c		optional	powerpc | powerpcspe
-libkern/divdi3.c		optional	powerpc | powerpcspe
-libkern/lshrdi3.c		optional	powerpc | powerpcspe
+libkern/cmpdi2.c		optional	powerpc
+libkern/divdi3.c		optional	powerpc
+libkern/lshrdi3.c		optional	powerpc
 libkern/memcmp.c		standard
 libkern/memset.c		standard
-libkern/moddi3.c		optional	powerpc | powerpcspe
-libkern/qdivrem.c		optional	powerpc | powerpcspe
+libkern/moddi3.c		optional	powerpc
+libkern/qdivrem.c		optional	powerpc
 libkern/strcmp.c		standard
 libkern/strlen.c		standard
 libkern/strncmp.c		standard
-libkern/ucmpdi2.c		optional	powerpc | powerpcspe
-libkern/udivdi3.c		optional	powerpc | powerpcspe
-libkern/umoddi3.c		optional	powerpc | powerpcspe
+libkern/ucmpdi2.c		optional	powerpc
+libkern/udivdi3.c		optional	powerpc
+libkern/umoddi3.c		optional	powerpc
 powerpc/aim/locore.S		optional	aim no-obj
 powerpc/aim/aim_machdep.c	optional	aim
 powerpc/aim/mmu_oea.c		optional	aim powerpc
@@ -263,29 +263,28 @@ powerpc/aim/moea64_native.c	optional	aim
 powerpc/aim/mp_cpudep.c		optional	aim
 powerpc/aim/slb.c		optional	aim powerpc64 | aim powerpc64le
 powerpc/amigaone/platform_amigaone.c	optional	amigaone
-powerpc/amigaone/cpld_a1222.c	optional	powerpc amigaone | powerpcspe amigaone
-powerpc/amigaone/cpld_x5000.c	optional	powerpc amigaone | powerpc64 amigaone
+powerpc/amigaone/cpld_a1222.c	optional	powerpc amigaone
+powerpc/amigaone/cpld_x5000.c	optional	powerpc amigaone
 powerpc/booke/locore.S		optional	booke no-obj
 powerpc/booke/booke_machdep.c	optional	booke
 powerpc/booke/machdep_e500.c	optional	booke_e500
 powerpc/booke/mp_cpudep.c	optional	booke smp
 powerpc/booke/platform_bare.c	optional	booke
 powerpc/booke/pmap.c		optional	booke
-powerpc/booke/spe.c		optional	powerpcspe
 powerpc/cpufreq/dfs.c		optional	cpufreq
 powerpc/cpufreq/mpc85xx_jog.c	optional	cpufreq mpc85xx
 powerpc/cpufreq/pcr.c		optional	cpufreq aim
 powerpc/cpufreq/pmcr.c		optional	cpufreq aim powerpc64 | cpufreq aim powerpc64le
 powerpc/cpufreq/pmufreq.c	optional	cpufreq aim pmu
-powerpc/fpu/fpu_add.c		optional	fpu_emu | powerpcspe
-powerpc/fpu/fpu_compare.c	optional	fpu_emu | powerpcspe
-powerpc/fpu/fpu_div.c		optional	fpu_emu | powerpcspe
+powerpc/fpu/fpu_add.c		optional	fpu_emu
+powerpc/fpu/fpu_compare.c	optional	fpu_emu
+powerpc/fpu/fpu_div.c		optional	fpu_emu
 powerpc/fpu/fpu_emu.c		optional	fpu_emu
-powerpc/fpu/fpu_explode.c	optional	fpu_emu | powerpcspe
-powerpc/fpu/fpu_implode.c	optional	fpu_emu | powerpcspe
-powerpc/fpu/fpu_mul.c		optional	fpu_emu | powerpcspe
+powerpc/fpu/fpu_explode.c	optional	fpu_emu
+powerpc/fpu/fpu_implode.c	optional	fpu_emu
+powerpc/fpu/fpu_mul.c		optional	fpu_emu
 powerpc/fpu/fpu_sqrt.c		optional	fpu_emu
-powerpc/fpu/fpu_subr.c		optional	fpu_emu | powerpcspe
+powerpc/fpu/fpu_subr.c		optional	fpu_emu
 powerpc/mambo/mambocall.S	optional	mambo
 powerpc/mambo/mambo.c		optional	mambo
 powerpc/mambo/mambo_console.c	optional	mambo
@@ -358,7 +357,7 @@ powerpc/powernv/platform_powernv.c optional	powernv
 powerpc/powernv/powernv_centaur.c	optional	powernv
 powerpc/powernv/powernv_xscom.c	optional	powernv
 powerpc/powernv/xive.c		optional	powernv
-powerpc/powerpc/altivec.c	optional	!powerpcspe
+powerpc/powerpc/altivec.c	standard
 powerpc/powerpc/autoconf.c	standard
 powerpc/powerpc/bus_machdep.c	standard
 powerpc/powerpc/busdma_machdep.c standard
@@ -371,7 +370,7 @@ powerpc/powerpc/db_hwwatch.c	optional	ddb
 powerpc/powerpc/db_interface.c	optional	ddb
 powerpc/powerpc/db_trace.c	optional	ddb
 powerpc/powerpc/dump_machdep.c	standard
-powerpc/powerpc/elf32_machdep.c	optional	powerpc | powerpcspe | compat_freebsd32
+powerpc/powerpc/elf32_machdep.c	optional	powerpc | compat_freebsd32
 powerpc/powerpc/elf64_machdep.c	optional	powerpc64 | powerpc64le
 powerpc/powerpc/exec_machdep.c	standard
 powerpc/powerpc/fpu.c		standard
@@ -393,9 +392,9 @@ powerpc/powerpc/ptrace_machdep.c	standard
 powerpc/powerpc/sc_machdep.c	optional	sc
 powerpc/powerpc/sdt_machdep.c	optional	powerpc64 kdtrace_hooks
 powerpc/powerpc/setjmp.S	standard
-powerpc/powerpc/sigcode32.S	optional	powerpc | powerpcspe | compat_freebsd32
+powerpc/powerpc/sigcode32.S	optional	powerpc | compat_freebsd32
 powerpc/powerpc/sigcode64.S	optional	powerpc64 | powerpc64le
-powerpc/powerpc/swtch32.S	optional	powerpc | powerpcspe
+powerpc/powerpc/swtch32.S	optional	powerpc
 powerpc/powerpc/swtch64.S	optional	powerpc64 | powerpc64le
 powerpc/powerpc/stack_machdep.c	optional	ddb | stack
 powerpc/powerpc/support.S	optional	powerpc64 | powerpc64le | booke
diff --git a/sys/conf/ldscript.powerpcspe b/sys/conf/ldscript.powerpcspe
deleted file mode 100644
index fa82cbe8330f..000000000000
--- a/sys/conf/ldscript.powerpcspe
+++ /dev/null
@@ -1,143 +0,0 @@
-OUTPUT_FORMAT("elf32-powerpc-freebsd", "elf32-powerpc-freebsd",
-	      "elf32-powerpc-freebsd")
-OUTPUT_ARCH(powerpc)
-ENTRY(__start)
-SEARCH_DIR(/usr/lib);
-PROVIDE (__stack = 0);
-PHDRS
-{
-	kernel PT_LOAD;
-	dynamic PT_DYNAMIC;
-}
-SECTIONS
-{
-  /* Read-only sections, merged into text segment: */
-
-  . = kernbase + SIZEOF_HEADERS;
-  PROVIDE (begin = . - SIZEOF_HEADERS);
-
-  .text      :
-  {
-    *(.glink)
-    *(.text)
-    *(.stub)
-    /* .gnu.warning sections are handled specially by elf32.em.  */
-    *(.gnu.warning)
-    *(.gnu.linkonce.t*)
-  } :kernel =0
-  _etext = .;
-  PROVIDE (etext = .);
-
-  .interp     : { *(.interp) 	}
-  .hash          : { *(.hash)		}
-  .dynsym        : { *(.dynsym)		}
-  .dynstr        : { *(.dynstr)		}
-  .gnu.version   : { *(.gnu.version)	}
-  .gnu.version_d   : { *(.gnu.version_d)	}
-  .gnu.version_r   : { *(.gnu.version_r)	}
-  .rela.text     :
-    { *(.rela.text) *(.rela.gnu.linkonce.t*) }
-  .rela.data     :
-    { *(.rela.data) *(.rela.gnu.linkonce.d*) }
-  .rela.rodata   :
-    { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
-  .rela.got      : { *(.rela.got)		}
-  .rela.got1     : { *(.rela.got1)		}
-  .rela.got2     : { *(.rela.got2)		}
-  .rela.ctors    : { *(.rela.ctors)	}
-  .rela.dtors    : { *(.rela.dtors)	}
-  .rela.init     : { *(.rela.init)	}
-  .rela.fini     : { *(.rela.fini)	}
-  .rela.bss      : { *(.rela.bss)		}
-  .rela.plt      : { *(.rela.plt)		}
-  .rela.sdata    : { *(.rela.sdata)		}
-  .rela.sbss     : { *(.rela.sbss)		}
-  .rela.sdata2   : { *(.rela.sdata2)		}
-  .rela.sbss2    : { *(.rela.sbss2)		}
-
-  .init      : { *(.init)    } =0
-  .fini      : { *(.fini)    } =0
-  .rodata    : { *(.rodata) *(.gnu.linkonce.r*) }
-  .rodata1   : { *(.rodata1) }
-  .note.gnu.build-id : {
-    PROVIDE (__build_id_start = .);
-    *(.note.gnu.build-id)
-    PROVIDE (__build_id_end = .);
-  }
-  .sdata2    : { *(.sdata2)  }
-  .sbss2     : { *(.sbss2)   }
-  /* Adjust the address for the data segment to the next page up. */
-  . = ((. + 0x1000) & ~(0x1000 - 1));
-  .data    :
-  {
-    *(.data)
-    *(.gnu.linkonce.d*)
-    CONSTRUCTORS
-  }
-  .data1   : { *(.data1) }
-  .got1           : { *(.got1) }
-  . = ALIGN(4096);
-  .got            : { *(.got) }
-  .got.plt        : { *(.got.plt) }
-  .init_array     :
-  {
-    PROVIDE_HIDDEN (__init_array_start = .);
-    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*)))
-    KEEP (*(.init_array))
-    PROVIDE_HIDDEN (__init_array_end = .);
-  }
-  .fini_array     :
-  {
-    PROVIDE_HIDDEN (__fini_array_start = .);
-    KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*)))
-    KEEP (*(.fini_array))
-    PROVIDE_HIDDEN (__fini_array_end = .);
-  }
-  .dynamic        : { *(.dynamic) } :kernel :dynamic
-  /* Put .ctors and .dtors next to the .got2 section, so that the pointers
-     get relocated with -mrelocatable. Also put in the .fixup pointers.
-     The current compiler no longer needs this, but keep it around for 2.7.2  */
-                PROVIDE (_GOT2_START_ = .);
-  .got2           :  { *(.got2) } :kernel
-                PROVIDE (__CTOR_LIST__ = .);
-  .ctors          : { *(.ctors) }
-                PROVIDE (__CTOR_END__ = .);
-                PROVIDE (__DTOR_LIST__ = .);
-  .dtors          : { *(.dtors) }
-                PROVIDE (__DTOR_END__ = .);
-                PROVIDE (_FIXUP_START_ = .);
-  .fixup          : { *(.fixup) }
-                PROVIDE (_FIXUP_END_ = .);
-                PROVIDE (_GOT2_END_ = .);
-  /* We want the small data sections together, so single-instruction offsets
-     can access them all, and initialized data all before uninitialized, so
-     we can shorten the on-disk segment size.  */
-  .sdata     : { *(.sdata) }
-  _edata  =  .;
-  PROVIDE (edata = .);
-  .sbss      :
-  {
-    PROVIDE (__sbss_start = .);
-    *(.sbss)
-    *(.scommon)
-    *(.dynsbss)
-    PROVIDE (__sbss_end = .);
-  }
-  .plt   : { *(.plt) }
-  .bss       :
-  {
-   PROVIDE (__bss_start = .);
-   *(.dynbss)
-   *(.bss)
-   *(COMMON)
-  }
-  _end = . ;
-  PROVIDE (end = .);
-
-  /* Debug */
-  INCLUDE debuginfo.ldscript
-
-  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
-  /DISCARD/ : { *(.note.GNU-stack) }
-}
-
diff --git a/sys/conf/options.powerpc b/sys/conf/options.powerpc
index a6096d1b32ca..c8ab0e066f49 100644
--- a/sys/conf/options.powerpc
+++ b/sys/conf/options.powerpc
@@ -8,7 +8,6 @@ CELL
 POWERPC
 POWERPC64
 POWERPC64LE
-POWERPCSPE
 
 FPU_EMU
 
diff --git a/sys/powerpc/booke/spe.c b/sys/powerpc/booke/spe.c
deleted file mode 100644
index e10392508e4e..000000000000
--- a/sys/powerpc/booke/spe.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*-
- * Copyright (C) 1996 Wolfgang Solfrank.
- * Copyright (C) 1996 TooLs GmbH.
- * 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 TooLs GmbH.
- * 4. The name of TooLs GmbH may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
- *
- *	$NetBSD: fpu.c,v 1.5 2001/07/22 11:29:46 wiz Exp $
- */
-
-#include <sys/param.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-#include <sys/limits.h>
-
-#include <machine/altivec.h>
-#include <machine/fpu.h>
-#include <machine/ieeefp.h>
-#include <machine/pcb.h>
-#include <machine/psl.h>
-
-#include <powerpc/fpu/fpu_arith.h>
-#include <powerpc/fpu/fpu_emu.h>
-#include <powerpc/fpu/fpu_extern.h>
-
-void spe_handle_fpdata(struct trapframe *);
-void spe_handle_fpround(struct trapframe *);
-static int spe_emu_instr(uint32_t, struct fpemu *, struct fpn **, uint32_t *);
-
-static void
-save_vec_int(struct thread *td)
-{
-	int	msr;
-	struct	pcb *pcb;
-
-	pcb = td->td_pcb;
-
-	/*
-	 * Temporarily re-enable the vector unit during the save
-	 */
-	msr = mfmsr();
-	mtmsr(msr | PSL_VEC);
-
-	/*
-	 * Save the vector registers and SPEFSCR to the PCB
-	 */
-#define EVSTDW(n)   __asm ("evstdw %1,0(%0)" \
-		:: "b"(pcb->pcb_vec.vr[n]), "n"(n));
-	EVSTDW(0);	EVSTDW(1);	EVSTDW(2);	EVSTDW(3);
-	EVSTDW(4);	EVSTDW(5);	EVSTDW(6);	EVSTDW(7);
-	EVSTDW(8);	EVSTDW(9);	EVSTDW(10);	EVSTDW(11);
-	EVSTDW(12);	EVSTDW(13);	EVSTDW(14);	EVSTDW(15);
-	EVSTDW(16);	EVSTDW(17);	EVSTDW(18);	EVSTDW(19);
-	EVSTDW(20);	EVSTDW(21);	EVSTDW(22);	EVSTDW(23);
-	EVSTDW(24);	EVSTDW(25);	EVSTDW(26);	EVSTDW(27);
-	EVSTDW(28);	EVSTDW(29);	EVSTDW(30);	EVSTDW(31);
-#undef EVSTDW
-
-	__asm ( "evxor 0,0,0\n"
-		"evmwumiaa 0,0,0\n"
-		"evstdd 0,0(%0)" :: "b"(&pcb->pcb_vec.spare[0]));
-	pcb->pcb_vec.vscr = mfspr(SPR_SPEFSCR);
-
-	/*
-	 * Disable vector unit again
-	 */
-	isync();
-	mtmsr(msr);
-
-}
-
-void
-enable_vec(struct thread *td)
-{
-	int	msr;
-	struct	pcb *pcb;
-	struct	trapframe *tf;
-
-	pcb = td->td_pcb;
-	tf = trapframe(td);
-
-	/*
-	 * Save the thread's SPE CPU number, and set the CPU's current
-	 * vector thread
-	 */
-	td->td_pcb->pcb_veccpu = PCPU_GET(cpuid);
-	PCPU_SET(vecthread, td);
-
-	/*
-	 * Enable the vector unit for when the thread returns from the
-	 * exception. If this is the first time the unit has been used by
-	 * the thread, initialise the vector registers and VSCR to 0, and
-	 * set the flag to indicate that the vector unit is in use.
-	 */
-	tf->srr1 |= PSL_VEC;
-	if (!(pcb->pcb_flags & PCB_VEC)) {
-		memset(&pcb->pcb_vec, 0, sizeof pcb->pcb_vec);
-		pcb->pcb_flags |= PCB_VEC;
-		pcb->pcb_vec.vscr = mfspr(SPR_SPEFSCR);
-	}
-
-	/*
-	 * Temporarily enable the vector unit so the registers
-	 * can be restored.
-	 */
-	msr = mfmsr();
-	mtmsr(msr | PSL_VEC);
-
-	/* Restore SPEFSCR and ACC.  Use %r0 as the scratch for ACC. */
-	mtspr(SPR_SPEFSCR, pcb->pcb_vec.vscr);
-	__asm __volatile("isync;evldd 0, 0(%0); evmra 0,0\n"
-	    :: "b"(&pcb->pcb_vec.spare[0]));
-
-	/* 
-	 * The lower half of each register will be restored on trap return.  Use
-	 * %r0 as a scratch register, and restore it last.
-	 */
-#define	EVLDW(n)   __asm __volatile("evldw 0, 0(%0); evmergehilo "#n",0,"#n \
-	    :: "b"(&pcb->pcb_vec.vr[n]));
-	EVLDW(1);	EVLDW(2);	EVLDW(3);	EVLDW(4);
-	EVLDW(5);	EVLDW(6);	EVLDW(7);	EVLDW(8);
-	EVLDW(9);	EVLDW(10);	EVLDW(11);	EVLDW(12);
-	EVLDW(13);	EVLDW(14);	EVLDW(15);	EVLDW(16);
-	EVLDW(17);	EVLDW(18);	EVLDW(19);	EVLDW(20);
-	EVLDW(21);	EVLDW(22);	EVLDW(23);	EVLDW(24);
-	EVLDW(25);	EVLDW(26);	EVLDW(27);	EVLDW(28);
-	EVLDW(29);	EVLDW(30);	EVLDW(31);	EVLDW(0);
-#undef EVLDW
-
-	isync();
-	mtmsr(msr);
-}
-
-void
-save_vec(struct thread *td)
-{
-	struct pcb *pcb;
-
-	pcb = td->td_pcb;
-
-	save_vec_int(td);
-
-	/*
-	 * Clear the current vec thread and pcb's CPU id
-	 * XXX should this be left clear to allow lazy save/restore ?
-	 */
-	pcb->pcb_veccpu = INT_MAX;
-	PCPU_SET(vecthread, NULL);
-}
-
-/*
- * Save SPE state without dropping ownership.  This will only save state if
- * the current vector-thread is `td'.  This is used for taking core dumps, so
- * don't leak kernel information; overwrite the low words of each vector with
- * their real value, taken from the thread's trap frame, unconditionally.
- */
-void
-save_vec_nodrop(struct thread *td)
-{
-	struct pcb *pcb;
-	int i;
-
-	if (td == PCPU_GET(vecthread))
-		save_vec_int(td);
-
-	pcb = td->td_pcb;
-
-	for (i = 0; i < 32; i++) {
-		pcb->pcb_vec.vr[i][1] =
-		    td->td_frame ? td->td_frame->fixreg[i] : 0;
-	}
-}
-
-#define	SPE_INST_MASK	0x31f
-#define	EADD	0x200
-#define	ESUB	0x201
-#define	EABS	0x204
-#define	ENABS	0x205
-#define	ENEG	0x206
-#define	EMUL	0x208
-#define	EDIV	0x209
-#define	ECMPGT	0x20c
-#define	ECMPLT	0x20d
-#define	ECMPEQ	0x20e
-#define	ECFUI	0x210
-#define	ECFSI	0x211
-#define	ECTUI	0x214
-#define	ECTSI	0x215
-#define	ECTUF	0x216
-#define	ECTSF	0x217
-#define	ECTUIZ	0x218
-#define	ECTSIZ	0x21a
-
-#define	SPE		0x4
-#define	SPFP		0x6
-#define	DPFP		0x7
-
-#define	SPE_OPC		4
-#define	OPC_SHIFT	26
-
-#define	EVFSADD		0x280
-#define	EVFSSUB		0x281
-#define	EVFSABS		0x284
-#define	EVFSNABS	0x285
-#define	EVFSNEG		0x286
-#define	EVFSMUL		0x288
-#define	EVFSDIV		0x289
-#define	EVFSCMPGT	0x28c
-#define	EVFSCMPLT	0x28d
-#define	EVFSCMPEQ	0x28e
-#define	EVFSCFUI	0x290
-#define	EVFSCFSI	0x291
-#define	EVFSCTUI	0x294
-#define	EVFSCTSI	0x295
-#define	EVFSCTUF	0x296
-#define	EVFSCTSF	0x297
-#define	EVFSCTUIZ	0x298
-#define	EVFSCTSIZ	0x29a
-
-#define	EFSADD		0x2c0
-#define	EFSSUB		0x2c1
-#define	EFSABS		0x2c4
-#define	EFSNABS		0x2c5
-#define	EFSNEG		0x2c6
-#define	EFSMUL		0x2c8
-#define	EFSDIV		0x2c9
-#define	EFSCMPGT	0x2cc
-#define	EFSCMPLT	0x2cd
-#define	EFSCMPEQ	0x2ce
-#define	EFSCFD		0x2cf
-#define	EFSCFUI		0x2d0
-#define	EFSCFSI		0x2d1
-#define	EFSCTUI		0x2d4
-#define	EFSCTSI		0x2d5
-#define	EFSCTUF		0x2d6
-#define	EFSCTSF		0x2d7
-#define	EFSCTUIZ	0x2d8
-#define	EFSCTSIZ	0x2da
-
-#define	EFDADD		0x2e0
-#define	EFDSUB		0x2e1
-#define	EFDABS		0x2e4
-#define	EFDNABS		0x2e5
-#define	EFDNEG		0x2e6
-#define	EFDMUL		0x2e8
-#define	EFDDIV		0x2e9
-#define	EFDCMPGT	0x2ec
-#define	EFDCMPLT	0x2ed
-#define	EFDCMPEQ	0x2ee
-#define	EFDCFS		0x2ef
-#define	EFDCFUI		0x2f0
-#define	EFDCFSI		0x2f1
-#define	EFDCTUI		0x2f4
-#define	EFDCTSI		0x2f5
-#define	EFDCTUF		0x2f6
-#define	EFDCTSF		0x2f7
-#define	EFDCTUIZ	0x2f8
-#define	EFDCTSIZ	0x2fa
-
-enum {
-	NONE,
-	SINGLE,
-	DOUBLE,
-	VECTOR,
-};
-
-static uint32_t fpscr_to_spefscr(uint32_t fpscr)
-{
-	uint32_t spefscr;
-
-	spefscr = 0;
-
-	if (fpscr & FPSCR_VX)
-		spefscr |= SPEFSCR_FINV;
-	if (fpscr & FPSCR_OX)
-		spefscr |= SPEFSCR_FOVF;
-	if (fpscr & FPSCR_UX)
-		spefscr |= SPEFSCR_FUNF;
-	if (fpscr & FPSCR_ZX)
-		spefscr |= SPEFSCR_FDBZ;
-	if (fpscr & FPSCR_XX)
-		spefscr |= SPEFSCR_FX;
-
-	return (spefscr);
-}
-
-/* Sign is 0 for unsigned, 1 for signed. */
-static int
-spe_to_int(struct fpemu *fpemu, struct fpn *fpn, uint32_t *val, int sign)
-{
-	uint32_t res[2];
-
-	res[0] = fpu_ftox(fpemu, fpn, res);
-	if (res[0] != UINT_MAX && res[0] != 0)
-		fpemu->fe_cx |= FPSCR_OX;
-	else if (sign == 0 && res[0] != 0)
-		fpemu->fe_cx |= FPSCR_UX;
-	else
-		*val = res[1];
-
-	return (0);
-}
-
-/* Masked instruction */
-/*
- * For compare instructions, returns 1 if success, 0 if not.  For all others,
- * returns -1, or -2 if no result needs recorded.
- */
-static int
-spe_emu_instr(uint32_t instr, struct fpemu *fpemu,
-    struct fpn **result, uint32_t *iresult)
-{
-	switch (instr & SPE_INST_MASK) {
-	case EABS:
-	case ENABS:
-	case ENEG:
-		/* Taken care of elsewhere. */
-		break;
-	case ECTUIZ:
-		fpemu->fe_cx &= ~FPSCR_RN;
-		fpemu->fe_cx |= FP_RZ;
-	case ECTUI:
-		spe_to_int(fpemu, &fpemu->fe_f2, iresult, 0);
-		return (-1);
-	case ECTSIZ:
-		fpemu->fe_cx &= ~FPSCR_RN;
-		fpemu->fe_cx |= FP_RZ;
-	case ECTSI:
-		spe_to_int(fpemu, &fpemu->fe_f2, iresult, 1);
-		return (-1);
-	case EADD:
-		*result = fpu_add(fpemu);
-		break;
-	case ESUB:
-		*result = fpu_sub(fpemu);
-		break;
-	case EMUL:
-		*result = fpu_mul(fpemu);
-		break;
-	case EDIV:
-		*result = fpu_div(fpemu);
-		break;
-	case ECMPGT:
-		fpu_compare(fpemu, 0);
-		if (fpemu->fe_cx & FPSCR_FG)
-			return (1);
-		return (0);
-	case ECMPLT:
-		fpu_compare(fpemu, 0);
-		if (fpemu->fe_cx & FPSCR_FL)
-			return (1);
-		return (0);
-	case ECMPEQ:
-		fpu_compare(fpemu, 0);
-		if (fpemu->fe_cx & FPSCR_FE)
-			return (1);
-		return (0);
-	default:
-		printf("Unknown instruction %x\n", instr);
-	}
-
-	return (-1);
-}
-
-static int
-spe_explode(struct fpemu *fe, struct fpn *fp, uint32_t type,
-    uint32_t hi, uint32_t lo)
-{
-	uint32_t s;
-
-	fp->fp_sign = hi >> 31;
-	fp->fp_sticky = 0;
-	switch (type) {
-	case SINGLE:
-		s = fpu_stof(fp, hi);
-		break;
-
-	case DOUBLE:
-		s = fpu_dtof(fp, hi, lo);
-		break;
-	}
-
-	if (s == FPC_QNAN && (fp->fp_mant[0] & FP_QUIETBIT) == 0) {
-		/*
-		 * Input is a signalling NaN.  All operations that return
-		 * an input NaN operand put it through a ``NaN conversion'',
-		 * which basically just means ``turn on the quiet bit''.
-		 * We do this here so that all NaNs internally look quiet
-		 * (we can tell signalling ones by their class).
-		 */
-		fp->fp_mant[0] |= FP_QUIETBIT;
-		fe->fe_cx = FPSCR_VXSNAN;	/* assert invalid operand */
-		s = FPC_SNAN;
-	}
-	fp->fp_class = s;
-
-	return (0);
-}
-
-/*
- * Save the high word of a 64-bit GPR for manipulation in the exception handler.
- */
-static uint32_t
-spe_save_reg_high(int reg)
-{
-	uint32_t vec[2];
-#define EVSTDW(n)   case n: __asm __volatile ("evstdw %1,0(%0)" \
-		:: "b"(vec), "n"(n) : "memory"); break;
-	switch (reg) {
-	EVSTDW(0);	EVSTDW(1);	EVSTDW(2);	EVSTDW(3);
-	EVSTDW(4);	EVSTDW(5);	EVSTDW(6);	EVSTDW(7);
-	EVSTDW(8);	EVSTDW(9);	EVSTDW(10);	EVSTDW(11);
-	EVSTDW(12);	EVSTDW(13);	EVSTDW(14);	EVSTDW(15);
-	EVSTDW(16);	EVSTDW(17);	EVSTDW(18);	EVSTDW(19);
-	EVSTDW(20);	EVSTDW(21);	EVSTDW(22);	EVSTDW(23);
-	EVSTDW(24);	EVSTDW(25);	EVSTDW(26);	EVSTDW(27);
-	EVSTDW(28);	EVSTDW(29);	EVSTDW(30);	EVSTDW(31);
-	}
-#undef EVSTDW
-
-	return (vec[0]);
-}
-
-/*
- * Load the given value into the high word of the requested register.
- */
-static void
-spe_load_reg_high(int reg, uint32_t val)
-{
-#define	EVLDW(n)   case n: __asm __volatile("evmergelo "#n",%0,"#n \
-	    :: "r"(val)); break;
-	switch (reg) {
-	EVLDW(1);	EVLDW(2);	EVLDW(3);	EVLDW(4);
-	EVLDW(5);	EVLDW(6);	EVLDW(7);	EVLDW(8);
-	EVLDW(9);	EVLDW(10);	EVLDW(11);	EVLDW(12);
-	EVLDW(13);	EVLDW(14);	EVLDW(15);	EVLDW(16);
-	EVLDW(17);	EVLDW(18);	EVLDW(19);	EVLDW(20);
-	EVLDW(21);	EVLDW(22);	EVLDW(23);	EVLDW(24);
-	EVLDW(25);	EVLDW(26);	EVLDW(27);	EVLDW(28);
-	EVLDW(29);	EVLDW(30);	EVLDW(31);	EVLDW(0);
-	}
-#undef EVLDW
-
-}
-
-void
-spe_handle_fpdata(struct trapframe *frame)
-{
-	struct fpemu fpemu;
-	struct fpn *result;
-	uint32_t instr, instr_sec_op;
-	uint32_t cr_shift, ra, rb, rd, src;
-	uint32_t high, low, res, tmp; /* For vector operations. */
-	uint32_t spefscr = 0;
-	uint32_t ftod_res[2];
-	int width; /* Single, Double, Vector, Integer */
-	int err;
-	uint32_t msr;
-
-	err = fueword32((void *)frame->srr0, &instr);
-
-	if (err != 0)
-		return;
-		/* Fault. */;
-
-	if ((instr >> OPC_SHIFT) != SPE_OPC)
-		return;
-
-	msr = mfmsr();
-	/*
-	 * 'cr' field is the upper 3 bits of rd.  Magically, since a) rd is 5
-	 * bits, b) each 'cr' field is 4 bits, and c) Only the 'GT' bit is
-	 * modified for most compare operations, the full value of rd can be
-	 * used as a shift value.
-	 */
-	rd = (instr >> 21) & 0x1f;
-	ra = (instr >> 16) & 0x1f;
-	rb = (instr >> 11) & 0x1f;
-	src = (instr >> 5) & 0x7;
-	cr_shift = 28 - (rd & 0x1f);
-
-	instr_sec_op = (instr & 0x7ff);
-
-	memset(&fpemu, 0, sizeof(fpemu));
-
-	width = NONE;
-	switch (src) {
-	case SPE:
-		mtmsr(msr | PSL_VEC);
-		switch (instr_sec_op) {
-		case EVFSABS:
-			high = spe_save_reg_high(ra) & ~(1U << 31);
-			frame->fixreg[rd] = frame->fixreg[ra] & ~(1U << 31);
-			spe_load_reg_high(rd, high);
-			break;
-		case EVFSNABS:
-			high = spe_save_reg_high(ra) | (1U << 31);
-			frame->fixreg[rd] = frame->fixreg[ra] | (1U << 31);
-			spe_load_reg_high(rd, high);
-			break;
-		case EVFSNEG:
-			high = spe_save_reg_high(ra) ^ (1U << 31);
-			frame->fixreg[rd] = frame->fixreg[ra] ^ (1U << 31);
-			spe_load_reg_high(rd, high);
-			break;
-		default:
-			/* High word */
-			spe_explode(&fpemu, &fpemu.fe_f1, SINGLE,
-			    spe_save_reg_high(ra), 0);
-			spe_explode(&fpemu, &fpemu.fe_f2, SINGLE,
-			    spe_save_reg_high(rb), 0);
-			high = spe_emu_instr(instr_sec_op, &fpemu, &result,
-			    &tmp);
-
-			if (high < 0)
-				spe_load_reg_high(rd, tmp);
-
-			spefscr = fpscr_to_spefscr(fpemu.fe_cx) << 16;
-			/* Clear the fpemu to start over on the lower bits. */
-			memset(&fpemu, 0, sizeof(fpemu));
-
-			/* Now low word */
-			spe_explode(&fpemu, &fpemu.fe_f1, SINGLE,
-			    frame->fixreg[ra], 0);
-			spe_explode(&fpemu, &fpemu.fe_f2, SINGLE,
-			    frame->fixreg[rb], 0);
-			spefscr |= fpscr_to_spefscr(fpemu.fe_cx);
-			low = spe_emu_instr(instr_sec_op, &fpemu, &result,
-			    &frame->fixreg[rd]);
-			if (instr_sec_op == EVFSCMPEQ ||
-			    instr_sec_op == EVFSCMPGT ||
-			    instr_sec_op == EVFSCMPLT) {
-				res = (high << 3) | (low << 2) |
-				    ((high | low) << 1) | (high & low);
-				width = NONE;
-			} else
-				width = VECTOR;
-			break;
-		}
-		goto end;
-
-	case SPFP:
-		switch (instr_sec_op) {
-		case EFSABS:
-			frame->fixreg[rd] = frame->fixreg[ra] & ~(1U << 31);
-			break;
-		case EFSNABS:
-			frame->fixreg[rd] = frame->fixreg[ra] | (1U << 31);
-			break;
-		case EFSNEG:
-			frame->fixreg[rd] = frame->fixreg[ra] ^ (1U << 31);
-			break;
-		case EFSCFD:
-			mtmsr(msr | PSL_VEC);
-			spe_explode(&fpemu, &fpemu.fe_f3, DOUBLE,
-			    spe_save_reg_high(rb), frame->fixreg[rb]);
-			result = &fpemu.fe_f3;
-			width = SINGLE;
-			break;
-		default:
-			spe_explode(&fpemu, &fpemu.fe_f1, SINGLE,
-			    frame->fixreg[ra], 0);
-			spe_explode(&fpemu, &fpemu.fe_f2, SINGLE,
-			    frame->fixreg[rb], 0);
-			width = SINGLE;
-		}
-		break;
-	case DPFP:
-		mtmsr(msr | PSL_VEC);
-		switch (instr_sec_op) {
-		case EFDABS:
-			high = spe_save_reg_high(ra) & ~(1U << 31);
-			frame->fixreg[rd] = frame->fixreg[ra];
-			spe_load_reg_high(rd, high);
-			break;
-		case EFDNABS:
-			high = spe_save_reg_high(ra) | (1U << 31);
-			frame->fixreg[rd] = frame->fixreg[ra];
-			spe_load_reg_high(rd, high);
-			break;
-		case EFDNEG:
-			high = spe_save_reg_high(ra) ^ (1U << 31);
-			frame->fixreg[rd] = frame->fixreg[ra];
-			spe_load_reg_high(rd, high);
-			break;
-		case EFDCFS:
-			spe_explode(&fpemu, &fpemu.fe_f3, SINGLE,
-			    frame->fixreg[rb], 0);
-			result = &fpemu.fe_f3;
-			width = DOUBLE;
-			break;
-		default:
-			spe_explode(&fpemu, &fpemu.fe_f1, DOUBLE,
-			    spe_save_reg_high(ra), frame->fixreg[ra]);
-			spe_explode(&fpemu, &fpemu.fe_f2, DOUBLE,
-			    spe_save_reg_high(rb), frame->fixreg[rb]);
-			width = DOUBLE;
-		}
-		break;
-	}
-	switch (instr_sec_op) {
-	case EFDCFS:
-	case EFSCFD:
-		/* Already handled. */
-		break;
-	default:
-		res = spe_emu_instr(instr_sec_op, &fpemu, &result,
-		    &frame->fixreg[rd]);
-		if (res != -1)
-			res <<= 2;
-		break;
-	}
-
-	switch (instr_sec_op & SPE_INST_MASK) {
-	case ECMPEQ:
-	case ECMPGT:
-	case ECMPLT:
-		frame->cr &= ~(0xf << cr_shift);
-		frame->cr |= (res << cr_shift);
-		break;
-	case ECTUI:
-	case ECTUIZ:
-	case ECTSI:
-	case ECTSIZ:
-		break;
-	default:
-		switch (width) {
-		case NONE:
-		case VECTOR:
-			break;
-		case SINGLE:
-			frame->fixreg[rd] = fpu_ftos(&fpemu, result);
-			break;
-		case DOUBLE:
-			spe_load_reg_high(rd, fpu_ftod(&fpemu, result, ftod_res));
-			frame->fixreg[rd] = ftod_res[1];
-			break;
-		default:
-			panic("Unknown storage width %d", width);
-			break;
-		}
-	}
-
-end:
-	spefscr |= (mfspr(SPR_SPEFSCR) & ~SPEFSCR_FINVS);
-	mtspr(SPR_SPEFSCR, spefscr);
-	frame->srr0 += 4;
-	mtmsr(msr);
-
-	return;
-}
-
-void
-spe_handle_fpround(struct trapframe *frame)
*** 8 LINES SKIPPED ***


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6961616f.8363.487560a9>