Subversion Repositories Kolibri OS

Rev

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

Rev 8097 Rev 8859
Line 1... Line 1...
1
(*
1
(*
2
    BSD 2-Clause License
2
    BSD 2-Clause License
Line 3... Line 3...
3
 
3
 
4
    Copyright (c) 2018-2020, Anton Krotov
4
    Copyright (c) 2018-2021, Anton Krotov
5
    All rights reserved.
5
    All rights reserved.
Line 6... Line 6...
6
*)
6
*)
Line 270... Line 270...
270
PROCEDURE GetAnyReg (): INTEGER;
270
PROCEDURE GetAnyReg (): INTEGER;
271
    RETURN REG.GetAnyReg(R)
271
    RETURN REG.GetAnyReg(R)
272
END GetAnyReg;
272
END GetAnyReg;
Line 273... Line -...
273
 
-
 
274
 
-
 
275
PROCEDURE GetVarReg (offs: INTEGER): INTEGER;
-
 
276
    RETURN REG.GetVarReg(R, offs)
-
 
277
END GetVarReg;
-
 
278
 
273
 
279
 
274
 
280
PROCEDURE callimp (label: INTEGER);
275
PROCEDURE callimp (label: INTEGER);
281
BEGIN
276
BEGIN
282
    OutByte2(0FFH, 15H);    (* call qword[rip + label + IMP] *)
277
    OutByte2(0FFH, 15H);    (* call qword[rip + label + IMP] *)
Line 299... Line 294...
299
PROCEDURE CallRTL (proc: INTEGER);
294
PROCEDURE CallRTL (proc: INTEGER);
300
VAR
295
VAR
301
    label: INTEGER;
296
    label: INTEGER;
Line 302... Line 297...
302
 
297
 
303
BEGIN
-
 
304
    REG.Store(R);
298
BEGIN
305
    label := IL.codes.rtl[proc];
299
    label := IL.codes.rtl[proc];
306
    IF label < 0 THEN
300
    IF label < 0 THEN
307
        callimp(-label)
301
        callimp(-label)
308
    ELSE
302
    ELSE
309
        X86.call(label)
303
        X86.call(label)
310
    END;
-
 
311
    REG.Restore(R)
304
    END
Line 312... Line 305...
312
END CallRTL;
305
END CallRTL;
313
 
306
 
Line 565... Line 558...
565
        OutByte(n)
558
        OutByte(n)
566
    END
559
    END
567
END shiftrc;
560
END shiftrc;
Line 568... Line -...
568
 
-
 
569
 
-
 
570
PROCEDURE getVar (variables: LISTS.LIST; offset: INTEGER): IL.LOCALVAR;
-
 
571
VAR
-
 
572
    cur: IL.LOCALVAR;
-
 
573
 
-
 
574
BEGIN
-
 
575
    cur := variables.first(IL.LOCALVAR);
-
 
