|
|
1.1 root 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.