Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
7983 leency 1
(*
2
    BSD 2-Clause License
3
 
4
    Copyright (c) 2018-2020, Anton Krotov
5
    All rights reserved.
6
*)
7
 
8
MODULE RTL;
9
 
10
IMPORT SYSTEM, API;
11
 
12
 
13
CONST
14
 
15
    bit_depth* = 64;
16
    maxint* = 7FFFFFFFFFFFFFFFH;
17
    minint* = 8000000000000000H;
18
 
19
    WORD = bit_depth DIV 8;
20
    MAX_SET = bit_depth - 1;
21
 
22
 
23
VAR
24
 
25
    name:  INTEGER;
26
    types: INTEGER;
27
    sets:  ARRAY (MAX_SET + 1) * (MAX_SET + 1) OF INTEGER;
28
 
29
 
30
PROCEDURE [stdcall64] _move* (bytes, dest, source: INTEGER);
31
BEGIN
32
    SYSTEM.CODE(
33
    048H, 08BH, 045H, 010H,    (*  mov     rax, qword [rbp + 16]  *)
34
    048H, 085H, 0C0H,          (*  test    rax, rax               *)
35
    07EH, 020H,                (*  jle     L                      *)
36
    0FCH,                      (*  cld                            *)
37
    057H,                      (*  push    rdi                    *)
38
    056H,                      (*  push    rsi                    *)
39
    048H, 08BH, 075H, 020H,    (*  mov     rsi, qword [rbp + 32]  *)
40
    048H, 08BH, 07DH, 018H,    (*  mov     rdi, qword [rbp + 24]  *)
41
    048H, 089H, 0C1H,          (*  mov     rcx, rax               *)
42
    048H, 0C1H, 0E9H, 003H,    (*  shr     rcx, 3                 *)
43
    0F3H, 048H, 0A5H,          (*  rep     movsd                  *)
44
    048H, 089H, 0C1H,          (*  mov     rcx, rax               *)
45
    048H, 083H, 0E1H, 007H,    (*  and     rcx, 7                 *)
46
    0F3H, 0A4H,                (*  rep     movsb                  *)
47
    05EH,                      (*  pop     rsi                    *)
48
    05FH                       (*  pop     rdi                    *)
49
                               (*  L:                             *)
50
                )
51
END _move;
52
 
53
 
54
PROCEDURE [stdcall64] _arrcpy* (base_size, len_dst, dst, len_src, src: INTEGER): BOOLEAN;
55
VAR
56
    res: BOOLEAN;
57
 
58
BEGIN
59
    IF len_src > len_dst THEN
60
        res := FALSE
61
    ELSE
62
        _move(len_src * base_size, dst, src);
63
        res := TRUE
64
    END
65
 
66
    RETURN res
67
END _arrcpy;
68
 
69
 
70
PROCEDURE [stdcall64] _strcpy* (chr_size, len_src, src, len_dst, dst: INTEGER);
71
BEGIN
72
    _move(MIN(len_dst, len_src) * chr_size, dst, src)
73
END _strcpy;
74
 
75
 
76
PROCEDURE [stdcall64] _rot* (VAR A: ARRAY OF INTEGER);
77
VAR
78
    i, n, k: INTEGER;
79
 
80
BEGIN
81
    k := LEN(A) - 1;
82
    n := A[0];
83
    i := 0;
84
    WHILE i < k DO
85
        A[i] := A[i + 1];
86
        INC(i)
87
    END;
88
    A[k] := n
89
END _rot;
90
 
91
 
92
PROCEDURE [stdcall64] _set* (b, a: INTEGER): INTEGER;
93
BEGIN
94
    IF (a <= b) & (a <= MAX_SET) & (b >= 0) THEN
95
        SYSTEM.GET((MIN(b, MAX_SET) * (MAX_SET + 1) + MAX(a, 0)) * WORD + SYSTEM.ADR(sets[0]), a)
96
    ELSE
97
        a := 0
98
    END
99
 
100
    RETURN a
101
END _set;
102
 
103
 
104
PROCEDURE [stdcall64] _set1* (a: INTEGER); (* {a} -> rax *)
105
BEGIN
106
    SYSTEM.CODE(
107
    048H, 031H, 0C0H,         (*  xor  rax, rax               *)
108
    048H, 08BH, 04DH, 010H,   (*  mov  rcx, qword [rbp + 16]  *)  (* rcx <- a *)
109
    048H, 083H, 0F9H, 03FH,   (*  cmp  rcx, 63                *)
110
    077H, 004H,               (*  ja   L                      *)
111
    048H, 00FH, 0ABH, 0C8H    (*  bts  rax, rcx               *)
112
                              (*  L:                          *)
113
    )
