Annotation of researchv10no/cmd/cfront/libC/otask/fudge.c.vax, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.