Rev 7597 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 7597 | Rev 7693 | ||
---|---|---|---|
1 | (* |
1 | (* |
2 | BSD 2-Clause License |
2 | BSD 2-Clause License |
3 | 3 | ||
4 | Copyright (c) 2018, 2019, Anton Krotov |
4 | Copyright (c) 2018, 2019, Anton Krotov |
5 | All rights reserved. |
5 | All rights reserved. |
6 | *) |
6 | *) |
7 | 7 | ||
8 | MODULE REG; |
8 | MODULE REG; |
9 | 9 | ||
10 | 10 | ||
11 | CONST |
11 | CONST |
12 | 12 | ||
13 | N = 16; |
13 | N = 16; |
14 | 14 | ||
- | 15 | R0* = 0; R1* = 1; R2* = 2; R3* = 3; |
|
15 | R0* = 0; R1* = 1; R2* = 2; |
16 | R4* = 4; R5* = 5; R6* = 6; R7* = 7; |
- | 17 | R8* = 8; R9* = 9; R10* = 10; R11* = 11; |
|
16 | R8* = 8; R9* = 9; R10* = 10; R11* = 11; |
18 | R12* = 12; R13* = 13; R14* = 14; R15* = 15; |
17 | 19 | ||
18 | NVR = 32; |
20 | NVR = 32; |
19 | 21 | ||
20 | 22 | ||
21 | TYPE |
23 | TYPE |
22 | 24 | ||
23 | OP1 = PROCEDURE (arg: INTEGER); |
25 | OP1 = PROCEDURE (arg: INTEGER); |
24 | OP2 = PROCEDURE (arg1, arg2: INTEGER); |
26 | OP2 = PROCEDURE (arg1, arg2: INTEGER); |
25 | OP3 = PROCEDURE (arg1, arg2, arg3: INTEGER); |
27 | OP3 = PROCEDURE (arg1, arg2, arg3: INTEGER); |
26 | 28 | ||
27 | REGS* = POINTER TO RECORD |
29 | REGS* = RECORD |
28 | 30 | ||
29 | regs*: SET; |
31 | regs*: SET; |
30 | stk*: ARRAY N OF INTEGER; |
32 | stk*: ARRAY N OF INTEGER; |
31 | top*: INTEGER; |
33 | top*: INTEGER; |
32 | pushed*: INTEGER; |
34 | pushed*: INTEGER; |
33 | 35 | ||
34 | vregs*: SET; |
36 | vregs*: SET; |
35 | offs: ARRAY NVR OF INTEGER; |
37 | offs: ARRAY NVR OF INTEGER; |
36 | size: ARRAY NVR OF INTEGER; |
38 | size: ARRAY NVR OF INTEGER; |
37 | 39 | ||
38 | push, pop: OP1; |
40 | push, pop: OP1; |
39 | mov, xch: OP2; |
41 | mov, xch: OP2; |
40 | load, save: OP3 |
42 | load, save: OP3 |
41 | 43 | ||
42 | END; |
44 | END; |
43 | 45 | ||
44 | 46 | ||
45 | PROCEDURE push (R: REGS); |
47 | PROCEDURE push (VAR R: REGS); |
46 | VAR |
48 | VAR |
47 | i, reg: INTEGER; |
49 | i, reg: INTEGER; |
48 | 50 | ||
49 | BEGIN |
51 | BEGIN |
50 | reg := R.stk[0]; |
52 | reg := R.stk[0]; |
51 | INCL(R.regs, reg); |
53 | INCL(R.regs, reg); |
52 | R.push(reg); |
54 | R.push(reg); |
53 | FOR i := 0 TO R.top - 1 DO |
55 | FOR i := 0 TO R.top - 1 DO |
54 | R.stk[i] := R.stk[i + 1] |
56 | R.stk[i] := R.stk[i + 1] |
55 | END; |
57 | END; |
56 | DEC(R.top); |
58 | DEC(R.top); |
57 | INC(R.pushed) |
59 | INC(R.pushed) |
58 | END push; |
60 | END push; |
59 | 61 | ||
60 | 62 | ||
61 | PROCEDURE pop (R: REGS; reg: INTEGER); |
63 | PROCEDURE pop (VAR R: REGS; reg: INTEGER); |
62 | VAR |
64 | VAR |
63 | i: INTEGER; |
65 | i: INTEGER; |
64 | 66 | ||
65 | BEGIN |
67 | BEGIN |
66 | FOR i := R.top + 1 TO 1 BY -1 DO |
68 | FOR i := R.top + 1 TO 1 BY -1 DO |
67 | R.stk[i] := R.stk[i - 1] |
69 | R.stk[i] := R.stk[i - 1] |
68 | END; |
70 | END; |
69 | R.stk[0] := reg; |
71 | R.stk[0] := reg; |
70 | EXCL(R.regs, reg); |
72 | EXCL(R.regs, reg); |
71 | R.pop(reg); |
73 | R.pop(reg); |
72 | INC(R.top); |
74 | INC(R.top); |
73 | DEC(R.pushed) |
75 | DEC(R.pushed) |
74 | END pop; |
76 | END pop; |
75 | 77 | ||
76 | 78 | ||
77 | PROCEDURE InStk (R: REGS; reg: INTEGER): INTEGER; |
79 | PROCEDURE InStk (R: REGS; reg: INTEGER): INTEGER; |
78 | VAR |
80 | VAR |
79 | i, n: INTEGER; |
81 | i, n: INTEGER; |
80 | 82 | ||
81 | BEGIN |
83 | BEGIN |
82 | i := 0; |
84 | i := 0; |
83 | n := R.top; |
85 | n := R.top; |
84 | WHILE (i <= n) & (R.stk[i] # reg) DO |
86 | WHILE (i <= n) & (R.stk[i] # reg) DO |
85 | INC(i) |
87 | INC(i) |
86 | END; |
88 | END; |
87 | 89 | ||
88 | IF i > n THEN |
90 | IF i > n THEN |
89 | i := -1 |
91 | i := -1 |
90 | END |
92 | END |
91 | 93 | ||
92 | RETURN i |
94 | RETURN i |
93 | END InStk; |
95 | END InStk; |
94 | 96 | ||
95 | 97 | ||
96 | PROCEDURE GetFreeReg (R: REGS): INTEGER; |
98 | PROCEDURE GetFreeReg (R: REGS): INTEGER; |
97 | VAR |
99 | VAR |
98 | i: INTEGER; |
100 | i: INTEGER; |
99 | 101 | ||
100 | BEGIN |
102 | BEGIN |
101 | i := 0; |
103 | i := 0; |
102 | WHILE (i < N) & ~(i IN R.regs) DO |
104 | WHILE (i < N) & ~(i IN R.regs) DO |
103 | INC(i) |
105 | INC(i) |
104 | END; |
106 | END; |
105 | 107 | ||
106 | IF i = N THEN |
108 | IF i = N THEN |
107 | i := -1 |
109 | i := -1 |
108 | END |
110 | END |
109 | 111 | ||
110 | RETURN i |
112 | RETURN i |
111 | END GetFreeReg; |
113 | END GetFreeReg; |
112 | 114 | ||
113 | 115 | ||
114 | PROCEDURE Put (R: REGS; reg: INTEGER); |
116 | PROCEDURE Put (VAR R: REGS; reg: INTEGER); |
115 | BEGIN |
117 | BEGIN |
116 | EXCL(R.regs, reg); |
118 | EXCL(R.regs, reg); |
117 | INC(R.top); |
119 | INC(R.top); |
118 | R.stk[R.top] := reg |
120 | R.stk[R.top] := reg |
119 | END Put; |
121 | END Put; |
120 | 122 | ||
121 | 123 | ||
122 | PROCEDURE PopAnyReg (R: REGS): INTEGER; |
124 | PROCEDURE PopAnyReg (VAR R: REGS): INTEGER; |
123 | VAR |
125 | VAR |
124 | reg: INTEGER; |
126 | reg: INTEGER; |
125 | 127 | ||
126 | BEGIN |
128 | BEGIN |
127 | reg := GetFreeReg(R); |
129 | reg := GetFreeReg(R); |
128 | ASSERT(reg # -1); |
130 | ASSERT(reg # -1); |
129 | ASSERT(R.top < LEN(R.stk) - 1); |
131 | ASSERT(R.top < LEN(R.stk) - 1); |
130 | ASSERT(R.pushed > 0); |
132 | ASSERT(R.pushed > 0); |
131 | pop(R, reg) |
133 | pop(R, reg) |
132 | 134 | ||
133 | RETURN reg |
135 | RETURN reg |
134 | END PopAnyReg; |
136 | END PopAnyReg; |
135 | 137 | ||
136 | 138 | ||
137 | PROCEDURE GetAnyReg* (R: REGS): INTEGER; |
139 | PROCEDURE GetAnyReg* (VAR R: REGS): INTEGER; |
138 | VAR |
140 | VAR |
139 | reg: INTEGER; |
141 | reg: INTEGER; |
140 | 142 | ||
141 | BEGIN |
143 | BEGIN |
142 | reg := GetFreeReg(R); |
144 | reg := GetFreeReg(R); |
143 | IF reg = -1 THEN |
145 | IF reg = -1 THEN |
144 | ASSERT(R.top >= 0); |
146 | ASSERT(R.top >= 0); |
145 | reg := R.stk[0]; |
147 | reg := R.stk[0]; |
146 | push(R) |
148 | push(R) |
147 | END; |
149 | END; |
148 | 150 | ||
149 | Put(R, reg) |
151 | Put(R, reg) |
150 | 152 | ||
151 | RETURN reg |
153 | RETURN reg |
152 | END GetAnyReg; |
154 | END GetAnyReg; |
153 | 155 | ||
154 | 156 | ||
155 | PROCEDURE GetReg* (R: REGS; reg: INTEGER): BOOLEAN; |
157 | PROCEDURE GetReg* (VAR R: REGS; reg: INTEGER): BOOLEAN; |
156 | VAR |
158 | VAR |
157 | free, n: INTEGER; |
159 | free, n: INTEGER; |
158 | res: BOOLEAN; |
160 | res: BOOLEAN; |
159 | 161 | ||
160 | 162 | ||
161 | PROCEDURE exch (R: REGS; reg1, reg2: INTEGER); |
163 | PROCEDURE exch (VAR R: REGS; reg1, reg2: INTEGER); |
162 | VAR |
164 | VAR |
163 | n1, n2: INTEGER; |
165 | n1, n2: INTEGER; |
164 | 166 | ||
165 | BEGIN |
167 | BEGIN |
166 | n1 := InStk(R, reg1); |
168 | n1 := InStk(R, reg1); |
167 | n2 := InStk(R, reg2); |
169 | n2 := InStk(R, reg2); |
168 | R.stk[n1] := reg2; |
170 | R.stk[n1] := reg2; |
169 | R.stk[n2] := reg1; |
171 | R.stk[n2] := reg1; |
170 | R.xch(reg1, reg2) |
172 | R.xch(reg1, reg2) |
171 | END exch; |
173 | END exch; |
172 | 174 | ||
173 | 175 | ||
174 | BEGIN |
176 | BEGIN |
175 | IF reg IN R.regs THEN |
177 | IF reg IN R.regs THEN |
176 | Put(R, reg); |
178 | Put(R, reg); |
177 | res := TRUE |
179 | res := TRUE |
178 | ELSE |
180 | ELSE |
179 | n := InStk(R, reg); |
181 | n := InStk(R, reg); |
180 | IF n # -1 THEN |
182 | IF n # -1 THEN |
181 | free := GetFreeReg(R); |
183 | free := GetFreeReg(R); |
182 | IF free # -1 THEN |
184 | IF free # -1 THEN |
183 | Put(R, free); |
185 | Put(R, free); |
184 | exch(R, reg, free) |
186 | exch(R, reg, free) |
185 | ELSE |
187 | ELSE |
186 | push(R); |
188 | push(R); |
187 | free := GetFreeReg(R); |
189 | free := GetFreeReg(R); |
188 | ASSERT(free # -1); |
190 | ASSERT(free # -1); |
189 | Put(R, free); |
191 | Put(R, free); |
190 | IF free # reg THEN |
192 | IF free # reg THEN |
191 | exch(R, reg, free) |
193 | exch(R, reg, free) |
192 | END |
194 | END |
193 | END; |
195 | END; |
194 | res := TRUE |
196 | res := TRUE |
195 | ELSE |
197 | ELSE |
196 | res := FALSE |
198 | res := FALSE |
197 | END |
199 | END |
198 | END |
200 | END |
199 | 201 | ||
200 | RETURN res |
202 | RETURN res |
201 | END GetReg; |
203 | END GetReg; |
202 | 204 | ||
203 | 205 | ||
204 | PROCEDURE Exchange* (R: REGS; reg1, reg2: INTEGER): BOOLEAN; |
206 | PROCEDURE Exchange* (VAR R: REGS; reg1, reg2: INTEGER): BOOLEAN; |
205 | VAR |
207 | VAR |
206 | n1, n2: INTEGER; |
208 | n1, n2: INTEGER; |
207 | res: BOOLEAN; |
209 | res: BOOLEAN; |
208 | 210 | ||
209 | BEGIN |
211 | BEGIN |
210 | res := FALSE; |
212 | res := FALSE; |
211 | 213 | ||
212 | IF reg1 # reg2 THEN |
214 | IF reg1 # reg2 THEN |
213 | n1 := InStk(R, reg1); |
215 | n1 := InStk(R, reg1); |
214 | n2 := InStk(R, reg2); |
216 | n2 := InStk(R, reg2); |
215 | 217 | ||
216 | IF (n1 # -1) & (n2 # -1) THEN |
218 | IF (n1 # -1) & (n2 # -1) THEN |
217 | R.stk[n1] := reg2; |
219 | R.stk[n1] := reg2; |
218 | R.stk[n2] := reg1; |
220 | R.stk[n2] := reg1; |
219 | R.xch(reg2, reg1); |
221 | R.xch(reg2, reg1); |
220 | res := TRUE |
222 | res := TRUE |
221 | ELSIF (n1 # -1) & (reg2 IN R.regs) THEN |
223 | ELSIF (n1 # -1) & (reg2 IN R.regs) THEN |
222 | R.stk[n1] := reg2; |
224 | R.stk[n1] := reg2; |
223 | INCL(R.regs, reg1); |
225 | INCL(R.regs, reg1); |
224 | EXCL(R.regs, reg2); |
226 | EXCL(R.regs, reg2); |
225 | R.mov(reg2, reg1); |
227 | R.mov(reg2, reg1); |
226 | res := TRUE |
228 | res := TRUE |
227 | ELSIF (n2 # -1) & (reg1 IN R.regs) THEN |
229 | ELSIF (n2 # -1) & (reg1 IN R.regs) THEN |
228 | R.stk[n2] := reg1; |
230 | R.stk[n2] := reg1; |
229 | EXCL(R.regs, reg1); |
231 | EXCL(R.regs, reg1); |
230 | INCL(R.regs, reg2); |
232 | INCL(R.regs, reg2); |
231 | R.mov(reg1, reg2); |
233 | R.mov(reg1, reg2); |
232 | res := TRUE |
234 | res := TRUE |
233 | END |
235 | END |
234 | ELSE |
236 | ELSE |
235 | res := TRUE |
237 | res := TRUE |
236 | END |
238 | END |
237 | 239 | ||
238 | RETURN res |
240 | RETURN res |
239 | END Exchange; |
241 | END Exchange; |
240 | 242 | ||
241 | 243 | ||
242 | PROCEDURE Drop* (R: REGS); |
244 | PROCEDURE Drop* (VAR R: REGS); |
243 | BEGIN |
245 | BEGIN |
244 | INCL(R.regs, R.stk[R.top]); |
246 | INCL(R.regs, R.stk[R.top]); |
245 | DEC(R.top) |
247 | DEC(R.top) |
246 | END Drop; |
248 | END Drop; |
247 | 249 | ||
248 | 250 | ||
249 | PROCEDURE BinOp* (R: REGS; VAR reg1, reg2: INTEGER); |
251 | PROCEDURE BinOp* (VAR R: REGS; VAR reg1, reg2: INTEGER); |
250 | BEGIN |
252 | BEGIN |
251 | IF R.top > 0 THEN |
253 | IF R.top > 0 THEN |
252 | reg1 := R.stk[R.top - 1]; |
254 | reg1 := R.stk[R.top - 1]; |
253 | reg2 := R.stk[R.top] |
255 | reg2 := R.stk[R.top] |
254 | ELSIF R.top = 0 THEN |
256 | ELSIF R.top = 0 THEN |
255 | reg1 := PopAnyReg(R); |
257 | reg1 := PopAnyReg(R); |
256 | reg2 := R.stk[R.top] |
258 | reg2 := R.stk[R.top] |
257 | ELSIF R.top < 0 THEN |
259 | ELSIF R.top < 0 THEN |
258 | reg2 := PopAnyReg(R); |
260 | reg2 := PopAnyReg(R); |
259 | reg1 := PopAnyReg(R) |
261 | reg1 := PopAnyReg(R) |
260 | END |
262 | END |
261 | END BinOp; |
263 | END BinOp; |
262 | 264 | ||
263 | 265 | ||
264 | PROCEDURE UnOp* (R: REGS; VAR reg: INTEGER); |
266 | PROCEDURE UnOp* (VAR R: REGS; VAR reg: INTEGER); |
265 | BEGIN |
267 | BEGIN |
266 | IF R.top >= 0 THEN |
268 | IF R.top >= 0 THEN |
267 | reg := R.stk[R.top] |
269 | reg := R.stk[R.top] |
268 | ELSE |
270 | ELSE |
269 | reg := PopAnyReg(R) |
271 | reg := PopAnyReg(R) |
270 | END |
272 | END |
271 | END UnOp; |
273 | END UnOp; |
272 | 274 | ||
273 | 275 | ||
274 | PROCEDURE PushAll* (R: REGS); |
276 | PROCEDURE PushAll* (VAR R: REGS); |
275 | BEGIN |
277 | BEGIN |
276 | WHILE R.top >= 0 DO |
278 | WHILE R.top >= 0 DO |
277 | push(R) |
279 | push(R) |
278 | END |
280 | END |
279 | END PushAll; |
281 | END PushAll; |
280 | 282 | ||
- | 283 | ||
- | 284 | PROCEDURE PushAll_1* (VAR R: REGS); |
|
- | 285 | BEGIN |
|
- | 286 | WHILE R.top >= 1 DO |
|
- | 287 | push(R) |
|
- | 288 | END |
|
- | 289 | END PushAll_1; |
|
- | 290 | ||
281 | 291 | ||
282 | PROCEDURE Lock* (R: REGS; reg, offs, size: INTEGER); |
292 | PROCEDURE Lock* (VAR R: REGS; reg, offs, size: INTEGER); |
283 | BEGIN |
293 | BEGIN |
284 | ASSERT(reg IN R.vregs); |
294 | ASSERT(reg IN R.vregs); |
285 | ASSERT(offs # 0); |
295 | ASSERT(offs # 0); |
286 | R.offs[reg] := offs; |
296 | R.offs[reg] := offs; |
287 | IF size = 0 THEN |
297 | IF size = 0 THEN |
288 | size := 8 |
298 | size := 8 |
289 | END; |
299 | END; |
290 | R.size[reg] := size |
300 | R.size[reg] := size |
291 | END Lock; |
301 | END Lock; |
292 | 302 | ||
293 | 303 | ||
294 | PROCEDURE Release* (R: REGS; reg: INTEGER); |
304 | PROCEDURE Release* (VAR R: REGS; reg: INTEGER); |
295 | BEGIN |
305 | BEGIN |
296 | ASSERT(reg IN R.vregs); |
306 | ASSERT(reg IN R.vregs); |
297 | R.offs[reg] := 0 |
307 | R.offs[reg] := 0 |
298 | END Release; |
308 | END Release; |
299 | 309 | ||
300 | 310 | ||
301 | PROCEDURE Load* (R: REGS; reg: INTEGER); |
311 | PROCEDURE Load* (R: REGS; reg: INTEGER); |
302 | VAR |
312 | VAR |
303 | offs: INTEGER; |
313 | offs: INTEGER; |
304 | 314 | ||
305 | BEGIN |
315 | BEGIN |
306 | ASSERT(reg IN R.vregs); |
316 | ASSERT(reg IN R.vregs); |
307 | offs := R.offs[reg]; |
317 | offs := R.offs[reg]; |
308 | IF offs # 0 THEN |
318 | IF offs # 0 THEN |
309 | R.load(reg, offs, R.size[reg]) |
319 | R.load(reg, offs, R.size[reg]) |
310 | END |
320 | END |
311 | END Load; |
321 | END Load; |
312 | 322 | ||
313 | 323 | ||
314 | PROCEDURE Save* (R: REGS; reg: INTEGER); |
324 | PROCEDURE Save* (R: REGS; reg: INTEGER); |
315 | VAR |
325 | VAR |
316 | offs: INTEGER; |
326 | offs: INTEGER; |
317 | 327 | ||
318 | BEGIN |
328 | BEGIN |
319 | ASSERT(reg IN R.vregs); |
329 | ASSERT(reg IN R.vregs); |
320 | offs := R.offs[reg]; |
330 | offs := R.offs[reg]; |
321 | IF offs # 0 THEN |
331 | IF offs # 0 THEN |
322 | R.save(reg, offs, R.size[reg]) |
332 | R.save(reg, offs, R.size[reg]) |
323 | END |
333 | END |
324 | END Save; |
334 | END Save; |
325 | 335 | ||
326 | 336 | ||
327 | PROCEDURE Store* (R: REGS); |
337 | PROCEDURE Store* (R: REGS); |
328 | VAR |
338 | VAR |
329 | i: INTEGER; |
339 | i: INTEGER; |
330 | 340 | ||
331 | BEGIN |
341 | BEGIN |
332 | FOR i := 0 TO NVR - 1 DO |
342 | FOR i := 0 TO NVR - 1 DO |
333 | IF i IN R.vregs THEN |
343 | IF i IN R.vregs THEN |
334 | Save(R, i) |
344 | Save(R, i) |
335 | END |
345 | END |
336 | END |
346 | END |
337 | END Store; |
347 | END Store; |
338 | 348 | ||
339 | 349 | ||
340 | PROCEDURE Restore* (R: REGS); |
350 | PROCEDURE Restore* (R: REGS); |
341 | VAR |
351 | VAR |
342 | i: INTEGER; |
352 | i: INTEGER; |
343 | 353 | ||
344 | BEGIN |
354 | BEGIN |
345 | FOR i := 0 TO NVR - 1 DO |
355 | FOR i := 0 TO NVR - 1 DO |
346 | IF i IN R.vregs THEN |
356 | IF i IN R.vregs THEN |
347 | Load(R, i) |
357 | Load(R, i) |
348 | END |
358 | END |
349 | END |
359 | END |
350 | END Restore; |
360 | END Restore; |
351 | 361 | ||
352 | 362 | ||
353 | PROCEDURE Reset* (R: REGS); |
363 | PROCEDURE Reset* (VAR R: REGS); |
354 | VAR |
364 | VAR |
355 | i: INTEGER; |
365 | i: INTEGER; |
356 | 366 | ||
357 | BEGIN |
367 | BEGIN |
358 | FOR i := 0 TO NVR - 1 DO |
368 | FOR i := 0 TO NVR - 1 DO |
359 | IF i IN R.vregs THEN |
369 | IF i IN R.vregs THEN |
360 | R.offs[i] := 0 |
370 | R.offs[i] := 0 |
361 | END |
371 | END |
362 | END |
372 | END |
363 | END Reset; |
373 | END Reset; |
364 | 374 | ||
365 | 375 | ||
366 | PROCEDURE GetVarReg* (R: REGS; offs: INTEGER): INTEGER; |
376 | PROCEDURE GetVarReg* (R: REGS; offs: INTEGER): INTEGER; |
367 | VAR |
377 | VAR |
368 | i, res: INTEGER; |
378 | i, res: INTEGER; |
369 | 379 | ||
370 | BEGIN |
380 | BEGIN |
371 | res := -1; |
381 | res := -1; |
372 | i := 0; |
382 | i := 0; |
373 | WHILE i < NVR DO |
383 | WHILE i < NVR DO |
374 | IF (i IN R.vregs) & (R.offs[i] = offs) THEN |
384 | IF (i IN R.vregs) & (R.offs[i] = offs) THEN |
375 | res := i; |
385 | res := i; |
376 | i := NVR |
386 | i := NVR |
377 | END; |
387 | END; |
378 | INC(i) |
388 | INC(i) |
379 | END |
389 | END |
380 | 390 | ||
381 | RETURN res |
391 | RETURN res |
382 | END GetVarReg; |
392 | END GetVarReg; |
383 | 393 | ||
384 | 394 | ||
385 | PROCEDURE GetAnyVarReg* (R: REGS): INTEGER; |
395 | PROCEDURE GetAnyVarReg* (R: REGS): INTEGER; |
386 | VAR |
396 | VAR |
387 | i, res: INTEGER; |
397 | i, res: INTEGER; |
388 | 398 | ||
389 | BEGIN |
399 | BEGIN |
390 | res := -1; |
400 | res := -1; |
391 | i := 0; |
401 | i := 0; |
392 | WHILE i < NVR DO |
402 | WHILE i < NVR DO |
393 | IF (i IN R.vregs) & (R.offs[i] = 0) THEN |
403 | IF (i IN R.vregs) & (R.offs[i] = 0) THEN |
394 | res := i; |
404 | res := i; |
395 | i := NVR |
405 | i := NVR |
396 | END; |
406 | END; |
397 | INC(i) |
407 | INC(i) |
398 | END |
408 | END |
399 | 409 | ||
400 | RETURN res |
410 | RETURN res |
401 | END GetAnyVarReg; |
411 | END GetAnyVarReg; |
402 | 412 | ||
403 | 413 | ||
404 | PROCEDURE Create* (push, pop: OP1; mov, xch: OP2; load, save: OP3; regs, vregs: SET): REGS; |
414 | PROCEDURE Init* (VAR R: REGS; push, pop: OP1; mov, xch: OP2; load, save: OP3; regs, vregs: SET); |
405 | VAR |
- | |
406 | R: REGS; |
415 | VAR |
407 | i: INTEGER; |
416 | i: INTEGER; |
408 | 417 | ||
409 | BEGIN |
418 | BEGIN |
410 | NEW(R); |
- | |
411 | - | ||
412 | R.regs := regs; |
419 | R.regs := regs; |
413 | R.pushed := 0; |
420 | R.pushed := 0; |
414 | R.top := -1; |
421 | R.top := -1; |
415 | 422 | ||
416 | R.push := push; |
423 | R.push := push; |
417 | R.pop := pop; |
424 | R.pop := pop; |
418 | R.mov := mov; |
425 | R.mov := mov; |
419 | R.xch := xch; |
426 | R.xch := xch; |
420 | R.load := load; |
427 | R.load := load; |
421 | R.save := save; |
428 | R.save := save; |
422 | 429 | ||
423 | R.vregs := vregs; |
430 | R.vregs := vregs; |
424 | 431 | ||
425 | FOR i := 0 TO NVR - 1 DO |
432 | FOR i := 0 TO NVR - 1 DO |
426 | R.offs[i] := 0; |
433 | R.offs[i] := 0; |
427 | R.size[i] := 0 |
434 | R.size[i] := 0 |
428 | END |
435 | END |
429 | - | ||
430 | RETURN R |
436 | |
431 | END Create; |
437 | END Init; |
432 | 438 | ||
433 | 439 | ||
434 | END REG.>>>>>=> |
440 | END REG.>>>>>=> |