Subversion Repositories Kolibri OS

Rev

Rev 7696 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7696 Rev 7983
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-2019, Anton Krotov
4
    Copyright (c) 2018-2020, Anton Krotov
5
    All rights reserved.
5
    All rights reserved.
Line 6... Line 6...
6
*)
6
*)
Line 7... Line 7...
7
 
7
 
8
MODULE AMD64;
8
MODULE AMD64;
Line 9... Line 9...
9
 
9
 
Line 10... Line 10...
10
IMPORT IL, BIN, WR := WRITER, CHL := CHUNKLISTS, LISTS, PATHS, PROG,
10
IMPORT IL, BIN, WR := WRITER, CHL := CHUNKLISTS, LISTS, PATHS, PROG, TARGETS,
Line 72... Line 72...
72
END OutByte;
72
END OutByte;
Line 73... Line 73...
73
 
73
 
74
 
74
 
75
PROCEDURE OutByte2 (a, b: BYTE);
75
PROCEDURE OutByte2 (a, b: BYTE);
76
BEGIN
76
BEGIN
77
    OutByte(a);
77
    X86.OutByte(a);
Line 78... Line 78...
78
    OutByte(b)
78
    X86.OutByte(b)
79
END OutByte2;
79
END OutByte2;
80
 
80
 
81
 
81
 
82
PROCEDURE OutByte3 (a, b, c: BYTE);
82
PROCEDURE OutByte3 (a, b, c: BYTE);
83
BEGIN
83
BEGIN
Line 84... Line 84...
84
    OutByte(a);
84
    X86.OutByte(a);
85
    OutByte(b);
85
    X86.OutByte(b);
86
    OutByte(c)
86
    X86.OutByte(c)
87
END OutByte3;
87
END OutByte3;
88
 
88
 
89
 
89
 
90
PROCEDURE OutInt (n: INTEGER);
90
PROCEDURE OutInt (n: INTEGER);
Line 91... Line 91...
91
BEGIN
91
BEGIN
92
    OutByte(UTILS.Byte(n, 0));
92
    X86.OutByte(n MOD 256);
Line 112... Line 112...
112
 
112
 
113
 
113
 
114
PROCEDURE OutIntByte (n: INTEGER);
114
PROCEDURE OutIntByte (n: INTEGER);
115
BEGIN
115
BEGIN
116
    IF isByte(n) THEN
116
    IF isByte(n) THEN
117
        OutByte(UTILS.Byte(n, 0))
117
        OutByte(n MOD 256)
118
    ELSE
118
    ELSE
119
        OutInt(n)
119
        OutInt(n)
Line 152... Line 152...
152
 
152
 
153
 
153
 
154
PROCEDURE lea (reg, offset, section: INTEGER);
154
PROCEDURE lea (reg, offset, section: INTEGER);
155
BEGIN
155
BEGIN
156
    Rex(0, reg);
156
    Rex(0, reg);
157
    OutByte2(8DH, 05H + 8 * (reg MOD 8)); // lea reg, [rip + offset]
157
    OutByte2(8DH, 05H + 8 * (reg MOD 8)); (* lea reg, [rip + offset] *)
Line 158... Line 158...
158
    X86.Reloc(section, offset)
158
    X86.Reloc(section, offset)
159
END lea;
159
END lea;
160
 
160
 
161
 
161
 
162
PROCEDURE oprr (op: BYTE; reg1, reg2: INTEGER);  // op reg1, reg2
162
PROCEDURE oprr (op: BYTE; reg1, reg2: INTEGER); (* op reg1, reg2 *)
Line 163... Line 163...
163
BEGIN
163
BEGIN
164
    Rex(reg1, reg2);
164
    Rex(reg1, reg2);
165
    OutByte2(op, 0C0H + 8 * (reg2 MOD 8) + reg1 MOD 8)
165
    OutByte2(op, 0C0H + 8 * (reg2 MOD 8) + reg1 MOD 8)
166
END oprr;
166
END oprr;
167
 
167
 
Line 168... Line 168...
168
 
168
 
169
PROCEDURE oprr2 (op1, op2: BYTE; reg1, reg2: INTEGER);  // op reg1, reg2
169
PROCEDURE oprr2 (op1, op2: BYTE; reg1, reg2: INTEGER); (* op reg1, reg2 *)
170
BEGIN
170
BEGIN
171
    Rex(reg1, reg2);
171
    Rex(reg1, reg2);
Line 172... Line 172...
172
    OutByte3(op1, op2, 0C0H + 8 * (reg2 MOD 8) + reg1 MOD 8)
172
    OutByte3(op1, op2, 0C0H + 8 * (reg2 MOD 8) + reg1 MOD 8)
173
END oprr2;
173
END oprr2;
174
 
174
 
175
 
175
 
Line 176... Line 176...
176
PROCEDURE mov (reg1, reg2: INTEGER); // mov reg1, reg2
176
PROCEDURE mov (reg1, reg2: INTEGER); (* mov reg1, reg2 *)
177
BEGIN
177
BEGIN
178
    oprr(89H, reg1, reg2)
178
    oprr(89H, reg1, reg2)
179
END mov;
179
END mov;
Line 180... Line 180...
180
 
180
 
181
 
181
 
182
PROCEDURE xor (reg1, reg2: INTEGER); // xor reg1, reg2
182
PROCEDURE xor (reg1, reg2: INTEGER); (* xor reg1, reg2 *)
183
BEGIN
183
BEGIN
Line 184... Line 184...
184
    oprr(31H, reg1, reg2)
184
    oprr(31H, reg1, reg2)
185
END xor;
185
END xor;
186
 
186
 
187
 
187
 
Line 188... Line 188...
188
PROCEDURE and (reg1, reg2: INTEGER); // and reg1, reg2
188
PROCEDURE and (reg1, reg2: INTEGER); (* and reg1, reg2 *)
189
BEGIN
189
BEGIN
190
    oprr(21H, reg1, reg2)
190
    oprr(21H, reg1, reg2)
191
END and;
191
END and;
Line 192... Line 192...
192
 
192
 
193
 
193
 
194
PROCEDURE or (reg1, reg2: INTEGER); // and reg1, reg2
194
PROCEDURE or (reg1, reg2: INTEGER); (* or reg1, reg2 *)
195
BEGIN
195
BEGIN
Line 196... Line 196...
196
    oprr(09H, reg1, reg2)
196
    oprr(09H, reg1, reg2)
197
END or;
197
END or;
198
 
198
 
199
 
199
 
Line 200... Line 200...
200
PROCEDURE add (reg1, reg2: INTEGER); // add reg1, reg2
200
PROCEDURE add (reg1, reg2: INTEGER); (* add reg1, reg2 *)
201
BEGIN
201
BEGIN
202
    oprr(01H, reg1, reg2)
202
    oprr(01H, reg1, reg2)
203
END add;
203
END add;
204
 
204
 
205
 
205
 
206
PROCEDURE sub (reg1, reg2: INTEGER); // sub reg1, reg2
206
PROCEDURE sub (reg1, reg2: INTEGER); (* sub reg1, reg2 *)
Line 207... Line 207...
207
BEGIN
207
BEGIN
208
    oprr(29H, reg1, reg2)
208
    oprr(29H, reg1, reg2)
209
END sub;
209
END sub;
210
 
210
 
211
 
211
 
212
PROCEDURE xchg (reg1, reg2: INTEGER); // xchg reg1, reg2
212
PROCEDURE xchg (reg1, reg2: INTEGER); (* xchg reg1, reg2 *)
Line 240... Line 240...
240
 
240
 
241
 
241
 
242
PROCEDURE decr (reg: INTEGER);
242
PROCEDURE decr (reg: INTEGER);
243
BEGIN
243
BEGIN
244
    Rex(reg, 0);
244
    Rex(reg, 0);
Line 245... Line 245...
245
    OutByte2(0FFH, 0C8H + reg MOD 8) // dec reg1
245
    OutByte2(0FFH, 0C8H + reg MOD 8) (* dec reg1 *)
246
END decr;
246
END decr;
247
 
247
 
248
 
248
 
249
PROCEDURE incr (reg: INTEGER);
249
PROCEDURE incr (reg: INTEGER);
Line 250... Line 250...
250
BEGIN
250
BEGIN
251
    Rex(reg, 0);
251
    Rex(reg, 0);
Line 274... Line 274...
274
    reg: INTEGER;
274
    reg: INTEGER;
Line 275... Line 275...
275
 
275
 
276
BEGIN
276
BEGIN
277
    reg := GetAnyReg();
277
    reg := GetAnyReg();
278
    lea(reg, label, sIMP);
278
    lea(reg, label, sIMP);
279
    IF reg >= 8 THEN // call qword[reg]
279
    IF reg >= 8 THEN (* call qword[reg] *)
280
        OutByte(41H)
280
        OutByte(41H)
281
    END;
281
    END;
282
    OutByte2(0FFH, 10H + reg MOD 8);
282
    OutByte2(0FFH, 10H + reg MOD 8);
283
    drop
283
    drop
Line 335... Line 335...
335
VAR
335
VAR
336
    i: INTEGER;
336
    i: INTEGER;
Line 337... Line 337...
337
 
337
 
338
BEGIN
338
BEGIN
339
    Rex(reg, 0);
339
    Rex(reg, 0);
340
    OutByte(0B8H + reg MOD 8);  // movabs reg, n
340
    OutByte(0B8H + reg MOD 8); (* movabs reg, n *)
341
    FOR i := 0 TO 7 DO
341
    FOR i := 0 TO 7 DO
342
        OutByte(UTILS.Byte(n, i))
342
        OutByte(UTILS.Byte(n, i))
343
    END
343
    END
Line 344... Line 344...
344
END movabs;
344
END movabs;
345
 
345
 
346
 
346
 
347
PROCEDURE movrc (reg, n: INTEGER); // mov reg, n
347
PROCEDURE movrc (reg, n: INTEGER); (* mov reg, n *)
348
BEGIN
348
BEGIN
349
    IF isLong(n) THEN
349
    IF isLong(n) THEN
Line 356... Line 356...
356
        OutInt(n)
356
        OutInt(n)
357
    END
357
    END
358
END movrc;
358
END movrc;
Line 359... Line 359...
359
 
359
 
360
 
360
 
361
PROCEDURE test (reg: INTEGER); // test reg, reg
361
PROCEDURE test (reg: INTEGER); (* test reg, reg *)
362
BEGIN
362
BEGIN
Line 368... Line 368...
368
VAR
368
VAR
369
    reg2: INTEGER;
369
    reg2: INTEGER;
Line 370... Line 370...
370
 
370
 
371
BEGIN
371
BEGIN
-
 
372
    reg2 := GetAnyReg();
372
    reg2 := GetAnyReg();
