Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/alpha/alpha - In unaligned_fixup(), use defined con...



details:   https://anonhg.NetBSD.org/src/rev/b542330760b9
branches:  trunk
changeset: 984725:b542330760b9
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Mon Jul 19 22:21:36 2021 +0000

description:
- In unaligned_fixup(), use defined constants for opcodes, not magic numbers.

- In handle_opdec(), use ufetch_int() to fetch the instruction and
  _u{fetch,store}_{8,16}() when emulating BWX instructions rather
  than copyin() / copyout() (they're faster).

- Add event counters for BWX instruction emulation.

diffstat:

 sys/arch/alpha/alpha/trap.c |  88 ++++++++++++++++++++++++++++++++------------
 1 files changed, 63 insertions(+), 25 deletions(-)

diffs (223 lines):

diff -r d7cfb587111a -r b542330760b9 sys/arch/alpha/alpha/trap.c
--- a/sys/arch/alpha/alpha/trap.c       Mon Jul 19 21:16:33 2021 +0000
+++ b/sys/arch/alpha/alpha/trap.c       Mon Jul 19 22:21:36 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.135 2019/11/21 19:23:58 ad Exp $ */
+/* $NetBSD: trap.c,v 1.136 2021/07/19 22:21:36 thorpej Exp $ */
 
 /*-
  * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
@@ -87,13 +87,15 @@
  * rights to redistribute these changes.
  */
 
+#define        __UFETCHSTORE_PRIVATE   /* see handle_opdec() */
+
 #include "opt_fix_unaligned_vax_fp.h"
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.135 2019/11/21 19:23:58 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.136 2021/07/19 22:21:36 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -875,65 +877,65 @@
        signo = SIGSEGV;
        if (dofix && selected_tab->fixable) {
                switch (opcode) {
-               case 0x0c:                      /* ldwu */
+               case op_ldwu:
                        /* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */
                        unaligned_load_integer(worddata);
                        break;
 
-               case 0x0d:                      /* stw */
+               case op_stw:
                        /* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */
                        unaligned_store_integer(worddata);
                        break;
 
 #ifdef FIX_UNALIGNED_VAX_FP
-               case 0x20:                      /* ldf */
+               case op_ldf:
                        unaligned_load_floating(intdata, Ffloat_to_reg);
                        break;
 
-               case 0x21:                      /* ldg */
+               case op_ldg:
                        unaligned_load_floating(longdata, Gfloat_reg_cvt);
                        break;
 #endif
 
-               case 0x22:                      /* lds */
+               case op_lds:
                        unaligned_load_floating(intdata, Sfloat_to_reg);
                        break;
 
-               case 0x23:                      /* ldt */
+               case op_ldt:
                        unaligned_load_floating(longdata, Tfloat_reg_cvt);
                        break;
 
 #ifdef FIX_UNALIGNED_VAX_FP
-               case 0x24:                      /* stf */
+               case op_stf:
                        unaligned_store_floating(intdata, reg_to_Ffloat);
                        break;
 
-               case 0x25:                      /* stg */
+               case op_stg:
                        unaligned_store_floating(longdata, Gfloat_reg_cvt);
                        break;
 #endif
 
-               case 0x26:                      /* sts */
+               case op_sts:
                        unaligned_store_floating(intdata, reg_to_Sfloat);
                        break;
 
-               case 0x27:                      /* stt */
+               case op_stt:
                        unaligned_store_floating(longdata, Tfloat_reg_cvt);
                        break;
 
-               case 0x28:                      /* ldl */
+               case op_ldl:
                        unaligned_load_integer(intdata);
                        break;
 
-               case 0x29:                      /* ldq */
+               case op_ldq:
                        unaligned_load_integer(longdata);
                        break;
 
-               case 0x2c:                      /* stl */
+               case op_stl:
                        unaligned_store_integer(intdata);
                        break;
 
-               case 0x2d:                      /* stq */
+               case op_stq:
                        unaligned_store_integer(longdata);
                        break;
 
@@ -958,6 +960,28 @@
        return (signo);
 }
 
+static struct evcnt emul_bwx_ldbu =
+    EVCNT_INITIALIZER(EVCNT_TYPE_TRAP, NULL, "emul bwx", "ldbu");
+static struct evcnt emul_bwx_ldwu =
+    EVCNT_INITIALIZER(EVCNT_TYPE_TRAP, NULL, "emul bwx", "ldwu");
+static struct evcnt emul_bwx_stb =
+    EVCNT_INITIALIZER(EVCNT_TYPE_TRAP, NULL, "emul bwx", "stb");
+static struct evcnt emul_bwx_stw =
+    EVCNT_INITIALIZER(EVCNT_TYPE_TRAP, NULL, "emul bwx", "stw");
+static struct evcnt emul_bwx_sextb =
+    EVCNT_INITIALIZER(EVCNT_TYPE_TRAP, NULL, "emul bwx", "sextb");
+static struct evcnt emul_bwx_sextw =
+    EVCNT_INITIALIZER(EVCNT_TYPE_TRAP, NULL, "emul bwx", "sextw");
+
+EVCNT_ATTACH_STATIC(emul_bwx_ldbu);
+EVCNT_ATTACH_STATIC(emul_bwx_ldwu);
+EVCNT_ATTACH_STATIC(emul_bwx_stb);
+EVCNT_ATTACH_STATIC(emul_bwx_stw);
+EVCNT_ATTACH_STATIC(emul_bwx_sextb);
+EVCNT_ATTACH_STATIC(emul_bwx_sextw);
+
+#define        EMUL_COUNT(ev)  atomic_inc_64(&(ev).ev_count)
+
 /*
  * Reserved/unimplemented instruction (opDec fault) handler
  *
@@ -986,7 +1010,7 @@
        l->l_md.md_tf->tf_regs[FRAME_SP] = alpha_pal_rdusp();
 
        inst_pc = memaddr = l->l_md.md_tf->tf_regs[FRAME_PC] - 4;
-       if (copyin((void *)inst_pc, &inst, sizeof (inst)) != 0) {
+       if (ufetch_int((void *)inst_pc, &inst.bits) != 0) {
                /*
                 * really, this should never happen, but in case it
                 * does we handle it.
@@ -1012,6 +1036,11 @@
                if (inst.mem_format.opcode == op_ldwu ||
                    inst.mem_format.opcode == op_stw) {
                        if (memaddr & 0x01) {
+                               if (inst.mem_format.opcode == op_ldwu) {
+                                       EMUL_COUNT(emul_bwx_ldwu);
+                               } else {
+                                       EMUL_COUNT(emul_bwx_stw);
+                               }
                                sig = unaligned_fixup(memaddr,
                                    inst.mem_format.opcode,
                                    inst.mem_format.ra, l);
@@ -1021,35 +1050,42 @@
                        }
                }
 
+               /*
+                * We know the addresses are aligned, so it's safe to
+                * use _u{fetch,store}_{8,16}().  Note, these are
+                * __UFETCHSTORE_PRIVATE, but this is MD code, and
+                * we know the details of the alpha implementation.
+                */
+
                if (inst.mem_format.opcode == op_ldbu) {
                        uint8_t b;
 
-                       /* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */
-                       if (copyin((void *)memaddr, &b, sizeof (b)) != 0)
+                       EMUL_COUNT(emul_bwx_ldbu);
+                       if (_ufetch_8((void *)memaddr, &b) != 0)
                                goto sigsegv;
                        if (regptr != NULL)
                                *regptr = b;
                } else if (inst.mem_format.opcode == op_ldwu) {
                        uint16_t w;
 
-                       /* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */
-                       if (copyin((void *)memaddr, &w, sizeof (w)) != 0)
+                       EMUL_COUNT(emul_bwx_ldwu);
+                       if (_ufetch_16((void *)memaddr, &w) != 0)
                                goto sigsegv;
                        if (regptr != NULL)
                                *regptr = w;
                } else if (inst.mem_format.opcode == op_stw) {
                        uint16_t w;
 
-                       /* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */
+                       EMUL_COUNT(emul_bwx_stw);
                        w = (regptr != NULL) ? *regptr : 0;
-                       if (copyout(&w, (void *)memaddr, sizeof (w)) != 0)
+                       if (_ustore_16((void *)memaddr, w) != 0)
                                goto sigsegv;
                } else if (inst.mem_format.opcode == op_stb) {
                        uint8_t b;
 
-                       /* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */
+                       EMUL_COUNT(emul_bwx_stb);
                        b = (regptr != NULL) ? *regptr : 0;
-                       if (copyout(&b, (void *)memaddr, sizeof (b)) != 0)
+                       if (_ustore_8((void *)memaddr, b) != 0)
                                goto sigsegv;
                }
                break;
@@ -1059,6 +1095,7 @@
                    inst.operate_generic_format.ra == 31) {
                        int8_t b;
 
+                       EMUL_COUNT(emul_bwx_sextb);
                        if (inst.operate_generic_format.is_lit) {
                                b = inst.operate_lit_format.literal;
                        } else {
@@ -1077,6 +1114,7 @@
                    inst.operate_generic_format.ra == 31) {
                        int16_t w;
 
+                       EMUL_COUNT(emul_bwx_sextw);
                        if (inst.operate_generic_format.is_lit) {
                                w = inst.operate_lit_format.literal;
                        } else {



Home | Main Index | Thread Index | Old Index