diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2003-07-14 02:03:17 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2003-07-14 02:03:17 +0000 |
commit | fcdfc75c96edb08ba07c7fbf98d108e4ec0660f9 (patch) | |
tree | 9f153d9e87d98fed12afd9eac78d75fc2a1dab43 /sys/arch/sparc64 | |
parent | 66bfd898bd6c8e73e49221583a9e32dda685d89a (diff) |
For completeness, handle ldqf/stqf alignment faults by calling the emulation
routine. According to the spec, ldqf/stqf requires word alignment, but
can generate a ldqf/stqf alignment exception if the data isn't quad word
aligned. Since the emulation routine only requires word alignment anyway,
this seems to be the right thing to do.
Diffstat (limited to 'sys/arch/sparc64')
-rw-r--r-- | sys/arch/sparc64/sparc64/trap.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/sys/arch/sparc64/sparc64/trap.c b/sys/arch/sparc64/sparc64/trap.c index 7bd266c7ac7..97f720d7aae 100644 --- a/sys/arch/sparc64/sparc64/trap.c +++ b/sys/arch/sparc64/sparc64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.29 2003/07/10 19:33:19 jason Exp $ */ +/* $OpenBSD: trap.c,v 1.30 2003/07/14 02:03:16 jason Exp $ */ /* $NetBSD: trap.c,v 1.73 2001/08/09 01:03:01 eeh Exp $ */ /* @@ -605,11 +605,26 @@ badtrap: } case T_LDQF_ALIGN: - trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv); /* XXX code?? */ - break; case T_STQF_ALIGN: - trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv); /* XXX code?? */ + { + union instr ins; + + if (copyin((caddr_t)pc, &ins, sizeof(ins)) != 0) { + /* XXX Can this happen? */ + trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv); + break; + } + if (ins.i_any.i_op == IOP_mem && + (ins.i_op3.i_op3 == IOP3_LDQF || + ins.i_op3.i_op3 == IOP3_STQF || + ins.i_op3.i_op3 == IOP3_LDQFA || + ins.i_op3.i_op3 == IOP3_STQFA)) { + if (emul_qf(ins.i_int, p, sv, tf)) + ADVANCE; + } else + trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv); break; + } case T_ALIGN: case T_LDDF_ALIGN: |