|
|
1.1 ! root 1: #include "../h/config.h" ! 2: /* ! 3: * suspend suspends from a built-in procedure (a C function). ! 4: * The function calling suspend is suspending and the value to ! 5: * suspend is contained in arg0 of its argument list. The generator ! 6: * or expression frame immediately containing the frame of the ! 7: * suspending procedure is duplicated. ! 8: * ! 9: * suspend returns through the duplicated procedure frame and the ! 10: * arg0 descriptor of the suspending function is left on the ! 11: * top of the stack. When an alternative is needed, efail causes ! 12: * a return through the original procedure frame which was created ! 13: * by the original call to the built-in procedure. ! 14: */ ! 15: Global(_boundary) /* Icon/C boundary address */ ! 16: Global(_file) /* Current file name */ ! 17: Global(_k_level) /* Value of &level */ ! 18: Global(_line) /* Current line number */ ! 19: ! 20: Global(_suspend) ! 21: #ifdef VAX ! 22: _suspend: ! 23: /* ! 24: * Construct the generator frame ! 25: */ ! 26: Mask 0x0fc0 # Start new generator frame by saving ! 27: # registers upon entry to suspend. ! 28: movl _boundary,r6 # Establish new boundary value and ! 29: pushl r6 # save it in the new generator frame. ! 30: movl sp,gfp # Point gfp at boundary word in new frame ! 31: pushl _k_level # Push &level, ! 32: pushl _line # line number, ! 33: pushl _file # and file name to complete the frame. ! 34: /* ! 35: * Determine region to be duplicated and copy it. This is just ! 36: * like it's done in psusp. ! 37: */ ! 38: movl 12(fp),r7 # Low word of region to copy is the ! 39: # low word of procedure frame of suspending ! 40: # procedure. ! 41: movl 8(fp),r2 # Get ap of suspending procedure in r2 ! 42: movl -8(r2),r4 # Get gfp from procedure frame of suspending ! 43: # procedure. ! 44: bneq f1 # If it is zero, ! 45: movl -4(r2),r4 # get saved efp and ! 46: subl2 $8,r4 # use efp - 8. ! 47: jmp f2 ! 48: f1: # gfp is not zero, ! 49: subl2 $12,r4 # use gfp - 12. ! 50: ! 51: /* ! 52: * Copy region to be duplicated to top of stack. ! 53: */ ! 54: # r7 points at the low word of the region ! 55: # to be copied. r4 points at the high end ! 56: # of the region. (i.e. r4 is the first ! 57: # word not_ to copy.) ! 58: f2: ! 59: subl2 r7,r4 # r4 = r4 - r7, giving r4 number of bytes ! 60: # in region. ! 61: subl2 r4,sp # Move stack pointer down to make space ! 62: # for region. ! 63: movc3 r4,(r7),(sp) # Copy the region by moving r4 bytes starting ! 64: # at r7 to the top of the stack. ! 65: /* ! 66: * Return from suspending function; resumption will return from suspend. ! 67: */ ! 68: subl3 12(fp),8(fp),r0 # Calculate distance between fp and ap ! 69: # in suspender's frame, specifically, ! 70: # r0 = ap - fp ! 71: addl2 sp,r0 # sp points at the first word of the ! 72: # duplicated procedure frame on the ! 73: # stack. By adding it to r0, r0 points ! 74: # at nwords word in argument list of ! 75: # duplicated frame. That is, r0 is ! 76: # serving as a pseudo ap. ! 77: subl2 $8,r0 # Point r0 at location of saved gfp ! 78: # in duplicated frame. ! 79: movl gfp,(r0) # Replace saved gfp with new gfp value ! 80: ! 81: movl sp,fp # Point fp at duplicated procedure frame ! 82: # in preparation for return through it. ! 83: clrl _boundary # Clear the boundary since control is ! 84: # going back into Icon code. ! 85: ret # Return through duplicated frame. This ! 86: # looks like a return from the original ! 87: # call to the built-in function. ! 88: ! 89: #endif VAX ! 90: ! 91: #ifdef PORT ! 92: DummyFcn(_suspend) ! 93: #endif PORT ! 94: ! 95: #ifdef PDP11 ! 96: / suspend - Suspend from a (C) function. ! 97: / Duplicates the most recent generator frame outside the ! 98: / current boundary. Suspend does not return directly. ! 99: / The caller is reactivated when an alternative is needed; ! 100: / the return actually comes from efail. ! 101: ! 102: / Register usage: ! 103: / r0: pointer to top of stack region to be copied, ! 104: / which is just above the procedure descriptor (arg0) of the ! 105: / suspending procedure ! 106: / r2: suspending procedure frame pointer ! 107: / r3: new generator frame pointer ! 108: / r4: old generator frame pointer, indexed down to r0 during copy ! 109: / r5: current procedure frame pointer ! 110: ! 111: _suspend: ! 112: mov r5,-(sp) / create new procedure frame ! 113: mov sp,r5 ! 114: mov r4,-(sp) / save registers ! 115: mov r3,-(sp) ! 116: mov r2,-(sp) ! 117: mov _boundary,r2 / r2 <- pointer to suspending procedure frame ! 118: mov r2,-(sp) / save Icon/C boundary address ! 119: ! 120: / Calculate addresses of new generator frame. ! 121: ! 122: mov sp,r3 / r3 <- pointer to new generator frame ! 123: mov _k_level,-(sp) / save &level ! 124: mov _line,-(sp) / save current line number ! 125: mov _file,-(sp) / and file name ! 126: mov 4(r2),r0 / r0 <- pointer to top of region to be copied ! 127: asl r0 / (= r2 + 10 + 4*nargs) ! 128: asl r0 ! 129: add r2,r0 ! 130: add $10.,r0 ! 131: mov -4(r2),r4 / r4 <- generator frame pointer from caller ! 132: bne 1f / use saved r3 (gfp) - 6 if non-zero, ! 133: mov -2(r2),r4 / else use saved r4 (efp) - 4 ! 134: cmp -(r4),-(r4) ! 135: br 2f ! 136: 1: ! 137: sub $6,r4 ! 138: br 2f ! 139: ! 140: / Copy surrounding expression frame. ! 141: ! 142: 1: ! 143: mov -(r4),-(sp) ! 144: 2: ! 145: cmp r4,r0 / stop at end of frame ! 146: bhi 1b ! 147: ! 148: / Copy return value of suspending function. ! 149: ! 150: mov -(r4),-(sp) ! 151: mov -(r4),-(sp) ! 152: ! 153: / Return from suspending function; reactivation will return from suspend. ! 154: ! 155: mov 2(r2),r1 / r1 <- return pc ! 156: mov (r2),r5 / restore old registers ! 157: mov -(r2),r4 ! 158: tst -(r2) / except generator frame pointer ! 159: mov -(r2),r2 ! 160: clr _boundary / returning to Icon code ! 161: jmp (r1) / this really suspends ! 162: #endif PDP11
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.