373
    ASSERT(reg2 # reg);
373
    movabs(reg2, n);
374
    movabs(reg2, n);
374
    oprr(reg, reg2);
375
    oprr(reg, reg2);
375
    drop
376
    drop
Line 386... Line 387...
386
        OutIntByte(n)
387
        OutIntByte(n)
387
    END
388
    END
388
END oprc;
389
END oprc;
Line 389... Line 390...
389
 
390
 
390
 
391
 
-
 
392
PROCEDURE cmprc (reg, n: INTEGER); (* cmp reg, n *)
-
 
393
BEGIN
-
 
394
    IF n = 0 THEN
391
PROCEDURE cmprc (reg, n: INTEGER); // cmp reg, n
395
        test(reg)
-
 
396
    ELSE
392
BEGIN
397
        oprc(0F8H, reg, n, cmprr)
Line 393... Line 398...
393
    oprc(0F8H, reg, n, cmprr)
398
    END
394
END cmprc;
399
END cmprc;
395
 
400
 
396
 
401
 
Line 397... Line 402...
397
PROCEDURE addrc (reg, n: INTEGER); // add reg, n
402
PROCEDURE addrc (reg, n: INTEGER); (* add reg, n *)
398
BEGIN
403
BEGIN
399
    oprc(0C0H, reg, n, add)
404
    oprc(0C0H, reg, n, add)
400
END addrc;
405
END addrc;
Line 401... Line 406...
401
 
406
 
402
 
407
 
403
PROCEDURE subrc (reg, n: INTEGER); // sub reg, n
408
PROCEDURE subrc (reg, n: INTEGER); (* sub reg, n *)
404
BEGIN
409
BEGIN
Line -... Line 410...
-
 
410
    oprc(0E8H, reg, n, sub)
-
 
411
END subrc;
-
 
412
 
-
 
413
 
-
 
414
PROCEDURE andrc (reg, n: INTEGER); (* and reg, n *)
-
 
415
BEGIN
-
 
416
    oprc(0E0H, reg, n, and)
-
 
417
END andrc;
-
 
418
 
-
 
419
 
-
 
420
PROCEDURE orrc (reg, n: INTEGER); (* or reg, n *)
-
 
421
BEGIN
405
    oprc(0E8H, reg, n, sub)
422
    oprc(0C8H, reg, n, or)
406
END subrc;
423
END orrc;
407
 
424
 
Line 408... Line 425...
408
 
425
 
Line 421... Line 438...
421
        reg2 := GetAnyReg();
438
        reg2 := GetAnyReg();
422
        movabs(reg2, n);
439
        movabs(reg2, n);
423
        push(reg2);
440
        push(reg2);
424
        drop
441
        drop
425
    ELSE
442
    ELSE
426
        OutByte(68H + short(n)); OutIntByte(n) // push n
443
        OutByte(68H + short(n)); OutIntByte(n) (* push n *)
427
    END
444
    END
428
END pushc;
445
END pushc;
Line 429... Line 446...
429
 
446
 
430
 
447
 
431
PROCEDURE not (reg: INTEGER); // not reg
448
PROCEDURE not (reg: INTEGER); (* not reg *)
432
BEGIN
449
BEGIN
433
    Rex(reg, 0);
450
    Rex(reg, 0);
Line 434... Line 451...
434
    OutByte2(0F7H, 0D0H + reg MOD 8)
451
    OutByte2(0F7H, 0D0H + reg MOD 8)
435
END not;
452
END not;
436
 
453
 
437
 
454
 
438
PROCEDURE neg (reg: INTEGER); // neg reg
455
PROCEDURE neg (reg: INTEGER); (* neg reg *)
Line 439... Line 456...
439
BEGIN
456
BEGIN
440
    Rex(reg, 0);
-
 
441
    OutByte2(0F7H, 0D8H + reg MOD 8)
-
 
442
END neg;
-
 
443
 
457
    Rex(reg, 0);
444
 
458
    OutByte2(0F7H, 0D8H + reg MOD 8)
445
PROCEDURE movzx (reg1, reg2, offs: INTEGER; word: BOOLEAN);  // movzx reg1, byte/word[reg2 + offs]
459
END neg;
446
VAR
-
 
447
    b: BYTE;
-
 
448
 
-
 
449
BEGIN
-
 
450
    Rex(reg2, reg1);
-
 
451
    OutByte2(0FH, 0B6H + ORD(word));
-
 
452
    IF (offs = 0) & (reg2 # rbp) THEN
-
 
453
        b := 0
-
 
454
    ELSE
-
 
455
        b := 40H + long(offs)
-
 
456
    END;
-
 
457
    OutByte(b + (reg1 MOD 8) * 8 + reg2 MOD 8);
-
 
458
    IF reg2 = rsp THEN
460
 
Line 459... Line 461...
459
        OutByte(24H)
461
 
460
    END;
-
 
461
    IF b # 0 THEN
-
 
462
        OutIntByte(offs)
-
 
463
    END
462
PROCEDURE movzx (reg1, reg2, offs: INTEGER; word: BOOLEAN); (* movzx reg1, byte/word[reg2 + offs] *)
464
END movzx;
-
 
465
 
-
 
466
 
-
 
467
PROCEDURE _movrm (reg1, reg2, offs, size: INTEGER; mr: BOOLEAN);
-
 
468
VAR
-
 
469
    b: BYTE;
-
 
470
 
-
 
471
BEGIN
-
 
472
    IF size = 16 THEN
-
 
473
        OutByte(66H)
-
 
474
    END;
-
 
475
    IF (reg1 >= 8) OR (reg2 >= 8) OR (size = 64) THEN
-
 
476
        OutByte(40H + reg2 DIV 8 + 4 * (reg1 DIV 8) + 8 * ORD(size = 64))
-
 
477
    END;
-
 
478
    OutByte(8BH - 2 * ORD(mr) - ORD(size = 8));
-
 
479
    IF (offs = 0) & (reg2 # rbp) THEN
-
 
480
        b := 0
-
 
481
    ELSE
-
 
482
        b := 40H + long(offs)
-
 
483
    END;
-
 
484
    OutByte(b + (reg1 MOD 8) * 8 + reg2 MOD 8);
-
 
485
    IF reg2 = rsp THEN
-
 
486
        OutByte(24H)
-
 
487
    END;
-
 
488
    IF b # 0 THEN
463
BEGIN
489
        OutIntByte(offs)
464
    Rex(reg2, reg1);
Line 490... Line 465...
490
    END
465
    X86.movzx(reg1, reg2, offs, word)
491
END _movrm;
466
END movzx;
492
 
467
 
493
 
468
 
Line 494... Line 469...
494
PROCEDURE movmr32 (reg1, offs, reg2: INTEGER); // mov dword[reg1+offs], reg2_32
469
PROCEDURE movmr32 (reg1, offs, reg2: INTEGER); (* mov dword[reg1+offs], reg2_32 *)
495
BEGIN
470
BEGIN
496
    _movrm(reg2, reg1, offs, 32, TRUE)
-
 
497
END movmr32;
-
 
498
 
-
 
499
 
-
 
500
PROCEDURE movrm32 (reg1, reg2, offs: INTEGER); // mov reg1_32, dword[reg2+offs]
-
 
501
BEGIN
-
 
502
    _movrm(reg1, reg2, offs, 32, FALSE)
-
 
503
END movrm32;
-
 
504
 
-
 
505
 
-
 
506
PROCEDURE movmr8 (reg1, offs, reg2: INTEGER); // mov byte[reg1+offs], reg2_8
-
 
507
BEGIN
-
 
508
    _movrm(reg2, reg1, offs, 8, TRUE)
-
 
509
END movmr8;
-
 
510
 
-
 
511
 
-
 
512
PROCEDURE movrm8 (reg1, reg2, offs: INTEGER); // mov reg1_8, byte[reg2+offs]
-
 
513
BEGIN
-
 
514
    _movrm(reg1, reg2, offs, 8, FALSE)
-
 
515
END movrm8;
-
 
516
 
-
 
517
 
-
 
518
PROCEDURE movmr16 (reg1, offs, reg2: INTEGER); // mov word[reg1+offs], reg2_16
-
 
519
BEGIN
-
 
520
    _movrm(reg2, reg1, offs, 16, TRUE)
471
    X86._movrm(reg2, reg1, offs, 32, TRUE)
521
END movmr16;
472
END movmr32;
Line 522... Line 473...
522
 
473
 
523
 
474
 
524
PROCEDURE movrm16 (reg1, reg2, offs: INTEGER); // mov reg1_16, word[reg2+offs]
475
PROCEDURE movrm32 (reg1, reg2, offs: INTEGER); (* mov reg1_32, dword[reg2+offs] *)
525
BEGIN
476
BEGIN
Line 526... Line -...
526
    _movrm(reg1, reg2, offs, 16, FALSE)
-
 
527
END movrm16;
-
 
528
 
-
 
529
 
-
 
530
PROCEDURE movmr (reg1, offs, reg2: INTEGER); // mov qword[reg1+offs], reg2
-
 
531
BEGIN
-
 
532
    _movrm(reg2, reg1, offs, 64, TRUE)
-
 
533
END movmr;
-
 
534
 
-
 
535
 
-
 
536
PROCEDURE movrm (reg1, reg2, offs: INTEGER); // mov reg1, qword[reg2+offs]
-
 
537
BEGIN
-
 
538
    _movrm(reg1, reg2, offs, 64, FALSE)
-
 
539
END movrm;
-
 
540
 
-
 
541
 
-
 
542
PROCEDURE pushm (reg, offs: INTEGER); // push qword[reg+offs]
-
 
543
VAR
-
 
544
    b: BYTE;
-
 
545
 
-
 
546
BEGIN
-
 
547
    IF reg >= 8 THEN
-
 
548
        OutByte(41H)
-
 
549
    END;
-
 
550
    OutByte(0FFH);
477
    X86._movrm(reg1, reg2, offs, 32, FALSE)
551
    IF (offs = 0) & (reg # rbp) THEN
478
END movrm32;
552
        b := 30H
479
 
553
    ELSE
480
 
554
        b := 70H + long(offs)
481
PROCEDURE movmr (reg1, offs, reg2: INTEGER); (* mov qword[reg1+offs], reg2 *)
555
    END;
482
BEGIN
Line 596... Line 523...
596
        OutIntByte(offs)
523
        OutIntByte(offs)
597
    END
524
    END
598
END _movsdrm;
525
END _movsdrm;
Line 599... Line 526...
599
 
526
 
600
 
527
 
601
PROCEDURE movsdrm (xmm, reg, offs: INTEGER); // movsd xmm, qword[reg+offs]
528
PROCEDURE movsdrm (xmm, reg, offs: INTEGER); (* movsd xmm, qword[reg+offs] *)
602
BEGIN
529
BEGIN
Line 603... Line 530...
603
    _movsdrm(xmm, reg, offs, FALSE)
530
    _movsdrm(xmm, reg, offs, FALSE)
604
END movsdrm;
531
END movsdrm;
605
 
532
 
606
 
533
 
Line 618... Line 545...
618
    END;
545
    END;
619
    OutByte3(0FH, op, 0C0H + (xmm1 MOD 8) * 8 + xmm2 MOD 8)
546
    OutByte3(0FH, op, 0C0H + (xmm1 MOD 8) * 8 + xmm2 MOD 8)
620
END opxx;
547
END opxx;
Line 621... Line 548...
621
 
548
 
622
 
549
 
623
PROCEDURE jcc (cc, label: INTEGER); // jcc label
550
PROCEDURE jcc (cc, label: INTEGER); (* jcc label *)
624
BEGIN
551
BEGIN
Line 625... Line 552...
625
    X86.jcc(cc, label)
552
    X86.jcc(cc, label)
626
END jcc;
553
END jcc;
627
 
554
 
628
 
555
 
Line 629... Line 556...
629
PROCEDURE jmp (label: INTEGER); // jmp label
556
PROCEDURE jmp (label: INTEGER); (* jmp label *)
630
BEGIN
557
BEGIN
631
    X86.jmp(label)
558
    X86.jmp(label)
632
END jmp;
559
END jmp;
633
 
560
 
634
 
561
 
Line 678... Line 605...
678
    variables:  LISTS.LIST;
605
    variables:  LISTS.LIST;
679
    lvar, rvar: IL.LOCALVAR;
606
    lvar, rvar: IL.LOCALVAR;
680
    reg:        INTEGER;
607
    reg:        INTEGER;
681
    max:        INTEGER;
608
    max:        INTEGER;
682
    loop:       INTEGER;
609
    loop:       INTEGER;
683
    param2:     INTEGER;
-
 
Line 684... Line 610...
684
 
610
 
685
BEGIN
611
BEGIN
686
    loop := 1;
612
    loop := 1;
687
    variables := cmd.variables;
613
    variables := cmd.variables;
Line 754... Line 680...
754
         IL.opDIVL, IL.opMOD,
680
         IL.opDIVL, IL.opMOD,
755
         IL.opMODL, IL.opLENGTH, IL.opLENGTHW:
681
         IL.opMODL, IL.opLENGTH, IL.opLENGTHW:
756
            leaf := FALSE
682
            leaf := FALSE
Line 757... Line 683...
757
 
683
 
758
        |IL.opDIVR, IL.opMODR:
-
 
759
            param2 := cur.param2;
-
 
760
            IF param2 >= 1 THEN
-
 
761
                param2 := UTILS.Log2(param2)
-
 
762
            ELSIF param2 <= -1 THEN
684
        |IL.opDIVR, IL.opMODR:
763
                param2 := UTILS.Log2(-param2)
-
 
764
            ELSE
-
 
765
                param2 := -1
-
 
766
            END;
-
 
767
            IF param2 < 0 THEN
-
 
768
                leaf := FALSE
-
 
Line 769... Line 685...
769
            END
685
            leaf := UTILS.Log2(cur.param2) >= 0
Line 770... Line 686...
770
 
686
 
771
        ELSE
687
        ELSE
Line 910... Line 826...
910
 
826
 
911
    |IL.opGEF:
827
    |IL.opGEF:
912
        comisd(xmm - 1, xmm);
828
        comisd(xmm - 1, xmm);
913
        cc := setnc
829
        cc := setnc
914
    END;
830
    END;
915
    OutByte2(7AH, 3 + reg DIV 8); // jp L
831
    OutByte2(7AH, 3 + reg DIV 8); (* jp L *)
916
    setcc(cc, reg);
832
    setcc(cc, reg);
917
    //L:
833
    (* L: *)
Line 918... Line 834...
918
END fcmp;
834
END fcmp;
919
 
835
 
Line 967... Line 883...
967
            CASE opcode OF
883
            CASE opcode OF
968
            |IL.opCALLP:
884
            |IL.opCALLP:
969
            |IL.opWIN64CALLP: Win64Passing(param2)
885
            |IL.opWIN64CALLP: Win64Passing(param2)
970
            |IL.opSYSVCALLP:  SysVPassing(param2)
886
            |IL.opSYSVCALLP:  SysVPassing(param2)
971
            END;
887
            END;
972
            OutByte2(0FFH, 0D0H); // call rax
888
            OutByte2(0FFH, 0D0H); (* call rax *)
973
            REG.Restore(R);
889
            REG.Restore(R);
974
            ASSERT(R.top = -1)
890
            ASSERT(R.top = -1)
Line 975... Line 891...
975
 
891
 
976
        |IL.opCALLI, IL.opWIN64CALLI, IL.opSYSVCALLI:
892
        |IL.opCALLI, IL.opWIN64CALLI, IL.opSYSVCALLI:
Line 987... Line 903...
987
            X86.SetLabel(param1)
903
            X86.SetLabel(param1)
Line 988... Line 904...
988
 
904
 
989
        |IL.opERR:
905
        |IL.opERR:
Line -... Line 906...
-
 
906
            CallRTL(IL._error)
-
 
907
 
-
 
908
        |IL.opONERR:
-
 
909
            pushc(param2);
990
            CallRTL(IL._error)
910
            jmp(param1)
991
 
911
 
Line 992... Line 912...
992
        |IL.opPUSHC:
912
        |IL.opPUSHC:
993
            pushc(param2)
913
            pushc(param2)
Line 1115... Line 1035...
1115
            END;
1035
            END;
Line 1116... Line 1036...
1116
 
1036
 
1117
            n := param2;
1037
            n := param2;
1118
            IF n > 4 THEN
1038
            IF n > 4 THEN
1119
                movrc(rcx, n);
1039
                movrc(rcx, n);
1120
                                      // L:
1040
                                     (* L: *)
1121
                pushc(0);
1041
                pushc(0);
1122
                OutByte2(0E2H, 0FCH) // loop L
1042
                OutByte2(0E2H, 0FCH) (* loop L *)
1123
            ELSE
1043
            ELSE
1124
                WHILE n > 0 DO
1044
                WHILE n > 0 DO
1125
                    pushc(0);
1045
                    pushc(0);
1126
                    DEC(n)
1046
                    DEC(n)
Line 1154... Line 1074...
1154
                mov(rsp, rbp)
1074
                mov(rsp, rbp)
1155
            END;
1075
            END;
Line 1156... Line 1076...
1156
 
1076
 
1157
            pop(rbp);
1077
            pop(rbp);
1158
            IF param2 > 0 THEN
1078
            IF param2 > 0 THEN
1159
                OutByte3(0C2H, (param2 * 8) MOD 256, (param2 * 8) DIV 256)  // ret param2
1079
                OutByte3(0C2H, (param2 * 8) MOD 256, (param2 * 8) DIV 256) (* ret param2 *)
1160
            ELSE
1080
            ELSE
1161
                OutByte(0C3H) // ret
1081
                X86.ret
1162
            END;
1082
            END;
Line 1163... Line 1083...
1163
            REG.Reset(R)
1083
            REG.Reset(R)
1164
 
1084
 
Line 1263... Line 1183...
1263
            drop
1183
            drop
Line 1264... Line 1184...
1264
 
1184
 
1265
        |IL.opLADR:
1185
        |IL.opLADR:
1266
            n := param2 * 8;
1186
            n := param2 * 8;
1267
            next := cmd.next(COMMAND);
1187
            next := cmd.next(COMMAND);
1268
            IF next.opcode = IL.opSAVEF THEN
1188
            IF (next.opcode = IL.opSAVEF) OR (next.opcode = IL.opSAVEFI) THEN
1269
                movsdmr(rbp, n, xmm);
1189
                movsdmr(rbp, n, xmm);
1270
                DEC(xmm);
1190
                DEC(xmm);
1271
                cmd := next
1191
                cmd := next
1272
            ELSIF next.opcode = IL.opLOADF THEN
1192
            ELSIF next.opcode = IL.opLOADF THEN
1273
                INC(xmm);
1193
                INC(xmm);
1274
                movsdrm(xmm, rbp, n);
1194
                movsdrm(xmm, rbp, n);
1275
                cmd := next
1195
                cmd := next
1276
            ELSE
1196
            ELSE
1277
                reg1 := GetAnyReg();
1197
                reg1 := GetAnyReg();
1278
                Rex(0, reg1);
1198
                Rex(0, reg1);
1279
                OutByte2(8DH, 45H + long(n) + (reg1 MOD 8) * 8);  // lea reg1, qword[rbp+n]
1199
                OutByte2(8DH, 45H + long(n) + (reg1 MOD 8) * 8); (* lea reg1, qword[rbp+n] *)
1280
                OutIntByte(n)
1200
                OutIntByte(n)
Line 1281... Line 1201...
1281
            END
1201
            END
1282
 
1202
 
Line 1289... Line 1209...
1289
        |IL.opSAVE8C:
1209
        |IL.opSAVE8C:
1290
            UnOp(reg1);
1210
            UnOp(reg1);
1291
            IF reg1 >= 8 THEN
1211
            IF reg1 >= 8 THEN
1292
                OutByte(41H)
1212
                OutByte(41H)
1293
            END;
1213
            END;
1294
            OutByte3(0C6H, reg1 MOD 8, param2); // mov byte[reg1], param2
1214
            OutByte3(0C6H, reg1 MOD 8, param2); (* mov byte[reg1], param2 *)
1295
            drop
1215
            drop
Line 1296... Line 1216...
1296
 
1216
 
1297
        |IL.opSAVE16C:
1217
        |IL.opSAVE16C:
1298
            UnOp(reg1);
1218
            UnOp(reg1);
1299
            OutByte(66H);
1219
            OutByte(66H);
1300
            IF reg1 >= 8 THEN
1220
            IF reg1 >= 8 THEN
1301
                OutByte(41H)
1221
                OutByte(41H)
1302
            END;
1222
            END;
1303
            OutByte2(0C7H, reg1 MOD 8);
1223
            OutByte2(0C7H, reg1 MOD 8);
1304
            OutByte2(param2 MOD 256, param2 DIV 256); // mov word[reg1], param2
1224
            OutByte2(param2 MOD 256, param2 DIV 256); (* mov word[reg1], param2 *)
Line 1305... Line 1225...
1305
            drop
1225
            drop
1306
 
1226
 
1307
        |IL.opSAVEC:
1227
        |IL.opSAVEC:
Line 1311... Line 1231...
1311
                movrc(reg2, param2);
1231
                movrc(reg2, param2);
1312
                movmr(reg1, 0, reg2);
1232
                movmr(reg1, 0, reg2);
1313
                drop
1233
                drop
1314
            ELSE
1234
            ELSE
1315
                Rex(reg1, 0);
1235
                Rex(reg1, 0);
1316
                OutByte2(0C7H, reg1 MOD 8); // mov qword[reg1], param2
1236
                OutByte2(0C7H, reg1 MOD 8); (* mov qword[reg1], param2 *)
1317
                OutInt(param2)
1237
                OutInt(param2)
1318
            END;
1238
            END;
1319
            drop
1239
            drop
Line 1320... Line 1240...
1320
 
1240
 
Line 1344... Line 1264...
1344
            GetRegA
1264
            GetRegA
Line 1345... Line 1265...
1345
 
1265
 
1346
        |IL.opINCL, IL.opEXCL:
1266
        |IL.opINCL, IL.opEXCL:
1347
            BinOp(reg1, reg2);
1267
            BinOp(reg1, reg2);
1348
            cmprc(reg1, 64);
1268
            cmprc(reg1, 64);
1349
            OutByte2(73H, 04H); // jnb L
1269
            OutByte2(73H, 04H); (* jnb L *)
1350
            Rex(reg2, reg1);
1270
            Rex(reg2, reg1);
1351
            OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opEXCL), 8 * (reg1 MOD 8) + reg2 MOD 8); // bts/btr qword[reg2], reg1
1271
            OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opEXCL), 8 * (reg1 MOD 8) + reg2 MOD 8); (* bts/btr qword[reg2], reg1 *)
