Annotation of researchv10no/cmd/cfront/libC/task/fudge.c.vax, revision 1.1

1.1     ! root        1: /*ident        "%W%" */
        !             2: /**************************************************************************
        !             3:                        Copyright (c) 1984 AT&T
        !             4:                          All Rights Reserved   
        !             5: 
        !             6:        THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
        !             7:        
        !             8:        The copyright notice above does not evidence any        
        !             9:        actual or intended publication of such source code.
        !            10: 
        !            11: *****************************************************************************/
        !            12: #include <task.h>
        !            13: #include "hw_stack.h"
        !            14: 
        !            15: // VAX frame fudger
        !            16: 
        !            17: // STACK GROWS DOWN
        !            18: 
        !            19: /*
        !            20:  * Fudge frame of function-defined-by-f_fp (called "f" below)
        !            21:  * so that that function returns to its grandparent,
        !            22:  * in particular, so a parent task returns to the function that
        !            23:  * called the derived constructor (de_ctor), skipping de_ctor;
        !            24:  * the child will return to the derived constructor, which is its "main."
        !            25:  * To do this we will overwrite the old fp, ap, and pc (those saved by
        !            26:  * f) with the old-old ones (those saved by f's caller),
        !            27:  * and we will overwrite the register save area with registers saved by 
        !            28:  * f's caller (referred to as "skip" below).
        !            29:  *
        !            30:  * There are 2 register-save cases to deal with:
        !            31:  *     1. skip_n_saved <= f_n_saved
        !            32:  *     3. skip_n_saved >  f_n_saved
        !            33:  *
        !            34:  * These are handled as follows:
        !            35:  *     1. copy the saved skip_regs over the corresponding f_regs,
        !            36:  *        leaving any additional saved f_regs intact.
        !            37:  *        f's restore instruction will be correct.
        !            38:  *     2. f's restore instruction will restore too few regs, must take special
        !            39:  *       care to see that the extras are restored properly.
        !            40:  *       -Copy saved skip_regs over any corresponding f_regs,
        !            41:  *       -If fudge_return saved more regs than f did, then
        !            42:  *        copy saved extra saved skip_regs over any corresponding fudge_regs,
        !            43:  *       -If more extra skip_regs (not saved by either f or fudge_return,
        !            44:  *        and therefore not used by either) remain, restore them explicitly.
        !            45:  *        They will not be disturbed by the return from fudge_return or f,
        !            46:  */
        !            47: void
        !            48: task::fudge_return(int* f_fp)
        !            49: {
        !            50:        register int*   fp = f_fp;                 // fp of frame-to-be-fudged
        !            51:        register int*   skip_fp = (int*)OLD_FP(fp); // fp for f's caller (skip)
        !            52:        unsigned short  mask = ENTRY_MASK(fp);
        !            53:        unsigned        spa = mask >> 14;  // stack pointer alignment
        !            54:        mask &= 0xfff;  // mask of saved registers in the frame
        !            55:        unsigned short  skip_mask = ENTRY_MASK(skip_fp);
        !            56:        unsigned        skip_spa = skip_mask >> 14;
        !            57:        skip_mask &= 0xfff;
        !            58: 
        !            59:        OLD_AP(fp) = OLD_AP(skip_fp);
        !            60:        OLD_FP(fp) = OLD_FP(skip_fp);
        !            61:        OLD_PC(fp) = OLD_PC(skip_fp);
        !            62: 
        !            63:        // finally copy saved regs
        !            64:        // copy any saved skip regs over corresponding f regs; if there isn't
        !            65:        // a corresponding f reg, copy over corresponding fudge_return reg;
        !            66:        // if there isn't a corresponding fr_reg, restore it explicitly.
        !            67:        register int*   to = FIRST_SAVED_REG_P(fp,0);
        !            68:        register int*   from = FIRST_SAVED_REG_P(skip_fp,0);
        !            69:        register int*   fr_fp = FP();
        !            70:        register int*   fr_to = FIRST_SAVED_REG_P(fr_fp,0);
        !            71:        unsigned short  fr_mask = ENTRY_MASK(fr_fp);
        !            72:        fr_mask &= 0xfff;
        !            73:        for (int m = 1; m != 0x1000; m <<= 1) {
        !            74:                if (m & mask) {
        !            75:                        if (m & skip_mask) {
        !            76:                                *to++ = *from++;
        !            77:                                if (m & fr_mask) fr_to++;
        !            78:                        } else {  // nothing to copy
        !            79:                                to++;
        !            80:                                if (m & fr_mask) fr_to++;
        !            81:                        }
        !            82:                } else if (m & skip_mask)  {
        !            83:                        // No slot for *from in f's frame
        !            84:                        if (m & fr_mask) {  // copy to fudge_return's frame
        !            85:                                *fr_to++ = *from++;
        !            86:                        } else {
        !            87:                                // Not used in f or fudge_return;
        !            88:                                // restore explicitly
        !            89:                                switch(m)       {
        !            90:                                case 0x0020:
        !            91:                                        set_r6(from++);
        !            92:                                        break;
        !            93:                                case 0x0040:
        !            94:                                        set_r7(from++);
        !            95:                                        break;
        !            96:                                case 0x0080:
        !            97:                                        set_r8(from++);
        !            98:                                        break;
        !            99:                                case 0x0100:
        !           100:                                        set_r9(from++);
        !           101:                                        break;
        !           102:                                case 0x0200:
        !           103:                                        set_r10(from++);
        !           104:                                        break;
        !           105:                                case 0x0400:
        !           106:                                        set_r11(from++);
        !           107:                                        break;
        !           108:                                default:
        !           109:                                        // Oops--don't expect other regs
        !           110:                                        // to be saved
        !           111:                                        from++;
        !           112:                                        task_error(E_REGMASK, this);
        !           113:                                        break;
        !           114:                                }
        !           115:                        }
        !           116:                } else if (m & fr_mask) fr_to++;
        !           117:        }
        !           118: 
        !           119:        // to and from now point at argument descriptor (if spa == 0);
        !           120:        // add number of words in skip's frame to arg descriptor, so sp
        !           121:        // will be set properly when f returns (no need for fudge_sp here).
        !           122:        // WARNING:  spa != 0 untested.
        !           123:        to -= spa;
        !           124:        from -= skip_spa;
        !           125:        unsigned big_arg_list = *(unsigned char*)from + (from - to);
        !           126:        if (big_arg_list > 0xff)
        !           127:                task_error(E_FUDGE_SIZE, this);
        !           128:        *(unsigned char*)to = big_arg_list;
        !           129: }
        !           130: 

unix.superglobalmegacorp.com

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