The branch main has been updated by emaste:

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

commit c5d4a124d093f11784833f25d1332a54465678fb
Author:     Minsoo Choo <[email protected]>
AuthorDate: 2025-12-03 04:06:10 +0000
Commit:     Ed Maste <[email protected]>
CommitDate: 2026-01-09 20:11:22 +0000

    conf: remove powerpcspe
    
    Signed-off-by: Minsoo Choo <[email protected]>
    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 ***

Reply via email to