|
|
1.1 ! root 1: #include "../h/config.h" ! 2: ! 3: /* ! 4: * lsusp - suspends a result from a limited expression. The limit counter ! 5: * for the expression is decremented. If the counter becomes zero, ! 6: * lsusp exits the current expression frame, replacing the limit ! 7: * counter with the result which was to be suspended. Otherwise, ! 8: * lsusp suspends from the current expression frame leaving the ! 9: * value being suspended on top of the stack. A generator frame ! 10: * hiding the current expression frame is created. The surrounding ! 11: * expression frame is duplicated and the value being suspended ! 12: * is copied to the top of the stack. The generator frame that ! 13: * is created uses efail as a return point, thus if an alternative ! 14: * is needed, efail will return to itself via the generator frame ! 15: * and then resume execution at the failure label specified in ! 16: * the expression marker. ! 17: * ! 18: * The value being suspended appears as an argument. ! 19: */ ! 20: Global(_efail) /* Signal failure in an expression */ ! 21: Global(_boundary) /* Icon/C boundary address */ ! 22: Global(_line) /* Current line number */ ! 23: Global(_file) /* Current file name */ ! 24: Global(_k_level) /* Value of &level */ ! 25: ! 26: Global(_lsusp) ! 27: #ifdef VAX ! 28: _lsusp: ! 29: Mask STDSV # Partially create generator frame ! 30: # upon entry. ! 31: decl 8(efp) # Decrement the limit counter, ! 32: jneq dosusp # and if this result is not the last, go ! 33: # to dosusp to actually suspend the value. ! 34: /* ! 35: * The limit counter has reached zero. Replace the counter with the ! 36: * value that was to be suspended, remove the current expression frame ! 37: * and return. ! 38: */ ! 39: movq 8(ap),4(efp) # Replace limit counter with value ! 40: movl -4(efp),gfp # Restore gfp from expression frame ! 41: movl 16(sp),r0 # Save return pc in r0 for later use ! 42: movl efp,sp # Point sp at 0'th word of expression ! 43: movl (sp)+,efp # frame and restore efp from frame, ! 44: # also moving sp up to point at low ! 45: # word of return value. ! 46: movl 8(fp),ap # Restore ap ! 47: movl 12(fp),fp # and fp to state they were in before ! 48: # call to lsusp. ! 49: jmp (r0) # Return from lsusp ! 50: ! 51: /* ! 52: * From this point on, the code is EXACTLY the same as esusp, with the ! 53: * exception of the line denoted by "--->". ! 54: */ ! 55: dosusp: ! 56: /* ! 57: * Construct the generator frame. ! 58: */ ! 59: movl fp,_boundary # Set the boundary ! 60: pushl fp # Push boundary as part of generator frame ! 61: movl sp,gfp # The generator frame pointer points at ! 62: # the word containing the boundary. ! 63: pushl _k_level # Save &level, ! 64: pushl _line # line number, ! 65: pushl _file # and file name in generator frame, ! 66: # completing the frame. ! 67: /* ! 68: * Determine region to be copied. ! 69: */ ! 70: addl3 $12,efp,r0 # Point r0 at first word above the ! 71: # expression frame marker. This ! 72: # word is the lower end of the region ! 73: # that will be copied. ! 74: # ---> In esusp, the preceding instruction is ! 75: # addl3 $4,efp,r0 ! 76: # It is 12 instead of 4 here because the ! 77: # descriptor for the limit counter is ! 78: # on the stack above the expression marker ! 79: # and the limit counter is not to be ! 80: # in the duplicated region. ! 81: # ! 82: # If the saved gfp is non-zero, the ! 83: # generator frame marker serves as the ! 84: # upper bound of the expression frame. ! 85: # If it is zero, the expression frame ! 86: # marker pointed at by the saved ! 87: # efp is the upper bound of the frame ! 88: # to be copied. ! 89: # Note that the marker itself is not ! 90: # copied, the region only extends to ! 91: # the marker and not through it. ! 92: movl -4(efp),r2 # Get gfp from expression marker. ! 93: jneq f1 # If it is zero, ! 94: subl3 $8,(efp),r2 # use saved efp - 8. ! 95: jmp f2 ! 96: f1: # gfp is not zero, ! 97: subl2 $12,r2 # use gfp - 12. ! 98: /* ! 99: * Copy surrounding expression frame. ! 100: */ ! 101: # r0 points to the lowest word to be copied ! 102: # and r2 points to high end of the region. ! 103: # The word that r2 points at is part of ! 104: # a generator or expression frame marker ! 105: # is not copied. ! 106: f2: subl2 r0,r2 # Calculate length in bytes of region and ! 107: # put it in r2. ! 108: subl2 r2,sp # Move stack pointer down to accommodate ! 109: # copied region. ! 110: movc3 r2,(r0),(sp) # Copy the region by moving r2 bytes from ! 111: # the address pointed at by r2 to the ! 112: # address pointed at by the stack pointer. ! 113: ! 114: movq 8(ap),-(sp) # Copy the value being suspended to ! 115: # the top of the stack. ! 116: /* ! 117: * Fix things up for return. ! 118: */ ! 119: movl 16(fp),r1 # Get the saved pc (the return point for ! 120: # lsusp) out of the frame and save it in r1. ! 121: movl $_efail,16(fp) # Replace saved pc with efail so that when ! 122: # a return using the generator frame is ! 123: # performed, it will go to efail. ! 124: movl 8(fp),ap # Restore ap ! 125: movl 12(fp),fp # and fp. ! 126: clrl _boundary # Clear the boundary since control is ! 127: # going back into Icon code. ! 128: movl (efp),efp # Point efp at bounding expression frame ! 129: # marker. ! 130: jmp (r1) # Return by branching back to desired ! 131: # return point. The suspended value is ! 132: # on the top of the stack, gfp points ! 133: # at the newly constructed generator ! 134: # frame. ! 135: #endif VAX ! 136: ! 137: #ifdef PORT ! 138: DummyFcn(_lsusp) ! 139: #endif PORT ! 140: ! 141: #ifdef PDP11 ! 142: / lsusp - Suspend or return from a limited expression. ! 143: / Decrements the limit counter; if it becomes zero, lsusp ! 144: / exits the current expression frame. If not, lsusp ! 145: / suspends from the current expression frame. ! 146: ! 147: _lsusp: ! 148: dec 4(r4) / decrement the limit counter ! 149: bne 1f / branch if still > 0 ! 150: ! 151: / Return from the limited expression. ! 152: ! 153: mov (sp)+,r0 / pop return pc ! 154: tst (sp)+ / skip nargs ! 155: mov (sp)+,2(r4) / copy expression value ! 156: mov (sp)+,4(r4) ! 157: mov -2(r4),r3 / exit expression frame ! 158: mov r4,sp ! 159: mov (sp)+,r4 ! 160: jmp (r0) / return ! 161: ! 162: / Suspend from the limited expression. ! 163: / Duplicates the most recent generator frame outside the ! 164: / current expression frame. Lsusp does not return directly. ! 165: / The expression is reactivated when an alternative is needed; ! 166: / the return actually comes from efail. ! 167: ! 168: / Register usage: ! 169: / r0: pointer to top of stack region to be copied, ! 170: / which is just above the procedure descriptor (arg0) of the ! 171: / suspending procedure ! 172: / r2: old generator frame pointer, indexed down to r0 during copy ! 173: / r3: new generator frame pointer ! 174: / r4: suspending expression frame pointer ! 175: / r5: current procedure frame pointer ! 176: ! 177: / This code is exactly the same as esusp.s except for the line marked *** ! 178: / The difference is due to the extra descriptor below the expression frame ! 179: / marker that holds the limit counter. ! 180: ! 181: 1: ! 182: mov r5,-(sp) / create new procedure frame ! 183: mov sp,r5 ! 184: mov r4,-(sp) / save registers ! 185: mov r3,-(sp) ! 186: mov r2,-(sp) ! 187: mov r5,-(sp) / create Icon/C boundary ! 188: mov r5,_boundary ! 189: ! 190: / Calculate addresses of new generator frame. ! 191: ! 192: mov sp,r3 / r3 <- pointer to new generator frame ! 193: mov _k_level,-(sp) / save &level ! 194: mov _line,-(sp) / save current line number ! 195: mov _file,-(sp) / and file name ! 196: mov r4,r0 / r0 <- pointer to top of region to be copied ! 197: add $6,r0 / (= r4 + 6) *** ! 198: mov -2(r4),r2 / r2 <- generator frame pointer from caller ! 199: bne 1f / use saved gfp - 6 if non-zero, ! 200: mov (r4),r2 / else use saved efp - 4 ! 201: cmp -(r2),-(r2) ! 202: br 2f ! 203: 1: ! 204: sub $6,r2 ! 205: br 2f ! 206: ! 207: / Copy surrounding expression frame. ! 208: ! 209: 1: ! 210: mov -(r2),-(sp) ! 211: 2: ! 212: cmp r2,r0 / stop at end of frame ! 213: bhi 1b ! 214: ! 215: / Copy value of suspending expression. ! 216: ! 217: mov 8.(r5),-(sp) / push return value ! 218: mov 6(r5),-(sp) ! 219: ! 220: / Return to code; reactivation will go directly to efail. ! 221: ! 222: mov 2(r5),r1 / r1 <- return pc ! 223: mov $_efail,2(r5) / fix reactivation pc to propagate failure ! 224: mov -6(r5),r2 ! 225: mov (r5),r5 / restore old registers, ! 226: mov (r4),r4 / and exit suspending expression frame ! 227: clr _boundary / returning to Icon code ! 228: jmp (r1) / this really suspends ! 229: #endif PDP11
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.