1352
            // L:
1272
            (* L: *)
1353
            drop;
1273
            drop;
Line 1354... Line 1274...
1354
            drop
1274
            drop
1355
 
1275
 
1356
        |IL.opINCLC, IL.opEXCLC:
1276
        |IL.opINCLC, IL.opEXCLC:
1357
            UnOp(reg1);
1277
            UnOp(reg1);
1358
            Rex(reg1, 0);
1278
            Rex(reg1, 0);
1359
            OutByte2(0FH, 0BAH);  // bts/btr qword[reg1], param2
1279
            OutByte2(0FH, 0BAH); (* bts/btr qword[reg1], param2 *)
Line 1360... Line 1280...
1360
            OutByte2(28H + 8 * ORD(opcode = IL.opEXCLC) + reg1 MOD 8, param2);
1280
            OutByte2(28H + 8 * ORD(opcode = IL.opEXCLC) + reg1 MOD 8, param2);
1361
            drop
1281
            drop
Line 1382... Line 1302...
1382
                BinOp(reg1, reg2);
1302
                BinOp(reg1, reg2);
1383
                cmprr(reg1, reg2);
1303
                cmprr(reg1, reg2);
1384
                drop
1304
                drop
1385
            ELSE
1305
            ELSE
1386
                UnOp(reg1);
1306
                UnOp(reg1);
1387
                IF param2 = 0 THEN
-
 
1388
                    test(reg1)
-
 
1389
                ELSE
-
 
1390
                    cmprc(reg1, param2)
1307
                cmprc(reg1, param2)
1391
                END
-
 
1392
            END;
1308
            END;
Line 1393... Line 1309...
1393
 
1309
 
1394
            drop;
1310
            drop;
Line 1395... Line 1311...
1395
            cc := X86.cond(opcode);
1311
            cc := X86.cond(opcode);
1396
 
1312
 
1397
            IF cmd.next(COMMAND).opcode = IL.opJE THEN
1313
            next := cmd.next(COMMAND);
1398
                label := cmd.next(COMMAND).param1;
1314
            IF next.opcode = IL.opJE THEN
1399
                jcc(cc, label);
-
 
1400
                cmd := cmd.next(COMMAND)
1315
                jcc(cc, next.param1);
1401
 
-
 
