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

Defined functions

_suspend defined in line 111; used 2 times
f1 defined in line 48; used 1 times
  • in line 44
f2 defined in line 58; used 1 times
  • in line 47
Last modified: 1985-01-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 629
Valid CSS Valid XHTML 1.0 Strict