114
END _set1;
115
 
116
 
117
PROCEDURE [stdcall64] _divmod* (y, x: INTEGER); (* (x div y) -> rax; (x mod y) -> rdx *)
118
BEGIN
119
    SYSTEM.CODE(
120
    048H, 08BH, 045H, 018H,    (*  mov     rax, qword [rbp + 24]  *)  (* rax <- x *)
121
    048H, 031H, 0D2H,          (*  xor     rdx, rdx               *)
122
    048H, 085H, 0C0H,          (*  test    rax, rax               *)
123
    074H, 022H,                (*  je      L2                     *)
124
    07FH, 003H,                (*  jg      L1                     *)
125
    048H, 0F7H, 0D2H,          (*  not     rdx                    *)
126
                               (*  L1:                            *)
127
    049H, 089H, 0C0H,          (*  mov     r8, rax                *)
128
    048H, 08BH, 04DH, 010H,    (*  mov     rcx, qword [rbp + 16]  *)  (* rcx <- y *)
129
    048H, 0F7H, 0F9H,          (*  idiv    rcx                    *)
130
    048H, 085H, 0D2H,          (*  test    rdx, rdx               *)
131
    074H, 00EH,                (*  je      L2                     *)
132
    049H, 031H, 0C8H,          (*  xor     r8, rcx                *)
133
    04DH, 085H, 0C0H,          (*  test    r8, r8                 *)
134
    07DH, 006H,                (*  jge     L2                     *)
135
    048H, 0FFH, 0C8H,          (*  dec     rax                    *)
136
    048H, 001H, 0CAH           (*  add     rdx, rcx               *)
137
                               (*  L2:                            *)
138
               )
139
END _divmod;
140
 
141
 
142
PROCEDURE [stdcall64] _new* (t, size: INTEGER; VAR ptr: INTEGER);
143
BEGIN
144
    ptr := API._NEW(size);
145
    IF ptr # 0 THEN
146
        SYSTEM.PUT(ptr, t);
147
        INC(ptr, WORD)
148
    END
149
END _new;
150
 
151
 
152
PROCEDURE [stdcall64] _dispose* (VAR ptr: INTEGER);
153
BEGIN
154
    IF ptr # 0 THEN
155
        ptr := API._DISPOSE(ptr - WORD)
156
    END
157
END _dispose;
158
 
159
 
160
PROCEDURE [stdcall64] _length* (len, str: INTEGER);
161
BEGIN
162
    SYSTEM.CODE(
163
    048H, 08BH, 045H, 018H,     (*  mov     rax, qword [rbp + 24]  *)
164
    048H, 08BH, 04DH, 010H,     (*  mov     rcx, qword [rbp + 16]  *)
165
    048H, 0FFH, 0C8H,           (*  dec     rax                    *)
166
                                (*  L1:                            *)
167
    048H, 0FFH, 0C0H,           (*  inc     rax                    *)
168
    080H, 038H, 000H,           (*  cmp     byte [rax], 0          *)
169
    074H, 005H,                 (*  jz      L2                     *)
170
    0E2H, 0F6H,                 (*  loop    L1                     *)
171
    048H, 0FFH, 0C0H,           (*  inc     rax                    *)
172
                                (*  L2:                            *)
173
    048H, 02BH, 045H, 018H      (*  sub     rax, qword [rbp + 24]  *)
174
               )
175
END _length;
176
 
177
 
178
PROCEDURE [stdcall64] _lengthw* (len, str: INTEGER);
179
BEGIN
180
    SYSTEM.CODE(
181
    048H, 08BH, 045H, 018H,     (*  mov     rax, qword [rbp + 24]  *)
182
    048H, 08BH, 04DH, 010H,     (*  mov     rcx, qword [rbp + 16]  *)
183
    048H, 083H, 0E8H, 002H,     (*  sub     rax, 2                 *)
184
                                (*  L1:                            *)
185
    048H, 083H, 0C0H, 002H,     (*  add     rax, 2                 *)
186
    066H, 083H, 038H, 000H,     (*  cmp     word [rax], 0          *)
187
    074H, 006H,                 (*  jz      L2                     *)
188
    0E2H, 0F4H,                 (*  loop    L1                     *)
189
    048H, 083H, 0C0H, 002H,     (*  add     rax, 2                 *)
190
                                (*  L2:                            *)
191
    048H, 02BH, 045H, 018H,     (*  sub     rax, qword [rbp + 24]  *)
192
    048H, 0D1H, 0E8H            (*  shr     rax, 1                 *)
193
               )
