-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathdynstk.assemble
More file actions
166 lines (166 loc) · 7.39 KB
/
dynstk.assemble
File metadata and controls
166 lines (166 loc) · 7.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
******************************************************************
* DYNSTK ASSEMBLE *
* Dynamic Stack Controller Stubs *
* *
* Part of GCCLIB - VM/370 CMS Native Std C Library; *
* A Historic Computing Toy *
* *
* Proud Contributors: See contrib memo *
* *
* Released to the public domain. *
******************************************************************
* *
* Assembler stubs for the dynamic stack implemetation *
* These routines are called from PDPEPIL and PDPPRLG MACROs *
* To maximise performance, as they have not got a save area they *
* can use to save registers, and because Adrian's lack of *
* experience these use a register based linkage: *
* R5 for the base (called address) *
* R15 is used by callers - should not be touched *
* R14 Return Address *
* R13 Save Area / stack frame being manipulated *
* R12 is the callers base address - should not be touched *
* *
******************************************************************
* *
DYNSTK CSECT
*
******************************************************************
* @DSTAKIN - Into a new strack frame *
* The point of this stub is to call MORESTAK when the current *
* stack bin is used up *
******************************************************************
* Parameters (see also this file's header)
* R9 - Stack Space requested
* Register Usage:
* R11 - End of STACK BIN
* R8 - GCCCRAB
* R7 - Next Available byte on the Stack (i.e. the new save area)
* R6 - The end of the requested area in current bin (might be
* too big). The next free space after the new frame.
* R0 - Work Register
* R1 - MORESTAK parameter pointer
* R2 - Saved R1 during MORESTAK Call
* R3 - Saved R14 during MORESTAK call
* Output
* R13 - New Frame
******************************************************************
ENTRY @DSTAKIN
@DSTAKIN DS 0H
USING @DSTAKIN,R5
USING CMSCRAB,R13
L R8,GCCCRABA get address of the GCCCRAB
USING GCCCRAB,R8
* Get the dynamic stack information pointer
L R11,DSTACK Get the dynamic stack control
* from R13 save area reserved word
LA R11,0(,R11) Remove flag bits
* Get new save area in R7
L R7,STACKNXT get next available byte in GCC stack
* from the CMSCRAB work area
* Get the address after the frame of the required size in R6
LA R6,0(R7,R9) point to end of R9 sized stack
* Have we enough space?
CR R6,R11 Request bigger than available?
BNH OKSTACK
CLI DSTACK,X'01' Check stack flags
BL OKSTACK If flag is zero, no check is done
* Insufficient space in this stack segment, allocate some
BE OVERFLOW If static, then overflow error
*
* Calling MORESTAK
LR R3,R14 Return address to PDPPRLG
LR R2,R1 Hold R1 (C function parms)
*
* MORESTAK needs a two word parameter list.
* Word 1 is the address of the current stack frame
* Word 2 is the frame size requested
LR R6,R13 Pointer to current stack frame
LR R7,R9 Frame size wanted
L R13,AUXSTCK switching to the auxstack
* Set up R1 to point to the MORESTAK two word parameter plist
* (or rather where it will be after MORESTAK saves its
* entry registers.
LA R1,GR6 address of where parameter list
* will be after MORESTAK saves its
* registers at entry
L R15,=V(MORESTAK)
BALR R14,R15 call MORESTAK
LR R13,R15 R13 now holds the new stack frame
*
LR R1,R2 Restore R1 (C func params)
BR R3 RETURN TO PDPPRLG
*
OKSTACK DS 0F Stack space is fine
ST R7,FORWARD chain forwards to our save area
ST R13,BACK-CMSCRAB(,R7) chain back to caller savearea
ST R11,DSTACK-CMSCRAB(,R7) Save dynamic stack pointer
MVC DSTACK-CMSCRAB(1,R7),DSTACK Copy Stack fram flags over
NI DSTACK-CMSCRAB(R7),X'FF'-X'04' Unset "first frame" flag
LR R13,R7 R13 now points to our save area
*
* Sort out other words of the save area
ST R6,STACKNXT save next available byte in GCC stack
ST R8,GCCCRABA save address of GCCCRAB
*
BR R14 Done here
*
OVERFLOW DS 0H
LA R0,420 Aux Stack Overflow error
ST R0,GERRNO Set ERRNO
L R15,=V(ABORT) Is static so we bought a farm
BR R15
*
DROP R13
DROP R8
DROP R5
EJECT
**************************************************************
* @DSTAKOT - Out from a stack frame *
* The point of this stub is to call LESSSTAK when the first *
* frame in the current stack bin is popped (exited) *
**************************************************************
* Parameters (see also this file's header)
* R13 - Stack Frame
* Register Usage:
* R8 - GCCCRAB
* R3 - Saved parent / popped stack frame
* R1 - Param pointer
* R11 - Dynamic stack control
* R6 - Saved R15 - during LESSTAK call
* Output
* R13 - Popped Stack Frame
* R14 - Address to "return" to
******************************************************************
ENTRY @DSTAKOT
@DSTAKOT DS 0H
USING @DSTAKOT,R5
USING CMSCRAB,R13
L R3,BACK Point to previous save area
ST R15,GR15-CMSCRAB(R3) Set exiting routine RC
* Check if this frame is first in the bin
TM DSTACK,X'04' Is this the first frame?
BZ NOTFIRST flag is zero - not first frame
*
* First frame of stack bin so we must call LESSSTAK
L R8,GCCCRABA get address of the GCCCRAB
USING GCCCRAB,R8
* For LESSSTAK call, R1 points to a parm list containing
* the address of the R13 area being released. We already have
* that address in storage in the next s.a. pointer word of
* the previous save area.
LA R1,FORWARD-CMSCRAB(,R3) Point to current R13 value
* as argument to LESSSTAK
L R15,=V(LESSSTAK)
L R13,AUXSTCK switching to the auxstack
BALR R14,R15 call LESSSTAK
DROP R8
NOTFIRST DS 0H
LR R13,R3 Now R13 is address the popped area
LM R14,R12,GR14 Restore caller regs and return code
BR R14 return to the caller's caller
EJECT
REGEQU
CMSCRAB
GCCCRAB
END