1160040Smarcel/*-
2160040Smarcel * Copyright (c) 2006 Marcel Moolenaar
3160040Smarcel * All rights reserved.
4160040Smarcel *
5160040Smarcel * Redistribution and use in source and binary forms, with or without
6160040Smarcel * modification, are permitted provided that the following conditions
7160040Smarcel * are met:
8160040Smarcel *
9160040Smarcel * 1. Redistributions of source code must retain the above copyright
10160040Smarcel *    notice, this list of conditions and the following disclaimer.
11160040Smarcel * 2. Redistributions in binary form must reproduce the above copyright
12160040Smarcel *    notice, this list of conditions and the following disclaimer in the
13160040Smarcel *    documentation and/or other materials provided with the distribution.
14160040Smarcel *
15160040Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16160040Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17160040Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18160040Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19160040Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20160040Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21160040Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22160040Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23160040Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24160040Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25160040Smarcel */
26160040Smarcel
27160040Smarcel#include <sys/cdefs.h>
28160040Smarcel__FBSDID("$FreeBSD$");
29160040Smarcel
30160040Smarcel#include <sys/param.h>
31160040Smarcel#include <sys/systm.h>
32160040Smarcel#include <sys/proc.h>
33160040Smarcel
34160040Smarcel#include <machine/frame.h>
35160040Smarcel#include <machine/md_var.h>
36160040Smarcel
37160040Smarcel#include <ia64/disasm/disasm.h>
38160040Smarcel
39160040Smarcelint
40160040Smarcelia64_emulate(struct trapframe *tf, struct thread *td)
41160040Smarcel{
42160040Smarcel	struct asm_bundle bundle;
43160040Smarcel	struct asm_inst *i;
44160040Smarcel	int slot;
45160040Smarcel
46160040Smarcel	if (!asm_decode(tf->tf_special.iip, &bundle))
47160040Smarcel		return (SIGILL);
48160040Smarcel
49160040Smarcel	slot = ((tf->tf_special.psr & IA64_PSR_RI) == IA64_PSR_RI_0) ? 0 :
50160040Smarcel	    ((tf->tf_special.psr & IA64_PSR_RI) == IA64_PSR_RI_1) ? 1 : 2;
51160040Smarcel	if (slot == 1 && bundle.b_templ[slot] == 'L')
52160040Smarcel		slot++;
53160040Smarcel
54160040Smarcel	i = bundle.b_inst + slot;
55160040Smarcel	switch (i->i_op) {
56160040Smarcel	case ASM_OP_BRL:
57160040Smarcel		/*
58160040Smarcel		 * We get the fault even if the predicate is false, so we
59160040Smarcel		 * need to check the predicate first and simply advance to
60160040Smarcel		 * the next bundle in that case.
61160040Smarcel		 */
62160040Smarcel		if (!(tf->tf_special.pr & (1UL << i->i_oper[0].o_value))) {
63160040Smarcel			tf->tf_special.psr &= ~IA64_PSR_RI;
64160040Smarcel			tf->tf_special.iip += 16;
65160040Smarcel			return (0);
66160040Smarcel		}
67160040Smarcel		/*
68160040Smarcel		 * The brl.cond is the simplest form. We only have to set
69160040Smarcel		 * the IP to the address in the instruction and return.
70160040Smarcel		 */
71160040Smarcel		if (i->i_cmpltr[0].c_type == ASM_CT_COND) {
72160040Smarcel			tf->tf_special.psr &= ~IA64_PSR_RI;
73160040Smarcel			tf->tf_special.iip += i->i_oper[1].o_value;
74160040Smarcel			return (0);
75160040Smarcel		}
76160040Smarcel		/* Sanity check... */
77160040Smarcel		if (i->i_cmpltr[0].c_type != ASM_CT_CALL)
78160040Smarcel			break;
79160040Smarcel		/*
80160040Smarcel		 * The brl.call is more difficult as we need to set-up the
81160040Smarcel		 * call properly.
82160040Smarcel		 */
83160040Smarcel		break;
84160040Smarcel	default:
85160040Smarcel		break;
86160040Smarcel	}
87160040Smarcel
88160040Smarcel	return (SIGILL);
89160040Smarcel}
90