Annotation of coherent/b/bin/c/n1/i386/outmch.c, revision 1.1.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.