576
    WHILE (cur # NIL) & (cur.offset # offset) DO
-
 
577
        cur := cur.next(IL.LOCALVAR)
-
 
578
    END
-
 
579
 
-
 
580
    RETURN cur
-
 
581
END getVar;
-
 
582
 
-
 
583
 
-
 
584
PROCEDURE allocReg (cmd: COMMAND);
-
 
585
VAR
-
 
586
    leave:      BOOLEAN;
-
 
587
    leaf:       BOOLEAN;
-
 
588
    cur:        COMMAND;
-
 
589
    variables:  LISTS.LIST;
-
 
590
    lvar, rvar: IL.LOCALVAR;
-
 
591
    reg:        INTEGER;
-
 
592
    max:        INTEGER;
-
 
593
    loop:       INTEGER;
-
 
594
 
-
 
595
BEGIN
-
 
596
    loop := 1;
-
 
597
    variables := cmd.variables;
-
 
598
    leave := FALSE;
-
 
599
    leaf := TRUE;
-
 
600
 
-
 
601
    cur := cmd.next(COMMAND);
-
 
602
    REPEAT
-
 
603
        CASE cur.opcode OF
-
 
604
        |IL.opLLOAD64,
-
 
605
         IL.opLLOAD8,
-
 
606
         IL.opLLOAD16,
-
 
607
         IL.opLLOAD32,
-
 
608
         IL.opLLOAD64_PARAM,
-
 
609
         IL.opLLOAD32_PARAM,
-
 
610
         IL.opLADR_SAVE,
-
 
611
         IL.opLADR_INC,
-
 
612
         IL.opLADR_DEC,
-
 
613
         IL.opLADR_INCB,
-
 
614
         IL.opLADR_DECB,
-
 
615
         IL.opLADR_INCL,
-
 
616
         IL.opLADR_EXCL,
-
 
617
         IL.opLADR_UNPK:
-
 
618
            lvar := getVar(variables, cur.param2);
-
 
619
            IF (lvar # NIL) & (lvar.count # -1) THEN
-
 
620
                INC(lvar.count, loop)
-
 
621
            END
-
 
622
 
-
 
623
        |IL.opLADR_SAVEC,
-
 
624
         IL.opLADR_INCC,
-
 
625
         IL.opLADR_INCCB,
-
 
626
         IL.opLADR_DECCB,
-
 
627
         IL.opLADR_INCLC,
-
 
628
         IL.opLADR_EXCLC:
-
 
629
            lvar := getVar(variables, cur.param1);
-
 
630
            IF (lvar # NIL) & (lvar.count # -1) THEN
-
 
631
                INC(lvar.count, loop)
-
 
632
            END
-
 
633
 
-
 
634
        |IL.opLADR:
-
 
635
            lvar := getVar(variables, cur.param2);
-
 
636
            IF (lvar # NIL) & (lvar.count # -1) THEN
-
 
637
                lvar.count := -1
-
 
638
            END
-
 
639
 
-
 
640
        |IL.opLOOP:
-
 
641
            INC(loop, 10)
-
 
642
 
-
 
643
        |IL.opENDLOOP:
-
 
644
            DEC(loop, 10)
-
 
645
 
-
 
646
        |IL.opLEAVE,
-
 
647
         IL.opLEAVER,
-
 
648
         IL.opLEAVEF:
-
 
649
            leave := TRUE
-
 
650
 
-
 
651
        |IL.opCALL, IL.opCALLP, IL.opCALLI,
-
 
652
         IL.opWIN64CALL, IL.opWIN64CALLP, IL.opWIN64CALLI,
-
 
653
         IL.opSYSVCALL, IL.opSYSVCALLP, IL.opSYSVCALLI,
-
 
654
 
-
 
655
         IL.opSAVES, IL.opRSET, IL.opRSETR,
-
 
656
         IL.opRSETL, IL.opRSET1,
-
 
657
         IL.opEQS .. IL.opGES,
-
 
658
         IL.opEQSW .. IL.opGESW,
-
 
659
         IL.opCOPY, IL.opMOVE, IL.opCOPYA,
-
 
660
         IL.opCOPYS, IL.opROT,
-
 
661
         IL.opNEW, IL.opDISP, IL.opISREC,
-
 
662
         IL.opIS, IL.opTYPEGR, IL.opTYPEGP,
-
 
663
         IL.opTYPEGD, IL.opCASET, IL.opDIV,
-
 
664
         IL.opDIVL, IL.opMOD,
-
 
665
         IL.opMODL, IL.opLENGTH, IL.opLENGTHW:
-
 
666
            leaf := FALSE
-
 
667
 
-
 
668
        |IL.opDIVR, IL.opMODR:
-
 
669
            leaf := UTILS.Log2(cur.param2) >= 0
-
 
670
 
-
 
671
        ELSE
-
 
672
 
-
 
673
        END;
-
 
674
        cur := cur.next(COMMAND)
-
 
675
    UNTIL leave OR ~leaf;
-
 
676
 
-
 
677
    IF leaf THEN
-
 
678
        REPEAT
-
 
679
            reg := -1;
-
 
680
            max := -1;
-
 
681
            rvar := NIL;
-
 
682
            lvar := variables.first(IL.LOCALVAR);
-
 
683
            WHILE lvar # NIL DO
-
 
684
                IF lvar.count > max THEN
-
 
685
                    max := lvar.count;
-
 
686
                    rvar := lvar
-
 
687
                END;
-
 
688
                lvar := lvar.next(IL.LOCALVAR)
-
 
689
            END;
-
 
690
 
-
 
691
            IF rvar # NIL THEN
-
 
692
                reg := REG.GetAnyVarReg(R);
-
 
693
                IF reg # -1 THEN
-
 
694
                    REG.Lock(R, reg, rvar.offset, rvar.size);
-
 
695
                    REG.Load(R, reg);
-
 
696
                    rvar.count := -1
-
 
697
                END
-
 
698
            END
-
 
699
 
-
 
700
        UNTIL (rvar = NIL) OR (reg = -1)
-
 
701
    END
-
 
702
 
-
 
703
END allocReg;
-
 
704
 
561
 
705
 
562
 
706
PROCEDURE GetRegA;
563
PROCEDURE GetRegA;
707
BEGIN
564
BEGIN
Line 731... Line 588...
731
    n, i, s, p, ofs: INTEGER;
588
    n, i, s, p, ofs: INTEGER;
732
    i_count, f_count: INTEGER;
589
    i_count, f_count: INTEGER;
733
    reg: BOOLEAN;
590
    reg: BOOLEAN;
Line 734... Line 591...
734
 
591
 
735
BEGIN
592
BEGIN
736
    ASSERT(r10 IN R.regs);
593
    ASSERT(r11 IN R.regs);
737
    n := params MOD 32;
594
    n := params MOD 32;
738
    params := params DIV 32;
595
    params := params DIV 32;
Line 739... Line 596...
739
    s := 0;
596
    s := 0;
Line 770... Line 627...
770
                INC(i_count)
627
                INC(i_count)
771
            END
628
            END
772
        END;
629
        END;
Line 773... Line 630...
773
 
630
 
774
        IF ~reg THEN
631
        IF ~reg THEN
775
            movrm(r10, rsp, ofs);
632
            movrm(r11, rsp, ofs);
776
            movmr(rsp, p, r10);
633
            movmr(rsp, p, r11);
777
            INC(p, 8)
634
            INC(p, 8)
778
        END
635
        END
779
    END
636
    END
Line 826... Line 683...
826
 
683
 
Line 827... Line 684...
827
    reg1, reg2, xmm: INTEGER;
684
    reg1, reg2, xmm: INTEGER;
Line 828... Line -...
828
 
-
 
829
    float: REAL;
-
 
830
 
685
 
831
    regVar: BOOLEAN;
686
    float: REAL;
832
 
687
 
833
BEGIN
688
BEGIN
Line 844... Line 699...
844
 
699
 
845
        |IL.opJMP:
700
        |IL.opJMP:
Line 846... Line 701...
846
            X86.jmp(param1)
701
            X86.jmp(param1)
847
 
-
 
848
        |IL.opCALL, IL.opWIN64CALL, IL.opSYSVCALL:
702
 
849
            REG.Store(R);
703
        |IL.opCALL, IL.opWIN64CALL, IL.opSYSVCALL:
850
            CASE opcode OF
704
            CASE opcode OF
851
            |IL.opCALL:
705
            |IL.opCALL:
852
            |IL.opWIN64CALL: Win64Passing(param2)
706
            |IL.opWIN64CALL: Win64Passing(param2)
853
            |IL.opSYSVCALL:  SysVPassing(param2)
707
            |IL.opSYSVCALL:  SysVPassing(param2)
854
            END;
-
 
Line 855... Line 708...
855
            X86.call(param1);
708
            END;
856
            REG.Restore(R)
709
            X86.call(param1)
857
 
710
 
858
        |IL.opCALLP, IL.opWIN64CALLP, IL.opSYSVCALLP:
711
        |IL.opCALLP, IL.opWIN64CALLP, IL.opSYSVCALLP:
859
            UnOp(reg1);
-
 
860
            IF reg1 # rax THEN
-
 
861
                GetRegA;
712
            UnOp(reg1);
862
                ASSERT(REG.Exchange(R, reg1, rax));
713
            IF reg1 # rax THEN
863
                drop
-
 
864
            END;
714
                mov(rax, reg1)
865
            drop;
715
            END;
866
            REG.Store(R);
716
            drop;
867
            CASE opcode OF
717
            CASE opcode OF
868
            |IL.opCALLP:
718
            |IL.opCALLP:
869
            |IL.opWIN64CALLP: Win64Passing(param2)
719
            |IL.opWIN64CALLP: Win64Passing(param2)
870
            |IL.opSYSVCALLP:  SysVPassing(param2)
-
 
871
            END;
720
            |IL.opSYSVCALLP:  SysVPassing(param2)
Line 872... Line 721...
872
            OutByte2(0FFH, 0D0H); (* call rax *)
721
            END;
873
            REG.Restore(R);
-
 
874
            ASSERT(R.top = -1)
722
            OutByte2(0FFH, 0D0H); (* call rax *)
875
 
723
            ASSERT(R.top = -1)
876
        |IL.opCALLI, IL.opWIN64CALLI, IL.opSYSVCALLI:
724
 
877
            REG.Store(R);
725
        |IL.opCALLI, IL.opWIN64CALLI, IL.opSYSVCALLI:
878
            CASE opcode OF
726
            CASE opcode OF
879
            |IL.opCALLI:
727
            |IL.opCALLI:
880
            |IL.opWIN64CALLI: Win64Passing(param2)
-
 
Line 881... Line 728...
881
            |IL.opSYSVCALLI:  SysVPassing(param2)
728
            |IL.opWIN64CALLI: Win64Passing(param2)
882
            END;
729
            |IL.opSYSVCALLI:  SysVPassing(param2)
Line 883... Line 730...
883
            callimp(param1);
730
            END;
Line 976... Line 823...
976
                END
823
                END
977
            ELSIF param3 < 0 THEN
824
            ELSIF param3 < 0 THEN
978
                param3 := -param3;
825
                param3 := -param3;
979
                n := (param3 MOD 32) * 8;
826
                n := (param3 MOD 32) * 8;
980
                param3 := param3 DIV 32;
827
                param3 := param3 DIV 32;
981
                pop(r10);
828
                pop(r11);
982
                subrc(rsp, n);
829
                subrc(rsp, n);
983
                push(r10);
830
                push(r11);
984
                push(rbp);
831
                push(rbp);
985
                mov(rbp, rsp);
832
                mov(rbp, rsp);
Line 986... Line 833...
986
 
833
 
987
                a := 0;
834
                a := 0;
Line 994... Line 841...
994
                    IF ODD(param3) THEN
841
                    IF ODD(param3) THEN
995
                        IF b <= 7 THEN
842
                        IF b <= 7 THEN
996
                            movsdmr(rbp, i, b);
843
                            movsdmr(rbp, i, b);
997
                            INC(b)
844
                            INC(b)
998
                        ELSE
845
                        ELSE
999
                            movrm(r10, rbp, n + c);
846
                            movrm(r11, rbp, n + c);
1000
                            movmr(rbp, i, r10);
847
                            movmr(rbp, i, r11);
1001
                            INC(c, 8)
848
                            INC(c, 8)
1002
                        END
849
                        END
1003
                    ELSE
850
                    ELSE
1004
                        IF a <= 5 THEN
851
                        IF a <= 5 THEN
1005
                            movmr(rbp, i, SystemVRegPar[a]);
852
                            movmr(rbp, i, SystemVRegPar[a]);
1006
                            INC(a)
853
                            INC(a)
1007
                        ELSE
854
                        ELSE
1008
                            movrm(r10, rbp, n + c);
855
                            movrm(r11, rbp, n + c);
1009
                            movmr(rbp, i, r10);
856
                            movmr(rbp, i, r11);
1010
                            INC(c, 8)
857
                            INC(c, 8)
1011
                        END
858
                        END
1012
                    END;
859
                    END;
1013
                    param3 := param3 DIV 2
860
                    param3 := param3 DIV 2
1014
                END
861
                END
Line 1026... Line 873...
1026
            ELSE
873
            ELSE
1027
                WHILE n > 0 DO
874
                WHILE n > 0 DO
1028
                    pushc(0);
875
                    pushc(0);
1029
                    DEC(n)
876
                    DEC(n)
1030
                END
877
                END
1031
            END;
-
 
1032
 
-
 
1033
            IF cmd.allocReg THEN
-
 
1034
                allocReg(cmd)
-
 
1035
            END
878
            END
Line 1036... Line 879...
1036
 
879
 
1037
        |IL.opLEAVE, IL.opLEAVER, IL.opLEAVEF:
880
        |IL.opLEAVE, IL.opLEAVER, IL.opLEAVEF:
1038
            IF opcode = IL.opLEAVER THEN
881
            IF opcode = IL.opLEAVER THEN
1039
                UnOp(reg1);
882
                UnOp(reg1);
1040
                IF reg1 # rax THEN
883
                IF reg1 # rax THEN
1041
                    GetRegA;
-
 
1042
                    ASSERT(REG.Exchange(R, reg1, rax));
-
 
1043
                    drop
884
                    mov(rax, reg1)
1044
                END;
885
                END;
1045
                drop
886
                drop
Line 1046... Line 887...
1046
            END;
887
            END;
Line 1057... Line 898...
1057
                mov(rsp, rbp)
898
                mov(rsp, rbp)
1058
            END;
899
            END;
Line 1059... Line 900...
1059
 
900
 
1060
            pop(rbp);
901
            pop(rbp);
1061
            IF param2 > 0 THEN
902
            IF param2 > 0 THEN
1062
                OutByte3(0C2H, (param2 * 8) MOD 256, (param2 * 8) DIV 256) (* ret param2 *)
903
                OutByte3(0C2H, (param2 * 8) MOD 256, (param2 * 8) DIV 256) (* ret param2*8 *)
1063
            ELSE
904
            ELSE
1064
                X86.ret
905
                X86.ret
1065
            END;
-
 
Line 1066... Line 906...
1066
            REG.Reset(R)
906
            END
1067
 
907
 
1068
        |IL.opSAVES:
908
        |IL.opSAVES:
1069
            UnOp(reg1);
909
            UnOp(reg1);
Line 1095... Line 935...
1095
            UnOp(reg1);
935
            UnOp(reg1);
1096
            movrm(reg1, reg1, 0)
936
            movrm(reg1, reg1, 0)
Line 1097... Line 937...
1097
 
937
 
1098
        |IL.opLLOAD64:
938
        |IL.opLLOAD64:
1099
            reg1 := GetAnyReg();
-
 
1100
            reg2 := GetVarReg(param2);
-
 
1101
            IF reg2 # -1 THEN
-
 
1102
                mov(reg1, reg2)
-
 
1103
            ELSE
939
            reg1 := GetAnyReg();
1104
                movrm(reg1, rbp, param2 * 8)
-
 
Line 1105... Line 940...
1105
            END
940
            movrm(reg1, rbp, param2 * 8)
1106
 
941
 
1107
        |IL.opLLOAD8,
942
        |IL.opLLOAD8,
1108
         IL.opLLOAD16:
-
 
1109
            reg1 := GetAnyReg();
-
 
1110
            reg2 := GetVarReg(param2);
-
 
1111
            IF reg2 # -1 THEN
-
 
1112
                mov(reg1, reg2)
943
         IL.opLLOAD16:
1113
            ELSE
-
 
Line 1114... Line 944...
1114
                movzx(reg1, rbp, param2 * 8, opcode = IL.opLLOAD16)
944
            reg1 := GetAnyReg();
1115
            END
945
            movzx(reg1, rbp, param2 * 8, opcode = IL.opLLOAD16)
1116
 
-
 
1117
        |IL.opLLOAD32:
-
 
1118
            reg1 := GetAnyReg();
-
 
1119
            reg2 := GetVarReg(param2);
-
 
1120
            IF reg2 # -1 THEN
946
 
1121
                mov(reg1, reg2)
-
 
1122
            ELSE
947
        |IL.opLLOAD32:
1123
                movrm32(reg1, rbp, param2 * 8)
948
            reg1 := GetAnyReg();
Line 1124... Line 949...
1124
            END;
949
            movrm32(reg1, rbp, param2 * 8);
1125
            shiftrc(shl, reg1, 32);
950
            shiftrc(shl, reg1, 32);
Line 1488... Line 1313...
1488
            pushc(param2);
1313
            pushc(param2);
1489
            CallRTL(IL._rot)
1314
            CallRTL(IL._rot)
Line 1490... Line 1315...
1490
 
1315
 
1491
        |IL.opNEW:
1316
        |IL.opNEW:
1492
            PushAll(1);
1317
            PushAll(1);
1493
            n := param2 + 16;
1318
            n := param2 + 8;
1494
            ASSERT(UTILS.Align(n, 64));
1319
            ASSERT(UTILS.Align(n, 8));
1495
            pushc(n);
1320
            pushc(n);
1496
            pushc(param1);
1321
            pushc(param1);
Line 1497... Line 1322...
1497
            CallRTL(IL._new)
1322
            CallRTL(IL._new)
1498
 
1323
 
1499
        |IL.opDISP:
1324
        |IL.opDISP:
Line 1500... Line 1325...
1500
            PushAll(1);
1325
            PushAll(1);
1501
            CallRTL(IL._dispose)
1326
            CallRTL(IL._dispose)
1502
 
-
 
1503
        |IL.opPUSHT:
1327
 
Line 1504... Line 1328...
1504
            UnOp(reg1);
1328
        |IL.opPUSHT:
1505
            reg2 := GetAnyReg();
1329
            UnOp(reg1);
1506
            movrm(reg2, reg1, -8)
1330
            movrm(GetAnyReg(), reg1, -8)
1507
 
1331
 
Line 1538... Line 1362...
1538
            pushc(param2 * tcount);
1362
            pushc(param2 * tcount);
1539
            CallRTL(IL._guardrec);
1363
            CallRTL(IL._guardrec);
1540
            GetRegA
1364
            GetRegA
Line 1541... Line 1365...
1541
 
1365
 
1542
        |IL.opCASET:
1366
        |IL.opCASET:
1543
            push(r10);
1367
            push(rcx);
1544
            push(r10);
1368
            push(rcx);
1545
            pushc(param2 * tcount);
1369
            pushc(param2 * tcount);
1546
            CallRTL(IL._guardrec);
1370
            CallRTL(IL._guardrec);
1547
            pop(r10);
1371
            pop(rcx);
1548
            test(rax);
1372
            test(rax);
Line 1549... Line 1373...
1549
            jcc(jne, param1)
1373
            jcc(jne, param1)
1550
 
1374
 
Line 1712... Line 1536...
1712
                    ELSE
1536
                    ELSE
1713
                        addrc(reg1, param2)
1537
                        addrc(reg1, param2)
1714
                    END
1538
                    END
1715
                END
1539
                END
1716
            ELSIF isLong(param2) THEN
1540
            ELSIF isLong(param2) THEN
-
 
1541
                UnOp(reg1);
1717
                addrc(reg1, param2)
1542
                addrc(reg1, param2)
1718
            END
1543
            END
Line 1719... Line 1544...
1719
 
1544
 
1720
        |IL.opDIV:
1545
        |IL.opDIV:
Line 1846... Line 1671...
1846
        |IL.opSWITCH:
1671
        |IL.opSWITCH:
1847
            UnOp(reg1);
1672
            UnOp(reg1);
1848
            IF param2 = 0 THEN
1673
            IF param2 = 0 THEN
1849
                reg2 := rax
1674
                reg2 := rax
1850
            ELSE
1675
            ELSE
1851
                reg2 := r10
1676
                reg2 := rcx
1852
            END;
1677
            END;
1853
            IF reg1 # reg2 THEN
1678
            IF reg1 # reg2 THEN
1854
                ASSERT(REG.GetReg(R, reg2));
1679
                ASSERT(REG.GetReg(R, reg2));
1855
                ASSERT(REG.Exchange(R, reg1, reg2));
1680
                ASSERT(REG.Exchange(R, reg1, reg2));
1856
                drop
1681
                drop
Line 1872... Line 1697...
1872
            drop
1697
            drop
Line 1873... Line 1698...
1873
 
1698
 
1874
        |IL.opCASELR:
1699
        |IL.opCASELR:
1875
            GetRegA;
1700
            GetRegA;
-
 
1701
            cmprc(rax, param1);
-
 
1702
            IF param2 = cmd.param3 THEN
-
 
1703
                jcc(jne, param2)
1876
            cmprc(rax, param1);
1704
            ELSE
1877
            jcc(jl, param2);
1705
                jcc(jl, param2);
-
 
1706
                jcc(jg, cmd.param3)
1878
            jcc(jg, cmd.param3);
1707
            END;
Line 1879... Line 1708...
1879
            drop
1708
            drop
-
 
1709
 
-
 
1710
        |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR:
-
 
1711
            UnOp(reg1);
-
 
1712
            IF reg1 # rcx THEN
-
 
1713
                ASSERT(REG.GetReg(R, rcx));
-
 
1714
                ASSERT(REG.Exchange(R, reg1, rcx));
-
 
1715
                drop
1880
 
1716
            END;
1881
        |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR:
1717
 
1882
            BinOp(reg1, reg2);
1718
            BinOp(reg1, reg2);
1883
            xchg(reg2, rcx);
1719
            ASSERT(reg2 = rcx);
1884
            Rex(reg1, 0);
1720
            Rex(reg1, 0);
1885
            OutByte(0D3H);
-
 
1886
            X86.shift(opcode, reg1 MOD 8); (* shift reg1, cl *)
1721
            OutByte(0D3H);
Line 1887... Line 1722...
1887
            xchg(reg2, rcx);
1722
            X86.shift(opcode, reg1 MOD 8); (* shift reg1, cl *)
-
 
1723
            drop
-
 
1724
 
-
 
1725
        |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1:
-
 
1726
            UnOp(reg1);
-
 
1727
            IF reg1 # rcx THEN
-
 
1728
                ASSERT(REG.GetReg(R, rcx));
-
 
1729
                ASSERT(REG.Exchange(R, reg1, rcx));
1888
            drop
1730
                drop
1889
 
1731
            END;
1890
        |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1:
1732
 
1891
            reg1 := GetAnyReg();
1733
            reg1 := GetAnyReg();
1892
            movrc(reg1, param2);
1734
            movrc(reg1, param2);
1893
            BinOp(reg1, reg2);
1735
            BinOp(reg1, reg2);
1894
            xchg(reg1, rcx);
1736
            ASSERT(reg1 = rcx);
1895
            Rex(reg2, 0);
-
 
1896
            OutByte(0D3H);
1737
            Rex(reg2, 0);
1897
            X86.shift(opcode, reg2 MOD 8); (* shift reg2, cl *)
1738
            OutByte(0D3H);
1898
            xchg(reg1, rcx);
1739
            X86.shift(opcode, reg2 MOD 8); (* shift reg2, cl *)
Line 1899... Line 1740...
1899
            drop;
1740
            drop;
Line 2187... Line 2028...
2187
        |IL.opUNPK, IL.opLADR_UNPK:
2028
        |IL.opUNPK, IL.opLADR_UNPK:
Line 2188... Line 2029...
2188
 
2029
 
2189
            IF opcode = IL.opLADR_UNPK THEN
2030
            IF opcode = IL.opLADR_UNPK THEN
2190
                n := param2 * 8;
2031
                n := param2 * 8;
2191
                UnOp(reg1);
-
 
2192
                reg2 := GetVarReg(param2);
-
 
2193
                regVar := reg2 # -1;
-
 
2194
                IF ~regVar THEN
2032
                UnOp(reg1);
2195
                    reg2 := GetAnyReg();
2033
                reg2 := GetAnyReg();
2196
                    Rex(0, reg2);
2034
                Rex(0, reg2);
2197
                    OutByte2(8DH, 45H + long(n) + (reg2 MOD 8) * 8); (* lea reg2, qword[rbp+n] *)
2035
                OutByte2(8DH, 45H + long(n) + (reg2 MOD 8) * 8); (* lea reg2, qword[rbp+n] *)
2198
                    OutIntByte(n)
-
 
2199
                END
2036
                OutIntByte(n)
2200
            ELSE
2037
            ELSE
2201
                BinOp(reg1, reg2);
-
 
2202
                regVar := FALSE
2038
                BinOp(reg1, reg2)
Line 2203... Line 2039...
2203
            END;
2039
            END;
2204
 
2040
 
2205
            push(reg1);
2041
            push(reg1);
2206
            movrm(reg1, reg1, 0);
2042
            movrm(reg1, reg1, 0);
2207
            shiftrc(shl, reg1, 1);
2043
            shiftrc(shl, reg1, 1);
Line 2208... Line -...
2208
            shiftrc(shr, reg1, 53);
-
 
2209
            subrc(reg1, 1023);
-
 
2210
 
-
 
2211
            IF regVar THEN
-
 
2212
                mov(reg2, reg1);
2044
            shiftrc(shr, reg1, 53);
2213
                reg2 := GetAnyReg()
-
 
Line 2214... Line 2045...
2214
            ELSE
2045
            subrc(reg1, 1023);
2215
                movmr(reg2, 0, reg1)
2046
 
Line 2216... Line 2047...
2216
            END;
2047
            movmr(reg2, 0, reg1);
Line 2241... Line 2072...
2241
            UnOp(reg1);
2072
            UnOp(reg1);
2242
            X86.pushm(reg1, 0);
2073
            X86.pushm(reg1, 0);
2243
            drop
2074
            drop
Line 2244... Line 2075...
2244
 
2075
 
2245
        |IL.opLLOAD64_PARAM:
-
 
2246
            reg1 := GetVarReg(param2);
-
 
2247
            IF reg1 # -1 THEN
-
 
2248
                push(reg1)
-
 
2249
            ELSE
2076
        |IL.opLLOAD64_PARAM:
2250
                X86.pushm(rbp, param2 * 8)
-
 
Line 2251... Line 2077...
2251
            END
2077
            X86.pushm(rbp, param2 * 8)
2252
 
2078
 
2253
        |IL.opGLOAD64_PARAM:
2079
        |IL.opGLOAD64_PARAM:
Line 2270... Line 2096...
2270
            push(reg1);
2096
            push(reg1);
2271
            drop
2097
            drop
Line 2272... Line 2098...
2272
 
2098
 
2273
        |IL.opLLOAD32_PARAM:
2099
        |IL.opLLOAD32_PARAM:
2274
            reg1 := GetAnyReg();
-
 
2275
            reg2 := GetVarReg(param2);
-
 
2276
            IF reg2 # -1 THEN
-
 
2277
                mov(reg1, reg2)
-
 
2278
            ELSE
2100
            reg1 := GetAnyReg();
2279
                movrm32(reg1, rbp, param2 * 8)
-
 
2280
            END;
2101
            movrm32(reg1, rbp, param2 * 8);
2281
            shiftrc(shl, reg1, 32);
2102
            shiftrc(shl, reg1, 32);
2282
            shiftrc(shr, reg1, 32);
2103
            shiftrc(shr, reg1, 32);
2283
            push(reg1);
2104
            push(reg1);
Line 2284... Line 2105...
2284
            drop
2105
            drop
2285
 
2106
 
2286
        |IL.opLADR_SAVEC:
-
 
2287
            n := param1 * 8;
-
 
2288
            reg1 := GetVarReg(param1);
-
 
2289
            IF reg1 # -1 THEN
-
 
2290
                movrc(reg1, param2)
2107
        |IL.opLADR_SAVEC:
2291
            ELSE
2108
            n := param1 * 8;
2292
                IF isLong(param2) THEN
2109
            IF isLong(param2) THEN
2293
                    reg2 := GetAnyReg();
2110
                reg2 := GetAnyReg();
2294
                    movrc(reg2, param2);
2111
                movrc(reg2, param2);
2295
                    movmr(rbp, n, reg2);
2112
                movmr(rbp, n, reg2);
2296
                    drop
2113
                drop
2297
                ELSE
2114
            ELSE
2298
                    OutByte3(48H, 0C7H, 45H + long(n)); (* mov qword[rbp+n], param2 *)
2115
                OutByte3(48H, 0C7H, 45H + long(n)); (* mov qword[rbp+n], param2 *)
2299
                    OutIntByte(n);
2116
                OutIntByte(n);
2300
                    OutInt(param2)
-
 
Line 2301... Line 2117...
2301
                END
2117
                OutInt(param2)
2302
            END
2118
            END
2303
 
2119
 
2304
        |IL.opGADR_SAVEC:
2120
        |IL.opGADR_SAVEC:
Line 2317... Line 2133...
2317
                OutInt(param2)
2133
                OutInt(param2)
2318
            END
2134
            END
Line 2319... Line 2135...
2319
 
2135
 
2320
        |IL.opLADR_SAVE:
2136
        |IL.opLADR_SAVE:
2321
            UnOp(reg1);
-
 
2322
            reg2 := GetVarReg(param2);
-
 
2323
            IF reg2 # -1 THEN
-
 
2324
                mov(reg2, reg1)
-
 
2325
            ELSE
2137
            UnOp(reg1);
2326
                movmr(rbp, param2 * 8, reg1)
-
 
2327
            END;
2138
            movmr(rbp, param2 * 8, reg1);
Line 2328... Line 2139...
2328
            drop
2139
            drop
2329
 
-
 
2330
        |IL.opLADR_INCC:
2140
 
2331
            reg1 := GetVarReg(param1);
2141
        |IL.opLADR_INCC:
2332
            IF isLong(param2) THEN
2142
            IF isLong(param2) THEN
2333
                reg2 := GetAnyReg();
-
 
2334
                movrc(reg2, param2);
-
 
2335
                IF reg1 # -1 THEN
-
 
2336
                    add(reg1, reg2)
2143
                reg2 := GetAnyReg();
2337
                ELSE
2144
                movrc(reg2, param2);
2338
                    n := param1 * 8;
2145
                n := param1 * 8;
2339
                    Rex(0, reg2);
2146
                Rex(0, reg2);
2340
                    OutByte2(01H, 45H + long(n) + (reg2 MOD 8) * 8);
-
 
2341
                    OutIntByte(n) (* add qword[rbp+n], reg2 *)
2147
                OutByte2(01H, 45H + long(n) + (reg2 MOD 8) * 8);
2342
                END;
2148
                OutIntByte(n); (* add qword[rbp+n], reg2 *)
2343
                drop
-
 
2344
            ELSIF ABS(param2) = 1 THEN
-
 
2345
                IF reg1 # -1 THEN
-
 
2346
                    IF param2 = 1 THEN
-
 
2347
                        incr(reg1)
-
 
2348
                    ELSE
-
 
2349
                        decr(reg1)
-
 
2350
                    END
2149
                drop
2351
                ELSE
2150
            ELSIF ABS(param2) = 1 THEN
2352
                    n := param1 * 8;
2151
                n := param1 * 8;
2353
                    OutByte3(48H, 0FFH, 45H + 8 * ORD(param2 = -1) + long(n)); (* inc/dec qword[rbp+n] *)
-
 
2354
                    OutIntByte(n)
-
 
2355
                END
-
 
2356
            ELSE
-
 
2357
                IF reg1 # -1 THEN
2152
                OutByte3(48H, 0FFH, 45H + 8 * ORD(param2 = -1) + long(n)); (* inc/dec qword[rbp+n] *)
2358
                    addrc(reg1, param2)
2153
                OutIntByte(n)
2359
                ELSE
2154
            ELSE
2360
                    n := param1 * 8;
2155
                n := param1 * 8;
2361
                    OutByte3(48H, 81H + short(param2), 45H + long(n));
2156
                OutByte3(48H, 81H + short(param2), 45H + long(n));
2362
                    OutIntByte(n);
2157
                OutIntByte(n);
2363
                    OutIntByte(param2) (* add qword[rbp+n], param2 *)
-
 
Line 2364... Line 2158...
2364
                END
2158
                OutIntByte(param2) (* add qword[rbp+n], param2 *)
2365
            END
-
 
2366
 
2159
            END
2367
        |IL.opLADR_INCCB, IL.opLADR_DECCB:
-
 
2368
            reg1 := GetVarReg(param1);
-
 
2369
            param2 := param2 MOD 256;
-
 
2370
            IF reg1 # -1 THEN
-
 
2371
                IF opcode = IL.opLADR_DECCB THEN
-
 
2372
                    subrc(reg1, param2)
-
 
2373
                ELSE
-
 
2374
                    addrc(reg1, param2)
-
 
2375
                END;
2160
 
2376
                andrc(reg1, 255)
2161
        |IL.opLADR_INCCB, IL.opLADR_DECCB:
2377
            ELSE
2162
            param2 := param2 MOD 256;
2378
                n := param1 * 8;
2163
            n := param1 * 8;
2379
                OutByte2(80H, 45H + long(n) + 28H * ORD(opcode = IL.opLADR_DECCB));
-
 
Line 2380... Line 2164...
2380
                OutIntByte(n);
2164
            OutByte2(80H, 45H + long(n) + 28H * ORD(opcode = IL.opLADR_DECCB));
2381
                OutByte(param2) (* add/sub byte[rbp+n], param2 *)
2165
            OutIntByte(n);
2382
            END
-
 
2383
 
-
 
2384
        |IL.opLADR_INC, IL.opLADR_DEC:
-
 
2385
            UnOp(reg1);
-
 
2386
            reg2 := GetVarReg(param2);
-
 
2387
            IF reg2 # -1 THEN
-
 
2388
                IF opcode = IL.opLADR_DEC THEN
-
 
2389
                    sub(reg2, reg1)
-
 
2390
                ELSE
2166
            OutByte(param2) (* add/sub byte[rbp+n], param2 *)
2391
                    add(reg2, reg1)
2167
 
2392
                END
2168
        |IL.opLADR_INC, IL.opLADR_DEC:
2393
            ELSE
2169
            UnOp(reg1);
2394
                n := param2 * 8;
-
 
2395
                Rex(0, reg1);
2170
            n := param2 * 8;
Line 2396... Line 2171...
2396
                OutByte2(01H + 28H * ORD(opcode = IL.opLADR_DEC), 45H + long(n) + (reg1 MOD 8) * 8);
2171
            Rex(0, reg1);
2397
                OutIntByte(n) (* add/sub qword[rbp+n], reg1 *)
2172
            OutByte2(01H + 28H * ORD(opcode = IL.opLADR_DEC), 45H + long(n) + (reg1 MOD 8) * 8);
2398
            END;
-
 
2399
            drop
-
 
2400
 
-
 
2401
        |IL.opLADR_INCB, IL.opLADR_DECB:
-
 
2402
            UnOp(reg1);
-
 
2403
            reg2 := GetVarReg(param2);
-
 
2404
            IF reg2 # -1 THEN
-
 
2405
                IF opcode = IL.opLADR_DECB THEN
-
 
2406
                    sub(reg2, reg1)
-
 
2407
                ELSE
2173
            OutIntByte(n); (* add/sub qword[rbp+n], reg1 *)
2408
                    add(reg2, reg1)
2174
            drop
2409
                END;
2175
 
2410
                andrc(reg2, 255)
2176
        |IL.opLADR_INCB, IL.opLADR_DECB:
2411
            ELSE
2177
            UnOp(reg1);
2412
                n := param2 * 8;
2178
            n := param2 * 8;
2413
                IF reg1 >= 8 THEN
-
 
2414
                    OutByte(44H)
2179
            IF reg1 >= 8 THEN
Line 2415... Line 2180...
2415
                END;
2180
                OutByte(44H)
2416
                OutByte2(28H * ORD(opcode = IL.opLADR_DECB), 45H + long(n) + 8 * (reg1 MOD 8));
2181
            END;
2417
                OutIntByte(n) (* add/sub byte[rbp+n], reg1_8 *)
2182
            OutByte2(28H * ORD(opcode = IL.opLADR_DECB), 45H + long(n) + 8 * (reg1 MOD 8));
2418
            END;
-
 
2419
            drop
-
 
2420
 
-
 
2421
        |IL.opLADR_INCL, IL.opLADR_EXCL:
-
 
2422
            UnOp(reg1);
-
 
2423
            cmprc(reg1, 64);
2183
            OutIntByte(n); (* add/sub byte[rbp+n], reg1_8 *)
2424
            reg2 := GetVarReg(param2);
2184
            drop
2425
            IF reg2 # -1 THEN
2185
 
2426
                OutByte2(73H, 4); (* jnb L *)
2186
        |IL.opLADR_INCL, IL.opLADR_EXCL:
2427
                oprr2(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), reg2, reg1) (* bts/btr reg2, reg1 *)
2187
            UnOp(reg1);
2428
            ELSE
-
 
2429
                n := param2 * 8;
2188
            cmprc(reg1, 64);
2430
                OutByte2(73H, 5 + 3 * ORD(~X86.isByte(n))); (* jnb L *)
2189
            n := param2 * 8;
Line 2431... Line 2190...
2431
                Rex(0, reg1);
2190
            OutByte2(73H, 5 + 3 * ORD(~X86.isByte(n))); (* jnb L *)
2432
                OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), 45H + long(n) + 8 * (reg1 MOD 8));
-
 
2433
                OutIntByte(n) (* bts/btr qword[rbp+n], reg1 *)
-
 
2434
            END;
-
 
2435
            (* L: *)
-
 
2436
            drop
-
 
2437
 
-
 
2438
        |IL.opLADR_INCLC, IL.opLADR_EXCLC:
2191
            Rex(0, reg1);
2439
            reg1 := GetVarReg(param1);
2192
            OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), 45H + long(n) + 8 * (reg1 MOD 8));
