|
|
1.1 root 1: #include "task.h"
2:
3: // VAX frame fudger
4:
5: // STACK GROWS DOWN
6: /*
7: #define FP(p) ((int*)(&p+1))
8: #define OLD_AP(fp) (*(fp+2))
9: #define OLD_FP(fp) (*(fp+3))
10: #define OLD_PC(fp) (*(fp+4))
11: */
12:
13: /*
14: * fix a the frame so that when we return from it, all the registers will
15: * be restored.
16: * The idea is that task_fp points to the task::task() stack frame which
17: * contains all the saved registers. t_framep points to the My_task::Mytask()
18: * stack frame that contains the return address (and perhaps some registers).
19: * fill the frame pointed to by t_framep with the registers from task_fp.
20: * do this by copying the registers up from t_framep to task_fp, then
21: * copying the whole frame down and adjusting t_framep.
22: * see the VAX architecture reference manual for frame layout
23: * note we always use calls (not callg) and spa is always 0
24: */
25: void
26: task::fudge_return(register int* task_fp, int offset, task* next)
27: {
28: register int* this_fp = t_framep + offset;
29: task_fp += offset; // in case this is SHARED
30: // get masks of saved registers in the frames
31: unsigned short this_mask = *((short*)this_fp + 3);
32: unsigned short task_mask = *((short*)task_fp + 3);
33: // copy up the always fields
34: task_fp[0] = this_fp[0]; // condition handler (always zero?)
35: ((short*)task_fp)[2] = ((short*)this_fp)[2]; // psw but not mask
36: task_fp[2] = this_fp[2]; // saved argument pointer
37: task_fp[3] = this_fp[3]; // saved frame pointer
38: task_fp[4] = this_fp[4]; // saved program counter
39: // now copy up optional registers
40: register int* this_rp = this_fp + 5;
41: register int* task_rp = task_fp + 5;
42: for (register mask = 1; mask != 0x1000; mask <<= 1) {
43: if (mask & task_mask)
44: if (mask & this_mask)
45: *task_rp++ = *this_rp++;
46: else task_rp++;
47: else if (mask & this_mask) // task frame is supposed to save all
48: task_error(E_FUDGE);
49: }
50: // next copy the whole frame down
51: while (task_rp > task_fp)
52: *--this_rp = *--task_rp;
53: // finally fix t_framep to point to where the frame wound up
54: t_framep = this_rp - offset;
55: if (next) next->restore();
56: }
57:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.