|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.