194
END _lengthw;
195
 
196
 
197
PROCEDURE [stdcall64] strncmp (a, b, n: INTEGER): INTEGER;
198
BEGIN
199
    SYSTEM.CODE(
200
    048H, 08BH, 04DH, 010H,   (*  mov     rcx, qword[rbp + 16]; rcx <- a *)
201
    048H, 08BH, 055H, 018H,   (*  mov     rdx, qword[rbp + 24]; rdx <- b *)
202
    04CH, 08BH, 045H, 020H,   (*  mov     r8,  qword[rbp + 32]; r8  <- n *)
203
    04DH, 031H, 0C9H,         (*  xor     r9, r9                         *)
204
    04DH, 031H, 0D2H,         (*  xor     r10, r10                       *)
205
    048H, 0B8H, 000H, 000H,
206
    000H, 000H, 000H, 000H,
207
    000H, 080H,               (*  movabs  rax, minint                    *)
208
                              (*  L1:                                    *)
209
    04DH, 085H, 0C0H,         (*  test    r8, r8                         *)
210
    07EH, 024H,               (*  jle     L3                             *)
211
    044H, 08AH, 009H,         (*  mov     r9b, byte[rcx]                 *)
212
    044H, 08AH, 012H,         (*  mov     r10b, byte[rdx]                *)
213
    048H, 0FFH, 0C1H,         (*  inc     rcx                            *)
214
    048H, 0FFH, 0C2H,         (*  inc     rdx                            *)
215
    049H, 0FFH, 0C8H,         (*  dec     r8                             *)
216
    04DH, 039H, 0D1H,         (*  cmp     r9, r10                        *)
217
    074H, 008H,               (*  je      L2                             *)
218
    04CH, 089H, 0C8H,         (*  mov     rax, r9                        *)
219
    04CH, 029H, 0D0H,         (*  sub     rax, r10                       *)
220
    0EBH, 008H,               (*  jmp     L3                             *)
221
                              (*  L2:                                    *)
222
    04DH, 085H, 0C9H,         (*  test    r9, r9                         *)
223
    075H, 0DAH,               (*  jne     L1                             *)
224
    048H, 031H, 0C0H,         (*  xor     rax, rax                       *)
225
                              (*  L3:                                    *)
226
    05DH,                     (*  pop     rbp                            *)
227
    0C2H, 018H, 000H          (*  ret     24                             *)
228
    )
229
    RETURN 0
230
END strncmp;
231
 
232
 
233
PROCEDURE [stdcall64] strncmpw (a, b, n: INTEGER): INTEGER;
234
BEGIN
235
    SYSTEM.CODE(
236
    048H, 08BH, 04DH, 010H,   (*  mov     rcx, qword[rbp + 16]; rcx <- a *)
237
    048H, 08BH, 055H, 018H,   (*  mov     rdx, qword[rbp + 24]; rdx <- b *)
238
    04CH, 08BH, 045H, 020H,   (*  mov     r8,  qword[rbp + 32]; r8  <- n *)
239
    04DH, 031H, 0C9H,         (*  xor     r9, r9                         *)
240
    04DH, 031H, 0D2H,         (*  xor     r10, r10                       *)
241
    048H, 0B8H, 000H, 000H,
242
    000H, 000H, 000H, 000H,
243
    000H, 080H,               (*  movabs  rax, minint                    *)
244
                              (*  L1:                                    *)
245
    04DH, 085H, 0C0H,         (*  test    r8, r8                         *)
246
    07EH, 028H,               (*  jle     L3                             *)
247
    066H, 044H, 08BH, 009H,   (*  mov     r9w, word[rcx]                 *)
248
    066H, 044H, 08BH, 012H,   (*  mov     r10w, word[rdx]                *)
249
    048H, 083H, 0C1H, 002H,   (*  add     rcx, 2                         *)
250
    048H, 083H, 0C2H, 002H,   (*  add     rdx, 2                         *)
251
    049H, 0FFH, 0C8H,         (*  dec     r8                             *)
252
    04DH, 039H, 0D1H,         (*  cmp     r9, r10                        *)
253
    074H, 008H,               (*  je      L2                             *)
254
    04CH, 089H, 0C8H,         (*  mov     rax, r9                        *)
255
    04CH, 029H, 0D0H,         (*  sub     rax, r10                       *)
256
    0EBH, 008H,               (*  jmp     L3                             *)
257
                              (*  L2:                                    *)
258
    04DH, 085H, 0C9H,         (*  test    r9, r9                         *)
259
    075H, 0D6H,               (*  jne     L1                             *)
260
    048H, 031H, 0C0H,         (*  xor     rax, rax                       *)
261
                              (*  L3:                                    *)
262
    05DH,                     (*  pop     rbp                            *)
263
    0C2H, 018H, 000H          (*  ret     24                             *)
264
    )