2440
            IF reg1 # -1 THEN
2193
            OutIntByte(n); (* bts/btr qword[rbp+n], reg1 *)
2441
                Rex(reg1, 0);
2194
            (* L: *)
2442
                OutByte3(0FH, 0BAH, 0E8H); (* bts/btr reg1, param2 *)
2195
            drop
2443
                OutByte2(reg1 MOD 8 + 8 * ORD(opcode = IL.opLADR_EXCLC), param2)
-
 
Line 2444... Line 2196...
2444
            ELSE
2196
 
2445
                n := param1 * 8;
2197
        |IL.opLADR_INCLC, IL.opLADR_EXCLC:
Line 2446... Line -...
2446
                OutByte3(48H, 0FH, 0BAH); (* bts/btr qword[rbp+n], param2 *)
-
 
2447
                OutByte(6DH + long(n) + 8 * ORD(opcode = IL.opLADR_EXCLC));
-
 
2448
                OutIntByte(n);
2198
            n := param1 * 8;
Line 2449... Line 2199...
2449
                OutByte(param2)
2199
            OutByte3(48H, 0FH, 0BAH); (* bts/btr qword[rbp+n], param2 *)
2450
            END
2200
            OutByte(6DH + long(n) + 8 * ORD(opcode = IL.opLADR_EXCLC));
