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 |