Annotation of 43BSD/contrib/icon/lib/lsusp.s, revision 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.