Line 2598... Line 2348...
2598
 
2348
 
2599
    _import(IL.codes._import)
2349
    _import(IL.codes._import)
Line 2600... Line -...
2600
END epilog;
-
 
2601
 
-
 
2602
 
-
 
2603
PROCEDURE rload (reg, offs, size: INTEGER);
-
 
2604
BEGIN
-
 
2605
    offs := offs * 8;
-
 
2606
    CASE size OF
-
 
2607
    |1: movzx(reg, rbp, offs, FALSE)
-
 
2608
    |2: movzx(reg, rbp, offs, TRUE)
-
 
2609
    |4: xor(reg, reg); movrm32(reg, rbp, offs)
-
 
2610
    |8: movrm(reg, rbp, offs)
-
 
2611
    END
-
 
2612
END rload;
-
 
2613
 
-
 
2614
 
-
 
2615
PROCEDURE rsave (reg, offs, size: INTEGER);
-
 
2616
BEGIN
-
 
2617
    offs := offs * 8;
-
 
2618
    CASE size OF
-
 
2619
    |1: X86.movmr8(rbp, offs, reg)
-
 
2620
    |2: X86.movmr16(rbp, offs, reg)
-
 
2621
    |4: movmr32(rbp, offs, reg)
-
 
2622
    |8: movmr(rbp, offs, reg)
-
 
2623
    END
-
 
2624
END rsave;
2350
END epilog;
2625
 
2351
 
2626
 
2352
 
Line 2627... Line 2353...
2627
PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
2353
PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
Line 2645... Line 2371...
2645
    SystemVRegPar[5] := r9;
2371
    SystemVRegPar[5] := r9;
Line 2646... Line 2372...
2646
 
2372
 
2647
    PATHS.split(outname, path, modname, ext);
2373
    PATHS.split(outname, path, modname, ext);
Line 2648... Line 2374...
2648
    S.append(modname, ext);
2374
    S.append(modname, ext);
Line 2649... Line 2375...
2649
 
2375
 
Line 2650... Line 2376...
2650
    REG.Init(R, push, pop, mov, xchg, rload, rsave, {rax, r10, r11}, {rcx, rdx, r8, r9});
2376
    REG.Init(R, push, pop, mov, xchg, {rax, rcx, rdx, r8, r9, r10, r11});
2651
 
2377