diff options
| author | rin <rin@NetBSD.org> | 2022-06-02 00:32:14 +0000 |
|---|---|---|
| committer | rin <rin@NetBSD.org> | 2022-06-02 00:32:14 +0000 |
| commit | 2806888e7c78f82f09b8f6fced29bfcdaee7c7bb (patch) | |
| tree | 292996c2d614ae90bce026cfbe7be9ac3c87efc3 /sys | |
| parent | 92b19a2762ae63d2426e24c8cc645983d05e3882 (diff) | |
As a tiny optimization, rearrange cases as follows:
(1) load/store of format D (base + disp)
(2) load/store of format X (base + index)
(3) lmw and stmw
For clang-compiled userland (*), their frequencies are roughly,
(1) > (2) >> (3) ~ 0.
Improvement should be minor; we are already trapped in the alignment
fault handler.
(*) clang unconditionally emits unaligned memory access for powerpc.
Undocumented -disable-ppc-unaligned option does not work...
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/arch/powerpc/powerpc/fix_unaligned.c | 132 |
1 files changed, 66 insertions, 66 deletions
diff --git a/sys/arch/powerpc/powerpc/fix_unaligned.c b/sys/arch/powerpc/powerpc/fix_unaligned.c index 914950bd841..75611379710 100644 --- a/sys/arch/powerpc/powerpc/fix_unaligned.c +++ b/sys/arch/powerpc/powerpc/fix_unaligned.c @@ -1,4 +1,4 @@ -/* $NetBSD: fix_unaligned.c,v 1.1 2022/05/30 13:58:51 rin Exp $ */ +/* $NetBSD: fix_unaligned.c,v 1.2 2022/06/02 00:32:14 rin Exp $ */ /* * Copyright (c) 2022 The NetBSD Foundation, Inc. @@ -51,7 +51,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: fix_unaligned.c,v 1.1 2022/05/30 13:58:51 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fix_unaligned.c,v 1.2 2022/06/02 00:32:14 rin Exp $"); #include "opt_ddb.h" #include "opt_ppcarch.h" @@ -187,27 +187,55 @@ emul_unaligned(struct trapframe *tf, ksiginfo_t *ksi, const union instr *insn) int flags; switch (insn->i_any.i_opcd) { - case OPC_LMW: - UA_EVCNT_INCR(lmw); -#ifdef FIX_UNALIGNED_LSTMW + case OPC_LWZ: + UA_EVCNT_INCR(lwz); flags = UAF_LOAD; - if (do_lstmw(tf, insn, flags)) - goto fault; - return false; -#else - goto unknown; -#endif + break; - case OPC_STMW: - UA_EVCNT_INCR(stmw); -#ifdef FIX_UNALIGNED_LSTMW + case OPC_LWZU: + UA_EVCNT_INCR(lwzu); + flags = UAF_LOAD | UAF_UPDATE; + break; + + case OPC_STW: + UA_EVCNT_INCR(stw); flags = UAF_STORE; - if (do_lstmw(tf, insn, flags)) - goto fault; - return false; -#else - goto unknown; -#endif + break; + + case OPC_STWU: + UA_EVCNT_INCR(stwu); + flags = UAF_STORE | UAF_UPDATE; + break; + + case OPC_LHZ: + UA_EVCNT_INCR(lhz); + flags = UAF_LOAD | UAF_HALF; + break; + + case OPC_LHZU: + UA_EVCNT_INCR(lhzu); + flags = UAF_LOAD | UAF_HALF | UAF_UPDATE; + break; + + case OPC_LHA: + UA_EVCNT_INCR(lha); + flags = UAF_LOAD | UAF_HALF | UAF_ALGEBRA; + break; + + case OPC_LHAU: + UA_EVCNT_INCR(lhau); + flags = UAF_LOAD | UAF_HALF | UAF_ALGEBRA | UAF_UPDATE; + break; + + case OPC_STH: + UA_EVCNT_INCR(sth); + flags = UAF_STORE | UAF_HALF; + break; + + case OPC_STHU: + UA_EVCNT_INCR(sthu); + flags = UAF_STORE | UAF_HALF | UAF_UPDATE; + break; case OPC_integer_31: switch (insn->i_x.i_xo) { @@ -287,55 +315,27 @@ emul_unaligned(struct trapframe *tf, ksiginfo_t *ksi, const union instr *insn) } break; - case OPC_LWZ: - UA_EVCNT_INCR(lwz); + case OPC_LMW: + UA_EVCNT_INCR(lmw); +#ifdef FIX_UNALIGNED_LSTMW flags = UAF_LOAD; - break; - - case OPC_LWZU: - UA_EVCNT_INCR(lwzu); - flags = UAF_LOAD | UAF_UPDATE; - break; + if (do_lstmw(tf, insn, flags)) + goto fault; + return false; +#else + goto unknown; +#endif - case OPC_STW: - UA_EVCNT_INCR(stw); + case OPC_STMW: + UA_EVCNT_INCR(stmw); +#ifdef FIX_UNALIGNED_LSTMW flags = UAF_STORE; - break; - - case OPC_STWU: - UA_EVCNT_INCR(stwu); - flags = UAF_STORE | UAF_UPDATE; - break; - - case OPC_LHZ: - UA_EVCNT_INCR(lhz); - flags = UAF_LOAD | UAF_HALF; - break; - - case OPC_LHZU: - UA_EVCNT_INCR(lhzu); - flags = UAF_LOAD | UAF_HALF | UAF_UPDATE; - break; - - case OPC_LHA: - UA_EVCNT_INCR(lha); - flags = UAF_LOAD | UAF_HALF | UAF_ALGEBRA; - break; - - case OPC_LHAU: - UA_EVCNT_INCR(lhau); - flags = UAF_LOAD | UAF_HALF | UAF_ALGEBRA | UAF_UPDATE; - break; - - case OPC_STH: - UA_EVCNT_INCR(sth); - flags = UAF_STORE | UAF_HALF; - break; - - case OPC_STHU: - UA_EVCNT_INCR(sthu); - flags = UAF_STORE | UAF_HALF | UAF_UPDATE; - break; + if (do_lstmw(tf, insn, flags)) + goto fault; + return false; +#else + goto unknown; +#endif default: UA_EVCNT_INCR(unknown); |
