Subversion Repositories Kolibri OS

Rev

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

Rev 7667 Rev 7693
Line 5... Line 5...
5
    All rights reserved.
5
    All rights reserved.
6
*)
6
*)
Line 7... Line 7...
7
 
7
 
Line 8... Line 8...
8
MODULE AMD64;
8
MODULE AMD64;
9
 
9
 
Line 10... Line 10...
10
IMPORT CODE, BIN, WR := WRITER, CHL := CHUNKLISTS, MACHINE, LISTS, PATHS,
10
IMPORT IL, BIN, WR := WRITER, CHL := CHUNKLISTS, LISTS, PATHS, PROG,
Line 29... Line 29...
29
 
29
 
Line 30... Line 30...
30
    je = 84H; jne = 85H; jl = 8CH; jge = 8DH; jle = 8EH; jg = 8FH; jb = 82H;
30
    je = 84H; jne = 85H; jl = 8CH; jge = 8DH; jle = 8EH; jg = 8FH; jb = 82H;
Line 31... Line 31...
31
 
31
 
Line 32... Line 32...
32
    sete = 94H; setne = 95H; setl = 9CH; setge = 9DH; setle = 9EH; setg = 9FH; setc = 92H; setnc = 93H;
32
    sete = 94H; setne = 95H; setl = 9CH; setge = 9DH; setle = 9EH; setg = 9FH; setc = 92H; setnc = 93H;
33
 
33
 
34
    shl = CODE.opLSL2; shr = CODE.opLSR2; sar = CODE.opASR2; ror = CODE.opROR2;
34
    shl = IL.opLSL2; shr = IL.opLSR2; sar = IL.opASR2; ror = IL.opROR2;
35
 
35
 
Line 36... Line 36...
36
    sCODE = BIN.PICCODE;
36
    sCODE = BIN.PICCODE;
Line 37... Line 37...
37
    sDATA = BIN.PICDATA;
37
    sDATA = BIN.PICDATA;
Line 38... Line 38...
38
    sBSS  = BIN.PICBSS;
38
    sBSS  = BIN.PICBSS;
Line 39... Line 39...
39
    sIMP  = BIN.PICIMP;
39
    sIMP  = BIN.PICIMP;
Line 56... Line 56...
56
    Numbers_Count: INTEGER;
56
    Numbers_Count: INTEGER;
57
    Numbers_Offs: INTEGER;
57
    Numbers_Offs: INTEGER;
Line 58... Line 58...
58
 
58
 
Line 59... Line 59...
59
    prog: BIN.PROGRAM;
59
    prog: BIN.PROGRAM;
-
 
60
 
-
 
61
    tcount: INTEGER;
Line 60... Line 62...
60
 
62
 
61
    dllret: INTEGER;
63
    dllret, sofinit: INTEGER;
Line 85... Line 87...
85
END OutByte3;
87
END OutByte3;
Line 86... Line 88...
86
 
88
 
87
 
89
 
88
PROCEDURE OutInt (n: INTEGER);
90
PROCEDURE OutInt (n: INTEGER);
89
BEGIN
91
BEGIN
90
    OutByte(MACHINE.Byte(n, 0));
92
    OutByte(UTILS.Byte(n, 0));
91
    OutByte(MACHINE.Byte(n, 1));
93
    OutByte(UTILS.Byte(n, 1));
92
    OutByte(MACHINE.Byte(n, 2));
94
    OutByte(UTILS.Byte(n, 2));
Line 93... Line 95...
93
    OutByte(MACHINE.Byte(n, 3))
95
    OutByte(UTILS.Byte(n, 3))
94
END OutInt;
96
END OutInt;
Line 110... Line 112...
110
 
112
 
111
 
113
 
112
PROCEDURE OutIntByte (n: INTEGER);
114
PROCEDURE OutIntByte (n: INTEGER);
113
BEGIN
115
BEGIN
114
    IF isByte(n) THEN
116
    IF isByte(n) THEN
115
        OutByte(MACHINE.Byte(n, 0))
117
        OutByte(UTILS.Byte(n, 0))
116
    ELSE
118
    ELSE
117
        OutInt(n)
119
        OutInt(n)
Line 118... Line 120...
118
    END
120
    END
119
END OutIntByte;
121
END OutIntByte;
120
 
122
 
Line 121... Line 123...
121
 
123
 
122
PROCEDURE isLong (n: INTEGER): BOOLEAN;
124
PROCEDURE isLong (n: INTEGER): BOOLEAN;
Line 137... Line 139...
137
 
139
 
138
 
140
 
139
PROCEDURE NewLabel (): INTEGER;
141
PROCEDURE NewLabel (): INTEGER;
140
BEGIN
142
BEGIN
141
    BIN.NewLabel(prog)
143
    BIN.NewLabel(prog)
Line 142... Line 144...
142
    RETURN CODE.NewLabel()
144
    RETURN IL.NewLabel()
143
END NewLabel;
145
END NewLabel;
Line 255... Line 257...
255
BEGIN
257
BEGIN
256
    REG.Drop(R)
258
    REG.Drop(R)
257
END drop;
259
END drop;
Line -... Line 260...
-
 
260
 
-
 
261
 
-
 
262
PROCEDURE GetAnyReg (): INTEGER;
-
 
263
    RETURN REG.GetAnyReg(R)
-
 
264
END GetAnyReg;
-
 
265
 
-
 
266
 
-
 
267
PROCEDURE GetVarReg (offs: INTEGER): INTEGER;
-
 
268
    RETURN REG.GetVarReg(R, offs)
-
 
269
END GetVarReg;
258
 
270
 
259
 
271
 
260
PROCEDURE callimp (label: INTEGER);
272
PROCEDURE callimp (label: INTEGER);
Line 261... Line 273...
261
VAR
273
VAR
262
    reg: INTEGER;
274
    reg: INTEGER;
263
 
275
 
264
BEGIN
276
BEGIN
265
    reg := REG.GetAnyReg(R);
277
    reg := GetAnyReg();
266
    lea(reg, label, sIMP);
278
    lea(reg, label, sIMP);
267
    IF reg >= 8 THEN // call qword[reg]
279
    IF reg >= 8 THEN // call qword[reg]
Line 275... Line 287...
275
PROCEDURE pushDA (offs: INTEGER);
287
PROCEDURE pushDA (offs: INTEGER);
276
VAR
288
VAR
277
    reg: INTEGER;
289
    reg: INTEGER;
Line 278... Line 290...
278
 
290
 
279
BEGIN
291
BEGIN
280
    reg := REG.GetAnyReg(R);
292
    reg := GetAnyReg();
281
    lea(reg, offs, sDATA);
293
    lea(reg, offs, sDATA);
282
    push(reg);
294
    push(reg);
283
    drop
295
    drop
Line 288... Line 300...
288
VAR
300
VAR
289
    label: INTEGER;
301
    label: INTEGER;
Line 290... Line 302...
290
 
302
 
291
BEGIN
303
BEGIN
292
    REG.Store(R);
304
    REG.Store(R);
293
    label := CODE.codes.rtl[proc];
305
    label := IL.codes.rtl[proc];
294
    IF label < 0 THEN
306
    IF label < 0 THEN
295
        callimp(-label)
307
        callimp(-label)
296
    ELSE
308
    ELSE
297
        X86.call(label)
309
        X86.call(label)
Line 313... Line 325...
313
 
325
 
314
 
326
 
315
PROCEDURE PushAll (NumberOfParameters: INTEGER);
327
PROCEDURE PushAll (NumberOfParameters: INTEGER);
316
BEGIN
328
BEGIN
317
    REG.PushAll(R);
329
    REG.PushAll(R);
Line 318... Line 330...
318
    R.pushed := R.pushed - NumberOfParameters
330
    DEC(R.pushed, NumberOfParameters)
319
END PushAll;
331
END PushAll;
Line 325... Line 337...
325
 
337
 
326
BEGIN
338
BEGIN
327
    Rex(reg, 0);
339
    Rex(reg, 0);
328
    OutByte(0B8H + reg MOD 8);  // movabs reg, n
340
    OutByte(0B8H + reg MOD 8);  // movabs reg, n
329
    FOR i := 0 TO 7 DO
341
    FOR i := 0 TO 7 DO
330
        OutByte(MACHINE.Byte(n, i))
342
        OutByte(UTILS.Byte(n, i))
331
    END
343
    END
Line 332... Line 344...
332
END movabs;
344
END movabs;
333
 
345
 
334
 
346
 
335
PROCEDURE movrc (reg, n: INTEGER); // mov reg, n
347
PROCEDURE movrc (reg, n: INTEGER); // mov reg, n
-
 
348
BEGIN
-
 
349
    IF isLong(n) THEN
336
BEGIN
350
        movabs(reg, n)
337
    IF isLong(n) THEN
351
    ELSIF n = 0 THEN
338
        movabs(reg, n)
352
        xor(reg, reg)
339
    ELSE
353
    ELSE
340
        Rex(reg, 0);
354
        Rex(reg, 0);
Line 353... Line 367...
353
PROCEDURE oprlongc (reg, n: INTEGER; oprr: OPRR);
367
PROCEDURE oprlongc (reg, n: INTEGER; oprr: OPRR);
354
VAR
368
VAR
355
    reg2: INTEGER;
369
    reg2: INTEGER;
Line 356... Line 370...
356
 
370
 
357
BEGIN
371
BEGIN
358
    reg2 := REG.GetAnyReg(R);
372
    reg2 := GetAnyReg();
359
    movabs(reg2, n);
373
    movabs(reg2, n);
360
    oprr(reg, reg2);
374
    oprr(reg, reg2);
361
    drop
375
    drop
Line 402... Line 416...
402
VAR
416
VAR
403
    reg2: INTEGER;
417
    reg2: INTEGER;
Line 404... Line 418...
404
 
418
 
405
BEGIN
419
BEGIN
406
    IF isLong(n) THEN
420
    IF isLong(n) THEN
407
        reg2 := REG.GetAnyReg(R);
421
        reg2 := GetAnyReg();
408
        movabs(reg2, n);
422
        movabs(reg2, n);
409
        push(reg2);
423
        push(reg2);
410
        drop
424
        drop
411
    ELSE
425
    ELSE
Line 640... Line 654...
640
        OutByte(n)
654
        OutByte(n)
641
    END
655
    END
642
END shiftrc;
656
END shiftrc;
Line 643... Line 657...
643
 
657
 
644
 
658
 
645
PROCEDURE getVar (variables: LISTS.LIST; offset: INTEGER): CODE.LOCALVAR;
659
PROCEDURE getVar (variables: LISTS.LIST; offset: INTEGER): IL.LOCALVAR;
Line 646... Line 660...
646
VAR
660
VAR
647
    cur: CODE.LOCALVAR;
661
    cur: IL.LOCALVAR;
648
 
662
 
649
BEGIN
663
BEGIN
650
    cur := variables.first(CODE.LOCALVAR);
664
    cur := variables.first(IL.LOCALVAR);