1402
            ELSIF cmd.next(COMMAND).opcode = IL.opJNE THEN
1316
                cmd := next
1403
                label := cmd.next(COMMAND).param1;
1317
            ELSIF next.opcode = IL.opJNE THEN
1404
                jcc(X86.inv0(cc), label);
-
 
1405
                cmd := cmd.next(COMMAND)
1318
                jcc(X86.inv0(cc), next.param1);
1406
 
1319
                cmd := next
1407
            ELSE
1320
            ELSE
1408
                reg1 := GetAnyReg();
1321
                reg1 := GetAnyReg();
1409
                setcc(cc + 16, reg1);
1322
                setcc(cc + 16, reg1);
Line 1445... Line 1358...
1445
        |IL.opJZ:
1358
        |IL.opJZ:
1446
            UnOp(reg1);
1359
            UnOp(reg1);
1447
            test(reg1);
1360
            test(reg1);
1448
            jcc(je, param1)
1361
            jcc(je, param1)
Line -... Line 1362...
-
 
1362
 
-
 
1363
        |IL.opJG:
-
 
1364
            UnOp(reg1);
-
 
1365
            test(reg1);
-
 
1366
            jcc(jg, param1)
1449
 
1367
 
1450
        |IL.opJE:
1368
        |IL.opJE:
1451
            UnOp(reg1);
1369
            UnOp(reg1);
1452
            test(reg1);
1370
            test(reg1);
1453
            jcc(jne, param1);
1371
            jcc(jne, param1);
Line 1457... Line 1375...
1457
            UnOp(reg1);
1375
            UnOp(reg1);
1458
            test(reg1);
1376
            test(reg1);
1459
            jcc(je, param1);
1377
            jcc(je, param1);
1460
            drop
1378
            drop
Line 1461... Line 1379...
1461
 
1379
 
-
 
1380
        |IL.opIN, IL.opINR:
-
 
1381
            IF opcode = IL.opINR THEN
-
 
1382
                reg2 := GetAnyReg();
-
 
1383
                movrc(reg2, param2)
1462
        |IL.opIN:
1384
            END;
1463
            label := NewLabel();
1385
            label := NewLabel();
1464
            L := NewLabel();
1386
            L := NewLabel();
1465
            BinOp(reg1, reg2);
1387
            BinOp(reg1, reg2);
1466
            cmprc(reg1, 64);
1388
            cmprc(reg1, 64);
1467
            jcc(jb, L);
1389
            jcc(jb, L);
1468
            xor(reg1, reg1);
1390
            xor(reg1, reg1);
1469
            jmp(label);
1391
            jmp(label);
1470
            X86.SetLabel(L);
1392
            X86.SetLabel(L);
1471
            Rex(reg2, reg1);
1393
            Rex(reg2, reg1);
1472
            OutByte3(0FH, 0A3H, 0C0H + 8 * (reg1 MOD 8) + reg2 MOD 8); // bt reg2, reg1
-
 
1473
            setcc(setc, reg1);
-
 
1474
            andrc(reg1, 1);
-
 
1475
            X86.SetLabel(label);
-
 
1476
            drop
-
 
1477
 
-
 
1478
        |IL.opINR:
-
 
1479
            label := NewLabel();
-
 
1480
            L := NewLabel();
-
 
1481
            UnOp(reg1);
-
 
1482
            reg2 := GetAnyReg();
-
 
1483
            cmprc(reg1, 64);
-
 
1484
            jcc(jb, L);
-
 
1485
            xor(reg1, reg1);
-
 
1486
            jmp(label);
-
 
1487
            X86.SetLabel(L);
-
 
1488
            movrc(reg2, param2);
-
 
1489
            Rex(reg2, reg1);
-
 
1490
            OutByte3(0FH, 0A3H, 0C0H + 8 * (reg1 MOD 8) + reg2 MOD 8); // bt reg2, reg1
1394
            OutByte3(0FH, 0A3H, 0C0H + 8 * (reg1 MOD 8) + reg2 MOD 8); (* bt reg2, reg1 *)
1491
            setcc(setc, reg1);
1395
            setcc(setc, reg1);
1492
            andrc(reg1, 1);
1396
            andrc(reg1, 1);
1493
            X86.SetLabel(label);
1397
            X86.SetLabel(label);
Line 1494... Line 1398...
1494
            drop
1398
            drop
1495
 
1399
 
1496
        |IL.opINL:
1400
        |IL.opINL:
1497
            UnOp(reg1);
1401
            UnOp(reg1);
1498
            Rex(reg1, 0);
1402
            Rex(reg1, 0);
1499
            OutByte2(0FH, 0BAH);  // bt reg1, param2
1403
            OutByte2(0FH, 0BAH); (* bt reg1, param2 *)
1500
            OutByte2(0E0H + reg1 MOD 8, param2);
1404
            OutByte2(0E0H + reg1 MOD 8, param2);
Line 1501... Line 1405...
1501
            setcc(setc, reg1);
1405
            setcc(setc, reg1);
Line 1514... Line 1418...
1514
            andrc(reg1, 1)
1418
            andrc(reg1, 1)
Line 1515... Line 1419...
1515
 
1419
 
1516
        |IL.opABS:
1420
        |IL.opABS:
1517
            UnOp(reg1);
1421
            UnOp(reg1);
1518
            test(reg1);
1422
            test(reg1);
1519
            OutByte2(7DH, 03H); // jge L
1423
            OutByte2(7DH, 03H); (* jge L *)
1520
            neg(reg1)
1424
            neg(reg1)
Line 1521... Line 1425...
1521
            // L:
1425
            (* L: *)
1522
 
1426
 
1523
        |IL.opEQB, IL.opNEB:
1427
        |IL.opEQB, IL.opNEB:
1524
            BinOp(reg1, reg2);
1428
            BinOp(reg1, reg2);
Line 1543... Line 1447...
1543
 
1447
 
1544
        |IL.opMULSC:
1448
        |IL.opMULSC:
1545
            UnOp(reg1);
1449
            UnOp(reg1);
Line 1546... Line 1450...
1546
            andrc(reg1, param2)
1450
            andrc(reg1, param2)
1547
 
1451
 
1548
        |IL.opDIVSC, IL.opADDSL, IL.opADDSR:
1452
        |IL.opDIVSC:
-
 
1453
            UnOp(reg1);
1549
            UnOp(reg1);
1454
            xorrc(reg1, param2)
-
 
1455
 
1550
            Rex(reg1, 0);
1456
        |IL.opADDSL, IL.opADDSR:
Line 1551... Line 1457...
1551
            OutByte2(81H + short(param2), 0C8H + 28H * ORD(opcode = IL.opDIVSC) + reg1 MOD 8); // or/xor reg1, param2
1457
            UnOp(reg1);
1552
            OutIntByte(param2)
1458
            orrc(reg1, param2)
1553
 
1459
 
1554
        |IL.opSUBSL:
1460
        |IL.opSUBSL:
Line 1644... Line 1550...
1644
            GetRegA
1550
            GetRegA
Line 1645... Line 1551...
1645
 
1551
 
1646
        |IL.opTYPEGD:
1552
        |IL.opTYPEGD:
1647
            UnOp(reg1);
1553
            UnOp(reg1);
1648
            PushAll(0);
1554
            PushAll(0);
1649
            pushm(reg1, -8);
1555
            X86.pushm(reg1, -8);
1650
            pushc(param2 * tcount);
1556
            pushc(param2 * tcount);
1651
            CallRTL(IL._guardrec);
1557
            CallRTL(IL._guardrec);
Line 1652... Line 1558...
1652
            GetRegA
1558
            GetRegA
Line 1671... Line 1577...
1671
        |IL.opPUSHP:
1577
        |IL.opPUSHP:
1672
            lea(GetAnyReg(), param2, sCODE)
1578
            lea(GetAnyReg(), param2, sCODE)
Line 1673... Line 1579...
1673
 
1579
 
1674
        |IL.opINC, IL.opDEC:
1580
        |IL.opINC, IL.opDEC:
1675
            BinOp(reg1, reg2);
1581
            BinOp(reg1, reg2);
1676
            // add/sub qword[reg2], reg1
1582
            (* add/sub qword[reg2], reg1 *)
1677
            Rex(reg2, reg1);
1583
            Rex(reg2, reg1);
1678
            OutByte2(01H + 28H * ORD(opcode = IL.opDEC), reg2 MOD 8 + (reg1 MOD 8) * 8);
1584
            OutByte2(01H + 28H * ORD(opcode = IL.opDEC), reg2 MOD 8 + (reg1 MOD 8) * 8);
1679
            drop;
1585
            drop;
Line 1680... Line 1586...
1680
            drop
1586
            drop
1681
 
1587
 
1682
        |IL.opINCC:
1588
        |IL.opINCC:
1683
            UnOp(reg1);
1589
            UnOp(reg1);
1684
            IF isLong(param2) THEN
1590
            IF isLong(param2) THEN
1685
                reg2 := GetAnyReg();
1591
                reg2 := GetAnyReg();
1686
                movrc(reg2, param2);
1592
                movrc(reg2, param2);
1687
                // add qword[reg1], reg2
1593
                (* add qword[reg1], reg2 *)
1688
                Rex(reg1, reg2);
1594
                Rex(reg1, reg2);
1689
                OutByte2(01H, reg1 MOD 8 + (reg2 MOD 8) * 8);
1595
                OutByte2(01H, reg1 MOD 8 + (reg2 MOD 8) * 8);
1690
                drop
1596
                drop
1691
            ELSIF ABS(param2) = 1 THEN
1597
            ELSIF ABS(param2) = 1 THEN
1692
                Rex(reg1, 0);
1598
                Rex(reg1, 0);
1693
                OutByte2(0FFH, reg1 MOD 8 + 8 * ORD(param2 = -1)) // inc/dec qword[reg1]
1599
                OutByte2(0FFH, reg1 MOD 8 + 8 * ORD(param2 = -1)) (* inc/dec qword[reg1] *)
1694
            ELSE
1600
            ELSE
1695
                // add qword[reg1], param2
1601
                (* add qword[reg1], param2 *)
1696
                Rex(reg1, 0);
1602
                Rex(reg1, 0);
1697
                OutByte2(81H + short(param2), reg1 MOD 8);
1603
                OutByte2(81H + short(param2), reg1 MOD 8);
1698
                OutIntByte(param2)
1604
                OutIntByte(param2)
Line 1709... Line 1615...
1709
            drop;
1615
            drop;
1710
            drop
1616
            drop
Line 1711... Line 1617...
1711
 
1617
 
1712
        |IL.opSAVE8:
1618
        |IL.opSAVE8:
1713
            BinOp(reg2, reg1);
1619
            BinOp(reg2, reg1);
1714
            movmr8(reg1, 0, reg2);
1620
            X86.movmr8(reg1, 0, reg2);
1715
            drop;
1621
            drop;
Line 1716... Line 1622...
1716
            drop
1622
            drop
1717
 
1623
 
1718
        |IL.opSAVE16:
1624
        |IL.opSAVE16:
1719
            BinOp(reg2, reg1);
1625
            BinOp(reg2, reg1);
1720
            movmr16(reg1, 0, reg2);
1626
            X86.movmr16(reg1, 0, reg2);
Line 1721... Line 1627...
1721
            drop;
1627
            drop;
1722
            drop
1628
            drop
1723
 
1629
 
1724
        |IL.opSAVE32:
1630
        |IL.opSAVE32:
1725
            BinOp(reg2, reg1);
1631
            BinOp(reg2, reg1);
Line 1726... Line 1632...
1726
            movmr32(reg1, 0, reg2);
1632
            movmr32(reg1, 0, reg2);
1727
            drop;
1633
            drop;
1728
            drop
1634
            drop
1729
 
1635
 
1730
        |IL.opMIN:
1636
        |IL.opMAX, IL.opMIN:
1731
            BinOp(reg1, reg2);
1637
            BinOp(reg1, reg2);
1732
            cmprr(reg1, reg2);
