Annotation of 43BSD/contrib/icon/lib/lsusp.s, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.