265
    RETURN 0
266
END strncmpw;
267
 
268
 
269
PROCEDURE [stdcall64] _strcmp* (op, len2, str2, len1, str1: INTEGER): BOOLEAN;
270
VAR
271
    res:  INTEGER;
272
    bRes: BOOLEAN;
273
    c:    CHAR;
274
 
275
BEGIN
276
    res := strncmp(str1, str2, MIN(len1, len2));
277
    IF res = minint THEN
278
        IF len1 > len2 THEN
279
            SYSTEM.GET(str1 + len2, c);
280
            res := ORD(c)
281
        ELSIF len1 < len2 THEN
282
            SYSTEM.GET(str2 + len1, c);
283
            res := -ORD(c)
284
        ELSE
285
            res := 0
286
        END
287
    END;
288
 
289
    CASE op OF
290
    |0: bRes := res =  0
291
    |1: bRes := res #  0
292
    |2: bRes := res <  0
293
    |3: bRes := res <= 0
294
    |4: bRes := res >  0
295
    |5: bRes := res >= 0
296
    END
297
 
298
    RETURN bRes
299
END _strcmp;
300
 
301
 
302
PROCEDURE [stdcall64] _strcmpw* (op, len2, str2, len1, str1: INTEGER): BOOLEAN;
303
VAR
304
    res:  INTEGER;
305
    bRes: BOOLEAN;
306
    c:    WCHAR;
307
 
308
BEGIN
309
    res := strncmpw(str1, str2, MIN(len1, len2));
310
    IF res = minint THEN
311
        IF len1 > len2 THEN
312
            SYSTEM.GET(str1 + len2 * 2, c);
313
            res := ORD(c)
314
        ELSIF len1 < len2 THEN
315
            SYSTEM.GET(str2 + len1 * 2, c);
316
            res := -ORD(c)
317
        ELSE
318
            res := 0
319
        END
320
    END;
321
 
322
    CASE op OF
323
    |0: bRes := res =  0
324
    |1: bRes := res #  0
325
    |2: bRes := res <  0
326
    |3: bRes := res <= 0
327
    |4: bRes := res >  0
328
    |5: bRes := res >= 0
329
    END
330
 
331
    RETURN bRes
332
END _strcmpw;
333
 
334
 
335
PROCEDURE PCharToStr (pchar: INTEGER; VAR s: ARRAY OF CHAR);
336
VAR
337
    c: CHAR;
338
    i: INTEGER;
339
 
340
BEGIN
341
    i := 0;
342
    REPEAT
343
        SYSTEM.GET(pchar, c);
344
        s[i] := c;
345
        INC(pchar);
346
        INC(i)
347
    UNTIL c = 0X
348
END PCharToStr;
349
 
350
 
351
PROCEDURE IntToStr (x: INTEGER; VAR str: ARRAY OF CHAR);
352
VAR
353
    i, a, b: INTEGER;
354
    c: CHAR;
355
 
356
BEGIN
357
    i := 0;
358
    REPEAT
359
        str[i] := CHR(x MOD 10 + ORD("0"));
360
        x := x DIV 10;
361
        INC(i)
362
    UNTIL x = 0;
363
 
364
    a := 0;
365
    b := i - 1;
366
    WHILE a < b DO
367
        c := str[a];
368
        str[a] := str[b];
369
        str[b] := c;
370
        INC(a);
371
        DEC(b)
372
    END;
373
    str[i] := 0X
374
END IntToStr;
375
 
376
 
377
PROCEDURE append (VAR s1: ARRAY OF CHAR; s2: ARRAY OF CHAR);
378
VAR
379
    n1, n2, i, j: INTEGER;
380
 
381
BEGIN
382
    n1 := LENGTH(s1);
383
    n2 := LENGTH(s2);
384
 
385
    ASSERT(n1 + n2 < LEN(s1));
386
 
387
    i := 0;
388
    j := n1;