1638
            cmprr(reg1, reg2);
Line 1733... Line -...
1733
            OutByte2(7EH, 3); // jle L
-
 
1734
            mov(reg1, reg2);
-
 
1735
            // L:
-
 
1736
            drop
-
 
1737
 
-
 
1738
        |IL.opMAX:
-
 
1739
            BinOp(reg1, reg2);
-
 
1740
            cmprr(reg1, reg2);
-
 
1741
            OutByte2(7DH, 3);  // jge L
1639
            OutByte2(7DH + ORD(opcode = IL.opMIN), 3); (* jge/jle L *)
1742
            mov(reg1, reg2);
-
 
1743
            // L:
-
 
1744
            drop
-
 
1745
 
-
 
1746
        |IL.opMINC:
-
 
1747
            UnOp(reg1);
-
 
1748
            cmprc(reg1, param2);
-
 
1749
            label := NewLabel();
-
 
1750
            jcc(jle, label);
1640
            mov(reg1, reg2);
1751
            movrc(reg1, param2);
1641
            (* L: *)
1752
            X86.SetLabel(label)
1642
            drop
-
 
1643
 
-
 
1644
        |IL.opMAXC, IL.opMINC:
-
 
1645
            UnOp(reg1);
-
 
1646
            cmprc(reg1, param2);
-
 
1647
            label := NewLabel();
1753
 
1648
            IF opcode = IL.opMINC THEN
1754
        |IL.opMAXC:
1649
                cc := jle
1755
            UnOp(reg1);
1650
            ELSE
Line 1756... Line 1651...
1756
            cmprc(reg1, param2);
1651
                cc := jge
1757
            label := NewLabel();
1652
            END;
1758
            jcc(jge, label);
1653
            jcc(cc, label);
1759
            movrc(reg1, param2);
1654
            movrc(reg1, param2);
1760
            X86.SetLabel(label)
1655
            X86.SetLabel(label)
1761
 
1656
 
1762
        |IL.opSBOOL:
1657
        |IL.opSBOOL:
1763
            BinOp(reg2, reg1);
1658
            BinOp(reg2, reg1);
1764
            test(reg2);
1659
            test(reg2);
Line 1765... Line 1660...
1765
            IF reg1 >= 8 THEN
1660
            IF reg1 >= 8 THEN
1766
                OutByte(41H)
1661
                OutByte(41H)
1767
            END;
1662
            END;
1768
            OutByte3(0FH, 95H, reg1 MOD 8); // setne byte[reg1]
1663
            OutByte3(0FH, 95H, reg1 MOD 8); (* setne byte[reg1] *)
1769
            drop;
1664
            drop;
1770
            drop
1665
            drop
1771
 
1666
 
Line 1772... Line -...
1772
        |IL.opSBOOLC:
-
 
1773
            UnOp(reg1);
-
 
1774
            IF reg1 >= 8 THEN
-
 
1775
                OutByte(41H)
-
 
1776
            END;
1667
        |IL.opSBOOLC:
