1: #include "../h/rt.h" 2: #ifdef VAX 3: /* 4: * create - return an entry block for a co-expression. 5: */ 6: 7: create(nargs, arg1) 8: int nargs; 9: struct descrip arg1; 10: { 11: register int *ap, *sp, *tp; 12: register struct descrip *dp; 13: register struct b_estack *ep; 14: register struct b_eblock *hp; 15: int na, nl, *r5, i, j, *newap; 16: extern interp(); 17: extern struct b_estack *alcestk(); 18: extern struct b_eblock *alceblk(); 19: 20: SetBound; 21: if (QUAL(arg1) || TYPE(arg1) != T_INTEGER) 22: syserr("create: illegal entry point"); 23: 24: /* 25: * Get a new co-expression stack and initialize activator, result 26: * count, and stack base. 27: */ 28: esneed(); 29: ep = alcestk(); 30: ep->activator = nulldesc; 31: ep->nresults = 0; 32: ep->sbase = sp = (int *)ep; 33: /* 34: * Move hardware ap of calling function into the variable ap. 35: */ 36: asm(" addl3 8(fp),$4,r11"); 37: /* 38: * Calculate number of arguments and number of local variables. 39: */ 40: na = *ap; 41: tp = ap + 1 + (2 * na); 42: nl = ((struct descrip *)tp)->value.bptr->proc.ndynam; 43: 44: /* 45: * Get a new co-expression heap block. Note that the "+ 1" in 46: * na + nl + 1 is for arg0, the calling procedure. 47: */ 48: hneed(sizeof(struct b_eblock) + (na + nl + 1) * sizeof(struct descrip)); 49: hp = alceblk(INTVAL(arg1),na,nl); 50: ep->freshblk.type = D_EBLOCK; 51: BLKLOC(ep->freshblk) = (union block *) hp; 52: 53: /* 54: * Copy arguments into refresh block. dp starts at arg0 and works down. 55: */ 56: dp = (struct descrip *) ((int *)(ap + 1 + (2 * na))); 57: i = 0; 58: hp->elems[0] = *dp--; 59: j = na; 60: while (j-- > 0) { 61: hp->elems[++i] = *dp--; 62: } 63: 64: /* 65: * Copy arguments into new stack. This is more painful than copying 66: * into the refresh block because the arguments are copied a word 67: * at a time. tp starts at the high word of arg0 and goes down. 68: */ 69: tp = ap + 2 + (2 * na); 70: *--sp = *tp--; 71: *--sp = *tp--; 72: j = na; 73: while (j-- > 0) { 74: *--sp = *tp--; 75: *--sp = *tp--; 76: } 77: 78: /* 79: * Set up original procedure frame in new stack. 80: */ 81: *--sp = *tp--; /* copy nargs */ 82: *--sp = *tp; /* copy nwords (argc) */ 83: newap = sp; /* and save a pointer to it. */ 84: *--sp = 0; /* return pc */ 85: *--sp = 0; /* saved r5 (frame pointer) */ 86: *--sp = 0; /* saved ap */ 87: *--sp = 0; /* psw/reg. mask */ 88: *--sp = 0; /* condition handler */ 89: r5 = sp; /* and save a pointer to it */ 90: *--sp = line; /* saved line number */ 91: *--sp = (int) file; /* saved file name */ 92: 93: /* 94: * Copy local variables into new stack. The asm sets tp to the 95: * address of the start of local region in caller's procedure frame. 96: */ 97: asm(" addl3 12(fp),$-12,r9"); 98: j = nl; 99: while (j-- > 0) { 100: *--sp = *tp--; 101: *--sp = *tp--; 102: } 103: /* 104: * Copy local variables into the refresh block. The asm sets dp to 105: * the address of the first local. 106: */ 107: asm(" addl3 12(fp),$-16,r8"); 108: j = nl; 109: while (j-- > 0) 110: hp->elems[++i] = *dp--; 111: 112: /* 113: * Set up dummy call to coact. 114: */ 115: *--sp = nulldesc.type; /* place for result */ 116: *--sp = INTVAL(nulldesc); 117: *--sp = nulldesc.type; /* place for activate coexpr */ 118: *--sp = INTVAL(nulldesc); 119: *--sp = 1; /* nargs */ 120: *--sp = 3; /* 3 longwords in nargs */ 121: tp = sp; /* save pointer to start of arg 122: list in this frame */ 123: *--sp = INTVAL(arg1); /* saved r9 (coexpr entry point) */ 124: *--sp = (int) interp; /* return pc */ 125: *--sp = (int) r5; /* saved r5 */ 126: *--sp = (int) newap; /* saved ap */ 127: *--sp = 0x02000000; /* psw/reg mask with bit set to 128: restore r9, the ipc */ 129: *--sp = 0; /* condition handler */ 130: ep->boundary = sp; /* (initial boundary) */ 131: *--sp = line; /* saved line number */ 132: *--sp = (int) file; /* saved file name */ 133: ep->sp = sp; /* initial stack pointer */ 134: ep->ap = tp; /* initial arg. pointer */ 135: 136: /* 137: * Return the new co-expression. 138: */ 139: arg1.type = D_ESTACK; 140: BLKLOC(arg1) = (union block *) ep; 141: ClearBound; 142: } 143: #endif VAX 144: #ifdef PORT 145: create() 146: { 147: syserr("Attempt to create a co-expression"); 148: } 149: #endif PORT 150: 151: #ifdef PDP11 152: /* 153: * create - return an entry block for a co-expression 154: * 155: * NOTE: this code is highly dependent on stack frame layout. 156: */ 157: 158: create(nargs, arg1) 159: int nargs; 160: struct descrip arg1; 161: { 162: register int *ap, *sp; 163: register struct b_estack *ep; 164: register struct b_eblock *hp; 165: int na, nl, *r5, i; 166: extern interp(); 167: extern struct b_estack *alcestk(); 168: extern struct b_eblock *alceblk(); 169: 170: if (QUAL(arg1) || TYPE(arg1) != T_INTEGER) 171: syserr("create: illegal entry point"); 172: 173: esneed(); /* check for room in stack space */ 174: ep = alcestk(); /* allocate expression stack */ 175: ep->activator = nulldesc; 176: ep->nresults = 0; 177: 178: ep->sbase = sp = (int *)ep; /* initialize new stack pointer */ 179: ap = (int *)*(&nargs-2) + 2; /* find nargs of caller */ 180: na = *ap; /* get value of nargs */ 181: ap += 1 + 2 * na; /* find arg0 of caller */ 182: nl = ((struct descrip *)ap)->value.bptr->proc.ndynam; /* get # locals */ 183: 184: hneed(sizeof(struct b_eblock) + (na + nl + 1) * sizeof(struct descrip)); 185: hp = alceblk(INTVAL(arg1),na,nl); /* allocate refresh block */ 186: ep->freshblk.type = D_EBLOCK; 187: BLKLOC(ep->freshblk) = (union block *) hp; 188: 189: /* copy arguments into new stack and refresh block */ 190: i = 0; 191: hp->elems[i] = *--(struct descrip *)sp = *(struct descrip *)ap; 192: while (na-- > 0) 193: hp->elems[++i] = *--(struct descrip *)sp = *--(struct descrip *)ap; 194: 195: /* set up original procedure frame in new stack */ 196: *--sp = *--ap; /* copy nargs */ 197: *--sp = 0; /* return pc */ 198: *--sp = 0; /* saved r5 */ 199: r5 = sp; /* (save its address) */ 200: *--sp = 0; /* saved r4 */ 201: *--sp = 0; /* saved r3 */ 202: *--sp = 0; /* saved r2 */ 203: *--sp = line; /* saved line number */ 204: *--sp = (int) file; /* saved file name */ 205: 206: /* copy local variables into new stack */ 207: ap -= 7; 208: while (nl-- > 0) 209: hp->elems[++i] = *--(struct descrip *)sp = *--(struct descrip *)ap; 210: 211: /* set up dummy call to coact */ 212: *--(struct descrip *)sp = nulldesc; /* place for result */ 213: *--(struct descrip *)sp = nulldesc; /* place for activate coexpr */ 214: /* these values are the initial register state for the co-expression */ 215: *--sp = 1; /* nargs */ 216: *--sp = (int) interp; /* return pc */ 217: *--sp = (int) r5; /* saved r5 */ 218: ep->boundary = sp; /* (initial boundary) */ 219: *--sp = 0; /* saved r4 */ 220: *--sp = 0; /* saved r3 */ 221: *--sp = INTVAL(arg1); /* saved r2 (coexpr entry point) */ 222: *--sp = line; /* saved line number */ 223: *--sp = (int) file; /* saved file name */ 224: ep->sp = sp; /* initial stack pointer */ 225: arg1.type = D_ESTACK; 226: BLKLOC(arg1) = (union block *) ep; 227: } 228: #endif PDP11