Annotation of coherent/b/bin/c/n1/i386/outmch.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * n1/i386/outmch.c
        !             3:  * This file contains a number of small, machine dependent output
        !             4:  * routines called from the main code output routines in 'out.c'.
        !             5:  * Most have something to do with function calls and argument lists.
        !             6:  * i386.
        !             7:  */
        !             8: 
        !             9: #ifdef   vax
        !            10: #include "INC$LIB:cc1.h"
        !            11: #else
        !            12: #include "cc1.h"
        !            13: #endif
        !            14: 
        !            15: extern ival_t  outargs();
        !            16: 
        !            17: /*
        !            18:  * Output a call.
        !            19:  * Make the left subtree (the name) addressable if required.
        !            20:  * Take a quick look to see if the semantics of the indirect call will work.
        !            21:  * If this is not an indirect call (iflag==0), then the "nsef" flag is set
        !            22:  * in the call to "genadr", to supress the generation of escape prefix bytes.
        !            23:  */
        !            24: outcall(tp, cxt, lab) register TREE *tp;
        !            25: {
        !            26:        register ival_t nb;
        !            27:        register int    iflag;
        !            28: 
        !            29:        nb = outargs(tp->t_rp);
        !            30:        iflag = 0;
        !            31:        tp = tp->t_lp;
        !            32:        if (tp->t_op == STAR) {
        !            33:                iflag = 1;
        !            34:                tp = tp->t_lp;
        !            35:                if (!isadr(tp->t_flag)) {
        !            36:                        while (tp->t_op == LEAF)
        !            37:                                tp = tp->t_lp;
        !            38:                        outofs(tp);
        !            39:                }
        !            40:        }
        !            41:        outopcall(iflag);
        !            42:        genadr(tp, iflag==0, 0, NULL);
        !            43:        if (nb != 0) {
        !            44:                if (nb == 4)
        !            45:                        genr(ZPOP, A_RECX);
        !            46:                else
        !            47:                        genri(ZADD, A_RESP, nb);
        !            48:        }
        !            49: }
        !            50: 
        !            51: /*
        !            52:  * Output the argument list of a function.
        !            53:  * The arguments are moved to the stack right to left.
        !            54:  * Structure arguments, marked by a PTB type, get block moved into place.
        !            55:  * If the function is "alien" we push in the opposite order.
        !            56:  */
        !            57: ival_t
        !            58: outargs(atp) TREE *atp;
        !            59: {
        !            60:        register TREE *tp;
        !            61:        register ival_t s, n;
        !            62:        TYPE type;
        !            63: 
        !            64:        if ((tp=atp) == NULL)
        !            65:                return (ival_t)0;
        !            66:        if (tp->t_op == ARGLST) {
        !            67:                s = 0;
        !            68:                s += outargs(tp->t_rp);
        !            69:                s += outargs(tp->t_lp);
        !            70:                return s;
        !            71:        }
        !            72:        if ((type=tp->t_type)==PTB) {
        !            73:                /* UNDONE: fix for BCS struct passing! */
        !            74:                n = s = tp->t_size;
        !            75:                n = (s+3)&~03;
        !            76:                if (n != 0) {
        !            77:                        genri(ZSUB, A_RESP, n);         /* grab dest space */
        !            78:                        geni(ZPUSH, s);                 /* count */
        !            79:                        output(tp, MFNARG, 0, 0);       /* src */
        !            80:                        genrr(ZMOV, A_REAX, A_RESP);
        !            81:                        genri(ZADD, A_REAX, (ival_t)8);
        !            82:                        genr(ZPUSH, A_REAX);            /* dest */
        !            83:                        geng(ZCALL, "memcpy");
        !            84:                        genri(ZADD, A_RESP, (ival_t)12);
        !            85:                }
        !            86:                return n;
        !            87:        }
        !            88:        output(tp, MFNARG, 0, 0);
        !            89:        return (ival_t)pertype[type].p_size;
        !            90: }
        !            91: 
        !            92: /*
        !            93:  * This routine does the work of the [TL OP0], [TL OP1] and [TL OP2] macros.
        !            94:  * It is given an opcode and returns the opcode that is used.
        !            95:  * Allows collapsing of code table entries which differ only slightly,
        !            96:  * based on signed/unsigned and byte/word/dword differences.
        !            97:  */
        !            98: maptype(opvariant, opcode, tp)
        !            99: int            opvariant;
        !           100: register int   opcode;
        !           101: register TREE  *tp;
        !           102: {
        !           103:        int type, byteflag, wordflag, unsflag;
        !           104:        int fltflag;
        !           105: 
        !           106:        fltflag = is_ndp_op(opcode);
        !           107:        if (opvariant == M_TL)
        !           108:                tp = tp->t_lp;                  /* use left type */
        !           109:        else if (opvariant == M_TR)
        !           110:                tp = tp->t_rp;                  /* use right type */
        !           111:        else if (opvariant != M_TN)             /* use node type or */
        !           112:                return opcode;                  /* return opcode unchanged */
        !           113:        type = tp->t_type;
        !           114:        byteflag = isbyte(type);
        !           115:        wordflag = isword(type);
        !           116:        unsflag = isuns(type);
        !           117:        if (unsflag) {
        !           118:                /*
        !           119:                 * Replace opcode by unsigned variant.
        !           120:                 * ZSAL -> ZSHL is unnecessary because SAL == SHL.
        !           121:                 */
        !           122:                switch (opcode) {
        !           123:                case ZMOVSX:    opcode = ZMOVZX;        break;
        !           124:                case ZSAR:      opcode = ZSHR;          break;
        !           125:                case ZIDIV:     opcode = ZDIV;          break;
        !           126:                case ZIMUL:     opcode = ZMUL;          break;
        !           127:                }
        !           128:        }
        !           129:        if (byteflag || wordflag) {
        !           130:                /*
        !           131:                 * Replace opcode by byte or word variant.
        !           132:                 * This assumes a fixed order for variants
        !           133:                 * in h/i386/opcode.h: [dword, byte, word].
        !           134:                 */
        !           135:                switch (opcode) {
        !           136:                case ZADD:
        !           137:                case ZAND:
        !           138:                case ZCMP:
        !           139:                case ZDEC:
        !           140:                case ZINC:
        !           141:                case ZMOV:
        !           142:                case ZOR:
        !           143:                case ZSAL:
        !           144:                case ZSAR:
        !           145:                case ZSHR:
        !           146:                case ZSUB:
        !           147:                case ZTEST:
        !           148:                case ZXOR:
        !           149:                        return (byteflag) ? opcode + 1 : opcode + 2;
        !           150:                case ZMOVSX:    return (byteflag) ? ZMOVSXB : ZMOVSX;
        !           151:                case ZMOVZX:    return (byteflag) ? ZMOVZXB : ZMOVZX;
        !           152:                }
        !           153:        } else {
        !           154:                /* ZMOVSX or ZMOVZX with 32-bit operand just means ZMOV. */
        !           155:                switch (opcode) {
        !           156:                case ZMOVSX:
        !           157:                case ZMOVZX:    return ZMOV;
        !           158:                }
        !           159:        }
        !           160:        if (fltflag) {
        !           161:                /*
        !           162:                 * Replace opcode by type-dependent variant.
        !           163:                 * This assumes a fixed order for variants
        !           164:                 * in h/i386/opcode.h: [double, float, dword, word].
        !           165:                 */
        !           166:                switch(opcode) {
        !           167:                case ZFADDD:
        !           168:                case ZFCOMPD:
        !           169:                case ZFDIVD:
        !           170:                case ZFLDD:
        !           171:                case ZFMULD:
        !           172:                case ZFRDIVD:
        !           173:                case ZFRSUBD:
        !           174:                case ZFSTD:
        !           175:                case ZFSTPD:
        !           176:                case ZFSUBD:
        !           177:                        switch(type) {
        !           178:                        case F64:       return opcode;
        !           179:                        case F32:       return opcode + 1;
        !           180:                        case S32:       return opcode + 2;
        !           181:                        case S16:       return opcode + 3;
        !           182:                        }
        !           183:                }
        !           184:        }
        !           185:        return opcode;                  /* return opcode unchanged */
        !           186: }
        !           187: 
        !           188: /*
        !           189:  * Generate output prefix bytes
        !           190:  * (none for dword operands, LO for word operands, LO LO for byte operands)
        !           191:  * depending on the supplied type.
        !           192:  * Makes the code tables much more concise.
        !           193:  */
        !           194: mappfx(tp, opv, pfx, npfxp) TREE *tp; int opv; unsigned char *pfx; int *npfxp;
        !           195: {
        !           196:        register int type;
        !           197: 
        !           198:        if (opv == M_TL)
        !           199:                tp = tp->t_lp;
        !           200:        else if (opv == M_TR)
        !           201:                tp = tp->t_rp;
        !           202:        else if (opv != M_TN)
        !           203:                return;
        !           204:        type = tp->t_type;
        !           205:        if (isbyte(type) || isword(type)) {
        !           206:                pfx[*npfxp] = M_LO;
        !           207:                ++*npfxp;
        !           208:                if (isbyte(type)) {
        !           209:                        pfx[*npfxp] = M_LO;
        !           210:                        ++*npfxp;
        !           211:                }
        !           212:        }
        !           213: 
        !           214: }
        !           215: 
        !           216: /*
        !           217:  * Emit call opcode.
        !           218:  */
        !           219: outopcall(iflag)
        !           220: {
        !           221:        bput(CODE);
        !           222:        bput((iflag) ? ZICALL : ZCALL);
        !           223: }
        !           224: 
        !           225: /* end of n1/i386/outmch.c */

unix.superglobalmegacorp.com

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