1777
            OutByte3(0C6H, reg1 MOD 8, ORD(param2 # 0)); // mov byte[reg1], 0/1
1668
            UnOp(reg1);
1778
            drop
1669
            IF reg1 >= 8 THEN
Line 1779... Line 1670...
1779
 
1670
                OutByte(41H)
Line 1808... Line 1699...
1808
            IF opcode = IL.opSUBL THEN
1699
            IF opcode = IL.opSUBL THEN
1809
                neg(reg1)
1700
                neg(reg1)
1810
            END
1701
            END
Line 1811... Line 1702...
1811
 
1702
 
1812
        |IL.opADDL, IL.opADDR:
1703
        |IL.opADDL, IL.opADDR:
1813
            IF param2 # 0 THEN
1704
            IF (param2 # 0) & ~isLong(param2) THEN
-
 
1705
                UnOp(reg1);
-
 
1706
                next := cmd.next(COMMAND);
-
 
1707
                CASE next.opcode OF
-
 
1708
                |IL.opLOAD64:
-
 
1709
                    movrm(reg1, reg1, param2);
-
 
1710
                    cmd := next
-
 
1711
                |IL.opLOAD32:
-
 
1712
                    movrm32(reg1, reg1, param2);
-
 
1713
                    shiftrc(shl, reg1, 32);
-
 
1714
                    shiftrc(shr, reg1, 32);
-
 
1715
                    cmd := next
-
 
1716
                |IL.opLOAD16:
-
 
1717
                    movzx(reg1, reg1, param2, TRUE);
-
 
1718
                    cmd := next
-
 
1719
                |IL.opLOAD8:
-
 
1720
                    movzx(reg1, reg1, param2, FALSE);
-
 
1721
                    cmd := next
-
 
1722
                |IL.opLOAD64_PARAM:
-
 
1723
                    X86.pushm(reg1, param2);
-
 
1724
                    drop;
-
 
1725
                    cmd := next
1814
                UnOp(reg1);
1726
                ELSE
1815
                IF param2 = 1 THEN
1727
                    IF param2 = 1 THEN
1816
                    incr(reg1)
1728
                        incr(reg1)
1817
                ELSIF param2 = -1 THEN
1729
                    ELSIF param2 = -1 THEN
1818
                    decr(reg1)
1730
                        decr(reg1)
1819
                ELSE
1731
                    ELSE
1820
                    addrc(reg1, param2)
1732
                        addrc(reg1, param2)
1821
                END
1733
                    END
-
 
1734
                END
-
 
1735
            ELSIF isLong(param2) THEN
-
 
1736
                addrc(reg1, param2)
Line 1822... Line 1737...
1822
            END
1737
            END
1823
 
1738
 
1824
        |IL.opDIV:
1739
        |IL.opDIV:
1825
            PushAll(2);
1740
            PushAll(2);
Line 1826... Line 1741...
1826
            CallRTL(IL._divmod);
1741
            CallRTL(IL._divmod);
1827
            GetRegA
-
 
1828
 
-
 
1829
        |IL.opDIVR:
-
 
1830
            a := param2;
-
 
1831
            IF a > 1 THEN
1742
            GetRegA
1832
                n := UTILS.Log2(a)
-
 
1833
            ELSIF a < -1 THEN
-
 
1834
                n := UTILS.Log2(-a)
-
 
1835
            ELSE
-
 
1836
                n := -1
-
 
1837
            END;
-
 
1838
 
-
 
1839
            IF a = 1 THEN
-
 
1840
 
-
 
1841
            ELSIF a = -1 THEN
-
 
1842
                UnOp(reg1);
1743
 
1843
                neg(reg1)
1744
        |IL.opDIVR:
1844
            ELSE
-
 
1845
                IF n > 0 THEN
-
 
1846
                    UnOp(reg1);
-
 
1847
 
-
 
1848
                    IF a < 0 THEN
-
 
1849
                        reg2 := GetAnyReg();
-
 
1850
                        mov(reg2, reg1);
-
 
1851
                        shiftrc(sar, reg1, n);
-
 
1852
                        sub(reg1, reg2);
1745
            n := UTILS.Log2(param2);
1853
                        drop
1746
            IF n > 0 THEN
1854
                    ELSE
-
 
1855
                        shiftrc(sar, reg1, n)
-
 
1856
                    END
1747
                UnOp(reg1);
1857
 
1748
                shiftrc(sar, reg1, n)
1858
                ELSE
1749
            ELSIF n < 0 THEN
1859
                    PushAll(1);
1750
                PushAll(1);
1860
                    pushc(param2);
1751
                pushc(param2);
1861
                    CallRTL(IL._divmod);
-
 
Line 1862... Line 1752...
1862
                    GetRegA
1752
                CallRTL(IL._divmod);
1863
                END
1753
                GetRegA
1864
            END
1754
            END
1865
 
1755
 
Line 1877... Line 1767...
1877
            CallRTL(IL._divmod);
1767
            CallRTL(IL._divmod);
1878
            mov(rax, rdx);
1768
            mov(rax, rdx);
1879
            GetRegA
1769
            GetRegA
Line 1880... Line 1770...
1880
 
1770
 
1881
        |IL.opMODR:
-
 
1882
            a := param2;
-
 
1883
            IF a > 1 THEN
-
 
1884
                n := UTILS.Log2(a)
-
 
1885
            ELSIF a < -1 THEN
1771
        |IL.opMODR:
1886
                n := UTILS.Log2(-a)
-
 
1887
            ELSE
-
 
1888
                n := -1
-
 
1889
            END;
-
 
1890
 
-
 
1891
            IF ABS(a) = 1 THEN
-
 
1892
                UnOp(reg1);
-
 
1893
                xor(reg1, reg1)
-
 
1894
            ELSE
1772
            n := UTILS.Log2(param2);
1895
                IF n > 0 THEN
1773
            IF n > 0 THEN
1896
                    UnOp(reg1);
1774
                UnOp(reg1);
1897
                    andrc(reg1, ABS(a) - 1);
-
 
1898
 
1775
                andrc(reg1, param2 - 1);
1899
                    IF a < 0 THEN
-
 
1900
                        test(reg1);
-
 
1901
                        label := NewLabel();
-
 
1902
                        jcc(je, label);
-
 
1903
                        addrc(reg1, a);
-
 
1904
                        X86.SetLabel(label)
-
 
1905
                    END
-
 
1906
 
-
 
1907
                ELSE
1776
            ELSIF n < 0 THEN
1908
                    PushAll(1);
1777
                PushAll(1);
1909
                    pushc(param2);
1778
                pushc(param2);
1910
                    CallRTL(IL._divmod);
1779
                CallRTL(IL._divmod);
1911
                    mov(rax, rdx);
1780
                mov(rax, rdx);
1912
                    GetRegA
1781
                GetRegA
-
 
1782
            ELSE
-
 
1783
                UnOp(reg1);
1913
                END
1784
                xor(reg1, reg1)
Line 1914... Line 1785...
1914
            END
1785
            END
1915
 
1786
 
1916
        |IL.opMODL:
1787
        |IL.opMODL:
Line 1923... Line 1794...
1923
            mov(rax, rdx);
1794
            mov(rax, rdx);
1924
            GetRegA
1795
            GetRegA
Line 1925... Line 1796...
1925
 
1796
 
1926
        |IL.opMUL:
1797
        |IL.opMUL:
1927
            BinOp(reg1, reg2);
1798
            BinOp(reg1, reg2);
1928
            oprr2(0FH, 0AFH, reg2, reg1); // imul reg1, reg2
1799
            oprr2(0FH, 0AFH, reg2, reg1); (* imul reg1, reg2 *)
Line 1929... Line 1800...
1929
            drop
1800
            drop
-
 
1801
 
-
 
1802
        |IL.opMULC:
-
 
1803
            IF (cmd.next(COMMAND).opcode = IL.opADD) & ((param2 = 2) OR (param2 = 4) OR (param2 = 8)) THEN
-
 
1804
                BinOp(reg1, reg2);
-
 
1805
                OutByte2(48H + 5 * (reg1 DIV 8) + 2 * (reg2 DIV 8), 8DH); (* lea reg1, [reg1 + reg2 * param2] *)
-
 
1806
                reg1 := reg1 MOD 8;
-
 
1807
                reg2 := reg2 MOD 8;
-
 
1808
                OutByte2(04H + reg1 * 8, reg1 + reg2 * 8 + 40H * UTILS.Log2(param2));
-
 
1809
                drop;
1930
 
1810
                cmd := cmd.next(COMMAND)
Line 1931... Line 1811...
1931
        |IL.opMULC:
1811
            ELSE
1932
            UnOp(reg1);
1812
                UnOp(reg1);
1933
 
1813
 
Line 1951... Line 1831...
1951
                    IF a < 0 THEN
1831
                        IF a < 0 THEN
1952
                        neg(reg1)
1832
                            neg(reg1)
1953
                    END;
1833
                        END;
1954
                    shiftrc(shl, reg1, n)
1834
                        shiftrc(shl, reg1, n)
1955
                ELSE
1835
                    ELSE
-
 
1836
                        IF isLong(a) THEN
-
 
1837
                            reg2 := GetAnyReg();
-
 
1838
                            movabs(reg2, a);
-
 
1839
                            ASSERT(reg1 # reg2);
-
 
1840
                            oprr2(0FH, 0AFH, reg2, reg1); (* imul reg1, reg2 *)
-
 
1841
                            drop
-
 
1842
                        ELSE
1956
                    // imul reg1, a
1843
                            (* imul reg1, a *)
1957
                    Rex(reg1, reg1);
1844
                            Rex(reg1, reg1);
1958
                    OutByte2(69H + short(a), 0C0H + (reg1 MOD 8) * 9);
1845
                            OutByte2(69H + short(a), 0C0H + (reg1 MOD 8) * 9);
1959
                    OutIntByte(a)
1846
                            OutIntByte(a)
1960
                END
1847
                        END
1961
            END
1848
                    END
-
 
1849
                END
-
 
1850
            END
Line 1962... Line 1851...
1962
 
1851
 
1963
        |IL.opADDS:
1852
        |IL.opADDS:
1964
            BinOp(reg1, reg2);
1853
            BinOp(reg1, reg2);
1965
            or(reg1, reg2);
1854
            or(reg1, reg2);
Line 1988... Line 1877...
1988
            drop
1877
            drop
Line 1989... Line 1878...
1989
 
1878
 
Line 1990... Line 1879...
1990
        |IL.opENDSW:
1879
        |IL.opENDSW:
-
 
1880
 
1991
 
1881
        |IL.opCASEL:
1992
        |IL.opCASEL:
1882
            GetRegA;
-
 
1883
            cmprc(rax, param1);
Line 1993... Line 1884...
1993
            cmprc(rax, param1);
1884
            jcc(jl, param2);
-
 
1885
            drop
1994
            jcc(jl, param2)
1886
 
1995
 
1887
        |IL.opCASER:
-
 
1888
            GetRegA;
Line 1996... Line 1889...
1996
        |IL.opCASER:
1889
            cmprc(rax, param1);
-
 
1890
            jcc(jg, param2);
1997
            cmprc(rax, param1);
1891
            drop
1998
            jcc(jg, param2)
1892
 
1999
 
1893
        |IL.opCASELR:
-
 
1894
            GetRegA;
Line 2000... Line 1895...
2000
        |IL.opCASELR:
1895
            cmprc(rax, param1);
2001
            cmprc(rax, param1);
1896
            jcc(jl, param2);
2002
            jcc(jl, param2);
1897
            jcc(jg, cmd.param3);
2003
            jcc(jg, cmd.param3)
1898
            drop
2004
 
1899
 
2005
        |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR:
1900
        |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR:
2006
            BinOp(reg1, reg2);
1901
            BinOp(reg1, reg2);
2007
            xchg(reg2, rcx);
1902
            xchg(reg2, rcx);
Line 2008... Line 1903...
2008
            Rex(reg1, 0);
1903
            Rex(reg1, 0);
2009
            OutByte(0D3H);
1904
            OutByte(0D3H);
2010
            X86.shift(opcode, reg1 MOD 8); // shift reg1, cl
1905
            X86.shift(opcode, reg1 MOD 8); (* shift reg1, cl *)
2011
            xchg(reg2, rcx);
1906
            xchg(reg2, rcx);
2012
            drop
1907
            drop
2013
 
1908
 
2014
        |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1:
1909
        |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1:
2015
            reg1 := GetAnyReg();
1910
            reg1 := GetAnyReg();
2016
            movrc(reg1, param2);
1911
            movrc(reg1, param2);
2017
            BinOp(reg1, reg2);
1912
            BinOp(reg1, reg2);
2018
            xchg(reg1, rcx);
1913
            xchg(reg1, rcx);
2019
            Rex(reg2, 0);
1914
            Rex(reg2, 0);
Line 2036... Line 1931...
2036
                reg1 := GetAnyReg();
1931
                reg1 := GetAnyReg();
2037
                movrc(reg1, param1)
1932
                movrc(reg1, param1)
2038
            END;
1933
            END;
2039
            drop;
1934
            drop;
2040
            drop;
1935
            drop;
2041
            _movrm(reg1, reg1, 0, param2 * 8, FALSE);
1936
            X86._movrm(reg1, reg1, 0, param2 * 8, FALSE);
2042
            _movrm(reg1, reg2, 0, param2 * 8, TRUE)
1937
            X86._movrm(reg1, reg2, 0, param2 * 8, TRUE)
Line 2043... Line 1938...
2043
 
1938
 
2044
        |IL.opCHKBYTE:
1939
        |IL.opCHKBYTE:
2045
            BinOp(reg1, reg2);
1940
            BinOp(reg1, reg2);
2046
            cmprc(reg1, 256);
1941
            cmprc(reg1, 256);
Line 2053... Line 1948...
2053
 
1948
 
2054
        |IL.opCHKIDX2:
1949
        |IL.opCHKIDX2:
2055
            BinOp(reg1, reg2);
1950
            BinOp(reg1, reg2);
2056
            IF param2 # -1 THEN
1951
            IF param2 # -1 THEN
2057
                cmprr(reg2, reg1);
-
 
2058
                mov(reg1, reg2);
-
 
2059
                drop;
1952
                cmprr(reg2, reg1);
2060
                jcc(jb, param1)
1953
                jcc(jb, param1);
2061
            ELSE
1954
            END;
2062
                INCL(R.regs, reg1);
1955
            INCL(R.regs, reg1);
2063
                DEC(R.top);
1956
            DEC(R.top);
2064
                R.stk[R.top] := reg2
-
 
Line 2065... Line 1957...
2065
            END
1957
            R.stk[R.top] := reg2
2066
 
1958
 
2067
        |IL.opLENGTH:
1959
        |IL.opLENGTH:
2068
            PushAll(2);
1960
            PushAll(2);
Line 2125... Line 2017...
2125
        |IL.opINCCB, IL.opDECCB:
2017
        |IL.opINCCB, IL.opDECCB:
2126
            UnOp(reg1);
2018
            UnOp(reg1);
2127
            IF reg1 >= 8 THEN
2019
            IF reg1 >= 8 THEN
2128
                OutByte(41H)
2020
                OutByte(41H)
2129
            END;
2021
            END;
2130
            OutByte3(80H, 28H * ORD(opcode = IL.opDECCB) + reg1 MOD 8, param2 MOD 256); // add/sub byte[reg1], param2 MOD 256
2022
            OutByte3(80H, 28H * ORD(opcode = IL.opDECCB) + reg1 MOD 8, param2 MOD 256); (* add/sub byte[reg1], param2 MOD 256 *)
2131
            drop
2023
            drop
Line 2132... Line 2024...
2132
 
2024
 
2133
        |IL.opINCB, IL.opDECB:
2025
        |IL.opINCB, IL.opDECB:
2134
            BinOp(reg1, reg2);
2026
            BinOp(reg1, reg2);
2135
            IF (reg1 >= 8) OR (reg2 >= 8) THEN
2027
            IF (reg1 >= 8) OR (reg2 >= 8) THEN
2136
                OutByte(40H + reg2 DIV 8 + 4 * (reg1 DIV 8))
2028
                OutByte(40H + reg2 DIV 8 + 4 * (reg1 DIV 8))
2137
            END;
2029
            END;
2138
            OutByte2(28H * ORD(opcode = IL.opDECB), reg2 MOD 8 + 8 * (reg1 MOD 8)); // add/sub byte[reg2], reg1_8
2030
            OutByte2(28H * ORD(opcode = IL.opDECB), reg2 MOD 8 + 8 * (reg1 MOD 8)); (* add/sub byte[reg2], reg1_8 *)
2139
            drop;
2031
            drop;
Line 2140... Line 2032...
2140
            drop
2032
            drop
2141
 
2033
 
Line 2147... Line 2039...
2147
            push(reg2);
2039
            push(reg2);
2148
            drop;
2040
            drop;
2149
            IF reg1 >= 8 THEN
2041
            IF reg1 >= 8 THEN
2150
                OutByte(41H)
2042
                OutByte(41H)
2151
            END;
2043
            END;
2152
            OutByte2(8FH, reg1 MOD 8); // pop qword[reg1]
2044
            OutByte2(8FH, reg1 MOD 8); (* pop qword[reg1] *)
2153
            drop
2045
            drop
Line 2154... Line 2046...
2154
 
2046
 
2155
        |IL.opCLEANUP:
2047
        |IL.opCLEANUP:
2156
            n := param2 * 8;
2048
            n := param2 * 8;
Line 2179... Line 2071...
2179
            lea(reg1, Numbers_Offs + Numbers_Count * 8, sDATA);
2071
            lea(reg1, Numbers_Offs + Numbers_Count * 8, sDATA);
2180
            movsdrm(xmm, reg1, 0);
2072
            movsdrm(xmm, reg1, 0);
2181
            drop;
2073
            drop;
2182
            NewNumber(UTILS.splitf(float, a, b))
2074
            NewNumber(UTILS.splitf(float, a, b))
Line 2183... Line 2075...
2183
 
2075
 
2184
        |IL.opSAVEF:
2076
        |IL.opSAVEF, IL.opSAVEFI:
2185
            UnOp(reg1);
2077
            UnOp(reg1);
2186
            movsdmr(reg1, 0, xmm);
2078
            movsdmr(reg1, 0, xmm);
2187
            DEC(xmm);
2079
            DEC(xmm);
Line 2214... Line 2106...
2214
            DEC(xmm)
2106
            DEC(xmm)
Line 2215... Line 2107...
2215
 
2107
 
2216
        |IL.opUMINF:
2108
        |IL.opUMINF:
2217
            reg1 := GetAnyReg();
2109
            reg1 := GetAnyReg();
2218
            lea(reg1, Numbers_Offs, sDATA);
2110
            lea(reg1, Numbers_Offs, sDATA);
2219
            OutByte3(66H, 40H + reg1 DIV 8 + (xmm DIV 8) * 4, 0FH); // xorpd xmm, xmmword[reg1]
2111
            OutByte3(66H, 40H + reg1 DIV 8 + (xmm DIV 8) * 4, 0FH); (* xorpd xmm, xmmword[reg1] *)
2220
            OutByte2(57H, reg1 MOD 8 + (xmm MOD 8) * 8);
2112
            OutByte2(57H, reg1 MOD 8 + (xmm MOD 8) * 8);
Line 2221... Line 2113...
2221
            drop
2113
            drop
2222
 
2114
 
2223
        |IL.opFABS:
2115
        |IL.opFABS:
2224
            reg1 := GetAnyReg();
2116
            reg1 := GetAnyReg();
2225
            lea(reg1, Numbers_Offs + 16, sDATA);
2117
            lea(reg1, Numbers_Offs + 16, sDATA);
2226
            OutByte3(66H, 40H + reg1 DIV 8 + (xmm DIV 8) * 4, 0FH); // andpd xmm, xmmword[reg1]
2118
            OutByte3(66H, 40H + reg1 DIV 8 + (xmm DIV 8) * 4, 0FH); (* andpd xmm, xmmword[reg1] *)
Line 2227... Line 2119...
2227
            OutByte2(54H, reg1 MOD 8 + (xmm MOD 8) * 8);
2119
            OutByte2(54H, reg1 MOD 8 + (xmm MOD 8) * 8);
2228
            drop
2120
            drop
2229
 
2121
 
2230
        |IL.opFLT:
2122
        |IL.opFLT:
2231
            UnOp(reg1);
2123
            UnOp(reg1);
2232
            INC(xmm);
2124
            INC(xmm);
Line 2233... Line 2125...
2233
            OutByte(0F2H); Rex(reg1, xmm); OutByte(0FH); // cvtsi2sd xmm, reg1
2125
            OutByte(0F2H); Rex(reg1, xmm); OutByte(0FH); (* cvtsi2sd xmm, reg1 *)
2234
            OutByte2(2AH, 0C0H + (xmm MOD 8) * 8 + reg1 MOD 8);
2126
            OutByte2(2AH, 0C0H + (xmm MOD 8) * 8 + reg1 MOD 8);
2235
            drop
2127
            drop
2236
 
2128
 
2237
        |IL.opFLOOR:
2129
        |IL.opFLOOR:
2238
            reg1 := GetAnyReg();
2130
            reg1 := GetAnyReg();
2239
            subrc(rsp, 8);
2131
            subrc(rsp, 8);
2240
            OutByte3(00FH, 0AEH, 05CH); OutByte2(024H, 004H); // stmxcsr dword[rsp+4];
2132
            OutByte3(00FH, 0AEH, 05CH); OutByte2(024H, 004H);                       (* stmxcsr dword[rsp+4];                              *)
2241
            OutByte2(00FH, 0AEH); OutByte2(01CH, 024H);       // stmxcsr dword[rsp];
2133
            OutByte2(00FH, 0AEH); OutByte2(01CH, 024H);                             (* stmxcsr dword[rsp];                                *)
2242
            OutByte3(081H, 024H, 024H); OutByte2(0FFH, 09FH); OutByte2(0FFH, 0FFH); // and dword[rsp],11111111111111111001111111111111b;
2134
            OutByte3(081H, 024H, 024H); OutByte2(0FFH, 09FH); OutByte2(0FFH, 0FFH); (* and dword[rsp],11111111111111111001111111111111b;  *)
2243
            OutByte3(081H, 00CH, 024H); OutByte2(000H, 020H); OutByte2(000H, 000H); // or dword[rsp],00000000000000000010000000000000b;
2135
            OutByte3(081H, 00CH, 024H); OutByte2(000H, 020H); OutByte2(000H, 000H); (* or dword[rsp],00000000000000000010000000000000b;   *)
2244
            OutByte2(00FH, 0AEH); OutByte2(014H, 024H); // ldmxcsr dword[rsp];
2136
            OutByte2(00FH, 0AEH); OutByte2(014H, 024H);                             (* ldmxcsr dword[rsp];                                *)
2245
            OutByte(0F2H); Rex(xmm, reg1); OutByte(0FH); // cvtsd2si reg1, xmm
2137
            OutByte(0F2H); Rex(xmm, reg1); OutByte(0FH);                            (* cvtsd2si reg1, xmm                                 *)
Line 2246... Line 2138...
2246
            OutByte2(2DH, 0C0H + xmm MOD 8 + (reg1 MOD 8) * 8);
2138
            OutByte2(2DH, 0C0H + xmm MOD 8 + (reg1 MOD 8) * 8);
2247
            OutByte3(00FH, 0AEH, 054H); OutByte2(024H, 004H); // ldmxcsr dword[rsp+4];
2139
            OutByte3(00FH, 0AEH, 054H); OutByte2(024H, 004H);                       (* ldmxcsr dword[rsp+4];                              *)
Line 2276... Line 2168...
2276
            shiftrc(shl, reg1, 52);
2168
            shiftrc(shl, reg1, 52);
2277
            movrm(reg2, rsp, 0);
2169
            movrm(reg2, rsp, 0);
2278
            movrm(reg2, reg2, 0);
2170
            movrm(reg2, reg2, 0);
Line 2279... Line 2171...
2279
 
2171
 
2280
            push(reg1);
2172
            push(reg1);
2281
            lea(reg1, Numbers_Offs + 40, sDATA); // {0..51, 63}
2173
            lea(reg1, Numbers_Offs + 40, sDATA); (* {0..51, 63} *)
2282
            movrm(reg1, reg1, 0);
2174
            movrm(reg1, reg1, 0);
2283
            and(reg2, reg1);
2175
            and(reg2, reg1);
Line 2284... Line 2176...
2284
            pop(reg1);
2176
            pop(reg1);
Line 2297... Line 2189...
2297
                reg2 := GetVarReg(param2);
2189
                reg2 := GetVarReg(param2);
2298
                regVar := reg2 # -1;
2190
                regVar := reg2 # -1;
2299
                IF ~regVar THEN
2191
                IF ~regVar THEN
2300
                    reg2 := GetAnyReg();
2192
                    reg2 := GetAnyReg();
2301
                    Rex(0, reg2);
2193
                    Rex(0, reg2);
2302
                    OutByte2(8DH, 45H + long(n) + (reg2 MOD 8) * 8);  // lea reg2, qword[rbp+n]
2194
                    OutByte2(8DH, 45H + long(n) + (reg2 MOD 8) * 8); (* lea reg2, qword[rbp+n] *)
2303
                    OutIntByte(n)
2195
                    OutIntByte(n)
2304
                END
2196
                END
2305
            ELSE
2197
            ELSE
2306
                BinOp(reg1, reg2);
2198
                BinOp(reg1, reg2);
2307
                regVar := FALSE
2199
                regVar := FALSE
Line 2322... Line 2214...
2322
 
2214
 
2323
            pop(reg2);
2215
            pop(reg2);
Line 2324... Line 2216...
2324
            movrm(reg1, reg2, 0);
2216
            movrm(reg1, reg2, 0);
2325
 
2217
 
2326
            push(reg2);
2218
            push(reg2);
2327
            lea(reg2, Numbers_Offs + 48, sDATA); // {52..61}
2219
            lea(reg2, Numbers_Offs + 48, sDATA); (* {52..61} *)
2328
            movrm(reg2, reg2, 0);
2220
            movrm(reg2, reg2, 0);
Line 2329... Line 2221...
2329
            or(reg1, reg2);
2221
            or(reg1, reg2);
2330
            pop(reg2);
2222
            pop(reg2);
2331
 
2223
 
2332
            Rex(reg1, 0);
2224
            Rex(reg1, 0);
2333
            OutByte2(0FH, 0BAH);
2225
            OutByte2(0FH, 0BAH);
2334
            OutByte2(0F0H + reg1 MOD 8, 3EH); // btr reg1, 62
2226
            OutByte2(0F0H + reg1 MOD 8, 3EH); (* btr reg1, 62 *)
Line 2335... Line 2227...
2335
            movmr(reg2, 0, reg1);
2227
            movmr(reg2, 0, reg1);
2336
            drop;
2228
            drop;
Line 2337... Line 2229...
2337
            drop
2229
            drop
2338
 
2230
 
Line 2339... Line 2231...
2339
        |IL.opSADR_PARAM:
2231
        |IL.opSADR_PARAM:
2340
            pushDA(stroffs + param2)
2232
            pushDA(stroffs + param2)
2341
 
2233
 
2342
        |IL.opVADR_PARAM:
2234
        |IL.opVADR_PARAM:
Line 2343... Line 2235...
2343
            pushm(rbp, param2 * 8)
2235
            X86.pushm(rbp, param2 * 8)
2344
 
2236
 
2345
        |IL.opLOAD64_PARAM:
2237
        |IL.opLOAD64_PARAM:
2346
            UnOp(reg1);
2238
            UnOp(reg1);
2347
            pushm(reg1, 0);
2239
            X86.pushm(reg1, 0);
2348
            drop
2240
            drop
2349
 
2241
 
Line 2350... Line 2242...
2350
        |IL.opLLOAD64_PARAM:
2242
        |IL.opLLOAD64_PARAM:
2351
            reg1 := GetVarReg(param2);
2243
            reg1 := GetVarReg(param2);
2352
            IF reg1 # -1 THEN
2244
            IF reg1 # -1 THEN
Line 2403... Line 2295...
2403
                    reg2 := GetAnyReg();
2295
                    reg2 := GetAnyReg();
2404
                    movrc(reg2, param2);
2296
                    movrc(reg2, param2);
2405
                    movmr(rbp, n, reg2);
2297
                    movmr(rbp, n, reg2);
2406
                    drop
2298
                    drop
2407
                ELSE
2299
                ELSE
2408
                    OutByte3(48H, 0C7H, 45H + long(n)); // mov qword[rbp+n],param2
2300
                    OutByte3(48H, 0C7H, 45H + long(n)); (* mov qword[rbp+n], param2 *)
2409
                    OutIntByte(n);
2301
                    OutIntByte(n);
2410
                    OutInt(param2)
2302
                    OutInt(param2)
2411
                END
2303
                END
2412
            END
2304
            END
Line 2422... Line 2314...
2422
                drop
2314
                drop
2423
            ELSE
2315
            ELSE
2424
                reg2 := GetAnyReg();
2316
                reg2 := GetAnyReg();
2425
                lea(reg2, param1, sBSS);
2317
                lea(reg2, param1, sBSS);
2426
                Rex(reg2, 0);
2318
                Rex(reg2, 0);
2427
                OutByte2(0C7H, reg2 MOD 8); // mov qword[reg2], param2
2319
                OutByte2(0C7H, reg2 MOD 8); (* mov qword[reg2], param2 *)
2428
                OutInt(param2);
2320
                OutInt(param2);
2429
                drop
2321
                drop
2430
            END
2322
            END
Line 2431... Line 2323...
2431
 
2323
 
Line 2448... Line 2340...
2448
                    add(reg1, reg2)
2340
                    add(reg1, reg2)
2449
                ELSE
2341
                ELSE
2450
                    n := param1 * 8;
2342
                    n := param1 * 8;
2451
                    Rex(0, reg2);
2343
                    Rex(0, reg2);
2452
                    OutByte2(01H, 45H + long(n) + (reg2 MOD 8) * 8);
2344
                    OutByte2(01H, 45H + long(n) + (reg2 MOD 8) * 8);
2453
                    OutIntByte(n) // add qword[rbp+n],reg2
2345
                    OutIntByte(n) (* add qword[rbp+n], reg2 *)
2454
                END;
2346
                END;
2455
                drop
2347
                drop
2456
            ELSIF ABS(param2) = 1 THEN
2348
            ELSIF ABS(param2) = 1 THEN
2457
                IF reg1 # -1 THEN
2349
                IF reg1 # -1 THEN
2458
                    IF param2 = 1 THEN
2350
                    IF param2 = 1 THEN
Line 2460... Line 2352...
2460
                    ELSE
2352
                    ELSE
2461
                        decr(reg1)
2353
                        decr(reg1)
2462
                    END
2354
                    END
2463
                ELSE
2355
                ELSE
2464
                    n := param1 * 8;
2356
                    n := param1 * 8;
2465
                    OutByte3(48H, 0FFH, 45H + 8 * ORD(param2 = -1) + long(n)); // inc/dec qword[rbp+n]
2357
                    OutByte3(48H, 0FFH, 45H + 8 * ORD(param2 = -1) + long(n)); (* inc/dec qword[rbp+n] *)
2466
                    OutIntByte(n)
2358
                    OutIntByte(n)
2467
                END
2359
                END
2468
            ELSE
2360
            ELSE
2469
                IF reg1 # -1 THEN
2361
                IF reg1 # -1 THEN
2470
                    addrc(reg1, param2)
2362
                    addrc(reg1, param2)
2471
                ELSE
2363
                ELSE
2472
                    n := param1 * 8;
2364
                    n := param1 * 8;
2473
                    OutByte3(48H, 81H + short(param2), 45H + long(n));
2365
                    OutByte3(48H, 81H + short(param2), 45H + long(n));
2474
                    OutIntByte(n);
2366
                    OutIntByte(n);
2475
                    OutIntByte(param2) // add qword[rbp+n],param2
2367
                    OutIntByte(param2) (* add qword[rbp+n], param2 *)
2476
                END
2368
                END
2477
            END
2369
            END
Line 2478... Line 2370...
2478
 
2370
 
2479
        |IL.opLADR_INCCB, IL.opLADR_DECCB:
2371
        |IL.opLADR_INCCB, IL.opLADR_DECCB:
Line 2488... Line 2380...
2488
                andrc(reg1, 255)
2380
                andrc(reg1, 255)
2489
            ELSE
2381
            ELSE
2490
                n := param1 * 8;
2382
                n := param1 * 8;
2491
                OutByte2(80H, 45H + long(n) + 28H * ORD(opcode = IL.opLADR_DECCB));
2383
                OutByte2(80H, 45H + long(n) + 28H * ORD(opcode = IL.opLADR_DECCB));
2492
                OutIntByte(n);
2384
                OutIntByte(n);
2493
                OutByte(param2) // add/sub byte[rbp+n],param2
2385
                OutByte(param2) (* add/sub byte[rbp+n], param2 *)
2494
            END
2386
            END
Line 2495... Line 2387...
2495
 
2387
 
2496
        |IL.opLADR_INC, IL.opLADR_DEC:
2388
        |IL.opLADR_INC, IL.opLADR_DEC:
2497
            UnOp(reg1);
2389
            UnOp(reg1);
Line 2504... Line 2396...
2504
                END
2396
                END
2505
            ELSE
2397
            ELSE
2506
                n := param2 * 8;
2398
                n := param2 * 8;
2507
                Rex(0, reg1);
2399
                Rex(0, reg1);
2508
                OutByte2(01H + 28H * ORD(opcode = IL.opLADR_DEC), 45H + long(n) + (reg1 MOD 8) * 8);
2400
                OutByte2(01H + 28H * ORD(opcode = IL.opLADR_DEC), 45H + long(n) + (reg1 MOD 8) * 8);
2509
                OutIntByte(n) // add/sub qword[rbp+n],reg1
2401
                OutIntByte(n) (* add/sub qword[rbp+n], reg1 *)
2510
            END;
2402
            END;
2511
            drop
2403
            drop
Line 2512... Line 2404...
2512
 
2404
 
2513
        |IL.opLADR_INCB, IL.opLADR_DECB:
2405
        |IL.opLADR_INCB, IL.opLADR_DECB:
Line 2524... Line 2416...
2524
                n := param2 * 8;
2416
                n := param2 * 8;
2525
                IF reg1 >= 8 THEN
2417
                IF reg1 >= 8 THEN
2526
                    OutByte(44H)
2418
                    OutByte(44H)
2527
                END;
2419
                END;
2528
                OutByte2(28H * ORD(opcode = IL.opLADR_DECB), 45H + long(n) + 8 * (reg1 MOD 8));
2420
                OutByte2(28H * ORD(opcode = IL.opLADR_DECB), 45H + long(n) + 8 * (reg1 MOD 8));
2529
                OutIntByte(n) // add/sub byte[rbp+n], reg1_8
2421
                OutIntByte(n) (* add/sub byte[rbp+n], reg1_8 *)
2530
            END;
2422
            END;
2531
            drop
2423
            drop
Line 2532... Line 2424...
2532
 
2424
 
2533
        |IL.opLADR_INCL, IL.opLADR_EXCL:
2425
        |IL.opLADR_INCL, IL.opLADR_EXCL:
2534
            UnOp(reg1);
2426
            UnOp(reg1);
2535
            cmprc(reg1, 64);
2427
            cmprc(reg1, 64);
2536
            reg2 := GetVarReg(param2);
2428
            reg2 := GetVarReg(param2);
2537
            IF reg2 # -1 THEN
2429
            IF reg2 # -1 THEN
2538
                OutByte2(73H, 4); // jnb L
2430
                OutByte2(73H, 4); (* jnb L *)
2539
                oprr2(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), reg2, reg1) // bts/btr reg2, reg1
2431
                oprr2(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), reg2, reg1) (* bts/btr reg2, reg1 *)
2540
            ELSE
2432
            ELSE
2541
                n := param2 * 8;
2433
                n := param2 * 8;
2542
                OutByte2(73H, 5 + 3 * ORD(~isByte(n))); // jnb L
2434
                OutByte2(73H, 5 + 3 * ORD(~isByte(n))); (* jnb L *)
2543
                Rex(0, reg1);
2435
                Rex(0, reg1);
2544
                OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), 45H + long(n) + 8 * (reg1 MOD 8));
