|
|
1.1 ! root 1: /* ! 2: * This file contains a number of small, machine dependent output ! 3: * routines called from the main code output routines in 'out.c'. ! 4: * Most have something to do with function calls and argument lists. ! 5: */ ! 6: #ifdef vax ! 7: #include "INC$LIB:cc1.h" ! 8: #else ! 9: #include "cc1.h" ! 10: #endif ! 11: ! 12: /* ! 13: * Output a call. ! 14: * Make the left subtree (the name) addressable if required. ! 15: * Take a quick look to see if the semantics of the indirect call will work. ! 16: * If this is not an indirect call (iflag==0), then the "nsef" flag is set ! 17: * in the call to "genadr", to supress the generation of escape prefix bytes. ! 18: */ ! 19: outcall(tp, cxt, lab) ! 20: register TREE *tp; ! 21: { ! 22: register int nb; ! 23: register int iflag; ! 24: register int isalien; ! 25: register int isptr; ! 26: register int type; ! 27: ! 28: isalien = 0; ! 29: if (isvariant(VALIEN)) { ! 30: if (tp->t_lp->t_op == GID && tp->t_lp->t_seg == SALIEN) { ! 31: ++isalien; ! 32: type = tp->t_type; ! 33: isptr = ispoint(type); ! 34: /* Adjust types not adjusted in parser. */ ! 35: if (type == S8) ! 36: tp->t_type = S16; ! 37: else if (type == U8) ! 38: tp->t_type = U16; ! 39: #if !OMF286 ! 40: callfixup(tp->t_lp); ! 41: #endif ! 42: } ! 43: } ! 44: if (isalien) { ! 45: genr(ZPUSH, A_RSI); ! 46: genr(ZPUSH, A_RDI); ! 47: if (isvariant(VSMALL)) ! 48: genr(ZPUSH, A_RES); ! 49: } ! 50: nb = outargs(tp->t_rp, isalien); ! 51: iflag = 0; ! 52: tp = tp->t_lp; ! 53: if (tp->t_op == STAR) { ! 54: iflag = 1; ! 55: tp = tp->t_lp; ! 56: if (!isadr(tp->t_flag)) { ! 57: while (tp->t_op == LEAF) ! 58: tp = tp->t_lp; ! 59: outofs(tp); ! 60: } ! 61: } ! 62: outopcall(iflag); ! 63: genadr(tp, iflag==0, 0, NULL); ! 64: if (isalien) { ! 65: if (isptr) { ! 66: genrr(ZMOV, A_RAX, A_RBX); ! 67: #if !ONLYSMALL ! 68: if (isvariant(VLARGE)) ! 69: genrr(ZMOV, A_RDX, A_RES); ! 70: #endif ! 71: } ! 72: if (type == S8) { ! 73: bput(CODE); bput(ZCBW); ! 74: } ! 75: else if (type == U8) ! 76: genrr(ZSUBB, A_RAH, A_RAH); ! 77: if (isvariant(VSMALL)) ! 78: genr(ZPOP, A_RES); ! 79: genr(ZPOP, A_RDI); ! 80: genr(ZPOP, A_RSI); ! 81: } else if (nb != 0) ! 82: genri(ZADD, A_RSP, nb); ! 83: } ! 84: ! 85: #if !OMF286 ! 86: /* Remove the trailing '_' appended to GID's by cc0, for alien call. */ ! 87: callfixup(tp) ! 88: TREE *tp; ! 89: { ! 90: register char *cp1, *cp2; ! 91: ! 92: cp1 = tp->t_sp->s_id; ! 93: cp2 = id; ! 94: while (*cp2++ = *cp1++) ! 95: ; ! 96: cp2[-2] = 0; ! 97: tp->t_sp = gidpool(id); ! 98: } ! 99: #endif ! 100: ! 101: /* ! 102: * Output the argument list of a function. ! 103: * The arguments are moved to the stack right to left. ! 104: * Structure arguments, marked by a PTB type, get block moved into place. ! 105: * If the function is "alien" we push in the opposite order. ! 106: */ ! 107: outargs(atp, isalien) ! 108: TREE *atp; ! 109: { ! 110: register TREE *tp; ! 111: register s, n; ! 112: TYPE type; ! 113: ! 114: if ((tp=atp) == NULL) ! 115: return (0); ! 116: if (tp->t_op == ARGLST) { ! 117: s = 0; ! 118: if (isalien) ! 119: s += outargs(tp->t_lp, isalien); ! 120: s += outargs(tp->t_rp, isalien); ! 121: if ( ! isalien) ! 122: s += outargs(tp->t_lp, isalien); ! 123: return (s); ! 124: } ! 125: #if !ONLYSMALL ! 126: if ((type=tp->t_type)==LPTB || type==SPTB) { ! 127: #else ! 128: if ((type=tp->t_type) == SPTB) { ! 129: #endif ! 130: n = s = tp->t_size; ! 131: if (isvariant(VALIGN)) ! 132: n = (s+1)&~01; ! 133: if (n != 0) { ! 134: if (isvariant(V80186)) { ! 135: genri(ZSUB, A_RSP, n); ! 136: geni(ZPUSH, s); ! 137: } else { ! 138: if (s == n) { ! 139: genri(ZMOV, A_RAX, s); ! 140: genrr(ZSUB, A_RSP, A_RAX); ! 141: } else { ! 142: genri(ZSUB, A_RSP, n); ! 143: genri(ZMOV, A_RAX, s); ! 144: } ! 145: genr(ZPUSH, A_RAX); ! 146: } ! 147: output(tp, MFNARG, 0, 0); ! 148: #if !ONLYSMALL ! 149: if (type == LPTB) { ! 150: genr(ZPUSH, A_RSS); ! 151: genrr(ZMOV, A_RAX, A_RSP); ! 152: genri(ZADD, A_RAX, 8); ! 153: genr(ZPUSH, A_RAX); ! 154: geng(ZXCALL, "blkmv"); ! 155: genri(ZADD, A_RSP, 10); ! 156: } else { ! 157: #endif ! 158: genrr(ZMOV, A_RAX, A_RSP); ! 159: genri(ZADD, A_RAX, 4); ! 160: genr(ZPUSH, A_RAX); ! 161: geng(ZCALL, "blkmv"); ! 162: genri(ZADD, A_RSP, 6); ! 163: #if !ONLYSMALL ! 164: } ! 165: #endif ! 166: } ! 167: return (n); ! 168: } ! 169: output(tp, MFNARG, 0, 0); ! 170: return (pertype[type].p_size); ! 171: } ! 172: ! 173: /* ! 174: * This routine does the work of the [TLOP0], [TLOP1] and [TLOP2] macros. ! 175: * It is given an opcode and returns the opcode that is used. ! 176: */ ! 177: maptype(opvariant, opcode, tp) ! 178: int opvariant; ! 179: register int opcode; ! 180: register TREE *tp; ! 181: { ! 182: if (opvariant == M_TL) ! 183: tp = tp->t_lp; ! 184: else if (opvariant == M_TR) ! 185: tp = tp->t_rp; ! 186: else if (opvariant != M_TN) ! 187: return (opcode); ! 188: if (isbyte(tp->t_type)) { ! 189: if (opcode == ZADD) ! 190: opcode = ZADDB; ! 191: if (opcode == ZSUB) ! 192: opcode = ZSUBB; ! 193: if (opcode == ZINC) ! 194: opcode = ZINCB; ! 195: if (opcode == ZDEC) ! 196: opcode = ZDECB; ! 197: } ! 198: return (opcode); ! 199: } ! 200: ! 201: /* ! 202: * This routine does the ZLDES opcode mapping. ! 203: */ ! 204: mapzldes(tp) ! 205: register TREE *tp; ! 206: { ! 207: if (hihalf(tp->t_treg) == DS) ! 208: return (ZLDS); ! 209: else if (hihalf(tp->t_treg) == ES) ! 210: return (ZLES); ! 211: else ! 212: cbotch("ldes"); ! 213: } ! 214: ! 215: /* ! 216: * Emit call opcode. ! 217: */ ! 218: outopcall(iflag) ! 219: { ! 220: register op; ! 221: ! 222: #if !ONLYSMALL ! 223: if (notvariant(VSMALL)) { ! 224: op = ZXCALL; ! 225: if (iflag) ! 226: op = ZIXCALL; ! 227: } else { ! 228: #endif ! 229: op = ZCALL; ! 230: if (iflag) ! 231: op = ZICALL; ! 232: #if !ONLYSMALL ! 233: } ! 234: #endif ! 235: bput(CODE); ! 236: bput(op); ! 237: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.