Subversion Repositories Kolibri OS

Rev

Rev 8097 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8097 Rev 8859
Line 1... Line 1...
1
(*
1
(*
2
    BSD 2-Clause License
2
    BSD 2-Clause License
Line 3... Line 3...
3
 
3
 
4
    Copyright (c) 2018-2020, Anton Krotov
4
    Copyright (c) 2018-2021, Anton Krotov
5
    All rights reserved.
5
    All rights reserved.
Line 6... Line 6...
6
*)
6
*)
Line 15... Line 15...
15
    R0*  =  0;  R1*  =  1;  R2*  =  2;  R3*  =  3;
15
    R0*  =  0;  R1*  =  1;  R2*  =  2;  R3*  =  3;
16
    R4*  =  4;  R5*  =  5;  R6*  =  6;  R7*  =  7;
16
    R4*  =  4;  R5*  =  5;  R6*  =  6;  R7*  =  7;
17
    R8*  =  8;  R9*  =  9;  R10* = 10;  R11* = 11;
17
    R8*  =  8;  R9*  =  9;  R10* = 10;  R11* = 11;
18
    R12* = 12;  R13* = 13;  R14* = 14;  R15* = 15;
18
    R12* = 12;  R13* = 13;  R14* = 14;  R15* = 15;
Line 19... Line -...
19
 
-
 
20
    NVR = 32;
-
 
Line 21... Line 19...
21
 
19
 
Line 22... Line 20...
22
 
20
 
23
TYPE
21
TYPE
24
 
-
 
Line 25... Line 22...
25
    OP1 = PROCEDURE (arg: INTEGER);
22
 
Line 26... Line 23...
26
    OP2 = PROCEDURE (arg1, arg2: INTEGER);
23
    OP1 = PROCEDURE (arg: INTEGER);
27
    OP3 = PROCEDURE (arg1, arg2, arg3: INTEGER);
24
    OP2 = PROCEDURE (arg1, arg2: INTEGER);
28
 
25
 
29
    REGS* = RECORD
26
    REGS* = RECORD
Line 30... Line -...
30
 
-
 
31
        regs*:   SET;
-
 
32
        stk*:    ARRAY N OF INTEGER;
-
 
33
        top*:    INTEGER;
-
 
34
        pushed*: INTEGER;
27
 
35
 
28
        regs*:   SET;
36
        vregs*:  SET;
-
 
Line 37... Line 29...
37
        offs:    ARRAY NVR OF INTEGER;
29
        stk*:    ARRAY N OF INTEGER;
Line 38... Line 30...
38
        size:    ARRAY NVR OF INTEGER;
30
        top*:    INTEGER;
Line 76... Line 68...
76
END pop;
68
END pop;
Line 77... Line 69...
77
 
69
 
78
 
70
 
79
PROCEDURE InStk (R: REGS; reg: INTEGER): INTEGER;
71
PROCEDURE InStk (R: REGS; reg: INTEGER): INTEGER;
Line 80... Line 72...
80
VAR
72
VAR
81
    i, n: INTEGER;
-
 
82
 
73
    i: INTEGER;
83
BEGIN
74
 
84
    i := 0;
75
BEGIN
85
    n := R.top;
-
 
