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

Defined functions

_lsusp defined in line 147; used 2 times
dosusp defined in line 55; used 1 times
  • in line 32
f1 defined in line 96; used 1 times
  • in line 93
f2 defined in line 106; used 1 times
  • in line 95
Last modified: 1984-11-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 817
Valid CSS Valid XHTML 1.0 Strict