Annotation of researchv10no/cmd/cfront/libC/otask/fudge.c, revision 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.