389
    WHILE i < n2 DO
390
        s1[j] := s2[i];
391
        INC(i);
392
        INC(j)
393
    END;
394
 
395
    s1[j] := 0X
396
END append;
397
 
398
 
399
PROCEDURE [stdcall64] _error* (module, err, line: INTEGER);
400
VAR
401
    s, temp: ARRAY 1024 OF CHAR;
402
 
403
BEGIN
404
    CASE err OF
405
    | 1: s := "assertion failure"
406
    | 2: s := "NIL dereference"
407
    | 3: s := "bad divisor"
408
    | 4: s := "NIL procedure call"
409
    | 5: s := "type guard error"
410
    | 6: s := "index out of range"
411
    | 7: s := "invalid CASE"
412
    | 8: s := "array assignment error"
413
    | 9: s := "CHR out of range"
414
    |10: s := "WCHR out of range"
415
    |11: s := "BYTE out of range"
416
    END;
417
 
418
    append(s, API.eol);
419
 
420
    append(s, "module: "); PCharToStr(module, temp); append(s, temp); append(s, API.eol);
421
    append(s, "line: ");   IntToStr(line, temp);     append(s, temp);
422
 
423
    API.DebugMsg(SYSTEM.ADR(s[0]), name);
424
 
425
    API.exit_thread(0)
426
END _error;
427
 
428
 
429
PROCEDURE [stdcall64] _isrec* (t0, t1, r: INTEGER): INTEGER;
430
BEGIN
431
    SYSTEM.GET(t0 + t1 + types, t0)
432
    RETURN t0 MOD 2
433
END _isrec;
434
 
435
 
436
PROCEDURE [stdcall64] _is* (t0, p: INTEGER): INTEGER;
437
BEGIN
438
    IF p # 0 THEN
439
        SYSTEM.GET(p - WORD, p);
440
        SYSTEM.GET(t0 + p + types, p)
441
    END
442
 
443
    RETURN p MOD 2
444
END _is;
445
 
446
 
447
PROCEDURE [stdcall64] _guardrec* (t0, t1: INTEGER): INTEGER;
448
BEGIN
449
    SYSTEM.GET(t0 + t1 + types, t0)
450
    RETURN t0 MOD 2
451
END _guardrec;
452
 
453
 
454
PROCEDURE [stdcall64] _guard* (t0, p: INTEGER): INTEGER;
455
BEGIN
456
    SYSTEM.GET(p, p);
457
    IF p # 0 THEN
458
        SYSTEM.GET(p - WORD, p);
459
        SYSTEM.GET(t0 + p + types, p)
460
    ELSE
461
        p := 1
462
    END
463
 
464
    RETURN p MOD 2
465
END _guard;
466
 
467
 
468
PROCEDURE [stdcall64] _dllentry* (hinstDLL, fdwReason, lpvReserved: INTEGER): INTEGER;
469
    RETURN API.dllentry(hinstDLL, fdwReason, lpvReserved)
470
END _dllentry;
471
 
472
 
473
PROCEDURE [stdcall64] _sofinit*;
474
BEGIN
475
    API.sofinit
476
END _sofinit;
477
 
478
 
479
PROCEDURE [stdcall64] _exit* (code: INTEGER);
480
BEGIN
481
    API.exit(code)
482
END _exit;
483
 
484
 
485
PROCEDURE [stdcall64] _init* (modname: INTEGER; tcount, _types: INTEGER; code, param: INTEGER);
486
VAR
487
    t0, t1, i, j: INTEGER;
488
 
489
BEGIN
490
    API.init(param, code);
491
 
492
    types := API._NEW(tcount * tcount + SYSTEM.SIZE(INTEGER));
493
    ASSERT(types # 0);
494
    FOR i := 0 TO tcount - 1 DO
495
        FOR j := 0 TO tcount - 1 DO
496
            t0 := i; t1 := j;
497
 
498
            WHILE (t1 # 0) & (t1 # t0) DO
499
                SYSTEM.GET(_types + t1 * WORD, t1)
500
            END;
501
 
502
            SYSTEM.PUT8(i * tcount + j + types, ORD(t0 = t1))
503
        END
504
    END;
505
 
506
    FOR i := 0 TO MAX_SET DO
507
        FOR j := 0 TO i DO
508
            sets[i * (MAX_SET + 1) + j] := LSR(ASR(minint, i - j), MAX_SET - i)
509
        END
510
    END;
511
 
512
    name := modname
513
END _init;
514
 
515
 
516
END RTL.