2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2002 Jake Burkholder.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
25 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
31 #include <sys/types.h>
32 #include <machine/cpufunc.h>
33 #include <machine/instr.h>
37 #include "__sparc_utrap_private.h"
40 __unaligned_load(u_char *p, int size)
46 for (i = 0; i < size; i++)
47 val = (val << 8) | p[i];
52 __unaligned_store(u_char *p, u_long val, int size)
56 for (i = 0; i < size; i++)
57 p[i] = val >> ((size - i - 1) * 8);
61 __unaligned_fixup(struct utrapframe *uf)
69 addr = (u_char *)uf->uf_sfar;
70 insn = *(u_int *)uf->uf_pc;
72 switch (IF_OP(insn)) {
74 switch (IF_F3_OP3(insn)) {
76 val = __unaligned_load(addr, 2);
77 __emul_store_reg(uf, IF_F3_RD(insn), val);
80 val = __unaligned_load(addr, 4);
81 __emul_store_reg(uf, IF_F3_RD(insn), val);
84 val = __unaligned_load(addr, 8);
85 __emul_store_reg(uf, IF_F3_RD(insn), val);
88 val = __unaligned_load(addr, 2);
89 __emul_store_reg(uf, IF_F3_RD(insn),
93 val = __unaligned_load(addr, 4);
94 __emul_store_reg(uf, IF_F3_RD(insn),
98 val = __emul_fetch_reg(uf, IF_F3_RD(insn));
99 __unaligned_store(addr, val, 2);
102 val = __emul_fetch_reg(uf, IF_F3_RD(insn));
103 __unaligned_store(addr, val, 4);
106 val = __emul_fetch_reg(uf, IF_F3_RD(insn));
107 __unaligned_store(addr, val, 8);