2436
                OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), 45H + long(n) + 8 * (reg1 MOD 8));
2545
                OutIntByte(n) // bts/btr qword[rbp+n], reg1
2437
                OutIntByte(n) (* bts/btr qword[rbp+n], reg1 *)
2546
            END;
2438
            END;
2547
            // L:
2439
            (* L: *)
Line 2548... Line 2440...
2548
            drop
2440
            drop
2549
 
2441
 
2550
        |IL.opLADR_INCLC, IL.opLADR_EXCLC:
2442
        |IL.opLADR_INCLC, IL.opLADR_EXCLC:
2551
            reg1 := GetVarReg(param1);
2443
            reg1 := GetVarReg(param1);
2552
            IF reg1 # -1 THEN
2444
            IF reg1 # -1 THEN
2553
                Rex(reg1, 0);
2445
                Rex(reg1, 0);
2554
                OutByte3(0FH, 0BAH, 0E8H);  // bts/btr reg1, param2
2446
                OutByte3(0FH, 0BAH, 0E8H); (* bts/btr reg1, param2 *)
2555
                OutByte2(reg1 MOD 8 + 8 * ORD(opcode = IL.opLADR_EXCLC), param2)
2447
                OutByte2(reg1 MOD 8 + 8 * ORD(opcode = IL.opLADR_EXCLC), param2)
