xref: /original-bsd/sys/tahoe/align/exception.c (revision 262b24ac)
1 /*	exception.c	1.1	86/07/20	*/
2 
3 #include "../tahoealign/align.h"
4 
5 /*
6  * Signal an exception. It will be handled by 'locore.s'. Here, I:
7  *	1) Put the exception code where it belongs on the stack.
8  *	2) Restore pc and sp to show that the current opcode
9  *		'was not executed'.
10  *	3) Execute one big non-local-goto. In the process we take care
11  *		to reset the current HW fp such that 'alignment' will
12  *		indeed return to 'locore.s'.
13  *		IMPORTANT NOTE : the process I use will NOT restore
14  *		all registers (like normal returns) so the call to the
15  *		handling routine HAS TO BE the last thing in 'alignment'.
16  *		Otherwise, all its own register variables will be a mess !!
17  *		I also know that 'alignment' itself WILL restore all
18  *		registers for 'locore.s' since its entry mask is all-1.
19  */
20 exception(infop, type, param1, param2)
21 process_info *infop;
22 int	type, param1, param2;
23 {
24 	register long *my_fp;
25 	register long *current_fp, *prev_fp;
26 
27 	my_fp = (long *)&infop-1 ;
28 	infop->ret_exception = type;
29 	switch (type) {
30 	case ARITHMETIC:
31 		infop->ret_code = param1;
32 		break;
33 	case ILL_ACCESS:
34 		infop->ret_addr = param1;
35 		infop->ret_code = param2;
36 		break;
37 	case ALIGNMENT:
38 	case ILL_ADDRMOD:
39 	case ILL_OPRND:
40 		break;
41 	default :
42 		printf ("Bad exception type %d (alignment code)\n", type);
43 		break;
44 	}
45 /*
46  * Now the big trick. Look up the stack until the frame of
47  * 'alignment' is found. prev_fp will point to it and current_fp
48  * will then point to the frame of whoever 'alignment' called.
49  * This should better work ...
50  */
51 	prev_fp = my_fp;
52 	while (prev_fp != &fp) {
53 		current_fp = prev_fp;
54 		prev_fp = (long *) *prev_fp;
55 	}
56 /*
57  * Found it. Now fool the HW into thinking that 'alignment' called
58  * us directly here, so this routine's 'return' will go back
59  * all the way to 'alignment', stopping any further emulation
60  * for the current offending opcode.
61  *  "fool the HW..." ha ha, am I realy fooling myself ?
62  */
63 	*my_fp = *current_fp;
64 	*(my_fp - 2) = *(current_fp -2);	/* Alter program counter */
65 /*
66  * Without further ado, just go back now !!!!
67  */
68 }
69 
70 not_needed (infop)
71 process_info *infop;
72 {
73 /*
74  * Shouldn't ever come to this routine.
75  */
76 
77 	printf ("Opcode 0x%x should not trap to alignment code.",
78 		opCODE);
79 	printf (" OS or machine problem!! \n");
80 }
81 
82 
83 cannot_do (infop)
84 process_info *infop;
85 {
86 /*
87  * Some opcode-caused alignments cannot be emulated. See table.c for
88  * specific reasons. Reflect this back to the process as alignment
89  * exception.
90  */
91 	exception (infop, ALIGNMENT);
92 }
93