86
    WHILE (i <= n) & (R.stk[i] # reg) DO
-
 
87
        INC(i)
-
 
88
    END;
-
 
89
 
76
    i := R.top;
Line 90... Line 77...
90
    IF i > n THEN
77
    WHILE (i >= 0) & (R.stk[i] # reg) DO
91
        i := -1
78
        DEC(i)
Line 204... Line 191...
204
VAR
191
VAR
205
    n1, n2: INTEGER;
192
    n1, n2: INTEGER;
206
    res: BOOLEAN;
193
    res: BOOLEAN;
Line 207... Line 194...
207
 
194
 
208
BEGIN
195
BEGIN
Line 209... Line 196...
209
    res := FALSE;
196
    res := TRUE;
210
 
197
 
211
    IF reg1 # reg2 THEN
198
    IF reg1 # reg2 THEN
Line 212... Line 199...
212
        n1 := InStk(R, reg1);
199
        n1 := InStk(R, reg1);
213
        n2 := InStk(R, reg2);
200
        n2 := InStk(R, reg2);
214
 
201
 
215
        IF (n1 # -1) & (n2 # -1) THEN
202
        IF (n1 # -1) & (n2 # -1) THEN
216
            R.stk[n1] := reg2;
-
 
217
            R.stk[n2] := reg1;
203
            R.stk[n1] := reg2;
218
            R.xch(reg2, reg1);
204
            R.stk[n2] := reg1;
219
            res := TRUE
205
            R.xch(reg2, reg1)
220
        ELSIF (n1 # -1) & (reg2 IN R.regs) THEN
206
        ELSIF (n1 # -1) & (reg2 IN R.regs) THEN
221
            R.stk[n1] := reg2;
207
            R.stk[n1] := reg2;
222
            INCL(R.regs, reg1);
-
 
223
            EXCL(R.regs, reg2);
208
            INCL(R.regs, reg1);
224
            R.mov(reg2, reg1);
209
            EXCL(R.regs, reg2);
225
            res := TRUE
210
            R.mov(reg2, reg1)
226
        ELSIF (n2 # -1) & (reg1 IN R.regs) THEN
211
        ELSIF (n2 # -1) & (reg1 IN R.regs) THEN
227
            R.stk[n2] := reg1;
212
            R.stk[n2] := reg1;
228
            EXCL(R.regs, reg1);
-
 
229
            INCL(R.regs, reg2);
-
 
230
            R.mov(reg1, reg2);
213
            EXCL(R.regs, reg1);
231
            res := TRUE
214
            INCL(R.regs, reg2);
-
 
215
            R.mov(reg1, reg2)
232
        END
216
        ELSE
Line 233... Line 217...
233
    ELSE
217
            res := FALSE
234
        res := TRUE
218
        END
Line 250... Line 234...
250
    IF R.top > 0 THEN
234
    IF R.top > 0 THEN
251
        reg1 := R.stk[R.top - 1];
235
        reg1 := R.stk[R.top - 1];
252
        reg2 := R.stk[R.top]
236
        reg2 := R.stk[R.top]
253
    ELSIF R.top = 0 THEN
237
    ELSIF R.top = 0 THEN
254
        reg1 := PopAnyReg(R);
238
        reg1 := PopAnyReg(R);
255
        reg2 := R.stk[R.top]
239
        reg2 := R.stk[1]
256
    ELSIF R.top < 0 THEN
240
    ELSE (* R.top = -1 *)
257
        reg2 := PopAnyReg(R);
241
        reg2 := PopAnyReg(R);
258
        reg1 := PopAnyReg(R)
242
        reg1 := PopAnyReg(R)
259
    END
243
    END
260
END BinOp;
244
END BinOp;
Line 284... Line 268...
284
        push(R)
268
        push(R)
285
    END
269
    END
286
END PushAll_1;
270
END PushAll_1;
Line 287... Line -...
287
 
-
 
288
 
-
 
289
PROCEDURE Lock* (VAR R: REGS; reg, offs, size: INTEGER);
-
 
290
BEGIN
-
 
291
    ASSERT(reg IN R.vregs);
-
 
292
    ASSERT(offs # 0);
-
 
293
    ASSERT(size IN {1, 2, 4, 8});
-
 
294
    R.offs[reg] := offs;
-
 
295
    R.size[reg] := size
-
 
296
END Lock;
-
 
297
 
-
 
298
 
-
 
299
PROCEDURE Release* (VAR R: REGS; reg: INTEGER);
-
 
300
BEGIN
-
 
301
    ASSERT(reg IN R.vregs);
-
 
302
    R.offs[reg] := 0
-
 
303
END Release;
-
 
304
 
-
 
305
 
-
 
306
PROCEDURE Load* (R: REGS; reg: INTEGER);
-
 
307
VAR
-
 
308
    offs: INTEGER;
-
 
309
 
-
 
310
BEGIN
-
 
311
    ASSERT(reg IN R.vregs);
-
 
312
    offs := R.offs[reg];
-
 
313
    IF offs # 0 THEN
-
 
314
        R.load(reg, offs, R.size[reg])
-
 
315
    END
-
 
316
END Load;
-
 
317
 
-
 
318
 
-
 
319
PROCEDURE Save* (R: REGS; reg: INTEGER);
-
 
320
VAR
-
 
321
    offs: INTEGER;
-
 
322
 
-
 
323
BEGIN
-
 
324
    ASSERT(reg IN R.vregs);
-
 
325
    offs := R.offs[reg];
-
 
326
    IF offs # 0 THEN
-
 
327
        R.save(reg, offs, R.size[reg])
-
 
328
    END
-
 
329
END Save;
-
 
330
 
-
 
331
 
-
 
332
PROCEDURE Store* (R: REGS);
-
 
333
VAR
-
 
334
    i: INTEGER;
-
 
335
 
-
 
336
BEGIN
-
 
337
    FOR i := 0 TO NVR - 1 DO
-
 
338
        IF i IN R.vregs THEN
-
 
339
            Save(R, i)
-
 
340
        END
-
 
341
    END
-
 
342
END Store;
-
 
343
 
-
 
344
 
-
 
345
PROCEDURE Restore* (R: REGS);
-
 
346
VAR
-
 
347
    i: INTEGER;
-
 
348
 
-
 
349
BEGIN
-
 
350
    FOR i := 0 TO NVR - 1 DO
-
 
351
        IF i IN R.vregs THEN
-
 
352
            Load(R, i)
-
 
353
        END
-
 
354
    END
-
 
355
END Restore;
-
 
356
 
-
 
357
 
-
 
358
PROCEDURE Reset* (VAR R: REGS);
-
 
359
VAR
-
 
360
    i: INTEGER;
-
 
361
 
-
 
362
BEGIN
-
 
363
    FOR i := 0 TO NVR - 1 DO
-
 
364
        IF i IN R.vregs THEN
-
 
365
            R.offs[i] := 0
-
 
366
        END
-
 
367
    END
-
 
368
END Reset;
-
 
369
 
-
 
370
 
-
 
371
PROCEDURE GetVarReg* (R: REGS; offs: INTEGER): INTEGER;
-
 
372
VAR
-
 
373
    i, res: INTEGER;
-
 
374
 
-
 
375
BEGIN
-
 
376
    res := -1;
-
 
377
    i := 0;
-
 
378
    WHILE i < NVR DO
-
 
379
        IF (i IN R.vregs) & (R.offs[i] = offs) THEN
-
 
380
            res := i;
-
 
381
            i := NVR
-
 
382
        END;
-
 
383
        INC(i)
-
 
384
    END
-
 
385
 
-
 
386
    RETURN res
-
 
387
END GetVarReg;
-
 
388
 
-
 
389
 
-
 
390
PROCEDURE GetAnyVarReg* (R: REGS): INTEGER;
-
 
391
VAR
-
 
392
    i, res: INTEGER;
-
 
393
 
-
 
394
BEGIN
-
 
395
    res := -1;
-
 
396
    i := 0;
-
 
397
    WHILE i < NVR DO
-
 
398
        IF (i IN R.vregs) & (R.offs[i] = 0) THEN
-
 
399
            res := i;
-
 
400
            i := NVR
-
 
401
        END;
-
 
402
        INC(i)
-
 
403
    END
-
 
404
 
-
 
405
    RETURN res
-
 
406
END GetAnyVarReg;
-
 
407
 
271
 
408
 
-
 
409
PROCEDURE Init* (VAR R: REGS; push, pop: OP1; mov, xch: OP2; load, save: OP3; regs, vregs: SET);
-
 
410
VAR
-
 
411
    i: INTEGER;
272
 
412
 
273
PROCEDURE Init* (VAR R: REGS; push, pop: OP1; mov, xch: OP2; regs: SET);
413
BEGIN
274
BEGIN
414
    R.regs := regs;
275
    R.regs := regs;
Line 415... Line 276...
415
    R.pushed := 0;
276
    R.pushed := 0;
416
    R.top := -1;
277
    R.top := -1;
417
 
278
 
418
    R.push := push;
279
    R.push := push;
419
    R.pop  := pop;
-
 
420
    R.mov  := mov;
-
 
421
    R.xch  := xch;
-
 
422
    R.load := load;
-
 
423
    R.save := save;
-
 
424
 
-
 
425
    R.vregs := vregs;
-
 
426
 
-
 
427
    FOR i := 0 TO NVR - 1 DO
-
 
428
        R.offs[i] := 0;
-
 
429
        R.size[i] := 0
280
    R.pop  := pop;
Line 430... Line 281...
430
    END
281
    R.mov  := mov;
431
 
282
    R.xch  := xch;