2556
            ELSE
2448
            ELSE
2557
                n := param1 * 8;
2449
                n := param1 * 8;
2558
                OutByte3(48H, 0FH, 0BAH);  // bts/btr qword[rbp+n], param2
2450
                OutByte3(48H, 0FH, 0BAH); (* bts/btr qword[rbp+n], param2 *)
2559
                OutByte(6DH + long(n) + 8 * ORD(opcode = IL.opLADR_EXCLC));
2451
                OutByte(6DH + long(n) + 8 * ORD(opcode = IL.opLADR_EXCLC));
2560
                OutIntByte(n);
2452
                OutIntByte(n);
Line 2584... Line 2476...
2584
    ASSERT(UTILS.Align(Numbers_Offs, 16));
2476
    ASSERT(UTILS.Align(Numbers_Offs, 16));
Line 2585... Line 2477...
2585
 
2477
 
2586
    entry := NewLabel();
2478
    entry := NewLabel();
Line 2587... Line 2479...
2587
    X86.SetLabel(entry);
2479
    X86.SetLabel(entry);
2588
 
2480
 
2589
    IF target = mConst.Target_iDLL64 THEN
2481
    IF target = TARGETS.Win64DLL THEN
2590
        dllret := NewLabel();
2482
        dllret := NewLabel();
2591
        push(r8);
2483
        push(r8);
2592
        push(rdx);
2484
        push(rdx);
2593
        push(rcx);
2485
        push(rcx);
2594
        CallRTL(IL._dllentry);
2486
        CallRTL(IL._dllentry);
2595
        test(rax);
2487
        test(rax);
Line 2596... Line 2488...
2596
        jcc(je, dllret)
2488
        jcc(je, dllret)
2597
    END;
2489
    END;
2598
 
2490
 
2599
    IF target = mConst.Target_iELF64 THEN
2491
    IF target = TARGETS.Linux64 THEN
2600
        push(rsp)
2492
        push(rsp)
Line 2601... Line 2493...
2601
    ELSE
2493
    ELSE
2602
        pushc(0)
2494
        pushc(0)
2603
    END;
2495
    END;
2604
 
2496
 
2605
    lea(rax, entry, sCODE);
2497
    lea(rax, entry, sCODE);
2606
    push(rax);
2498
    push(rax);
Line 2607... Line 2499...
2607
    pushDA(0); //TYPES
2499
    pushDA(0); (* TYPES *)
2608
    pushc(tcount);
2500
    pushc(tcount);
2609
    pushDA(ModName_Offs); //MODNAME
2501
    pushDA(ModName_Offs); (* MODNAME *)
2610
    CallRTL(IL._init);
2502
    CallRTL(IL._init);
2611
 
2503
 
2612
    IF target IN {mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iELF64} THEN
2504
    IF target IN {TARGETS.Win64C, TARGETS.Win64GUI, TARGETS.Linux64} THEN
2613
        L := NewLabel();
2505
        L := NewLabel();
2614
        pushc(0);
2506
        pushc(0);
2615
        push(rsp);
2507
        push(rsp);
2616
        pushc(1024 * 1024 * stack_size);
2508
        pushc(1024 * 1024 * stack_size);
-
 
2509
        pushc(0);
2617
        pushc(0);
2510
        CallRTL(IL._new);
-
 
2511
        pop(rax);
2618
        CallRTL(IL._new);
2512
        test(rax);
2619
        pop(rax);
2513
        jcc(je, L);
2620
        test(rax);
2514
        GetRegA;
2621
        jcc(je, L);
2515
        addrc(rax, 1024 * 1024 * stack_size - 8);
Line 2653... Line 2547...
2653
 
2547
 
Line 2654... Line 2548...
2654
    END import;
2548
    END import;
2655
 
2549
 
2656
 
2550
 
2657
BEGIN
2551
BEGIN
2658
    IF target = mConst.Target_iDLL64 THEN
2552
    IF target = TARGETS.Win64DLL THEN
2659
        X86.SetLabel(dllret);
2553
        X86.SetLabel(dllret);
2660
        OutByte(0C3H) // ret
2554
        X86.ret
2661
    ELSIF target = mConst.Target_iELFSO64 THEN
2555
    ELSIF target = TARGETS.Linux64SO THEN
2662
        sofinit := NewLabel();
2556
        sofinit := NewLabel();
2663
        OutByte(0C3H);  // ret
2557
        X86.ret;
2664
        X86.SetLabel(sofinit);
2558
        X86.SetLabel(sofinit);
2665
        CallRTL(IL._sofinit);
2559
        CallRTL(IL._sofinit);
2666
        OutByte(0C3H)   // ret
2560
        X86.ret
2667
    ELSE
2561
    ELSE
Line 2722... Line 2616...
2722
 
2616
 
2723
PROCEDURE rsave (reg, offs, size: INTEGER);
2617
PROCEDURE rsave (reg, offs, size: INTEGER);
2724
BEGIN
2618
BEGIN
2725
    offs := offs * 8;
2619
    offs := offs * 8;
2726
    CASE size OF
2620
    CASE size OF
2727
    |1: movmr8(rbp, offs, reg)
2621
    |1: X86.movmr8(rbp, offs, reg)
2728
    |2: movmr16(rbp, offs, reg)
2622
    |2: X86.movmr16(rbp, offs, reg)
2729
    |4: movmr32(rbp, offs, reg)
2623
    |4: movmr32(rbp, offs, reg)
2730
    |8: movmr(rbp, offs, reg)
2624
    |8: movmr(rbp, offs, reg)
2731
    END
2625
    END
Line 2776... Line 2670...
2776
    prolog(modname, target, options.stack);
2670
    prolog(modname, target, options.stack);
2777
    translate(IL.codes.commands, tcount * 8);
2671
    translate(IL.codes.commands, tcount * 8);
2778
    epilog(modname, target);
2672
    epilog(modname, target);
Line 2779... Line 2673...
2779
 
2673
 
2780
    BIN.fixup(prog);
2674
    BIN.fixup(prog);
2781
    IF target IN {mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64} THEN
2675
    IF TARGETS.OS = TARGETS.osWIN64 THEN
2782
        PE32.write(prog, outname, target = mConst.Target_iConsole64, target = mConst.Target_iDLL64, TRUE)
2676
        PE32.write(prog, outname, target = TARGETS.Win64C, target = TARGETS.Win64DLL, TRUE)
2783
    ELSIF target IN {mConst.Target_iELF64, mConst.Target_iELFSO64} THEN
2677
    ELSIF TARGETS.OS = TARGETS.osLINUX64 THEN
2784
        ELF.write(prog, outname, sofinit, target = mConst.Target_iELFSO64, TRUE)
2678
        ELF.write(prog, outname, sofinit, target = TARGETS.Linux64SO, TRUE)
2785
    END
2679
    END
Line 2786... Line 2680...
2786
END CodeGen;
2680
END CodeGen;