Line 651... Line 665...
651
    WHILE (cur # NIL) & (cur.offset # offset) DO
665
    WHILE (cur # NIL) & (cur.offset # offset) DO
652
        cur := cur.next(CODE.LOCALVAR)
666
        cur := cur.next(IL.LOCALVAR)
Line 660... Line 674...
660
VAR
674
VAR
661
    leave:      BOOLEAN;
675
    leave:      BOOLEAN;
662
    leaf:       BOOLEAN;
676
    leaf:       BOOLEAN;
663
    cur:        COMMAND;
677
    cur:        COMMAND;
664
    variables:  LISTS.LIST;
678
    variables:  LISTS.LIST;
665
    lvar, rvar: CODE.LOCALVAR;
679
    lvar, rvar: IL.LOCALVAR;
666
    reg:        INTEGER;
680
    reg:        INTEGER;
667
    max:        INTEGER;
681
    max:        INTEGER;
668
    loop:       INTEGER;
682
    loop:       INTEGER;
669
    param2:     INTEGER;
683
    param2:     INTEGER;
Line 675... Line 689...
675
    leaf := TRUE;
689
    leaf := TRUE;
Line 676... Line 690...
676
 
690
 
677
    cur := cmd.next(COMMAND);
691
    cur := cmd.next(COMMAND);
678
    REPEAT
692
    REPEAT
679
        CASE cur.opcode OF
693
        CASE cur.opcode OF
680
        |CODE.opLLOAD64,
694
        |IL.opLLOAD64,
681
         CODE.opLLOAD8,
695
         IL.opLLOAD8,
682
         CODE.opLLOAD16,
696
         IL.opLLOAD16,
683
         CODE.opLLOAD32,
697
         IL.opLLOAD32,
684
         CODE.opLLOAD64_PARAM,
698
         IL.opLLOAD64_PARAM,
685
         CODE.opLLOAD32_PARAM,
699
         IL.opLLOAD32_PARAM,
686
         CODE.opLADR_SAVE,
-
 
687
         CODE.opLADR_INC1,
-
 
688
         CODE.opLADR_DEC1,
700
         IL.opLADR_SAVE,
689
         CODE.opLADR_INC,
701
         IL.opLADR_INC,
690
         CODE.opLADR_DEC,
-
 
691
         CODE.opLADR_INC1B,
-
 
692
         CODE.opLADR_DEC1B,
702
         IL.opLADR_DEC,
693
         CODE.opLADR_INCB,
703
         IL.opLADR_INCB,
694
         CODE.opLADR_DECB,
704
         IL.opLADR_DECB,
695
         CODE.opLADR_INCL,
705
         IL.opLADR_INCL,
696
         CODE.opLADR_EXCL,
706
         IL.opLADR_EXCL,
697
         CODE.opLADR_UNPK:
707
         IL.opLADR_UNPK:
698
            lvar := getVar(variables, cur.param2);
708
            lvar := getVar(variables, cur.param2);
699
            IF (lvar # NIL) & (lvar.count # -1) THEN
709
            IF (lvar # NIL) & (lvar.count # -1) THEN
700
                INC(lvar.count, loop)
710
                INC(lvar.count, loop)
Line 701... Line 711...
701
            END
711
            END
702
 
712
 
703
        |CODE.opLADR_SAVEC,
-
 
704
         CODE.opLADR_INCC,
713
        |IL.opLADR_SAVEC,
705
         CODE.opLADR_DECC,
714
         IL.opLADR_INCC,
706
         CODE.opLADR_INCCB,
715
         IL.opLADR_INCCB,
707
         CODE.opLADR_DECCB,
716
         IL.opLADR_DECCB,
708
         CODE.opLADR_INCLC,
717
         IL.opLADR_INCLC,
709
         CODE.opLADR_EXCLC:
718
         IL.opLADR_EXCLC:
710
            lvar := getVar(variables, cur.param1);
719
            lvar := getVar(variables, cur.param1);
711
            IF (lvar # NIL) & (lvar.count # -1) THEN
720
            IF (lvar # NIL) & (lvar.count # -1) THEN
Line 712... Line 721...
712
                INC(lvar.count, loop)
721
                INC(lvar.count, loop)
713
            END
722
            END
714
 
723
 
715
        |CODE.opLADR:
724
        |IL.opLADR:
716
            lvar := getVar(variables, cur.param2);
725
            lvar := getVar(variables, cur.param2);
Line 717... Line 726...
717
            IF (lvar # NIL) & (lvar.count # -1) THEN
726
            IF (lvar # NIL) & (lvar.count # -1) THEN
718
                lvar.count := -1
727
                lvar.count := -1
Line 719... Line 728...
719
            END
728
            END
720
 
729
 
Line 721... Line 730...
721
        |CODE.opLOOP:
730
        |IL.opLOOP:
722
            INC(loop, 10)
731
            INC(loop, 10)
723
 
732
 
724
        |CODE.opENDLOOP:
733
        |IL.opENDLOOP:
Line 725... Line 734...
725
            DEC(loop, 10)
734
            DEC(loop, 10)
726
 
735
 
727
        |CODE.opLEAVE,
736
        |IL.opLEAVE,
728
         CODE.opLEAVER,
737
         IL.opLEAVER,
729
         CODE.opLEAVEF:
738
         IL.opLEAVEF:
730
            leave := TRUE
739
            leave := TRUE
731
 
740
 
732
        |CODE.opCALL, CODE.opCALLP, CODE.opCALLI,
-
 
733
         CODE.opWIN64CALL, CODE.opWIN64CALLP, CODE.opWIN64CALLI,
741
        |IL.opCALL, IL.opCALLP, IL.opCALLI,
734
         CODE.opSYSVCALL, CODE.opSYSVCALLP, CODE.opSYSVCALLI,
-
 
735
 
742
         IL.opWIN64CALL, IL.opWIN64CALLP, IL.opWIN64CALLI,
736
         CODE.opSAVES, CODE.opRSET, CODE.opRSETR,
743
         IL.opSYSVCALL, IL.opSYSVCALLP, IL.opSYSVCALLI,
737
         CODE.opRSETL, CODE.opRSET1,
744
 
738
         CODE.opEQS .. CODE.opGES,
745
         IL.opSAVES, IL.opRSET, IL.opRSETR,
739
         CODE.opEQS2 .. CODE.opGES2,
746
         IL.opRSETL, IL.opRSET1,
740
         CODE.opEQSW .. CODE.opGESW,
747
         IL.opEQS .. IL.opGES,
741
         CODE.opEQSW2 .. CODE.opGESW2,
748
         IL.opEQSW .. IL.opGESW,
742
         CODE.opCOPY, CODE.opMOVE, CODE.opCOPYA,
749
         IL.opCOPY, IL.opMOVE, IL.opCOPYA,
Line 743... Line 750...
743
         CODE.opCOPYS, CODE.opCOPYS2, CODE.opROT,
750
         IL.opCOPYS, IL.opROT,
744
         CODE.opNEW, CODE.opDISP, CODE.opISREC,
751
         IL.opNEW, IL.opDISP, IL.opISREC,
745
         CODE.opIS, CODE.opTYPEGR, CODE.opTYPEGP,
752
         IL.opIS, IL.opTYPEGR, IL.opTYPEGP,
746
         CODE.opCASET, CODE.opDIV,
753
         IL.opCASET, IL.opDIV,
747
         CODE.opDIVL, CODE.opMOD,
754
         IL.opDIVL, IL.opMOD,
748
         CODE.opMODL, CODE.opLENGTH, CODE.opLENGTHW:
755
         IL.opMODL, IL.opLENGTH, IL.opLENGTHW:
749
            leaf := FALSE
756
            leaf := FALSE
750
 
757
 
751
        |CODE.opDIVR, CODE.opMODR:
758
        |IL.opDIVR, IL.opMODR:
752
            param2 := cur.param2;
759
            param2 := cur.param2;
753
            IF param2 >= 1 THEN
760
            IF param2 >= 1 THEN
Line 770... Line 777...
770
    IF leaf THEN
777
    IF leaf THEN
771
        REPEAT
778
        REPEAT
772
            reg := -1;
779
            reg := -1;
773
            max := -1;
780
            max := -1;
774
            rvar := NIL;
781
            rvar := NIL;
775
            lvar := variables.first(CODE.LOCALVAR);
782
            lvar := variables.first(IL.LOCALVAR);
776
            WHILE lvar # NIL DO
783
            WHILE lvar # NIL DO
777
                IF lvar.count > max THEN
784
                IF lvar.count > max THEN
778
                    max := lvar.count;
785
                    max := lvar.count;
779
                    rvar := lvar
786
                    rvar := lvar
780
                END;
787
                END;
781
                lvar := lvar.next(CODE.LOCALVAR)
788
                lvar := lvar.next(IL.LOCALVAR)
782
            END;
789
            END;
Line 783... Line 790...
783
 
790
 
784
            IF rvar # NIL THEN
791
            IF rvar # NIL THEN
785
                reg := REG.GetAnyVarReg(R);
792
                reg := REG.GetAnyVarReg(R);
Line 876... Line 883...
876
PROCEDURE fcmp (op: INTEGER; xmm: INTEGER);
883
PROCEDURE fcmp (op: INTEGER; xmm: INTEGER);
877
VAR
884
VAR
878
    cc, reg: INTEGER;
885
    cc, reg: INTEGER;
Line 879... Line 886...
879
 
886
 
880
BEGIN
887
BEGIN
881
    reg := REG.GetAnyReg(R);
888
    reg := GetAnyReg();
882
    xor(reg, reg);
889
    xor(reg, reg);
883
    CASE op OF
890
    CASE op OF
884
    |CODE.opEQF, CODE.opEQFI:
891
    |IL.opEQF:
885
        comisd(xmm - 1, xmm);
892
        comisd(xmm - 1, xmm);
Line 886... Line 893...
886
        cc := sete
893
        cc := sete
887
 
894
 
888
    |CODE.opNEF, CODE.opNEFI:
895
    |IL.opNEF:
Line 889... Line 896...
889
        comisd(xmm - 1, xmm);
896
        comisd(xmm - 1, xmm);
890
        cc := setne
897
        cc := setne
891
 
898
 
Line 892... Line 899...
892
    |CODE.opLTF, CODE.opGTFI:
899
    |IL.opLTF:
893
        comisd(xmm - 1, xmm);
900
        comisd(xmm - 1, xmm);
894
        cc := setc
901
        cc := setc
Line 895... Line 902...
895
 
902
 
896
    |CODE.opGTF, CODE.opLTFI:
903
    |IL.opGTF:
897
        comisd(xmm, xmm - 1);
904
        comisd(xmm, xmm - 1);
Line 898... Line 905...
898
        cc := setc
905
        cc := setc
899
 
906
 
900
    |CODE.opLEF, CODE.opGEFI:
907
    |IL.opLEF:
901
        comisd(xmm, xmm - 1);
908
        comisd(xmm, xmm - 1);
902
        cc := setnc
909
        cc := setnc
903
 
910
 
Line 913... Line 920...
913
 
920
 
914
PROCEDURE translate (commands: LISTS.LIST; stroffs: INTEGER);
921
PROCEDURE translate (commands: LISTS.LIST; stroffs: INTEGER);
915
VAR
922
VAR
Line 916... Line 923...
916
    cmd, next: COMMAND;
923
    cmd, next: COMMAND;
Line 917... Line 924...
917
 
924
 
Line 918... Line 925...
918
    param1, param2, param3, a, b, c, n, label, L, i, cc: INTEGER;
925
    opcode, param1, param2, param3, a, b, c, n, label, L, i, cc: INTEGER;
Line 929... Line 936...
929
    WHILE cmd # NIL DO
936
    WHILE cmd # NIL DO
Line 930... Line 937...
930
 
937
 
931
        param1 := cmd.param1;
938
        param1 := cmd.param1;
Line -... Line 939...
-
 
939
        param2 := cmd.param2;
-
 
940
 
932
        param2 := cmd.param2;
941
        opcode := cmd.opcode;
Line 933... Line 942...
933
 
942
 
934
        CASE cmd.opcode OF
943
        CASE opcode OF
Line 935... Line 944...
935
 
944
 
936
        |CODE.opJMP:
945
        |IL.opJMP:
937
            jmp(param1)
946
            jmp(param1)
938
 
947
 
939
        |CODE.opCALL, CODE.opWIN64CALL, CODE.opSYSVCALL:
948
        |IL.opCALL, IL.opWIN64CALL, IL.opSYSVCALL:
940
            REG.Store(R);
949
            REG.Store(R);
941
            CASE cmd.opcode OF
950
            CASE opcode OF
942
            |CODE.opCALL:
951
            |IL.opCALL:
943
            |CODE.opWIN64CALL: Win64Passing(param2)
952
            |IL.opWIN64CALL: Win64Passing(param2)
Line 944... Line 953...
944
            |CODE.opSYSVCALL:  SysVPassing(param2)
953
            |IL.opSYSVCALL:  SysVPassing(param2)
945
            END;
954
            END;
946
            X86.call(param1);
955
            X86.call(param1);
947
            REG.Restore(R)
956
            REG.Restore(R)
948
 
957
 
949
        |CODE.opCALLP, CODE.opWIN64CALLP, CODE.opSYSVCALLP:
958
        |IL.opCALLP, IL.opWIN64CALLP, IL.opSYSVCALLP:
950
            UnOp(reg1);
959
            UnOp(reg1);
951
            IF reg1 # rax THEN
960
            IF reg1 # rax THEN
952
                GetRegA;
961
                GetRegA;
953
                ASSERT(REG.Exchange(R, reg1, rax));
962
                ASSERT(REG.Exchange(R, reg1, rax));
954
                drop
963
                drop
955
            END;
964
            END;
956
            drop;
965
            drop;
957
            REG.Store(R);
966
            REG.Store(R);
958
            CASE cmd.opcode OF
967
            CASE opcode OF
959
            |CODE.opCALLP:
968
            |IL.opCALLP:
960
            |CODE.opWIN64CALLP: Win64Passing(param2)
969
            |IL.opWIN64CALLP: Win64Passing(param2)
Line 961... Line 970...
961
            |CODE.opSYSVCALLP:  SysVPassing(param2)
970
            |IL.opSYSVCALLP:  SysVPassing(param2)
962
            END;
971
            END;
963
            OutByte2(0FFH, 0D0H); // call rax
972
            OutByte2(0FFH, 0D0H); // call rax
964
            REG.Restore(R);
973
            REG.Restore(R);
965
            ASSERT(R.top = -1)
974
            ASSERT(R.top = -1)
966
 
975
 
967
        |CODE.opCALLI, CODE.opWIN64CALLI, CODE.opSYSVCALLI:
976
        |IL.opCALLI, IL.opWIN64CALLI, IL.opSYSVCALLI:
968
            REG.Store(R);
977
            REG.Store(R);
969
            CASE cmd.opcode OF
978
            CASE opcode OF
Line 970... Line 979...
970
            |CODE.opCALLI:
979
            |IL.opCALLI:
971
            |CODE.opWIN64CALLI: Win64Passing(param2)
980
            |IL.opWIN64CALLI: Win64Passing(param2)
Line 972... Line 981...
972
            |CODE.opSYSVCALLI:  SysVPassing(param2)
981
            |IL.opSYSVCALLI:  SysVPassing(param2)
973
            END;
982
            END;
Line 974... Line 983...
974
            callimp(param1);
983
            callimp(param1);
975
            REG.Restore(R)
984
            REG.Restore(R)
Line 976... Line 985...
976
 
985
 
977
        |CODE.opLABEL:
986
        |IL.opLABEL:
978
            X86.SetLabel(param2)
987
            X86.SetLabel(param1)
979
 
988
 
980
        |CODE.opERR:
989
        |IL.opERR:
981
            CallRTL(CODE._error)
990
            CallRTL(IL._error)
Line 995... Line 1004...
995
                DEC(n)
1004
                DEC(n)
996
            END;
1005
            END;
997
            ASSERT(xmm = -1);
1006
            ASSERT(xmm = -1);
998
            PushAll(0)
1007
            PushAll(0)
Line 999... Line 1008...
999
 
1008
 
1000
        |CODE.opWIN64ALIGN16:
1009
        |IL.opWIN64ALIGN16:
1001
            ASSERT(rax IN R.regs);
1010
            ASSERT(rax IN R.regs);
1002
            mov(rax, rsp);
1011
            mov(rax, rsp);
1003
            andrc(rsp, -16);
1012
            andrc(rsp, -16);
1004
            push(rax);
1013
            push(rax);
Line 1005... Line 1014...
1005
            subrc(rsp, (MAX(param2 - 4, 0) MOD 2 + MAX(4 - param2, 0) + 1) * 8)
1014
            subrc(rsp, (MAX(param2 - 4, 0) MOD 2 + MAX(4 - param2, 0) + 1) * 8)
1006
 
1015
 
1007
        |CODE.opSYSVALIGN16:
1016
        |IL.opSYSVALIGN16:
1008
            ASSERT(rax IN R.regs);
1017
            ASSERT(rax IN R.regs);
1009
            mov(rax, rsp);
1018
            mov(rax, rsp);
1010
            andrc(rsp, -16);
1019
            andrc(rsp, -16);
1011
            push(rax);
1020
            push(rax);
1012
            IF ~ODD(param2) THEN
1021
            IF ~ODD(param2) THEN
Line 1013... Line 1022...
1013
                push(rax)
1022
                push(rax)
1014
            END
1023
            END
1015
 
1024
 
1016
        |CODE.opRESF:
1025
        |IL.opRESF:
1017
            ASSERT(xmm = -1);
1026
            ASSERT(xmm = -1);
1018
            INC(xmm);
1027
            INC(xmm);
Line 1028... Line 1037...
1028
                movsdrm(xmm, rsp, 0);
1037
                movsdrm(xmm, rsp, 0);
1029
                addrc(rsp, 8);
1038
                addrc(rsp, 8);
1030
                DEC(n)
1039
                DEC(n)
1031
            END
1040
            END
Line 1032... Line 1041...
1032
 
1041
 
1033
        |CODE.opRES:
1042
        |IL.opRES:
1034
            ASSERT(R.top = -1);
1043
            ASSERT(R.top = -1);
1035
            GetRegA;
1044
            GetRegA;
1036
            n := param2;
1045
            n := param2;
1037
            WHILE n > 0 DO
1046
            WHILE n > 0 DO
1038
                INC(xmm);
1047
                INC(xmm);
1039
                movsdrm(xmm, rsp, 0);
1048
                movsdrm(xmm, rsp, 0);
1040
                addrc(rsp, 8);
1049
                addrc(rsp, 8);
1041
                DEC(n)
1050
                DEC(n)
Line 1042... Line 1051...
1042
            END
1051
            END
1043
 
1052
 
Line 1044... Line 1053...
1044
        |CODE.opENTER:
1053
        |IL.opENTER:
Line 1045... Line 1054...
1045
            ASSERT(R.top = -1);
1054
            ASSERT(R.top = -1);
Line 1120... Line 1129...
1120
 
1129
 
1121
            IF cmd.allocReg THEN
1130
            IF cmd.allocReg THEN
1122
                allocReg(cmd)
1131
                allocReg(cmd)
Line 1123... Line 1132...
1123
            END
1132
            END
1124
 
1133
 
1125
        |CODE.opLEAVE, CODE.opLEAVER, CODE.opLEAVEF:
1134
        |IL.opLEAVE, IL.opLEAVER, IL.opLEAVEF:
1126
            IF cmd.opcode = CODE.opLEAVER THEN
1135
            IF opcode = IL.opLEAVER THEN
1127
                UnOp(reg1);
1136
                UnOp(reg1);
1128
                IF reg1 # rax THEN
1137
                IF reg1 # rax THEN
1129
                    GetRegA;
1138
                    GetRegA;
Line 1133... Line 1142...
1133
                drop
1142
                drop
1134
            END;
1143
            END;
Line 1135... Line 1144...
1135
 
1144
 
Line 1136... Line 1145...
1136
            ASSERT(R.top = -1);
1145
            ASSERT(R.top = -1);
1137
 
1146
 
1138
            IF cmd.opcode = CODE.opLEAVEF THEN
1147
            IF opcode = IL.opLEAVEF THEN
Line 1139... Line 1148...
1139
                DEC(xmm)
1148
                DEC(xmm)
Line -... Line 1149...
-
 
1149
            END;
1140
            END;
1150
 
-
 
1151
            ASSERT(xmm = -1);
-
 
1152
 
1141
 
1153
            IF param1 > 0 THEN
1142
            ASSERT(xmm = -1);
1154
                mov(rsp, rbp)
1143
 
1155
            END;
1144
            mov(rsp, rbp);
1156
 
1145
            pop(rbp);
1157
            pop(rbp);
1146
            IF param2 > 0 THEN
1158
            IF param2 > 0 THEN
1147
                OutByte3(0C2H, (param2 * 8) MOD 256, (param2 * 8) DIV 256)  // ret param2
1159
                OutByte3(0C2H, (param2 * 8) MOD 256, (param2 * 8) DIV 256)  // ret param2
Line 1148... Line 1160...
1148
            ELSE
1160
            ELSE
1149
                OutByte(0C3H) // ret
-
 
1150
            END;
-
 
1151
            REG.Reset(R)
1161
                OutByte(0C3H) // ret
1152
 
-
 
1153
        |CODE.opSAVES:
1162
            END;
1154
            UnOp(reg1);
1163
            REG.Reset(R)
1155
            drop;
1164
 
Line 1156... Line 1165...
1156
            PushAll(0);
1165
        |IL.opSAVES:
1157
            push(reg1);
-
 
1158
            pushDA(stroffs + param2);
1166
            PushAll(1);
Line 1159... Line 1167...
1159
            pushc(param1);
1167
            pushDA(stroffs + param2);
1160
            CallRTL(CODE._move)
1168
            pushc(param1);
1161
 
1169
            CallRTL(IL._move)
Line 1162... Line 1170...
1162
        |CODE.opSADR:
1170
 
1163
            reg1 := REG.GetAnyReg(R);
1171
        |IL.opSADR:
1164
            lea(reg1, stroffs + param2, sDATA)
1172
            lea(GetAnyReg(), stroffs + param2, sDATA)
Line 1165... Line 1173...
1165
 
1173
 
1166
        |CODE.opLOAD8:
1174
        |IL.opLOAD8:
1167
            UnOp(reg1);
1175
            UnOp(reg1);
1168
            movzx(reg1, reg1, 0, FALSE)
1176
            movzx(reg1, reg1, 0, FALSE)
1169
 
1177
 
Line 1170... Line 1178...
1170
        |CODE.opLOAD16:
1178
        |IL.opLOAD16:
1171
            UnOp(reg1);
1179
            UnOp(reg1);
1172
            movzx(reg1, reg1, 0, TRUE)
1180
            movzx(reg1, reg1, 0, TRUE)
Line 1173... Line 1181...
1173
 
1181
 
1174
        |CODE.opLOAD32:
1182
        |IL.opLOAD32:
1175
            UnOp(reg1);
1183
            UnOp(reg1);
1176
            movrm32(reg1, reg1, 0);
1184
            movrm32(reg1, reg1, 0);
1177
            shiftrc(shl, reg1, 32);
1185
            shiftrc(shl, reg1, 32);
1178
            shiftrc(shr, reg1, 32)
1186
            shiftrc(shr, reg1, 32)
1179
 
1187
 
1180
        |CODE.opLOAD64:
1188
        |IL.opLOAD64:
Line 1181... Line 1189...
1181
            UnOp(reg1);
1189
            UnOp(reg1);
1182
            movrm(reg1, reg1, 0)
1190
            movrm(reg1, reg1, 0)
1183
 
1191
 
1184
        |CODE.opLLOAD64:
1192
        |IL.opLLOAD64:
1185
            reg1 := REG.GetAnyReg(R);
1193
            reg1 := GetAnyReg();
1186
            reg2 := REG.GetVarReg(R, param2);
1194
            reg2 := GetVarReg(param2);
1187
            IF reg2 # -1 THEN
1195
            IF reg2 # -1 THEN
1188
                mov(reg1, reg2)
1196
                mov(reg1, reg2)
1189
            ELSE
1197
            ELSE
Line 1190... Line 1198...
1190
                movrm(reg1, rbp, param2 * 8)
1198
                movrm(reg1, rbp, param2 * 8)
1191
            END
1199
            END
1192
 
1200
 
1193
        |CODE.opLLOAD8,
1201
        |IL.opLLOAD8,
1194
         CODE.opLLOAD16:
1202
         IL.opLLOAD16:
1195
            reg1 := REG.GetAnyReg(R);
1203
            reg1 := GetAnyReg();
1196
            reg2 := REG.GetVarReg(R, param2);
1204
            reg2 := GetVarReg(param2);
1197
            IF reg2 # -1 THEN
1205
            IF reg2 # -1 THEN
1198
                mov(reg1, reg2)
1206
                mov(reg1, reg2)
1199
            ELSE
1207
            ELSE
Line 1200... Line 1208...
1200
                movzx(reg1, rbp, param2 * 8, cmd.opcode = CODE.opLLOAD16)
1208
                movzx(reg1, rbp, param2 * 8, opcode = IL.opLLOAD16)
1201
            END
1209
            END
1202
 
1210
 
1203
        |CODE.opLLOAD32:
1211
        |IL.opLLOAD32:
Line 1204... Line 1212...
1204
            reg1 := REG.GetAnyReg(R);
1212
            reg1 := GetAnyReg();
1205
            reg2 := REG.GetVarReg(R, param2);
1213
            reg2 := GetVarReg(param2);
1206
            IF reg2 # -1 THEN
1214
            IF reg2 # -1 THEN
1207
                mov(reg1, reg2)
1215
                mov(reg1, reg2)
Line 1208... Line 1216...
1208
            ELSE
1216
            ELSE
1209
                n := param2 * 8;
1217
                n := param2 * 8;
1210
                xor(reg1, reg1);
1218
                xor(reg1, reg1);
1211
                movrm32(reg1, rbp, n)
1219
                movrm32(reg1, rbp, n)
Line 1212... Line 1220...
1212
            END
1220
            END
1213
 
1221
 
1214
        |CODE.opGLOAD64:
1222
        |IL.opGLOAD64:
1215
            reg1 := REG.GetAnyReg(R);
1223
            reg1 := GetAnyReg();
1216
            lea(reg1, param2, sBSS);
1224
            lea(reg1, param2, sBSS);
Line 1217... Line 1225...
1217
            movrm(reg1, reg1, 0)
1225
            movrm(reg1, reg1, 0)
1218
 
1226
 
1219
        |CODE.opGLOAD8:
1227
        |IL.opGLOAD8:
1220
            reg1 := REG.GetAnyReg(R);
1228
            reg1 := GetAnyReg();
Line 1221... Line 1229...
1221
            lea(reg1, param2, sBSS);
1229
            lea(reg1, param2, sBSS);
1222
            movzx(reg1, reg1, 0, FALSE)
1230
            movzx(reg1, reg1, 0, FALSE)
1223
 
1231
 
1224
        |CODE.opGLOAD16:
1232
        |IL.opGLOAD16:
1225
            reg1 := REG.GetAnyReg(R);
1233
            reg1 := GetAnyReg();
Line 1226... Line 1234...
1226
            lea(reg1, param2, sBSS);
1234
            lea(reg1, param2, sBSS);
1227
            movzx(reg1, reg1, 0, TRUE)
1235
            movzx(reg1, reg1, 0, TRUE)
1228
 
1236
 
1229
        |CODE.opGLOAD32:
1237
        |IL.opGLOAD32:
1230
            reg1 := REG.GetAnyReg(R);
1238
            reg1 := GetAnyReg();
1231
            xor(reg1, reg1);
1239
            xor(reg1, reg1);
1232
            lea(reg1, param2, sBSS);
1240
            lea(reg1, param2, sBSS);
Line 1233... Line 1241...
1233
            movrm32(reg1, reg1, 0)
1241
            movrm32(reg1, reg1, 0)
1234
 
1242
 
1235
        |CODE.opVLOAD64:
1243
        |IL.opVLOAD64:
1236
            reg1 := REG.GetAnyReg(R);
1244
            reg1 := GetAnyReg();
1237
            movrm(reg1, rbp, param2 * 8);
1245
            movrm(reg1, rbp, param2 * 8);
1238
            movrm(reg1, reg1, 0)
1246
            movrm(reg1, reg1, 0)
1239
 
1247
 
1240
        |CODE.opVLOAD8,
1248
        |IL.opVLOAD8,
1241
         CODE.opVLOAD16:
1249
         IL.opVLOAD16:
1242
            reg1 := REG.GetAnyReg(R);
1250
            reg1 := GetAnyReg();
1243
            movrm(reg1, rbp, param2 * 8);
1251
            movrm(reg1, rbp, param2 * 8);
1244
            movzx(reg1, reg1, 0, cmd.opcode = CODE.opVLOAD16)
1252
            movzx(reg1, reg1, 0, opcode = IL.opVLOAD16)
1245
 
1253
 
1246
        |CODE.opVLOAD32:
1254
        |IL.opVLOAD32:
1247
            reg1 := REG.GetAnyReg(R);
1255
            reg1 := GetAnyReg();
1248
            reg2 := REG.GetAnyReg(R);
1256
            reg2 := GetAnyReg();
1249
            xor(reg1, reg1);
1257
            xor(reg1, reg1);
Line 1250... Line 1258...
1250
            movrm(reg2, rbp, param2 * 8);
1258
            movrm(reg2, rbp, param2 * 8);
1251
            movrm32(reg1, reg2, 0);
-
 
1252
            drop
1259
            movrm32(reg1, reg2, 0);
Line 1253... Line 1260...
1253
 
1260
            drop
1254
        |CODE.opLADR:
-
 
1255
            n := param2 * 8;
1261
 
Line 1256... Line 1262...
1256
            next := cmd.next(COMMAND);
1262
        |IL.opLADR:
1257
            IF next.opcode = CODE.opSAVEF THEN
1263
            n := param2 * 8;
1258
                movsdmr(rbp, n, xmm);
1264
            next := cmd.next(COMMAND);
1259
                DEC(xmm);
1265
            IF next.opcode = IL.opSAVEF THEN
1260
                cmd := next
1266
                movsdmr(rbp, n, xmm);
1261
            ELSIF next.opcode = CODE.opLOADF THEN
1267
                DEC(xmm);
1262
                INC(xmm);
1268
                cmd := next
Line 1263... Line 1269...
1263
                movsdrm(xmm, rbp, n);
1269
            ELSIF next.opcode = IL.opLOADF THEN
1264
                cmd := next
1270
                INC(xmm);
1265
            ELSE
1271
                movsdrm(xmm, rbp, n);
1266
                reg1 := REG.GetAnyReg(R);
1272
                cmd := next
1267
                Rex(0, reg1);
1273
            ELSE
1268
                OutByte2(8DH, 45H + long(n) + (reg1 MOD 8) * 8);  // lea reg1, qword[rbp+n]
1274
                reg1 := GetAnyReg();
1269
                OutIntByte(n)
1275
                Rex(0, reg1);
1270
            END
1276
                OutByte2(8DH, 45H + long(n) + (reg1 MOD 8) * 8);  // lea reg1, qword[rbp+n]
1271
 
1277
                OutIntByte(n)
Line 1272... Line 1278...
1272
        |CODE.opGADR:
1278
            END
1273
            reg1 := REG.GetAnyReg(R);
1279
 
1274
            lea(reg1, param2, sBSS)
1280
        |IL.opGADR:
1275
 
1281
            lea(GetAnyReg(), param2, sBSS)
1276
        |CODE.opVADR:
1282
 
1277
            reg1 := REG.GetAnyReg(R);
1283
        |IL.opVADR:
1278
            movrm(reg1, rbp, param2 * 8)
1284
            movrm(GetAnyReg(), rbp, param2 * 8)
1279
 
1285
 
1280
        |CODE.opSAVE8C:
1286
        |IL.opSAVE8C:
1281
            UnOp(reg1);
1287
            UnOp(reg1);
1282
            IF reg1 >= 8 THEN
1288
            IF reg1 >= 8 THEN
1283
                OutByte(41H)
1289
                OutByte(41H)
1284
            END;
1290
            END;
Line 1285... Line 1291...
1285
            OutByte3(0C6H, reg1 MOD 8, param2); // mov byte[reg1], param2
1291
            OutByte3(0C6H, reg1 MOD 8, param2); // mov byte[reg1], param2
1286
            drop
1292
            drop
1287
 
1293
 
1288
        |CODE.opSAVE16C:
1294
        |IL.opSAVE16C:
Line 1289... Line 1295...
1289
            UnOp(reg1);
1295
            UnOp(reg1);
1290
            OutByte(66H);
1296
            OutByte(66H);
1291
            IF reg1 >= 8 THEN
1297
            IF reg1 >= 8 THEN
1292
                OutByte(41H)
1298
                OutByte(41H)
1293
            END;
1299
            END;
Line 1294... Line 1300...
1294
            OutByte2(0C7H, reg1 MOD 8);
1300
            OutByte2(0C7H, reg1 MOD 8);
1295
            OutByte2(param2 MOD 256, param2 DIV 256); // mov word[reg1], param2
1301
            OutByte2(param2 MOD 256, param2 DIV 256); // mov word[reg1], param2
1296
            drop
1302
            drop
1297
 
1303
 
1298
        |CODE.opSAVEC:
1304
        |IL.opSAVEC:
Line 1299... Line 1305...
1299
            UnOp(reg1);
1305
            UnOp(reg1);
1300
            IF isLong(param2) THEN
1306
            IF isLong(param2) THEN
1301
                reg2 := REG.GetAnyReg(R);
1307
                reg2 := GetAnyReg();
1302
                movrc(reg2, param2);
1308
                movrc(reg2, param2);
1303
                movmr(reg1, 0, reg2);
1309
                movmr(reg1, 0, reg2);
1304
                drop
1310
                drop
Line 1305... Line 1311...
1305
            ELSE
1311
            ELSE
1306
                Rex(reg1, 0);
1312
                Rex(reg1, 0);
1307
                OutByte2(0C7H, reg1 MOD 8); // mov qword[reg1], param2
1313
                OutByte2(0C7H, reg1 MOD 8); // mov qword[reg1], param2
1308
                OutInt(param2)
1314
                OutInt(param2)
1309
            END;
1315
            END;
1310
            drop
1316
            drop
1311
 
1317
 
1312
        |CODE.opRSET:
1318
        |IL.opRSET:
1313
            PushAll(2);
1319
            PushAll(2);
Line 1314... Line 1320...
1314
            CallRTL(CODE._set);
1320
            CallRTL(IL._set);
1315
            GetRegA
1321
            GetRegA
1316
 
1322
 
1317
        |CODE.opRSETR:
1323
        |IL.opRSETR:
1318
            PushAll(1);
1324
            PushAll(1);
1319
            pushc(param2);
1325
            pushc(param2);
Line 1320... Line 1326...
1320
            CallRTL(CODE._set);
1326
            CallRTL(IL._set);
1321
            GetRegA
-
 
1322
 
-
 
1323
        |CODE.opRSETL:
-
 
1324
            PushAll(1);
-
 
1325
            pushc(param2);
-
 
1326
            CallRTL(CODE._set2);
-
 
1327
            GetRegA
-
 
1328
 
-
 
1329
        |CODE.opRSET1:
-
 
1330
            UnOp(reg1);
-
 
1331
            PushAll(1);
-
 
1332
            push(reg1);
-
 
1333
            CallRTL(CODE._set);
1327
            GetRegA
1334
            GetRegA
1328
 
1335
 
1329
        |IL.opRSETL:
1336
        |CODE.opINCL, CODE.opEXCL:
1330
            PushAll(1);
Line 1337... Line 1331...
1337
            BinOp(reg1, reg2);
1331
            pushc(param2);
1338
            cmprc(reg1, 64);
1332
            CallRTL(IL._set2);
1339
            OutByte2(73H, 04H); // jnb L
1333
            GetRegA
1340
            Rex(reg2, reg1);
1334
 
1341
            OutByte3(0FH, 0ABH + 8 * ORD(cmd.opcode = CODE.opEXCL), 8 * (reg1 MOD 8) + reg2 MOD 8); // bts/btr qword[reg2], reg1
1335
        |IL.opRSET1:
Line 1342... Line -...
1342
            // L:
-
 
1343
            drop;
1336
            UnOp(reg1);
1344
            drop
1337
            PushAll(1);
1345
 
-
 
1346
        |CODE.opINCLC, CODE.opEXCLC:
-
 
Line 1347... Line 1338...
1347
            UnOp(reg1);
1338
            push(reg1);
1348
            Rex(reg1, 0);
-
 
1349
            OutByte2(0FH, 0BAH);  // bts/btr qword[reg1], param2
1339
            CallRTL(IL._set);
Line 1350... Line -...
1350
            OutByte2(28H + 8 * ORD(cmd.opcode = CODE.opEXCLC) + reg1 MOD 8, param2);
-
 
1351
            drop
1340
            GetRegA
1352
 
1341
 
1353
        |CODE.opEQS .. CODE.opGES:
1342
        |IL.opINCL, IL.opEXCL:
1354
            PushAll(4);
-
 
1355
            pushc(cmd.opcode - CODE.opEQS);
1343
            BinOp(reg1, reg2);
1356
            CallRTL(CODE._strcmp);
-
 
1357
            GetRegA
-
 
1358
 
-
 
1359
        |CODE.opEQS2 .. CODE.opGES2:
-
 
1360
            PushAll(4);
-
 
1361
            pushc(cmd.opcode - CODE.opEQS2);
-
 
1362
            CallRTL(CODE._strcmp2);
-
 
1363
            GetRegA
-
 
1364
 
-
 
1365
        |CODE.opEQSW .. CODE.opGESW:
-
 
1366
            PushAll(4);
-
 
1367
            pushc(cmd.opcode - CODE.opEQSW);
-
 
1368
            CallRTL(CODE._strcmpw);
1344
            cmprc(reg1, 64);
1369
            GetRegA
-
 
1370
 
-
 
1371
        |CODE.opEQSW2 .. CODE.opGESW2:
-
 
1372
            PushAll(4);
-
 
1373
            pushc(cmd.opcode - CODE.opEQSW2);
-
 
1374
            CallRTL(CODE._strcmpw2);
-
 
1375
            GetRegA
-
 
1376
 
-
 
1377
        |CODE.opINC1, CODE.opDEC1:
1345
            OutByte2(73H, 04H); // jnb L
1378
            UnOp(reg1);
1346
            Rex(reg2, reg1);
1379
            Rex(reg1, 0);
1347
            OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opEXCL), 8 * (reg1 MOD 8) + reg2 MOD 8); // bts/btr qword[reg2], reg1
1380
            OutByte2(0FFH, reg1 MOD 8 + 8 * ORD(cmd.opcode = CODE.opDEC1));
1348
            // L:
1381
            drop
1349
            drop;
-
 
1350
            drop
1382
 
1351
 
-
 
1352
        |IL.opINCLC, IL.opEXCLC:
1383
        |CODE.opCONST:
1353
            UnOp(reg1);
1384
            reg1 := REG.GetAnyReg(R);
1354
            Rex(reg1, 0);
Line 1385... Line 1355...
1385
            movrc(reg1, param2)
1355
            OutByte2(0FH, 0BAH);  // bts/btr qword[reg1], param2
1386
 
1356
            OutByte2(28H + 8 * ORD(opcode = IL.opEXCLC) + reg1 MOD 8, param2);
1387
        |CODE.opGT, CODE.opGE, CODE.opLT,
1357
            drop
1388
         CODE.opLE, CODE.opEQ, CODE.opNE:
1358
 
Line 1389... Line 1359...
1389
            BinOp(reg1, reg2);
1359
        |IL.opEQS .. IL.opGES:
1390
            cmprr(reg1, reg2);
1360
            PushAll(4);
1391
            drop;
1361
            pushc(opcode - IL.opEQS);
1392
            drop;
1362
            CallRTL(IL._strcmp);
Line 1393... Line 1363...
1393
            cc := X86.cond(cmd.opcode);
1363
            GetRegA
1394
 
1364
 
1395
            IF cmd.next(COMMAND).opcode = CODE.opJE THEN
1365
        |IL.opEQSW .. IL.opGESW:
1396
                label := cmd.next(COMMAND).param1;
1366
            PushAll(4);
1397
                jcc(cc, label);
1367
            pushc(opcode - IL.opEQSW);
Line 1398... Line 1368...
1398
                cmd := cmd.next(COMMAND)
1368
            CallRTL(IL._strcmpw);
1399
 
1369
            GetRegA
Line 1400... Line 1370...
1400
            ELSIF cmd.next(COMMAND).opcode = CODE.opJNE THEN
1370
 
1401
                label := cmd.next(COMMAND).param1;
1371
        |IL.opCONST:
1402
                jcc(X86.inv1(cc), label);
1372
            movrc(GetAnyReg(), param2)
1403
                cmd := cmd.next(COMMAND)
1373
 
Line 1404... Line 1374...
1404
 
1374
        |IL.opEQ..IL.opGE,
1405
            ELSE
1375
         IL.opEQC..IL.opGEC:
1406
                reg1 := REG.GetAnyReg(R);
1376
 
1407
                setcc(cc + 16, reg1);
1377
            IF (IL.opEQ <= opcode) & (opcode <= IL.opGE) THEN
1408
                andrc(reg1, 1)
1378
                BinOp(reg1, reg2);
1409
            END
1379
                cmprr(reg1, reg2);
1410
 
1380
                drop
1411
        |CODE.opGTR, CODE.opLTL, CODE.opGER, CODE.opLEL,
1381
            ELSE
1412
         CODE.opLER, CODE.opGEL, CODE.opLTR, CODE.opGTL,
1382
                UnOp(reg1);
1413
         CODE.opEQR, CODE.opEQL, CODE.opNER, CODE.opNEL:
1383
                IF param2 = 0 THEN
Line 1414... Line 1384...
1414
            UnOp(reg1);
1384
                    test(reg1)
1415
            IF param2 = 0 THEN
1385
                ELSE
1416
                test(reg1)
1386
                    cmprc(reg1, param2)
1417
            ELSE
1387
                END
1418
                cmprc(reg1, param2)
1388
            END;
1419
            END;
1389
 
1420
            drop;
1390
            drop;
Line 1421... Line 1391...
1421
            cc := X86.cond(cmd.opcode);
1391
            cc := X86.cond(opcode);
1422
 
1392
 
1423
            IF cmd.next(COMMAND).opcode = CODE.opJE THEN
1393
            IF cmd.next(COMMAND).opcode = IL.opJE THEN
1424
                label := cmd.next(COMMAND).param1;
1394
                label := cmd.next(COMMAND).param1;
Line 1425... Line 1395...
1425
                jcc(cc, label);
1395
                jcc(cc, label);
1426
                cmd := cmd.next(COMMAND)
1396
                cmd := cmd.next(COMMAND)
1427
 
1397
 
1428
            ELSIF cmd.next(COMMAND).opcode = CODE.opJNE THEN
1398
            ELSIF cmd.next(COMMAND).opcode = IL.opJNE THEN
Line 1429... Line 1399...
1429
                label := cmd.next(COMMAND).param1;
1399
                label := cmd.next(COMMAND).param1;
1430
                jcc(X86.inv1(cc), label);
1400
                jcc(X86.inv0(cc), label);
1431
                cmd := cmd.next(COMMAND)
1401
                cmd := cmd.next(COMMAND)
1432
 
1402
 
1433
            ELSE
1403
            ELSE
Line 1434... Line 1404...
1434
                reg1 := REG.GetAnyReg(R);
1404
                reg1 := GetAnyReg();
1435
                setcc(cc + 16, reg1);
1405
                setcc(cc + 16, reg1);
1436
                andrc(reg1, 1)
1406
                andrc(reg1, 1)
1437
            END
1407
            END
1438
 
1408
 
Line 1439... Line 1409...
1439
        |CODE.opCODE:
1409
        |IL.opCODE:
1440
            OutByte(param2)
1410
            OutByte(param2)
1441
 
1411
 
1442
        |CODE.opPUSHIP:
1412
        |IL.opPUSHIP:
1443
            reg1 := REG.GetAnyReg(R);
1413
            reg1 := GetAnyReg();
1444
            lea(reg1, param2, sIMP);
1414
            lea(reg1, param2, sIMP);
Line 1499... Line 1469...
1499
            setcc(setc, reg1);
1469
            setcc(setc, reg1);
1500
            andrc(reg1, 1);
1470
            andrc(reg1, 1);
1501
            X86.SetLabel(label);
1471
            X86.SetLabel(label);
1502
            drop
1472
            drop
Line 1503... Line 1473...
1503
 
1473
 
1504
        |CODE.opINR:
1474
        |IL.opINR:
1505
            label := NewLabel();
1475
            label := NewLabel();
1506
            L := NewLabel();
1476
            L := NewLabel();
1507
            UnOp(reg1);
1477
            UnOp(reg1);
1508
            reg2 := REG.GetAnyReg(R);
1478
            reg2 := GetAnyReg();
1509
            cmprc(reg1, 64);
1479
            cmprc(reg1, 64);
1510
            jcc(jb, L);
1480
            jcc(jb, L);
1511
            xor(reg1, reg1);
1481
            xor(reg1, reg1);
1512
            jmp(label);
1482
            jmp(label);
Line 1517... Line 1487...
1517
            setcc(setc, reg1);
1487
            setcc(setc, reg1);
1518
            andrc(reg1, 1);
1488
            andrc(reg1, 1);
1519
            X86.SetLabel(label);
1489
            X86.SetLabel(label);
1520
            drop
1490
            drop
Line 1521... Line 1491...
1521
 
1491
 
1522
        |CODE.opINL:
1492
        |IL.opINL:
1523
            UnOp(reg1);
1493
            UnOp(reg1);
1524
            Rex(reg1, 0);
1494
            Rex(reg1, 0);
1525
            OutByte2(0FH, 0BAH);  // bt reg1, param2
1495
            OutByte2(0FH, 0BAH);  // bt reg1, param2
1526
            OutByte2(0E0H + reg1 MOD 8, param2);
1496
            OutByte2(0E0H + reg1 MOD 8, param2);
1527
            setcc(setc, reg1);
1497
            setcc(setc, reg1);
Line 1528... Line 1498...
1528
            andrc(reg1, 1)
1498
            andrc(reg1, 1)
1529
 
1499
 
1530
        |CODE.opNOT:
1500
        |IL.opNOT:
1531
            UnOp(reg1);
1501
            UnOp(reg1);
1532
            test(reg1);
1502
            test(reg1);
Line 1533... Line 1503...
1533
            setcc(sete, reg1);
1503
            setcc(sete, reg1);
1534
            andrc(reg1, 1)
1504
            andrc(reg1, 1)
1535
 
1505
 
1536
        |CODE.opORD:
1506
        |IL.opORD:
1537
            UnOp(reg1);
1507
            UnOp(reg1);
Line 1538... Line 1508...
1538
            test(reg1);
1508
            test(reg1);
1539
            setcc(setne, reg1);
1509
            setcc(setne, reg1);
1540
            andrc(reg1, 1)
1510
            andrc(reg1, 1)
1541
 
1511
 
1542
        |CODE.opABS:
1512
        |IL.opABS:
1543
            UnOp(reg1);
1513
            UnOp(reg1);
Line 1544... Line 1514...
1544
            test(reg1);
1514
            test(reg1);
1545
            OutByte2(7DH, 03H); // jge L
1515
            OutByte2(7DH, 03H); // jge L
1546
            neg(reg1)
1516
            neg(reg1)
1547
            // L:
-
 
1548
 
-
 
1549
        |CODE.opEQB, CODE.opNEB:
1517
            // L:
-
 
1518
 
1550
            BinOp(reg1, reg2);
1519
        |IL.opEQB, IL.opNEB:
1551
            drop;
1520
            BinOp(reg1, reg2);
1552
            drop;
1521
            drop;
1553
 
1522
            test(reg1);
-
 
1523
            label := NewLabel();
1554
            test(reg1);
1524
            jcc(je, label);
1555
            OutByte2(74H, 07H); // je L1
1525
            movrc(reg1, 1);
1556
            movrc(reg1, 1);
1526
            X86.SetLabel(label);
1557
            // L1:
1527
            test(reg2);
1558
            test(reg2);
-
 
1559
            OutByte2(74H, 07H); // je L2
1528
            label := NewLabel();
1560
            movrc(reg2, 1);
1529
            jcc(je, label);
1561
            // L2:
1530
            movrc(reg2, 1);
1562
            cmprr(reg1, reg2);
1531
            X86.SetLabel(label);
1563
            reg1 := REG.GetAnyReg(R);
1532
            cmprr(reg1, reg2);
1564
            IF cmd.opcode = CODE.opEQB THEN
1533
            IF opcode = IL.opEQB THEN
Line 1565... Line 1534...
1565
                setcc(sete, reg1)
1534
                setcc(sete, reg1)
1566
            ELSE
1535
            ELSE
1567
                setcc(setne, reg1)
1536
                setcc(setne, reg1)
Line 1568... Line 1537...
1568
            END;
1537
            END;
1569
            andrc(reg1, 1)
1538
            andrc(reg1, 1)
1570
 
1539
 
1571
        |CODE.opMULSC:
1540
        |IL.opMULSC:
1572
            UnOp(reg1);
1541
            UnOp(reg1);
Line 1573... Line 1542...
1573
            andrc(reg1, param2)
1542
            andrc(reg1, param2)
1574
 
1543
 
1575
        |CODE.opDIVSC, CODE.opADDSL, CODE.opADDSR:
1544
        |IL.opDIVSC, IL.opADDSL, IL.opADDSR:
1576
            UnOp(reg1);
1545
            UnOp(reg1);
Line 1577... Line 1546...
1577
            Rex(reg1, 0);
1546
            Rex(reg1, 0);
1578
            OutByte2(81H + short(param2), 0C8H + 28H * ORD(cmd.opcode = CODE.opDIVSC) + reg1 MOD 8); // or/xor reg1, param2
1547
            OutByte2(81H + short(param2), 0C8H + 28H * ORD(opcode = IL.opDIVSC) + reg1 MOD 8); // or/xor reg1, param2
1579
            OutIntByte(param2)
1548
            OutIntByte(param2)
Line 1580... Line 1549...
1580
 
1549
 
1581
        |CODE.opSUBSL:
1550
        |IL.opSUBSL:
1582
            UnOp(reg1);
1551
            UnOp(reg1);
1583
            not(reg1);
1552
            not(reg1);
Line 1584... Line 1553...
1584
            andrc(reg1, param2)
1553
            andrc(reg1, param2)
1585
 
1554
 
1586
        |CODE.opSUBSR:
1555
        |IL.opSUBSR:
1587
            UnOp(reg1);
1556
            UnOp(reg1);
Line 1588... Line 1557...
1588
            andrc(reg1, ORD(-BITS(param2)))
1557
            andrc(reg1, ORD(-BITS(param2)))
1589
 
1558
 
1590
        |CODE.opMULS:
1559
        |IL.opMULS:
Line 1591... Line 1560...
1591
            BinOp(reg1, reg2);
1560
            BinOp(reg1, reg2);
1592
            and(reg1, reg2);
1561
            and(reg1, reg2);
1593
            drop
1562
            drop
1594
 
1563
 
Line 1595... Line 1564...
1595
        |CODE.opDIVS:
1564
        |IL.opDIVS:
1596
            BinOp(reg1, reg2);
1565
            BinOp(reg1, reg2);
1597
            xor(reg1, reg2);
1566
            xor(reg1, reg2);
Line 1598... Line 1567...
1598
            drop
1567
            drop
1599
 
1568
 
1600
        |CODE.opUMINS:
1569
        |IL.opUMINS:
1601
            UnOp(reg1);
1570
            UnOp(reg1);
1602
            not(reg1)
1571
            not(reg1)
Line 1603... Line 1572...
1603
 
1572
 
1604
        |CODE.opCOPY:
-
 
1605
            PushAll(2);
-
 
1606
            pushc(param2);
-
 
1607
            CallRTL(CODE._move2)
-
 
1608
 
-
 
1609
        |CODE.opMOVE:
1573
        |IL.opCOPY:
1610
            PushAll(3);
1574
            PushAll(2);
1611
            CallRTL(CODE._move2)
1575
            pushc(param2);
Line 1612... Line 1576...
1612
 
1576
            CallRTL(IL._move2)
1613
        |CODE.opCOPYA:
1577
 
1614
            PushAll(4);
1578
        |IL.opMOVE:
1615
            pushc(param2);
1579
            PushAll(3);
1616
            CallRTL(CODE._arrcpy);
1580
            CallRTL(IL._move2)
Line 1617... Line 1581...
1617
            GetRegA
1581
 
1618
 
1582
        |IL.opCOPYA:
1619
        |CODE.opCOPYS:
1583
            PushAll(4);
1620
            PushAll(4);
1584
            pushc(param2);
1621
            pushc(param2);
1585
            CallRTL(IL._arrcpy);
1622
            CallRTL(CODE._strcpy)
1586
            GetRegA
1623
 
1587
 
Line 1624... Line 1588...
1624
        |CODE.opCOPYS2:
1588
        |IL.opCOPYS:
1625
            PushAll(4);
1589
            PushAll(4);
1626
            pushc(param2);
1590
            pushc(param2);
Line 1627... Line 1591...
1627
            CallRTL(CODE._strcpy2)
1591
            CallRTL(IL._strcpy)
1628
 
1592
 
1629
        |CODE.opROT:
1593
        |IL.opROT:
1630
            PushAll(0);
1594
            PushAll(0);
Line 1631... Line 1595...
1631
            push(rsp);
1595
            push(rsp);
1632
            pushc(param2);
1596
            pushc(param2);
1633
            CallRTL(CODE._rot)
1597
            CallRTL(IL._rot)
1634
 
1598
 
1635
        |CODE.opNEW:
1599
        |IL.opNEW:
Line 1636... Line 1600...
1636
            PushAll(1);
1600
            PushAll(1);
1637
            n := param2 + 16;
1601
            n := param2 + 16;
1638
            ASSERT(MACHINE.Align(n, 64));
1602
            ASSERT(UTILS.Align(n, 64));
1639
            pushc(n);
1603
            pushc(n);
1640
            pushc(param1);
1604
            pushc(param1);
Line 1641... Line 1605...
1641
            CallRTL(CODE._new)
1605
            CallRTL(IL._new)
1642
 
1606
 
1643
        |CODE.opDISP:
1607
        |IL.opDISP:
1644
            PushAll(1);
1608
            PushAll(1);
1645
            CallRTL(CODE._dispose)
1609
            CallRTL(IL._dispose)
Line 1646... Line 1610...
1646
 
1610
 
1647
        |CODE.opPUSHT:
1611
        |IL.opPUSHT:
1648
            UnOp(reg1);
1612
            UnOp(reg1);
1649
            reg2 := REG.GetAnyReg(R);
1613
            reg2 := GetAnyReg();
1650
            movrm(reg2, reg1, -8)
1614
            movrm(reg2, reg1, -8)
1651
 
1615
 
1652
        |CODE.opISREC:
1616
        |IL.opISREC:
Line 1653... Line 1617...
1653
            PushAll(2);
1617
            PushAll(2);
1654
            pushc(param2);
1618
            pushc(param2 * tcount);
1655
            CallRTL(CODE._isrec);
1619
            CallRTL(IL._isrec);
1656
            GetRegA
1620
            GetRegA
1657
 
1621
 
1658
        |CODE.opIS:
1622
        |IL.opIS:
1659
            PushAll(1);
1623
            PushAll(1);
Line 1660... Line 1624...
1660
            pushc(param2);
1624
            pushc(param2 * tcount);
1661
            CallRTL(CODE._is);
1625
            CallRTL(IL._is);
1662
            GetRegA
1626
            GetRegA
1663
 
1627
 
1664
        |CODE.opTYPEGR:
1628
        |IL.opTYPEGR:
1665
            PushAll(1);
1629
            PushAll(1);
1666
            pushc(param2);
1630
            pushc(param2 * tcount);
1667
            CallRTL(CODE._guardrec);
1631
            CallRTL(IL._guardrec);
Line 1668... Line 1632...
1668
            GetRegA
1632
            GetRegA
1669
 
1633
 
1670
        |CODE.opTYPEGP:
1634
        |IL.opTYPEGP:
1671
            UnOp(reg1);
1635
            UnOp(reg1);
1672
            PushAll(0);
1636
            PushAll(0);
1673
            push(reg1);
1637
            push(reg1);
1674
            pushc(param2);
1638
            pushc(param2 * tcount);
Line 1675... Line 1639...
1675
            CallRTL(CODE._guard);
1639
            CallRTL(IL._guard);
1676
            GetRegA
-
 
1677
 
1640
            GetRegA
Line 1678... Line 1641...
1678
        |CODE.opTYPEGD:
1641
 
1679
            UnOp(reg1);
1642
        |IL.opTYPEGD:
1680
            PushAll(0);
1643
            UnOp(reg1);
1681
            pushm(reg1, -8);
1644
            PushAll(0);
1682
            pushc(param2);
1645
            pushm(reg1, -8);
1683
            CallRTL(CODE._guardrec);
1646
            pushc(param2 * tcount);
1684
            GetRegA
1647
            CallRTL(IL._guardrec);
Line 1685... Line 1648...
1685
 
1648
            GetRegA
1686
        |CODE.opCASET:
1649
 
1687
            push(r10);
1650
        |IL.opCASET:
1688
            push(r10);
1651
            push(r10);
1689
            pushc(param2);
1652
            push(r10);
1690
            CallRTL(CODE._guardrec);
1653
            pushc(param2 * tcount);
1691
            pop(r10);
1654
            CallRTL(IL._guardrec);
1692
            test(rax);
1655
            pop(r10);
1693
            jcc(jne, param1)
1656
            test(rax);
-
 
1657
            jcc(jne, param1)
-
 
1658
 
-
 
1659
        |IL.opSAVEP:
1694
 
1660
            UnOp(reg1);
1695
        |CODE.opSAVEP:
1661
            reg2 := GetAnyReg();
1696
            UnOp(reg1);
1662
            lea(reg2, param2, sCODE);
1697
            reg2 := REG.GetAnyReg(R);
1663
            movmr(reg1, 0, reg2);
1698
            lea(reg2, param2, sCODE);
1664
            drop;
1699
            movmr(reg1, 0, reg2);
1665
            drop
1700
            drop;
1666
 
Line 1701... Line 1667...
1701
            drop
1667
        |IL.opPUSHP:
1702
 
1668
            lea(GetAnyReg(), param2, sCODE)
1703
        |CODE.opPUSHP:
1669
 
Line 1704... Line 1670...
1704
            reg1 := REG.GetAnyReg(R);
1670
        |IL.opINC, IL.opDEC:
1705
            lea(reg1, param2, sCODE)
1671
            BinOp(reg1, reg2);
1706
 
1672
            // add/sub qword[reg2], reg1
1707
        |CODE.opINC, CODE.opDEC:
1673
            Rex(reg2, reg1);
1708
            BinOp(reg1, reg2);
1674
            OutByte2(01H + 28H * ORD(opcode = IL.opDEC), reg2 MOD 8 + (reg1 MOD 8) * 8);
Line 1709... Line 1675...
1709
            // add/sub qword[reg2], reg1
1675
            drop;
1710
            Rex(reg2, reg1);
1676
            drop
1711
            OutByte2(01H + 28H * ORD(cmd.opcode = CODE.opDEC), reg2 MOD 8 + (reg1 MOD 8) * 8);
1677
 
1712
            drop;
1678
        |IL.opINCC:
1713
            drop
1679
            UnOp(reg1);
Line 1714... Line 1680...
1714
 
1680
            IF isLong(param2) THEN
1715
        |CODE.opINCC, CODE.opDECC:
1681
                reg2 := GetAnyReg();
1716
            UnOp(reg1);
1682
                movrc(reg2, param2);
1717
            IF isLong(param2) THEN
1683
                // add qword[reg1], reg2
1718
                reg2 := REG.GetAnyReg(R);
1684
                Rex(reg1, reg2);
Line 1719... Line 1685...
1719
                movrc(reg2, param2);
1685
                OutByte2(01H, reg1 MOD 8 + (reg2 MOD 8) * 8);
1720
                // add/sub qword[reg1], reg2
1686
                drop
1721
                Rex(reg1, reg2);
1687
            ELSIF ABS(param2) = 1 THEN
1722
                OutByte2(01H + 28H * ORD(cmd.opcode = CODE.opDECC), reg1 MOD 8 + (reg2 MOD 8) * 8);
1688
                Rex(reg1, 0);
1723
                drop
1689
                OutByte2(0FFH, reg1 MOD 8 + 8 * ORD(param2 = -1)) // inc/dec qword[reg1]
Line 1724... Line 1690...
1724
            ELSE
1690
            ELSE
1725
                // add/sub qword[reg1], param2
1691
                // add qword[reg1], param2
1726
                Rex(reg1, 0);
1692
                Rex(reg1, 0);
1727
                OutByte2(81H + short(param2), 28H * ORD(cmd.opcode = CODE.opDECC) + reg1 MOD 8);
1693
                OutByte2(81H + short(param2), reg1 MOD 8);
1728
                OutIntByte(param2)
1694
                OutIntByte(param2)
1729
            END;
1695
            END;
1730
            drop
1696
            drop
Line 1731... Line 1697...
1731
 
1697
 
1732
        |CODE.opDROP:
1698
        |IL.opDROP:
1733
            UnOp(reg1);
1699
            UnOp(reg1);
1734
            drop
1700
            drop
1735
 
1701
 
1736
        |CODE.opSAVE, CODE.opSAVE64:
1702
        |IL.opSAVE, IL.opSAVE64:
1737
            BinOp(reg2, reg1);
1703
            BinOp(reg2, reg1);
Line 1738... Line 1704...
1738
            movmr(reg1, 0, reg2);
1704
            movmr(reg1, 0, reg2);
1739
            drop;
1705
            drop;
1740
            drop
1706
            drop
1741
 
1707
 
1742
        |CODE.opSAVE8:
1708
        |IL.opSAVE8:
1743
            BinOp(reg2, reg1);
1709
            BinOp(reg2, reg1);
1744
            movmr8(reg1, 0, reg2);
1710
            movmr8(reg1, 0, reg2);
Line 1745... Line 1711...
1745
            drop;
1711
            drop;
1746
            drop
1712
            drop
1747
 
1713
 
1748
        |CODE.opSAVE16:
1714
        |IL.opSAVE16:
1749
            BinOp(reg2, reg1);
1715
            BinOp(reg2, reg1);
1750
            movmr16(reg1, 0, reg2);
1716
            movmr16(reg1, 0, reg2);
1751
            drop;
1717
            drop;
Line 1752... Line 1718...
1752
            drop
1718
            drop
1753
 
1719
 
1754
        |CODE.opSAVE32:
1720
        |IL.opSAVE32:
1755
            BinOp(reg2, reg1);
1721
            BinOp(reg2, reg1);
1756
            movmr32(reg1, 0, reg2);
1722
            movmr32(reg1, 0, reg2);
-
 
1723
            drop;
-
 
1724
            drop
1757
            drop;
1725
 
1758
            drop
1726
        |IL.opMIN:
Line 1759... Line 1727...
1759
 
1727
            BinOp(reg1, reg2);
1760
        |CODE.opMIN:
1728
            cmprr(reg1, reg2);
1761
            BinOp(reg1, reg2);
1729
            OutByte2(7EH, 3); // jle L
1762
            cmprr(reg1, reg2);
1730
            mov(reg1, reg2);
1763
            OutByte2(7EH, 3); // jle L
1731
            // L:
1764
            mov(reg1, reg2);
1732
            drop
1765
            // L:
1733
 
Line 1766... Line 1734...
1766
            drop
1734
        |IL.opMAX:
1767
 
1735
            BinOp(reg1, reg2);
1768
        |CODE.opMAX:
1736
            cmprr(reg1, reg2);
Line 1769... Line 1737...
1769
            BinOp(reg1, reg2);
1737
            OutByte2(7DH, 3);  // jge L
1770
            cmprr(reg1, reg2);
1738
            mov(reg1, reg2);
1771
            OutByte2(7DH, 3);  // jge L
1739
            // L:
Line 1772... Line 1740...
1772
            mov(reg1, reg2);
1740
            drop
1773
            // L:
1741
 
1774
            drop
1742
        |IL.opMINC:
1775
 
1743
            UnOp(reg1);
Line 1776... Line 1744...
1776
        |CODE.opMINC:
1744
            cmprc(reg1, param2);
1777
            UnOp(reg1);
1745
            label := NewLabel();
1778
            cmprc(reg1, param2);
1746
            jcc(jle, label);
1779
            label := NewLabel();
1747
            movrc(reg1, param2);
Line 1780... Line 1748...
1780
            jcc(jle, label);
1748
            X86.SetLabel(label)
1781
            movrc(reg1, param2);
1749
 
1782
            X86.SetLabel(label)
1750
        |IL.opMAXC:
1783
 
1751
            UnOp(reg1);
1784
        |CODE.opMAXC:
1752
            cmprc(reg1, param2);
1785
            UnOp(reg1);
1753
            label := NewLabel();
1786
            cmprc(reg1, param2);
1754
            jcc(jge, label);
1787
            label := NewLabel();
1755
            movrc(reg1, param2);
1788
            jcc(jge, label);
1756
            X86.SetLabel(label)
1789
            movrc(reg1, param2);
1757
 
1790
            X86.SetLabel(label)
1758
        |IL.opSBOOL:
1791
 
1759
            BinOp(reg2, reg1);
1792
        |CODE.opSBOOL:
1760
            test(reg2);
Line 1793... Line 1761...
1793
            BinOp(reg2, reg1);
1761
            IF reg1 >= 8 THEN
1794
            test(reg2);
1762
                OutByte(41H)
1795
            setcc(setne, reg2);
1763
            END;
1796
            movmr8(reg1, 0, reg2);
1764
            OutByte3(0FH, 95H, reg1 MOD 8); // setne byte[reg1]
1797
            drop;
1765
            drop;
1798
            drop
1766
            drop
Line 1847... Line 1815...
1847
                ELSE
1815
                ELSE
1848
                    addrc(reg1, param2)
1816
                    addrc(reg1, param2)
1849
                END
1817
                END
1850
            END
1818
            END
Line 1851... Line 1819...
1851
 
1819
 
1852
        |CODE.opDIV:
1820
        |IL.opDIV:
1853
            PushAll(2);
1821
            PushAll(2);
1854
            CallRTL(CODE._div);
1822
            CallRTL(IL._div);
Line 1855... Line 1823...
1855
            GetRegA
1823
            GetRegA
1856
 
1824
 
1857
        |CODE.opDIVR:
1825
        |IL.opDIVR:
1858
            a := param2;
1826
            a := param2;
1859
            IF a > 1 THEN
1827
            IF a > 1 THEN
1860
                n := X86.log2(a)
1828
                n := UTILS.Log2(a)
1861
            ELSIF a < -1 THEN
1829
            ELSIF a < -1 THEN
1862
                n := X86.log2(-a)
1830
                n := UTILS.Log2(-a)
1863
            ELSE
1831
            ELSE
Line 1864... Line 1832...
1864
                n := -1
1832
                n := -1
Line 1872... Line 1840...
1872
            ELSE
1840
            ELSE
1873
                IF n > 0 THEN
1841
                IF n > 0 THEN
1874
                    UnOp(reg1);
1842
                    UnOp(reg1);
Line 1875... Line 1843...
1875
 
1843
 
1876
                    IF a < 0 THEN
1844
                    IF a < 0 THEN
1877
                        reg2 := REG.GetAnyReg(R);
1845
                        reg2 := GetAnyReg();
1878
                        mov(reg2, reg1);
1846
                        mov(reg2, reg1);
1879
                        shiftrc(sar, reg1, n);
1847
                        shiftrc(sar, reg1, n);
1880
                        sub(reg1, reg2);
1848
                        sub(reg1, reg2);
1881
                        drop
1849
                        drop
Line 1884... Line 1852...
1884
                    END
1852
                    END
Line 1885... Line 1853...
1885
 
1853
 
1886
                ELSE
1854
                ELSE
1887
                    PushAll(1);
1855
                    PushAll(1);
1888
                    pushc(param2);
1856
                    pushc(param2);
1889
                    CallRTL(CODE._div);
1857
                    CallRTL(IL._div);
1890
                    GetRegA
1858
                    GetRegA
1891
                END
1859
                END
Line 1892... Line 1860...
1892
            END
1860
            END
1893
 
1861
 
1894
        |CODE.opDIVL:
1862
        |IL.opDIVL:
1895
            PushAll(1);
1863
            PushAll(1);
1896
            pushc(param2);
1864
            pushc(param2);
Line 1897... Line 1865...
1897
            CallRTL(CODE._div2);
1865
            CallRTL(IL._div2);
1898
            GetRegA
1866
            GetRegA
1899
 
1867
 
1900
        |CODE.opMOD:
1868
        |IL.opMOD:
Line 1901... Line 1869...
1901
            PushAll(2);
1869
            PushAll(2);
1902
            CallRTL(CODE._mod);
1870
            CallRTL(IL._mod);
1903
            GetRegA
1871
            GetRegA
1904
 
1872
 
1905
        |CODE.opMODR:
1873
        |IL.opMODR:
1906
            a := param2;
1874
            a := param2;
1907
            IF a > 1 THEN
1875
            IF a > 1 THEN
1908
                n := X86.log2(a)
1876
                n := UTILS.Log2(a)
1909
            ELSIF a < -1 THEN
1877
            ELSIF a < -1 THEN
Line 1910... Line 1878...
1910
                n := X86.log2(-a)
1878
                n := UTILS.Log2(-a)
Line 1929... Line 1897...
1929
                    END
1897
                    END
Line 1930... Line 1898...
1930
 
1898
 
1931
                ELSE
1899
                ELSE
1932
                    PushAll(1);
1900
                    PushAll(1);
1933
                    pushc(param2);
1901
                    pushc(param2);
1934
                    CallRTL(CODE._mod);
1902
                    CallRTL(IL._mod);
1935
                    GetRegA
1903
                    GetRegA
1936
                END
1904
                END
Line 1937... Line 1905...
1937
            END
1905
            END
1938
 
1906
 
1939
        |CODE.opMODL:
1907
        |IL.opMODL:
1940
            PushAll(1);
1908
            PushAll(1);
1941
            pushc(param2);
1909
            pushc(param2);
Line 1942... Line 1910...
1942
            CallRTL(CODE._mod2);
1910
            CallRTL(IL._mod2);
1943
            GetRegA
1911
            GetRegA
1944
 
1912
 
1945
        |CODE.opMUL:
1913
        |IL.opMUL:
Line 1946... Line 1914...
1946
            BinOp(reg1, reg2);
1914
            BinOp(reg1, reg2);
1947
            oprr2(0FH, 0AFH, reg2, reg1); // imul reg1, reg2
1915
            oprr2(0FH, 0AFH, reg2, reg1); // imul reg1, reg2
Line 1948... Line 1916...
1948
            drop
1916
            drop
1949
 
1917
 
1950
        |CODE.opMULC:
1918
        |IL.opMULC:
1951
            UnOp(reg1);
1919
            UnOp(reg1);
1952
 
1920
 
1953
            a := param2;
1921
            a := param2;
1954
            IF a > 1 THEN
1922
            IF a > 1 THEN
1955
                n := X86.log2(a)
1923
                n := UTILS.Log2(a)
Line 1956... Line 1924...
1956
            ELSIF a < -1 THEN
1924
            ELSIF a < -1 THEN
Line 1977... Line 1945...
1977
                    OutByte2(69H + short(a), 0C0H + (reg1 MOD 8) * 9);
1945
                    OutByte2(69H + short(a), 0C0H + (reg1 MOD 8) * 9);
1978
                    OutIntByte(a)
1946
                    OutIntByte(a)
1979
                END
1947
                END
1980
            END
1948
            END
Line 1981... Line 1949...
1981
 
1949
 
1982
        |CODE.opADDS:
1950
        |IL.opADDS:
1983
            BinOp(reg1, reg2);
1951
            BinOp(reg1, reg2);
1984
            or(reg1, reg2);
1952
            or(reg1, reg2);
Line 1985... Line 1953...
1985
            drop
1953
            drop
1986
 
1954
 
1987
        |CODE.opSUBS:
1955
        |IL.opSUBS:
1988
            BinOp(reg1, reg2);
1956
            BinOp(reg1, reg2);
1989
            not(reg2);
1957
            not(reg2);
Line 1990... Line 1958...
1990
            and(reg1, reg2);
1958
            and(reg1, reg2);
Line 1991... Line 1959...
1991
            drop
1959
            drop
1992
 
1960
 
1993
        |CODE.opNOP:
1961
        |IL.opNOP:
1994
 
1962
 
1995
        |CODE.opSWITCH:
1963
        |IL.opSWITCH:
1996
            UnOp(reg1);
1964
            UnOp(reg1);
Line 2004... Line 1972...
2004
                ASSERT(REG.Exchange(R, reg1, reg2));
1972
                ASSERT(REG.Exchange(R, reg1, reg2));
2005
                drop
1973
                drop
2006
            END;
1974
            END;
2007
            drop
1975
            drop
Line 2008... Line 1976...
2008
 
1976
 
Line 2009... Line 1977...
2009
        |CODE.opENDSW:
1977
        |IL.opENDSW:
2010
 
1978
 
2011
        |CODE.opCASEL:
1979
        |IL.opCASEL:
Line 2012... Line 1980...
2012
            cmprc(rax, param1);
1980
            cmprc(rax, param1);
2013
            jcc(jl, param2)
1981
            jcc(jl, param2)
2014
 
1982
 
Line 2015... Line 1983...
2015
        |CODE.opCASER:
1983
        |IL.opCASER:
2016
            cmprc(rax, param1);
1984
            cmprc(rax, param1);
2017
            jcc(jg, param2)
1985
            jcc(jg, param2)
2018
 
1986
 
Line 2019... Line 1987...
2019
        |CODE.opCASELR:
1987
        |IL.opCASELR:
2020
            cmprc(rax, param1);
1988
            cmprc(rax, param1);
2021
            jcc(jl, param2);
1989
            jcc(jl, param2);
2022
            jcc(jg, cmd.param3)
1990
            jcc(jg, cmd.param3)
2023
 
1991
 
2024
        |CODE.opASR, CODE.opROR, CODE.opLSL, CODE.opLSR:
1992
        |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR:
2025
            BinOp(reg1, reg2);
1993
            BinOp(reg1, reg2);
2026
            xchg(reg2, rcx);
1994
            xchg(reg2, rcx);
Line 2027... Line 1995...
2027
            Rex(reg1, 0);
1995
            Rex(reg1, 0);
2028
            OutByte(0D3H);
1996
            OutByte(0D3H);
2029
            X86.shift(cmd.opcode, reg1 MOD 8); // shift reg1, cl
1997
            X86.shift(opcode, reg1 MOD 8); // shift reg1, cl
2030
            xchg(reg2, rcx);
1998
            xchg(reg2, rcx);
2031
            drop
1999
            drop
2032
 
2000
 
2033
        |CODE.opASR1, CODE.opROR1, CODE.opLSL1, CODE.opLSR1:
2001
        |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1:
2034
            reg1 := REG.GetAnyReg(R);
2002
            reg1 := GetAnyReg();
2035
            movrc(reg1, param2);
2003
            movrc(reg1, param2);
2036
            BinOp(reg1, reg2);
2004
            BinOp(reg1, reg2);
2037
            xchg(reg1, rcx);
2005
            xchg(reg1, rcx);
2038
            Rex(reg2, 0);
2006
            Rex(reg2, 0);
Line 2039... Line 2007...
2039
            OutByte(0D3H);
2007
            OutByte(0D3H);
2040
            X86.shift(cmd.opcode, reg2 MOD 8); // shift reg2, cl
2008
            X86.shift(opcode, reg2 MOD 8); // shift reg2, cl
2041
            xchg(reg1, rcx);
2009
            xchg(reg1, rcx);
Line 2042... Line 2010...
2042
            drop;
2010
            drop;
-
 
2011
            drop;
2043
            drop;
2012
            ASSERT(REG.GetReg(R, reg2))
-
 
2013
 
-
 
2014
        |IL.opASR2, IL.opROR2, IL.opLSL2, IL.opLSR2:
-
 
2015
            UnOp(reg1);
-
 
2016
            shiftrc(opcode, reg1, param2 MOD 64)
-
 
2017
 
2044
            ASSERT(REG.GetReg(R, reg2))
2018
        |IL.opGET, IL.opGETC:
2045
 
2019
            IF opcode = IL.opGET THEN
2046
        |CODE.opASR2, CODE.opROR2, CODE.opLSL2, CODE.opLSR2:
2020
                BinOp(reg1, reg2)
2047
            UnOp(reg1);
2021
            ELSIF opcode = IL.opGETC THEN
Line 2048... Line 2022...
2048
            shiftrc(cmd.opcode, reg1, ORD(BITS(param2) * {0..5}))
2022
                UnOp(reg2);
2049
 
2023
                reg1 := GetAnyReg();
2050
        |CODE.opGET:
2024
                movrc(reg1, param1)
2051
            BinOp(reg1, reg2);
2025
            END;
Line 2052... Line 2026...
2052
            drop;
2026
            drop;
2053
            drop;
2027
            drop;
2054
            _movrm(reg1, reg1, 0, param2 * 8, FALSE);
2028
            _movrm(reg1, reg1, 0, param2 * 8, FALSE);
2055
            _movrm(reg1, reg2, 0, param2 * 8, TRUE)
2029
            _movrm(reg1, reg2, 0, param2 * 8, TRUE)
Line 2056... Line 2030...
2056
 
2030
 
2057
        |CODE.opCHKBYTE:
2031
        |IL.opCHKBYTE:
2058
            BinOp(reg1, reg2);
2032
            BinOp(reg1, reg2);
2059
            cmprc(reg1, 256);
2033
            cmprc(reg1, 256);
2060
            jcc(jb, param1)
2034
            jcc(jb, param1)
2061
 
2035
 
Line 2075... Line 2049...
2075
                INCL(R.regs, reg1);
2049
                INCL(R.regs, reg1);
2076
                DEC(R.top);
2050
                DEC(R.top);
2077
                R.stk[R.top] := reg2
2051
                R.stk[R.top] := reg2
2078
            END
2052
            END
Line 2079... Line 2053...
2079
 
2053
 
2080
        |CODE.opLENGTH:
2054
        |IL.opLENGTH:
2081
            PushAll(2);
2055
            PushAll(2);
2082
            CallRTL(CODE._length);
2056
            CallRTL(IL._length);
Line 2083... Line 2057...
2083
            GetRegA
2057
            GetRegA
2084
 
2058
 
2085
        |CODE.opLENGTHW:
2059
        |IL.opLENGTHW:
2086
            PushAll(2);
2060
            PushAll(2);
Line 2087... Line 2061...
2087
            CallRTL(CODE._lengthw);
2061
            CallRTL(IL._lengthw);
2088
            GetRegA
2062
            GetRegA
2089
 
2063
 
2090
        |CODE.opLEN:
2064
        |IL.opLEN:
2091
            n := param2;
2065
            n := param2;
Line 2100... Line 2074...
2100
            END;
2074
            END;
Line 2101... Line 2075...
2101
 
2075
 
2102
            INCL(R.regs, reg1);
2076
            INCL(R.regs, reg1);
Line 2103... Line 2077...
2103
            ASSERT(REG.GetReg(R, reg1))
2077
            ASSERT(REG.GetReg(R, reg1))
2104
 
2078
 
2105
        |CODE.opCHR:
2079
        |IL.opCHR:
Line 2106... Line 2080...
2106
            UnOp(reg1);
2080
            UnOp(reg1);
2107
            andrc(reg1, 255)
2081
            andrc(reg1, 255)
2108
 
2082
 
Line 2109... Line 2083...
2109
        |CODE.opWCHR:
2083
        |IL.opWCHR:
2110
            UnOp(reg1);
2084
            UnOp(reg1);
2111
            andrc(reg1, 65535)
2085
            andrc(reg1, 65535)
Line 2112... Line 2086...
2112
 
2086
 
2113
        |CODE.opEQP, CODE.opNEP, CODE.opEQIP, CODE.opNEIP:
2087
        |IL.opEQP, IL.opNEP, IL.opEQIP, IL.opNEIP:
2114
            UnOp(reg1);
2088
            UnOp(reg1);
Line 2115... Line 2089...
2115
            reg2 := REG.GetAnyReg(R);
2089
            reg2 := GetAnyReg();
2116
 
2090
 
2117
            CASE cmd.opcode OF
2091
            CASE opcode OF
2118
            |CODE.opEQP, CODE.opNEP:
2092
            |IL.opEQP, IL.opNEP:
Line 2119... Line 2093...
2119
                lea(reg2, param1, sCODE)
2093
                lea(reg2, param1, sCODE)
2120
 
2094
 
2121
            |CODE.opEQIP, CODE.opNEIP:
2095
            |IL.opEQIP, IL.opNEIP:
2122
                lea(reg2, param1, sIMP);
2096
                lea(reg2, param1, sIMP);
Line 2123... Line 2097...
2123
                movrm(reg2, reg2, 0)
2097
                movrm(reg2, reg2, 0)
2124
            END;
2098
            END;
2125
 
2099
 
2126
            cmprr(reg1, reg2);
2100
            cmprr(reg1, reg2);
Line 2127... Line 2101...
2127
            drop;
2101
            drop;
Line 2128... Line -...
2128
            drop;
-
 
2129
            reg1 := REG.GetAnyReg(R);
-
 
2130
 
-
 
2131
            CASE cmd.opcode OF
-
 
2132
            |CODE.opEQP, CODE.opEQIP: setcc(sete,  reg1)
-
 
2133
            |CODE.opNEP, CODE.opNEIP: setcc(setne, reg1)
-
 
2134
            END;
-
 
2135
 
-
 
2136
            andrc(reg1, 1)
2102
            drop;
2137
 
2103
            reg1 := GetAnyReg();
2138
        |CODE.opINC1B, CODE.opDEC1B:
2104
 
2139
            UnOp(reg1);
2105
            CASE opcode OF
2140
            IF reg1 >= 8 THEN
2106
            |IL.opEQP, IL.opEQIP: setcc(sete,  reg1)
2141
                OutByte(41H)
2107
            |IL.opNEP, IL.opNEIP: setcc(setne, reg1)
2142
            END;
2108
            END;
Line 2143... Line 2109...
2143
            OutByte2(0FEH, 8 * ORD(cmd.opcode = CODE.opDEC1B) + reg1 MOD 8); // inc/dec byte[reg1]
2109
 
2144
            drop
2110
            andrc(reg1, 1)
2145
 
2111
 
2146
        |CODE.opINCCB, CODE.opDECCB:
2112
        |IL.opINCCB, IL.opDECCB:
2147
            UnOp(reg1);
2113
            UnOp(reg1);
2148
            IF reg1 >= 8 THEN
2114
            IF reg1 >= 8 THEN
2149
                OutByte(41H)
2115
                OutByte(41H)
2150
            END;
2116
            END;
Line 2151... Line 2117...
2151
            OutByte3(80H, 28H * ORD(cmd.opcode = CODE.opDECCB) + reg1 MOD 8, param2 MOD 256); // add/sub byte[reg1], param2 MOD 256
2117
            OutByte3(80H, 28H * ORD(opcode = IL.opDECCB) + reg1 MOD 8, param2 MOD 256); // add/sub byte[reg1], param2 MOD 256
2152
            drop
2118
            drop
2153
 
2119
 
2154
        |CODE.opINCB, CODE.opDECB:
2120
        |IL.opINCB, IL.opDECB:
2155
            BinOp(reg1, reg2);
2121
            BinOp(reg1, reg2);
2156
            IF (reg1 >= 8) OR (reg2 >= 8) THEN
2122
            IF (reg1 >= 8) OR (reg2 >= 8) THEN
2157
                OutByte(40H + reg2 DIV 8 + 4 * (reg1 DIV 8))
2123
                OutByte(40H + reg2 DIV 8 + 4 * (reg1 DIV 8))
2158
            END;
2124
            END;
2159
            OutByte2(28H * ORD(cmd.opcode = CODE.opDECB), reg2 MOD 8 + 8 * (reg1 MOD 8)); // add/sub byte[reg2], reg1_8
2125
            OutByte2(28H * ORD(opcode = IL.opDECB), reg2 MOD 8 + 8 * (reg1 MOD 8)); // add/sub byte[reg2], reg1_8
2160
            drop;
2126
            drop;
2161
            drop
2127
            drop
2162
 
2128
 
Line 2163... Line 2129...
2163
        |CODE.opSAVEIP:
2129
        |IL.opSAVEIP:
2164
            UnOp(reg1);
2130
            UnOp(reg1);
2165
            reg2 := REG.GetAnyReg(R);
2131
            reg2 := GetAnyReg();
2166
            lea(reg2, param2, sIMP);
2132
            lea(reg2, param2, sIMP);
2167
            movrm(reg2, reg2, 0);
2133
            movrm(reg2, reg2, 0);
Line 2168... Line 2134...
2168
            push(reg2);
2134
            push(reg2);
2169
            drop;
2135
            drop;
Line 2170... Line 2136...
2170
            IF reg1 >= 8 THEN
2136
            IF reg1 >= 8 THEN
2171
                OutByte(41H)
2137
                OutByte(41H)
2172
            END;
2138
            END;
2173
            OutByte2(8FH, reg1 MOD 8); // pop qword[reg1]
2139
            OutByte2(8FH, reg1 MOD 8); // pop qword[reg1]
2174
            drop
2140
            drop
Line 2175... Line 2141...
2175
 
2141
 
2176
        |CODE.opCLEANUP:
2142
        |IL.opCLEANUP:
2177
            n := param2 * 8;
2143
            n := param2 * 8;
2178
            IF n # 0 THEN
2144
            IF n # 0 THEN
Line 2179... Line 2145...
2179
                addrc(rsp, n)
2145
                addrc(rsp, n)
2180
            END
2146
            END
2181
 
2147
 
2182
        |CODE.opPOPSP:
2148
        |IL.opPOPSP:
2183
            pop(rsp)
2149
            pop(rsp)
2184
 
2150
 
2185
        |CODE.opLOADF:
2151
        |IL.opLOADF:
2186
            UnOp(reg1);
2152
            UnOp(reg1);
Line 2187... Line 2153...
2187
            INC(xmm);
2153
            INC(xmm);
2188
            movsdrm(xmm, reg1, 0);
2154
            movsdrm(xmm, reg1, 0);
2189
            drop
2155
            drop
2190
 
2156
 
2191
        |CODE.opPUSHF:
2157
        |IL.opPUSHF:
Line 2192... Line 2158...
2192
            subrc(rsp, 8);
2158
            subrc(rsp, 8);
2193
            movsdmr(rsp, 0, xmm);
2159
            movsdmr(rsp, 0, xmm);
2194
            DEC(xmm)
2160
            DEC(xmm)
Line 2195... Line 2161...
2195
 
2161
 
2196
        |CODE.opCONSTF:
2162
        |IL.opCONSTF:
2197
            float := cmd.float;
2163
            float := cmd.float;
Line 2198... Line 2164...
2198
            INC(xmm);
2164
            INC(xmm);
2199
            reg1 := REG.GetAnyReg(R);
2165
            reg1 := GetAnyReg();
2200
            lea(reg1, Numbers_Offs + Numbers_Count * 8, sDATA);
2166
            lea(reg1, Numbers_Offs + Numbers_Count * 8, sDATA);
2201
            movsdrm(xmm, reg1, 0);
2167
            movsdrm(xmm, reg1, 0);
Line 2202... Line 2168...
2202
            drop;
2168
            drop;
2203
            NewNumber(UTILS.splitf(float, a, b))
2169
            NewNumber(UTILS.splitf(float, a, b))
2204
 
2170
 
Line 2205... Line 2171...
2205
        |CODE.opSAVEF:
2171
        |IL.opSAVEF:
2206
            UnOp(reg1);
2172
            UnOp(reg1);
2207
            movsdmr(reg1, 0, xmm);
2173
            movsdmr(reg1, 0, xmm);
Line 2208... Line 2174...
2208
            DEC(xmm);
2174
            DEC(xmm);
2209
            drop
2175
            drop
2210
 
2176
 
2211
        |CODE.opADDF, CODE.opADDFI:
2177
        |IL.opADDF, IL.opADDFI:
Line 2212... Line 2178...
2212
            opxx(58H, xmm - 1, xmm);
2178
            opxx(58H, xmm - 1, xmm);
2213
            DEC(xmm)
2179
            DEC(xmm)
2214
 
2180
 
2215
        |CODE.opSUBF:
2181
        |IL.opSUBF:
2216
            opxx(5CH, xmm - 1, xmm);
2182
            opxx(5CH, xmm - 1, xmm);
2217
            DEC(xmm)
2183
            DEC(xmm)
Line 2218... Line 2184...
2218
 
2184
 
2219
        |CODE.opSUBFI:
2185
        |IL.opSUBFI:
2220
            opxx(5CH, xmm, xmm - 1);
2186
            opxx(5CH, xmm, xmm - 1);
2221
            opxx(10H, xmm - 1, xmm);
2187
            opxx(10H, xmm - 1, xmm);
2222
            DEC(xmm)
2188
            DEC(xmm)
2223
 
2189
 
Line 2224... Line 2190...
2224
        |CODE.opMULF:
2190
        |IL.opMULF:
2225
            opxx(59H, xmm - 1, xmm);
2191
            opxx(59H, xmm - 1, xmm);
2226
            DEC(xmm)
2192
            DEC(xmm)
2227
 
2193
 
2228
        |CODE.opDIVF:
2194
        |IL.opDIVF:
2229
            opxx(5EH, xmm - 1, xmm);
2195
            opxx(5EH, xmm - 1, xmm);
Line 2230... Line 2196...
2230
            DEC(xmm)
2196
            DEC(xmm)
2231
 
2197
 
2232
        |CODE.opDIVFI:
2198
        |IL.opDIVFI:
2233
            opxx(5EH, xmm, xmm - 1);
2199
            opxx(5EH, xmm, xmm - 1);
2234
            opxx(10H, xmm - 1, xmm);
2200
            opxx(10H, xmm - 1, xmm);
2235
            DEC(xmm)
2201
            DEC(xmm)
2236
 
2202
 
Line 2267... Line 2233...
2267
            OutByte2(2DH, 0C0H + xmm MOD 8 + (reg1 MOD 8) * 8);
2233
            OutByte2(2DH, 0C0H + xmm MOD 8 + (reg1 MOD 8) * 8);
2268
            OutByte3(00FH, 0AEH, 054H); OutByte2(024H, 004H); // ldmxcsr dword[rsp+4];
2234
            OutByte3(00FH, 0AEH, 054H); OutByte2(024H, 004H); // ldmxcsr dword[rsp+4];
2269
            addrc(rsp, 8);
2235
            addrc(rsp, 8);
2270
            DEC(xmm)
2236
            DEC(xmm)
Line 2271... Line 2237...
2271
 
2237
 
2272
        |CODE.opEQF .. CODE.opGEFI:
2238
        |IL.opEQF .. IL.opGEF:
2273
            fcmp(cmd.opcode, xmm);
2239
            fcmp(opcode, xmm);
Line 2274... Line 2240...
2274
            DEC(xmm, 2)
2240
            DEC(xmm, 2)
2275
 
2241
 
2276
        |CODE.opINF:
2242
        |IL.opINF:
2277
            INC(xmm);
2243
            INC(xmm);
2278
            reg1 := REG.GetAnyReg(R);
2244
            reg1 := GetAnyReg();
2279
            lea(reg1, Numbers_Offs + 32, sDATA);
2245
            lea(reg1, Numbers_Offs + 32, sDATA);
Line 2280... Line 2246...
2280
            movsdrm(xmm, reg1, 0);
2246
            movsdrm(xmm, reg1, 0);
2281
            drop
2247
            drop
2282
 
2248
 
2283
        |CODE.opPACK, CODE.opPACKC:
2249
        |IL.opPACK, IL.opPACKC:
2284
            IF cmd.opcode = CODE.opPACK THEN
2250
            IF opcode = IL.opPACK THEN
2285
                BinOp(reg1, reg2)
2251
                BinOp(reg1, reg2)
2286
            ELSE
2252
            ELSE
2287
                UnOp(reg1);
2253
                UnOp(reg1);
2288
                reg2 := REG.GetAnyReg(R);
2254
                reg2 := GetAnyReg();
2289
                movrc(reg2, param2)
2255
                movrc(reg2, param2)
2290
            END;
2256
            END;
Line 2308... Line 2274...
2308
            pop(reg1);
2274
            pop(reg1);
2309
            movmr(reg1, 0, reg2);
2275
            movmr(reg1, 0, reg2);
2310
            drop;
2276
            drop;
2311
            drop
2277
            drop
Line 2312... Line 2278...
2312
 
2278
 
Line 2313... Line 2279...
2313
        |CODE.opUNPK, CODE.opLADR_UNPK:
2279
        |IL.opUNPK, IL.opLADR_UNPK:
2314
 
2280
 
2315
            IF cmd.opcode = CODE.opLADR_UNPK THEN
2281
            IF opcode = IL.opLADR_UNPK THEN
2316
                n := param2 * 8;
2282
                n := param2 * 8;
2317
                UnOp(reg1);
2283
                UnOp(reg1);
2318
                reg2 := REG.GetVarReg(R, param2);
2284
                reg2 := GetVarReg(param2);
2319
                regVar := reg2 # -1;
2285
                regVar := reg2 # -1;
2320
                IF ~regVar THEN
2286
                IF ~regVar THEN
2321
                    reg2 := REG.GetAnyReg(R);
2287
                    reg2 := GetAnyReg();
2322
                    Rex(0, reg2);
2288
                    Rex(0, reg2);
2323
                    OutByte2(8DH, 45H + long(n) + (reg2 MOD 8) * 8);  // lea reg2, qword[rbp+n]
2289
                    OutByte2(8DH, 45H + long(n) + (reg2 MOD 8) * 8);  // lea reg2, qword[rbp+n]
2324
                    OutIntByte(n)
2290
                    OutIntByte(n)
Line 2334... Line 2300...
2334
            shiftrc(shr, reg1, 53);
2300
            shiftrc(shr, reg1, 53);
2335
            subrc(reg1, 1023);
2301
            subrc(reg1, 1023);
Line 2336... Line 2302...
2336
 
2302
 
2337
            IF regVar THEN
2303
            IF regVar THEN
2338
                mov(reg2, reg1);
2304
                mov(reg2, reg1);
2339
                reg2 := REG.GetAnyReg(R)
2305
                reg2 := GetAnyReg()
2340
            ELSE
2306
            ELSE
2341
                movmr(reg2, 0, reg1)
2307
                movmr(reg2, 0, reg1)
Line 2342... Line 2308...
2342
            END;
2308
            END;
Line 2355... Line 2321...
2355
            OutByte2(0F0H + reg1 MOD 8, 3EH); // btr reg1, 62
2321
            OutByte2(0F0H + reg1 MOD 8, 3EH); // btr reg1, 62
2356
            movmr(reg2, 0, reg1);
2322
            movmr(reg2, 0, reg1);
2357
            drop;
2323
            drop;
2358
            drop
2324
            drop
Line 2359... Line 2325...
2359
 
2325
 
2360
        |CODE.opSADR_PARAM:
2326
        |IL.opSADR_PARAM:
Line 2361... Line 2327...
2361
            pushDA(stroffs + param2)
2327
            pushDA(stroffs + param2)
2362
 
2328
 
Line 2363... Line 2329...
2363
        |CODE.opVADR_PARAM:
2329
        |IL.opVADR_PARAM:
2364
            pushm(rbp, param2 * 8)
2330
            pushm(rbp, param2 * 8)
2365
 
2331
 
2366
        |CODE.opLOAD64_PARAM:
2332
        |IL.opLOAD64_PARAM:
Line 2367... Line 2333...
2367
            UnOp(reg1);
2333
            UnOp(reg1);
2368
            pushm(reg1, 0);
2334
            pushm(reg1, 0);
2369
            drop
2335
            drop
2370
 
2336
 
2371
        |CODE.opLLOAD64_PARAM:
2337
        |IL.opLLOAD64_PARAM:
2372
            reg1 := REG.GetVarReg(R, param2);
2338
            reg1 := GetVarReg(param2);
2373
            IF reg1 # -1 THEN
2339
            IF reg1 # -1 THEN
Line 2374... Line 2340...
2374
                push(reg1)
2340
                push(reg1)
2375
            ELSE
2341
            ELSE
2376
                pushm(rbp, param2 * 8)
2342
                pushm(rbp, param2 * 8)
2377
            END
2343
            END
2378
 
2344
 
2379
        |CODE.opGLOAD64_PARAM:
2345
        |IL.opGLOAD64_PARAM:
Line 2380... Line 2346...
2380
            reg2 := REG.GetAnyReg(R);
2346
            reg2 := GetAnyReg();
2381
            lea(reg2, param2, sBSS);
2347
            lea(reg2, param2, sBSS);
Line 2382... Line 2348...
2382
            movrm(reg2, reg2, 0);
2348
            movrm(reg2, reg2, 0);
2383
            push(reg2);
2349
            push(reg2);
2384
            drop
2350
            drop
2385
 
2351
 
2386
        |CODE.opCONST_PARAM:
2352
        |IL.opCONST_PARAM:
2387
            pushc(param2)
2353
            pushc(param2)
2388
 
2354
 
Line 2389... Line 2355...
2389
        |CODE.opGLOAD32_PARAM:
2355
        |IL.opGLOAD32_PARAM:
2390
            reg1 := REG.GetAnyReg(R);
2356
            reg1 := GetAnyReg();
2391
            xor(reg1, reg1);
2357
            xor(reg1, reg1);
2392
            lea(reg1, param2, sBSS);
2358
            lea(reg1, param2, sBSS);
2393
            movrm32(reg1, reg1, 0);
2359
            movrm32(reg1, reg1, 0);
2394
            push(reg1);
2360
            push(reg1);
2395
            drop
2361
            drop
Line 2396... Line 2362...
2396
 
2362
 
2397
        |CODE.opLOAD32_PARAM:
2363
        |IL.opLOAD32_PARAM:
2398
            UnOp(reg1);
2364
            UnOp(reg1);
2399
            movrm32(reg1, reg1, 0);
2365
            movrm32(reg1, reg1, 0);
2400
            shiftrc(shl, reg1, 32);
2366
            shiftrc(shl, reg1, 32);
2401
            shiftrc(shr, reg1, 32);
2367
            shiftrc(shr, reg1, 32);
2402
            push(reg1);
2368
            push(reg1);
2403
            drop
2369
            drop
2404
 
2370
 
2405
        |CODE.opLLOAD32_PARAM:
2371
        |IL.opLLOAD32_PARAM:
2406
            reg1 := REG.GetAnyReg(R);
2372
            reg1 := GetAnyReg();
Line 2407... Line 2373...
2407
            xor(reg1, reg1);
2373
            xor(reg1, reg1);
2408
            reg2 := REG.GetVarReg(R, param2);
2374
            reg2 := GetVarReg(param2);
2409
            IF reg2 # -1 THEN
2375
            IF reg2 # -1 THEN
2410
                mov(reg1, reg2)
2376
                mov(reg1, reg2)
2411
            ELSE
2377
            ELSE
2412
                movrm32(reg1, rbp, param2 * 8)
2378
                movrm32(reg1, rbp, param2 * 8)
2413
            END;
2379
            END;
2414
            push(reg1);
2380
            push(reg1);
2415
            drop
2381
            drop
2416
 
2382
 
2417
        |CODE.opLADR_SAVEC:
2383
        |IL.opLADR_SAVEC:
2418
            n := param1 * 8;
2384
            n := param1 * 8;
2419
            reg1 := REG.GetVarReg(R, param1);
2385
            reg1 := GetVarReg(param1);
2420
            IF reg1 # -1 THEN
2386
            IF reg1 # -1 THEN
2421
                movrc(reg1, param2)
2387
                movrc(reg1, param2)
2422
            ELSE
2388
            ELSE
2423
                IF isLong(param2) THEN
2389
                IF isLong(param2) THEN
Line 2424... Line 2390...
2424
                    reg2 := REG.GetAnyReg(R);
2390
                    reg2 := GetAnyReg();
2425
                    movrc(reg2, param2);
2391
                    movrc(reg2, param2);
2426
                    movmr(rbp, n, reg2);
2392
                    movmr(rbp, n, reg2);
2427
                    drop
2393
                    drop
2428
                ELSE
2394
                ELSE
2429
                    OutByte3(48H, 0C7H, 45H + long(n)); // mov qword[rbp+n],param2
2395
                    OutByte3(48H, 0C7H, 45H + long(n)); // mov qword[rbp+n],param2
2430
                    OutIntByte(n);
2396
                    OutIntByte(n);
2431
                    OutInt(param2)
2397
                    OutInt(param2)
2432
                END
2398
                END
2433
            END
2399
            END
2434
 
2400
 
2435
        |CODE.opGADR_SAVEC:
2401
        |IL.opGADR_SAVEC:
2436
            IF isLong(param2) THEN
2402
            IF isLong(param2) THEN
2437
                reg1 := REG.GetAnyReg(R);
2403
                reg1 := GetAnyReg();
2438
                movrc(reg1, param2);
2404
                movrc(reg1, param2);
2439
                reg2 := REG.GetAnyReg(R);
2405
                reg2 := GetAnyReg();
2440
                lea(reg2, param1, sBSS);
2406
                lea(reg2, param1, sBSS);
Line 2441... Line 2407...
2441
                movmr(reg2, 0, reg1);
2407
                movmr(reg2, 0, reg1);
2442
                drop;
2408
                drop;
2443
                drop
2409
                drop
2444
            ELSE
2410
            ELSE
2445
                reg2 := REG.GetAnyReg(R);
2411
                reg2 := GetAnyReg();
2446
                lea(reg2, param1, sBSS);
2412
                lea(reg2, param1, sBSS);
2447
                Rex(reg2, 0);
2413
                Rex(reg2, 0);
2448
                OutByte2(0C7H, reg2 MOD 8); // mov qword[reg2], param2
2414
                OutByte2(0C7H, reg2 MOD 8); // mov qword[reg2], param2
2449
                OutInt(param2);
2415
                OutInt(param2);
Line 2450... Line 2416...
2450
                drop
2416
                drop
2451
            END
-
 
2452
 
-
 
2453
        |CODE.opLADR_SAVE:
-
 
2454
            UnOp(reg1);
-
 
2455
            reg2 := REG.GetVarReg(R, param2);
-
 
2456
            IF reg2 # -1 THEN
-
 
2457
                mov(reg2, reg1)
-
 
2458
            ELSE
-
 
2459
                movmr(rbp, param2 * 8, reg1)
-
 
2460
            END;
-
 
2461
            drop
-
 
2462
 
-
 
2463
        |CODE.opLADR_INC1:
-
 
2464
            reg1 := REG.GetVarReg(R, param2);
-
 
2465
            IF reg1 # -1 THEN
-
 
2466
                incr(reg1)
-
 
2467
            ELSE
-
 
2468
                n := param2 * 8;
-
 
2469
                OutByte3(48H, 0FFH, 45H + long(n)); // inc qword[rbp+n]
-
 
2470
                OutIntByte(n)
-
 
2471
            END
2417
            END
2472
 
2418
 
2473
        |CODE.opLADR_DEC1:
2419
        |IL.opLADR_SAVE:
2474
            reg1 := REG.GetVarReg(R, param2);
2420
            UnOp(reg1);
2475
            IF reg1 # -1 THEN
2421
            reg2 := GetVarReg(param2);
2476
                decr(reg1)
-
 
2477
            ELSE
-
 
2478
                n := param2 * 8;
-
 
2479
                OutByte3(48H, 0FFH, 4DH + long(n)); // dec qword[rbp+n]
2422
            IF reg2 # -1 THEN
2480
                OutIntByte(n)
-
 
2481
            END
2423
                mov(reg2, reg1)
2482
 
2424
            ELSE
2483
        |CODE.opLADR_INCC, CODE.opLADR_DECC:
2425
                movmr(rbp, param2 * 8, reg1)
2484
            reg1 := REG.GetVarReg(R, param1);
2426
            END;
2485
            IF isLong(param2) THEN
2427
            drop
2486
                reg2 := REG.GetAnyReg(R);
2428
 
2487
                movrc(reg2, param2);
2429
        |IL.opLADR_INCC:
2488
                IF reg1 # -1 THEN
2430
            reg1 := GetVarReg(param1);
2489
                    IF cmd.opcode = CODE.opLADR_DECC THEN
2431
            IF isLong(param2) THEN
2490
                        sub(reg1, reg2)
2432
                reg2 := GetAnyReg();
2491
                    ELSE
2433
                movrc(reg2, param2);
2492
                        add(reg1, reg2)
2434
                IF reg1 # -1 THEN
2493
                    END
2435
                    add(reg1, reg2)
2494
                ELSE
2436
                ELSE
2495
                    n := param1 * 8;
2437
                    n := param1 * 8;
2496
                    Rex(0, reg2);
2438
                    Rex(0, reg2);
2497
                    OutByte2(01H + 28H * ORD(cmd.opcode = CODE.opLADR_DECC), 45H + long(n) + (reg2 MOD 8) * 8);
2439
                    OutByte2(01H, 45H + long(n) + (reg2 MOD 8) * 8);
2498
                    OutIntByte(n) // add/sub qword[rbp+n],reg2
2440
                    OutIntByte(n) // add qword[rbp+n],reg2
2499
                END;
-
 
2500
                drop
-
 
2501
            ELSE
2441
                END;
2502
                IF reg1 # -1 THEN
-
 
2503
                    IF cmd.opcode = CODE.opLADR_DECC THEN
-
 
2504
                        subrc(reg1, param2)
-
 
2505
                    ELSE
-
 
2506
                        addrc(reg1, param2)
-
 
2507
                    END
-
 
2508
                ELSE
2442
                drop
2509
                    n := param1 * 8;
2443
            ELSIF ABS(param2) = 1 THEN
2510
                    OutByte3(48H, 81H + short(param2), 45H + long(n) + 28H * ORD(cmd.opcode = CODE.opLADR_DECC));
-
 
2511
                    OutIntByte(n);
2444
                IF reg1 # -1 THEN
2512
                    OutIntByte(param2) // add/sub qword[rbp+n],param2
2445
                    IF param2 = 1 THEN
2513
                END
2446
                        incr(reg1)
2514
            END
2447
                    ELSE
-
 
2448
                        decr(reg1)
2515
 
2449
                    END
-
 
2450
                ELSE
2516
        |CODE.opLADR_INC1B, CODE.opLADR_DEC1B:
2451
                    n := param1 * 8;
Line 2517... Line 2452...
2517
            reg1 := REG.GetVarReg(R, param2);
2452
                    OutByte3(48H, 0FFH, 45H + 8 * ORD(param2 = -1) + long(n)); // inc/dec qword[rbp+n]
2518
            IF reg1 # -1 THEN
2453
                    OutIntByte(n)
2519
                IF cmd.opcode = CODE.opLADR_DEC1B THEN
2454
                END
2520
                    decr(reg1)
2455
            ELSE
2521
                ELSE
2456
                IF reg1 # -1 THEN
2522
                    incr(reg1)
2457
                    addrc(reg1, param2)
2523
                END;
2458
                ELSE
2524
                andrc(reg1, 255)
2459
                    n := param1 * 8;
2525
            ELSE
2460
                    OutByte3(48H, 81H + short(param2), 45H + long(n));
2526
                n := param2 * 8;
2461
                    OutIntByte(n);
2527
                OutByte2(0FEH, 45H + long(n) + 8 * ORD(cmd.opcode = CODE.opLADR_DEC1B));
2462
                    OutIntByte(param2) // add qword[rbp+n],param2
2528
                OutIntByte(n)  // inc/dec byte[rbp+n]
2463
                END
2529
            END
2464
            END
2530
 
2465
 
2531
        |CODE.opLADR_INCCB, CODE.opLADR_DECCB:
2466
        |IL.opLADR_INCCB, IL.opLADR_DECCB:
2532
            reg1 := REG.GetVarReg(R, param1);
2467
            reg1 := GetVarReg(param1);
Line 2533... Line 2468...
2533
            param2 := param2 MOD 256;
2468
            param2 := param2 MOD 256;
2534
            IF reg1 # -1 THEN
2469
            IF reg1 # -1 THEN
2535
                IF cmd.opcode = CODE.opLADR_DECCB THEN
2470
                IF opcode = IL.opLADR_DECCB THEN
2536
                    subrc(reg1, param2)
2471
                    subrc(reg1, param2)
2537
                ELSE
2472
                ELSE
2538
                    addrc(reg1, param2)
2473
                    addrc(reg1, param2)
2539
                END;
2474
                END;
2540
                andrc(reg1, 255)
2475
                andrc(reg1, 255)
2541
            ELSE
2476
            ELSE
2542
                n := param1 * 8;
2477
                n := param1 * 8;
2543
                OutByte2(80H, 45H + long(n) + 28H * ORD(cmd.opcode = CODE.opLADR_DECCB));
2478
                OutByte2(80H, 45H + long(n) + 28H * ORD(opcode = IL.opLADR_DECCB));
2544
                OutIntByte(n);
2479
                OutIntByte(n);
2545
                OutByte(param2) // add/sub byte[rbp+n],param2
2480
                OutByte(param2) // add/sub byte[rbp+n],param2
2546
            END
2481
            END
2547
 
2482
 
2548
        |CODE.opLADR_INC, CODE.opLADR_DEC:
2483
        |IL.opLADR_INC, IL.opLADR_DEC:
Line 2549... Line 2484...
2549
            UnOp(reg1);
2484
            UnOp(reg1);
2550
            reg2 := REG.GetVarReg(R, param2);
2485
            reg2 := GetVarReg(param2);
2551
            IF reg2 # -1 THEN
2486
            IF reg2 # -1 THEN
2552
                IF cmd.opcode = CODE.opLADR_DEC THEN
2487
                IF opcode = IL.opLADR_DEC THEN
2553
                    sub(reg2, reg1)
2488
                    sub(reg2, reg1)
2554
                ELSE
2489
                ELSE
2555
                    add(reg2, reg1)
2490
                    add(reg2, reg1)
2556
                END
2491
                END
2557
            ELSE
2492
            ELSE
2558
                n := param2 * 8;
2493
                n := param2 * 8;
2559
                Rex(0, reg1);
2494
                Rex(0, reg1);
2560
                OutByte2(01H + 28H * ORD(cmd.opcode = CODE.opLADR_DEC), 45H + long(n) + (reg1 MOD 8) * 8);
2495
                OutByte2(01H + 28H * ORD(opcode = IL.opLADR_DEC), 45H + long(n) + (reg1 MOD 8) * 8);
2561
                OutIntByte(n) // add/sub qword[rbp+n],reg1
2496
                OutIntByte(n) // add/sub qword[rbp+n],reg1
2562
            END;
2497
            END;
2563
            drop
2498
            drop
2564
 
2499
 
2565
        |CODE.opLADR_INCB, CODE.opLADR_DECB:
2500
        |IL.opLADR_INCB, IL.opLADR_DECB:
2566
            UnOp(reg1);
2501
            UnOp(reg1);
2567
            reg2 := REG.GetVarReg(R, param2);
2502
            reg2 := GetVarReg(param2);
Line 2568... Line 2503...
2568
            IF reg2 # -1 THEN
2503
            IF reg2 # -1 THEN
2569
                IF cmd.opcode = CODE.opLADR_DECB THEN
2504
                IF opcode = IL.opLADR_DECB THEN
2570
                    sub(reg2, reg1)
2505
                    sub(reg2, reg1)
2571
                ELSE
2506
                ELSE
2572
                    add(reg2, reg1)
2507
                    add(reg2, reg1)
2573
                END;
2508
                END;
2574
                andrc(reg2, 255)
2509
                andrc(reg2, 255)
2575
            ELSE
2510
            ELSE
2576
                n := param2 * 8;
2511
                n := param2 * 8;
2577
                IF reg1 >= 8 THEN
2512
                IF reg1 >= 8 THEN
2578
                    OutByte(44H)
2513
                    OutByte(44H)
2579
                END;
2514
                END;
2580
                OutByte2(28H * ORD(cmd.opcode = CODE.opLADR_DECB), 45H + long(n) + 8 * (reg1 MOD 8));
2515
                OutByte2(28H * ORD(opcode = IL.opLADR_DECB), 45H + long(n) + 8 * (reg1 MOD 8));
2581
                OutIntByte(n) // add/sub byte[rbp+n], reg1_8
2516
                OutIntByte(n) // add/sub byte[rbp+n], reg1_8
2582
            END;
2517
            END;
2583
            drop
2518
            drop
Line 2584... Line 2519...
2584
 
2519
 
2585
        |CODE.opLADR_INCL, CODE.opLADR_EXCL:
2520
        |IL.opLADR_INCL, IL.opLADR_EXCL:
2586
            UnOp(reg1);
2521
            UnOp(reg1);
2587
            cmprc(reg1, 64);
2522
            cmprc(reg1, 64);
2588
            reg2 := REG.GetVarReg(R, param2);
2523
            reg2 := GetVarReg(param2);
2589
            IF reg2 # -1 THEN
2524
            IF reg2 # -1 THEN
2590
                OutByte2(73H, 4); // jnb L
2525
                OutByte2(73H, 4); // jnb L
2591
                oprr2(0FH, 0ABH + 8 * ORD(cmd.opcode = CODE.opLADR_EXCL), reg2, reg1) // bts/btr reg2, reg1
2526
                oprr2(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), reg2, reg1) // bts/btr reg2, reg1
2592
            ELSE
2527
            ELSE
2593
                n := param2 * 8;
2528
                n := param2 * 8;
2594
                OutByte2(73H, 5 + 3 * ORD(~isByte(n))); // jnb L
2529
                OutByte2(73H, 5 + 3 * ORD(~isByte(n))); // jnb L
2595
                Rex(0, reg1);
2530
                Rex(0, reg1);
2596
                OutByte3(0FH, 0ABH + 8 * ORD(cmd.opcode = CODE.opLADR_EXCL), 45H + long(n) + 8 * (reg1 MOD 8));
2531
                OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), 45H + long(n) + 8 * (reg1 MOD 8));
Line 2597... Line 2532...
2597
                OutIntByte(n) // bts/btr qword[rbp+n], reg1
2532
                OutIntByte(n) // bts/btr qword[rbp+n], reg1
Line 2598... Line 2533...
2598
            END;
2533
            END;
Line 2599... Line 2534...
2599
            // L:
2534
            // L:
2600
            drop
2535
            drop
Line 2624... Line 2559...
2624
    ASSERT(R.top = -1);
2559
    ASSERT(R.top = -1);
2625
    ASSERT(xmm = -1)
2560
    ASSERT(xmm = -1)
2626
END translate;
2561
END translate;
Line 2627... Line 2562...
2627
 
2562
 
2628
 
2563
 
2629
PROCEDURE prolog (code: CODE.CODES; modname: ARRAY OF CHAR; target, stack_size: INTEGER);
2564
PROCEDURE prolog (code: IL.CODES; modname: ARRAY OF CHAR; target, stack_size: INTEGER);
Line 2630... Line 2565...
2630
VAR
2565
VAR
2631
    ModName_Offs, entry: INTEGER;
2566
    ModName_Offs, entry, L: INTEGER;
2632
 
2567
 
2633
BEGIN
2568
BEGIN
Line 2634... Line 2569...
2634
    ModName_Offs := CHL.Length(code.types) * 8 + CHL.Length(code.data);
2569
    ModName_Offs := tcount * 8 + CHL.Length(code.data);
2635
    Numbers_Offs := ModName_Offs + LENGTH(modname) + 1;
2570
    Numbers_Offs := ModName_Offs + LENGTH(modname) + 1;
Line 2636... Line 2571...
2636
    ASSERT(MACHINE.Align(Numbers_Offs, 16));
2571
    ASSERT(UTILS.Align(Numbers_Offs, 16));
2637
 
2572
 
2638
    entry := NewLabel();
2573
    entry := NewLabel();
2639
    X86.SetLabel(entry);
2574
    X86.SetLabel(entry);
2640
 
2575
 
2641
    IF target = mConst.Target_iDLL64 THEN
2576
    IF target = mConst.Target_iDLL64 THEN
2642
        dllret := NewLabel();
2577
        dllret := NewLabel();
2643
        push(r8);
2578
        push(r8);
2644
        push(rdx);
2579
        push(rdx);
Line -... Line 2580...
-
 
2580
        push(rcx);
2645
        push(rcx);
2581
        CallRTL(IL._dllentry);
-
 
2582
        test(rax);
-
 
2583
        jcc(je, dllret)
-
 
2584
    END;
-
 
2585
 
2646
        CallRTL(CODE._dllentry);
2586
    IF target = mConst.Target_iELF64 THEN
2647
        test(rax);
2587
        push(rsp)
2648
        jcc(je, dllret)
2588
    ELSE
2649
    END;
2589
        pushc(0)
2650
 
2590
    END;
2651
    push(rsp);
2591
 
-
 
2592
    lea(rax, entry, sCODE);
-
 
2593
    push(rax);
-
 
2594
    pushDA(0); //TYPES
-
 
2595
    pushc(tcount);
-
 
2596
    pushDA(ModName_Offs); //MODNAME
-
 
2597
    CallRTL(IL._init);
-
 
2598
 
-
 
2599
    IF target IN {mConst.Target_iConsole64, mConst.Target_iGUI64} THEN
-
 
2600
        L := NewLabel();
-
 
2601
        pushc(0);
-
 
2602
        push(rsp);
-
 
2603
        pushc(1024 * 1024 * stack_size);
-
 
2604
        pushc(0);
-
 
2605
        CallRTL(IL._new);
-
 
2606
        pop(rax);
2652
    lea(rax, entry, sCODE);
2607
        test(rax);
Line 2653... Line 2608...
2653
    push(rax);
2608
        jcc(je, L);
2654
    pushDA(0); //TYPES
2609
        addrc(rax, 1024 * 1024 * stack_size - 8);
2655
    pushc(CHL.Length(code.types));
2610
        mov(rsp, rax);
2656
    pushDA(ModName_Offs); //MODNAME
2611
        X86.SetLabel(L)
2657
    CallRTL(CODE._init)
2612
    END
Line 2658... Line 2613...
2658
END prolog;
2613
END prolog;
2659
 
2614
 
2660
 
2615
 
2661
PROCEDURE epilog (code: CODE.CODES; modname: ARRAY OF CHAR; target: INTEGER);
2616
PROCEDURE epilog (code: IL.CODES; modname: ARRAY OF CHAR; target: INTEGER);
Line 2662... Line 2617...
2662
VAR
2617
VAR
Line 2663... Line 2618...
2663
    i, n: INTEGER;
2618
    i, n: INTEGER;
2664
    number: Number;
2619
    number: Number;
2665
    exp: CODE.EXPORT_PROC;
2620
    exp: IL.EXPORT_PROC;
2666
 
2621
 
2667
 
2622
 
2668
    PROCEDURE import (imp: LISTS.LIST);
2623
    PROCEDURE import (imp: LISTS.LIST);
2669
    VAR
2624
    VAR
2670
        lib:  CODE.IMPORT_LIB;
2625
        lib:  IL.IMPORT_LIB;
2671
        proc: CODE.IMPORT_PROC;
2626
        proc: IL.IMPORT_PROC;
2672
 
2627
 
Line 2673... Line 2628...
2673
    BEGIN
2628
    BEGIN
Line 2674... Line 2629...
2674
 
2629
 
2675
        lib := imp.first(CODE.IMPORT_LIB);
2630
        lib := imp.first(IL.IMPORT_LIB);
2676
        WHILE lib # NIL DO
2631
        WHILE lib # NIL DO
2677
            BIN.Import(prog, lib.name, 0);
2632
            BIN.Import(prog, lib.name, 0);
-
 
2633
            proc := lib.procs.first(IL.IMPORT_PROC);
-
 
2634
            WHILE proc # NIL DO
-
 
2635
                BIN.Import(prog, proc.name, proc.label);
-
 
2636
                proc := proc.next(IL.IMPORT_PROC)
-
 
2637
            END;
-
 
2638
            lib := lib.next(IL.IMPORT_LIB)
2678
            proc := lib.procs.first(CODE.IMPORT_PROC);
2639
        END
2679
            WHILE proc # NIL DO
2640
 
2680
                BIN.Import(prog, proc.name, proc.label);
2641
    END import;
2681
                proc := proc.next(CODE.IMPORT_PROC)
2642
 
Line 2682... Line 2643...
2682
            END;
2643
 
Line 2683... Line 2644...
2683
            lib := lib.next(CODE.IMPORT_LIB)
2644
BEGIN
2684
        END
2645
    IF target = mConst.Target_iDLL64 THEN
2685
 
2646
        X86.SetLabel(dllret);
2686
    END import;
2647
        OutByte(0C3H) // ret
2687
 
2648
    ELSIF target = mConst.Target_iELFSO64 THEN
Line 2688... Line 2649...
2688
 
2649
        sofinit := NewLabel();
Line 2710... Line 2671...
2710
    END;
2671
    END;
Line 2711... Line 2672...
2711
 
2672
 
2712
    BIN.PutDataStr(prog, modname);
2673
    BIN.PutDataStr(prog, modname);
2713
    BIN.PutData(prog, 0);
2674
    BIN.PutData(prog, 0);
2714
    n := CHL.Length(prog.data);
2675
    n := CHL.Length(prog.data);
2715
    ASSERT(MACHINE.Align(n, 16));
2676
    ASSERT(UTILS.Align(n, 16));
2716
    i := n - CHL.Length(prog.data);
2677
    i := n - CHL.Length(prog.data);
2717
    WHILE i > 0 DO
2678
    WHILE i > 0 DO
2718
        BIN.PutData(prog, 0);
2679
        BIN.PutData(prog, 0);
2719
        DEC(i)
2680
        DEC(i)
Line 2722... Line 2683...
2722
    FOR i := 0 TO Numbers_Count - 1 DO
2683
    FOR i := 0 TO Numbers_Count - 1 DO
2723
        BIN.PutData64LE(prog, number.value);
2684
        BIN.PutData64LE(prog, number.value);
2724
        number := number.next(Number)
2685
        number := number.next(Number)
2725
    END;
2686
    END;
Line 2726... Line 2687...
2726
 
2687
 
2727
    exp := code.export.first(CODE.EXPORT_PROC);
2688
    exp := code.export.first(IL.EXPORT_PROC);
2728
    WHILE exp # NIL DO
2689
    WHILE exp # NIL DO
2729
        BIN.Export(prog, exp.name, exp.label);
2690
        BIN.Export(prog, exp.name, exp.label);
2730
        exp := exp.next(CODE.EXPORT_PROC)
2691
        exp := exp.next(IL.EXPORT_PROC)
Line 2731... Line 2692...
2731
    END;
2692
    END;
2732
 
2693
 
Line 2756... Line 2717...
2756
    |8: movmr(rbp, offs, reg)
2717
    |8: movmr(rbp, offs, reg)
2757
    END
2718
    END
2758
END rsave;
2719
END rsave;
Line 2759... Line 2720...
2759
 
2720
 
2760
 
2721
 
2761
PROCEDURE CodeGen* (code: CODE.CODES; outname: ARRAY OF CHAR; target, stack, base: INTEGER);
2722
PROCEDURE CodeGen* (code: IL.CODES; outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
2762
VAR
-
 
Line 2763... Line 2723...
2763
    path, modname, ext: PATHS.PATH;
2723
VAR
-
 
2724
    path, modname, ext: PATHS.PATH;
-
 
2725
 
2764
    n: INTEGER;
2726
BEGIN
2765
 
2727
    tcount := CHL.Length(code.types);
2766
BEGIN
2728
 
2767
    Win64RegPar[0] := rcx;
2729
    Win64RegPar[0] := rcx;
Line 2777... Line 2739...
2777
    SystemVRegPar[5] := r9;
2739
    SystemVRegPar[5] := r9;
Line 2778... Line 2740...
2778
 
2740
 
2779
    PATHS.split(outname, path, modname, ext);
2741
    PATHS.split(outname, path, modname, ext);
Line 2780... Line 2742...
2780
    S.append(modname, ext);
2742
    S.append(modname, ext);
Line 2781... Line 2743...
2781
 
2743
 
2782
    R := REG.Create(push, pop, mov, xchg, rload, rsave, {rax, r10, r11}, {rcx, rdx, r8, r9});
-
 
2783
 
-
 
2784
    n := code.dmin - CHL.Length(code.data);
-
 
2785
    IF n > 0 THEN
-
 
Line 2786... Line 2744...
2786
        INC(code.bss, n)
2744
    REG.Init(R, push, pop, mov, xchg, rload, rsave, {rax, r10, r11}, {rcx, rdx, r8, r9});
2787
    END;
2745
 
2788
    code.bss := MAX(code.bss, 8);
2746
    code.bss := MAX(code.bss, MAX(code.dmin - CHL.Length(code.data), 8));
2789
 
2747
 
Line 2796... Line 2754...
2796
    NewNumber(ROR(7FFH, 12));  (* +Infinity *)
2754
    NewNumber(ROR(7FFH, 12));  (* +Infinity *)
2797
    NewNumber(ORD(-BITS(LSR(ASR(ROR(1, 1), 10), 1))));  (* {0..51, 63} *)
2755
    NewNumber(ORD(-BITS(LSR(ASR(ROR(1, 1), 10), 1))));  (* {0..51, 63} *)
2798
    NewNumber(LSR(ASR(ROR(1, 1), 9), 2));  (* {52..61} *)
2756
    NewNumber(LSR(ASR(ROR(1, 1), 9), 2));  (* {52..61} *)
Line 2799... Line 2757...
2799
 
2757
 
2800
    prog := BIN.create(code.lcount);
2758
    prog := BIN.create(code.lcount);
Line 2801... Line 2759...
2801
    BIN.SetParams(prog, code.bss, stack, WCHR(1), WCHR(0));
2759
    BIN.SetParams(prog, code.bss, 1, WCHR(1), WCHR(0));
Line 2802... Line 2760...
2802
 
2760
 
2803
    X86.SetProgram(prog);
2761
    X86.SetProgram(prog);
2804
 
2762
 
Line 2805... Line 2763...
2805
    prolog(code, modname, target, stack);
2763
    prolog(code, modname, target, options.stack);
2806
    translate(code.commands, CHL.Length(code.types) * 8);
2764
    translate(code.commands, tcount * 8);
2807
    epilog(code, modname, target);
2765
    epilog(code, modname, target);
2808
 
2766
 
2809
    BIN.fixup(prog);
2767
    BIN.fixup(prog);
2810
    IF target IN {mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64} THEN
2768
    IF target IN {mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64} THEN
2811
        PE32.write(prog, outname, base, target = mConst.Target_iConsole64, target = mConst.Target_iDLL64, TRUE)
2769
        PE32.write(prog, outname, options.base, target = mConst.Target_iConsole64, target = mConst.Target_iDLL64, TRUE)
Line 2812... Line 2770...
2812
    ELSIF target = mConst.Target_iELF64 THEN
2770
    ELSIF target IN {mConst.Target_iELF64, mConst.Target_iELFSO64} THEN
2813
        ELF.write(prog, outname, TRUE)
2771
        ELF.write(prog, outname, sofinit, target = mConst.Target_iELFSO64, TRUE)