Subversion Repositories Kolibri OS

Rev

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

Rev 7696 Rev 7983
Line 1... Line 1...
1
(*
1
(*
2
    BSD 2-Clause License
2
    BSD 2-Clause License
Line 3... Line 3...
3
 
3
 
4
    Copyright (c) 2019, Anton Krotov
4
    Copyright (c) 2019-2020, Anton Krotov
5
    All rights reserved.
5
    All rights reserved.
Line 6... Line 6...
6
*)
6
*)
Line 7... Line 7...
7
 
7
 
8
MODULE MSP430;
8
MODULE MSP430;
Line 9... Line 9...
9
 
9
 
Line 10... Line 10...
10
IMPORT IL, LISTS, REG, CHL := CHUNKLISTS, ERRORS, FILES, WRITER,
10
IMPORT IL, LISTS, REG, CHL := CHUNKLISTS, ERRORS, WR := WRITER, HEX,
11
       UTILS, C := CONSOLE, PROG, RTL := MSP430RTL;
11
       UTILS, C := CONSOLE, PROG, RTL := MSP430RTL;
Line 12... Line 12...
12
 
12
 
Line 13... Line 13...
13
 
13
 
Line 14... Line 14...
14
CONST
14
CONST
Line 15... Line 15...
15
 
15
 
Line 16... Line 16...
16
    minRAM* = 128;  maxRAM* = 10240;
16
    minRAM* = 128;  maxRAM* = 2048;
Line 17... Line 17...
17
    minROM* = 2048; maxROM* = 49152;
17
    minROM* = 2048; maxROM* = 24576;
Line 18... Line 18...
18
 
18
 
19
    minStackSize = 64;
19
    minStackSize = 64;
Line 106... Line 106...
106
 
106
 
Line 107... Line 107...
107
    IV: ARRAY RTL.LenIV OF INTEGER;
107
    IV: ARRAY RTL.LenIV OF INTEGER;
Line -... Line 108...
-
 
108
 
-
 
109
    IdxWords: RECORD src, dst: INTEGER END;
Line 108... Line 110...
108
 
110
 
109
    IdxWords: RECORD src, dst: INTEGER END;
111
    StkCnt: INTEGER;
110
 
112
 
Line 165... Line 167...
165
    RETURN BW * ORD(b)
167
    RETURN BW * ORD(b)
166
END bw;
168
END bw;
Line 167... Line 169...
167
 
169
 
-
 
170
 
-
 
171
PROCEDURE src_x (x, Rn: INTEGER): INTEGER;
-
 
172
VAR
168
 
173
    res: INTEGER;
-
 
174
 
-
 
175
BEGIN
-
 
176
    IF (x = 0) & ~(Rn IN {PC, SR, CG}) THEN
169
PROCEDURE src_x (x, Rn: INTEGER): INTEGER;
177
        res := Rn * 256 + sINDIR
170
BEGIN
178
    ELSE
-
 
179
        IdxWords.src := x;
-
 
180
        res := Rn * 256 + sIDX
-
 
181
    END
171
    IdxWords.src := x
182
 
Line 172... Line 183...
172
    RETURN Rn * 256 + sIDX
183
    RETURN res
173
END src_x;
184
END src_x;
Line 195... Line 206...
195
    res: INTEGER;
206
    res: INTEGER;
Line 196... Line 207...
196
 
207
 
197
BEGIN
208
BEGIN
198
    CASE x OF
209
    CASE x OF
199
    | 0: res := CG * 256
210
    | 0: res := CG * 256
200
    | 1: res := src_x(0, CG); IdxWords.src := NOWORD
211
    | 1: res := CG * 256 + sIDX
201
    | 2: res := indir(CG)
212
    | 2: res := indir(CG)
202
    | 4: res := indir(SR)
213
    | 4: res := indir(SR)
203
    | 8: res := incr(SR)
214
    | 8: res := incr(SR)
204
    |-1: res := incr(CG)
215
    |-1: res := incr(CG)
Line 211... Line 222...
211
END imm;
222
END imm;
Line 212... Line 223...
212
 
223
 
213
 
224
 
214
PROCEDURE Op2 (op, src, dst: INTEGER);
225
PROCEDURE Op2 (op, src, dst: INTEGER);
215
BEGIN
226
BEGIN
216
    ASSERT(BITS(op) + {6, 12..15} = {6, 12..15});
227
    ASSERT(BITS(op) - {6, 12..15} = {});
Line 217... Line 228...
217
    ASSERT(BITS(src) + {4, 5, 8..11} = {4, 5, 8..11});
228
    ASSERT(BITS(src) - {4, 5, 8..11} = {});
Line 218... Line 229...
218
    ASSERT(BITS(dst) + {0..3, 7} = {0..3, 7});
229
    ASSERT(BITS(dst) - {0..3, 7} = {});
219
 
230
 
Line 252... Line 263...
252
    | 2: Op1(opPUSH, CG, sINDIR)
263
    | 2: Op1(opPUSH, CG, sINDIR)
253
    |-1: Op1(opPUSH, CG, sINCR)
264
    |-1: Op1(opPUSH, CG, sINCR)
254
    ELSE
265
    ELSE
255
        Op1(opPUSH, PC, sINCR);
266
        Op1(opPUSH, PC, sINCR);
256
        EmitWord(imm)
267
        EmitWord(imm)
257
    END
268
    END;
-
 
269
    INC(StkCnt)
258
END PushImm;
270
END PushImm;
Line 259... Line 271...
259
 
271
 
260
 
272
 
Line 374... Line 386...
374
END Fixup;
386
END Fixup;
Line 375... Line 387...
375
 
387
 
376
 
388
 
377
PROCEDURE Push (reg: INTEGER);
389
PROCEDURE Push (reg: INTEGER);
-
 
390
BEGIN
378
BEGIN
391
    Op1(opPUSH, reg, sREG);
Line 379... Line 392...
379
    Op1(opPUSH, reg, sREG)
392
    INC(StkCnt)
380
END Push;
393
END Push;
381
 
394
 
-
 
395
 
382
 
396
PROCEDURE Pop (reg: INTEGER);
Line 383... Line 397...
383
PROCEDURE Pop (reg: INTEGER);
397
BEGIN
384
BEGIN
398
    Op2(opMOV, incr(SP), reg);
Line 428... Line 442...
428
PROCEDURE CallRTL (proc, params: INTEGER);
442
PROCEDURE CallRTL (proc, params: INTEGER);
429
BEGIN
443
BEGIN
430
    EmitCall(RTL.rtl[proc].label);
444
    EmitCall(RTL.rtl[proc].label);
431
    RTL.Used(proc);
445
    RTL.Used(proc);
432
    IF params > 0 THEN
446
    IF params > 0 THEN
433
        Op2(opADD, imm(params * 2), SP)
447
        Op2(opADD, imm(params * 2), SP);
-
 
448
        DEC(StkCnt, params)
434
    END
449
    END
435
END CallRTL;
450
END CallRTL;
Line 436... Line 451...
436
 
451
 
Line 580... Line 595...
580
    Op2(opXOR, imm(-1), reg);
595
    Op2(opXOR, imm(-1), reg);
581
    Op2(opADD, imm(1), reg)
596
    Op2(opADD, imm(1), reg)
582
END Neg;
597
END Neg;
Line -... Line 598...
-
 
598
 
-
 
599
 
-
 
600
PROCEDURE LocalOffset (offset: INTEGER): INTEGER;
-
 
601
    RETURN (offset + StkCnt - ORD(offset > 0)) * 2
-
 
602
END LocalOffset;
-
 
603
 
-
 
604
 
-
 
605
PROCEDURE LocalDst (offset: INTEGER): INTEGER;
-
 
606
    RETURN dst_x(LocalOffset(offset), SP)
-
 
607
END LocalDst;
-
 
608
 
-
 
609
 
-
 
610
PROCEDURE LocalSrc (offset: INTEGER): INTEGER;
-
 
611
    RETURN src_x(LocalOffset(offset), SP)
-
 
612
END LocalSrc;
583
 
613
 
584
 
614
 
585
PROCEDURE translate;
615
PROCEDURE translate;
Line 586... Line 616...
586
VAR
616
VAR
Line 587... Line 617...
587
    cmd, next: COMMAND;
617
    cmd, next: COMMAND;
Line 588... Line 618...
588
 
618
 
Line 621... Line 651...
621
        |IL.opLABEL:
651
        |IL.opLABEL:
622
            EmitLabel(param1)
652
            EmitLabel(param1)
Line 623... Line 653...
623
 
653
 
624
        |IL.opSADR_PARAM:
654
        |IL.opSADR_PARAM:
-
 
655
            Op1(opPUSH, PC, sINCR);
625
            Op1(opPUSH, PC, sINCR);
656
            INC(StkCnt);
626
            EmitWord(param2);
657
            EmitWord(param2);
Line 627... Line 658...
627
            Reloc(RDATA)
658
            Reloc(RDATA)
628
 
659
 
Line 629... Line 660...
629
        |IL.opERR:
660
        |IL.opERR:
630
            CallRTL(RTL._error, 2)
661
            CallRTL(RTL._error, 2)
Line -... Line 662...
-
 
662
 
-
 
663
        |IL.opPUSHC:
-
 
664
            PushImm(param2)
-
 
665
 
-
 
666
        |IL.opONERR:
631
 
667
            PushImm(param2);
632
        |IL.opPUSHC:
668
            DEC(StkCnt);
Line 633... Line 669...
633
            PushImm(param2)
669
            EmitJmp(opJMP, param1)
634
 
670
 
635
        |IL.opLEAVEC:
-
 
-
 
671
        |IL.opLEAVEC:
636
            Pop(PC)
672
            Pop(PC)
637
 
-
 
638
        |IL.opENTER:
-
 
639
            ASSERT(R.top = -1);
-
 
640
 
-
 
641
            EmitLabel(param1);
673
 
642
 
674
        |IL.opENTER:
643
            Push(BP);
675
            ASSERT(R.top = -1);
644
            MovRR(SP, BP);
676
            StkCnt := 0;
645
 
677
            EmitLabel(param1);
Line 666... Line 698...
666
                    ASSERT(REG.Exchange(R, reg1, ACC));
698
                    ASSERT(REG.Exchange(R, reg1, ACC));
667
                    drop
699
                    drop
668
                END;
700
                END;
669
                drop
701
                drop
670
            END;
702
            END;
671
 
-
 
672
            ASSERT(R.top = -1);
703
            ASSERT(R.top = -1);
673
 
-
 
-
 
704
            ASSERT(StkCnt = param1);
674
            IF param1 > 0 THEN
705
            IF param1 > 0 THEN
675
                MovRR(BP, SP)
706
                Op2(opADD, imm(param1 * 2), SP)
676
            END;
707
            END;
677
 
-
 
678
            Pop(BP);
-
 
679
            Pop(PC)
708
            Pop(PC)
Line 680... Line 709...
680
 
709
 
681
        |IL.opRES:
710
        |IL.opRES:
682
            ASSERT(R.top = -1);
711
            ASSERT(R.top = -1);
Line 683... Line 712...
683
            GetRegA
712
            GetRegA
684
 
713
 
685
        |IL.opCLEANUP:
714
        |IL.opCLEANUP:
-
 
715
            IF param2 # 0 THEN
686
            IF param2 # 0 THEN
716
                Op2(opADD, imm(param2 * 2), SP);
Line 687... Line 717...
687
                Op2(opADD, imm(param2 * 2), SP)
717
                DEC(StkCnt, param2)
688
            END
718
            END
689
 
719
 
Line 718... Line 748...
718
            EmitWord(param2);
748
            EmitWord(param2);
719
            Reloc(RBSS)
749
            Reloc(RBSS)
Line 720... Line 750...
720
 
750
 
721
        |IL.opLADR:
751
        |IL.opLADR:
-
 
752
            reg1 := GetAnyReg();
722
            reg1 := GetAnyReg();
753
            n := LocalOffset(param2);
-
 
754
            Op2(opMOV, SP * 256, reg1);
723
            MovRR(BP, reg1);
755
            IF n # 0 THEN
-
 
756
                Op2(opADD, imm(n), reg1)
Line 724... Line 757...
724
            Op2(opADD, imm(param2 * 2), reg1)
757
            END
725
 
758
 
Line 726... Line 759...
726
        |IL.opLLOAD8:
759
        |IL.opLLOAD8:
727
            Op2(opMOV + BW, src_x(param2 * 2, BP), GetAnyReg())
760
            Op2(opMOV + BW, LocalSrc(param2), GetAnyReg())
Line 728... Line 761...
728
 
761
 
729
        |IL.opLLOAD16, IL.opVADR:
762
        |IL.opLLOAD16, IL.opVADR:
730
            Op2(opMOV, src_x(param2 * 2, BP), GetAnyReg())
763
            Op2(opMOV, LocalSrc(param2), GetAnyReg())
Line 745... Line 778...
745
            UnOp(reg1);
778
            UnOp(reg1);
746
            Op2(opMOV, indir(reg1), reg1)
779
            Op2(opMOV, indir(reg1), reg1)
Line 747... Line 780...
747
 
780
 
748
        |IL.opVLOAD8:
781
        |IL.opVLOAD8:
749
            reg1 := GetAnyReg();
782
            reg1 := GetAnyReg();
750
            Op2(opMOV, src_x(param2 * 2, BP), reg1);
783
            Op2(opMOV, LocalSrc(param2), reg1);
Line 751... Line 784...
751
            Op2(opMOV + BW, indir(reg1), reg1)
784
            Op2(opMOV + BW, indir(reg1), reg1)
752
 
785
 
753
        |IL.opVLOAD16:
786
        |IL.opVLOAD16:
754
            reg1 := GetAnyReg();
787
            reg1 := GetAnyReg();
Line 755... Line 788...
755
            Op2(opMOV, src_x(param2 * 2, BP), reg1);
788
            Op2(opMOV, LocalSrc(param2), reg1);
756
            Op2(opMOV, indir(reg1), reg1)
789
            Op2(opMOV, indir(reg1), reg1)
757
 
790
 
Line 801... Line 834...
801
            UnOp(reg1);
834
            UnOp(reg1);
802
            IF param2 # 0 THEN
835
            IF param2 # 0 THEN
803
                Op2(opSUB, imm(param2), reg1)
836
                Op2(opSUB, imm(param2), reg1)
804
            END;
837
            END;
805
            IF opcode = IL.opSUBL THEN
838
            IF opcode = IL.opSUBL THEN
806
                reg2 := GetAnyReg();
-
 
807
                Clear(reg2);
839
                Neg(reg1)
808
                Op2(opSUB, reg1 * 256, reg2);
-
 
809
                drop;
-
 
810
                drop;
-
 
811
                ASSERT(REG.GetReg(R, reg2))
-
 
812
            END
840
            END
Line 813... Line 841...
813
 
841
 
814
        |IL.opLADR_SAVEC:
842
        |IL.opLADR_SAVEC:
Line 815... Line 843...
815
            Op2(opMOV, imm(param2), dst_x(param1 * 2, BP))
843
            Op2(opMOV, imm(param2), LocalDst(param1))
816
 
844
 
817
        |IL.opLADR_SAVE:
845
        |IL.opLADR_SAVE:
818
            UnOp(reg1);
846
            UnOp(reg1);
Line 819... Line 847...
819
            Op2(opMOV, reg1 * 256, dst_x(param2 * 2, BP));
847
            Op2(opMOV, reg1 * 256, LocalDst(param2));
820
            drop
848
            drop
821
 
849
 
Line 848... Line 876...
848
                Op2(opCMP, imm(param2), reg1)
876
                Op2(opCMP, imm(param2), reg1)
849
            END;
877
            END;
Line 850... Line 878...
850
 
878
 
851
            drop;
879
            drop;
-
 
880
            cc := cond(opcode);
Line 852... Line 881...
852
            cc := cond(opcode);
881
            next := cmd.next(COMMAND);
853
 
-
 
854
            IF cmd.next(COMMAND).opcode = IL.opJE THEN
882
 
855
                label := cmd.next(COMMAND).param1;
883
            IF next.opcode = IL.opJE THEN
856
                jcc(cc, label);
-
 
857
                cmd := cmd.next(COMMAND)
884
                jcc(cc, next.param1);
858
 
-
 
859
            ELSIF cmd.next(COMMAND).opcode = IL.opJNE THEN
885
                cmd := next
860
                label := cmd.next(COMMAND).param1;
886
            ELSIF next.opcode = IL.opJNE THEN
861
                jcc(ORD(BITS(cc) / {0}), label);
-
 
862
                cmd := cmd.next(COMMAND)
887
                jcc(ORD(BITS(cc) / {0}), next.param1);
863
 
888
                cmd := next
864
            ELSE
889
            ELSE
Line 865... Line 890...
865
                setcc(cc, GetAnyReg())
890
                setcc(cc, GetAnyReg())
Line 940... Line 965...
940
 
965
 
941
        |IL.opCHKIDX2:
966
        |IL.opCHKIDX2:
942
            BinOp(reg1, reg2);
967
            BinOp(reg1, reg2);
943
            IF param2 # -1 THEN
968
            IF param2 # -1 THEN
944
                Op2(opCMP, reg1 * 256, reg2);
-
 
945
                MovRR(reg2, reg1);
-
 
946
                drop;
969
                Op2(opCMP, reg1 * 256, reg2);
947
                jcc(jb, param1)
970
                jcc(jb, param1)
948
            ELSE
971
            END;
949
                INCL(R.regs, reg1);
972
            INCL(R.regs, reg1);
950
                DEC(R.top);
973
            DEC(R.top);
951
                R.stk[R.top] := reg2
-
 
Line 952... Line 974...
952
            END
974
            R.stk[R.top] := reg2
953
 
975
 
954
        |IL.opINCC, IL.opINCCB:
976
        |IL.opINCC, IL.opINCCB:
955
            UnOp(reg1);
977
            UnOp(reg1);
Line 972... Line 994...
972
            Op2(opSUB + bw(opcode = IL.opDECB), reg1 * 256, dst_x(0, reg2));
994
            Op2(opSUB + bw(opcode = IL.opDECB), reg1 * 256, dst_x(0, reg2));
973
            drop;
995
            drop;
974
            drop
996
            drop
Line 975... Line 997...
975
 
997
 
976
        |IL.opLADR_INCC, IL.opLADR_INCCB:
998
        |IL.opLADR_INCC, IL.opLADR_INCCB:
Line 977... Line 999...
977
            Op2(opADD + bw(opcode = IL.opLADR_INCCB), imm(param2), dst_x(param1 * 2, BP))
999
            Op2(opADD + bw(opcode = IL.opLADR_INCCB), imm(param2), LocalDst(param1))
978
 
1000
 
Line 979... Line 1001...
979
        |IL.opLADR_DECCB:
1001
        |IL.opLADR_DECCB:
980
            Op2(opSUB + BW, imm(param2), dst_x(param1 * 2, BP))
1002
            Op2(opSUB + BW, imm(param2), LocalDst(param1))
981
 
1003
 
982
        |IL.opLADR_INC, IL.opLADR_INCB:
1004
        |IL.opLADR_INC, IL.opLADR_INCB:
Line 983... Line 1005...
983
            UnOp(reg1);
1005
            UnOp(reg1);
984
            Op2(opADD + bw(opcode = IL.opLADR_INCB), reg1 * 256, dst_x(param2 * 2, BP));
1006
            Op2(opADD + bw(opcode = IL.opLADR_INCB), reg1 * 256, LocalDst(param2));
985
            drop
1007
            drop
986
 
1008
 
Line 987... Line 1009...
987
        |IL.opLADR_DEC, IL.opLADR_DECB:
1009
        |IL.opLADR_DEC, IL.opLADR_DECB:
988
            UnOp(reg1);
1010
            UnOp(reg1);
989
            Op2(opSUB + bw(opcode = IL.opLADR_DECB), reg1 * 256, dst_x(param2 * 2, BP));
1011
            Op2(opSUB + bw(opcode = IL.opLADR_DECB), reg1 * 256, LocalDst(param2));
Line 1021... Line 1043...
1021
 
1043
 
1022
        |IL.opTYPEGD:
1044
        |IL.opTYPEGD:
1023
            UnOp(reg1);
1045
            UnOp(reg1);
1024
            PushAll(0);
1046
            PushAll(0);
-
 
1047
            Op1(opPUSH, reg1, sIDX);
1025
            Op1(opPUSH, reg1, sIDX);
1048
            INC(StkCnt);
1026
            EmitWord(-2);
1049
            EmitWord(-2);
1027
            PushImm(param2);
1050
            PushImm(param2);
1028
            CallRTL(RTL._guardrec, 2);
1051
            CallRTL(RTL._guardrec, 2);
Line 1076... Line 1099...
1076
        |IL.opLENGTH:
1099
        |IL.opLENGTH:
1077
            PushAll(2);
1100
            PushAll(2);
1078
            CallRTL(RTL._length, 2);
1101
            CallRTL(RTL._length, 2);
1079
            GetRegA
1102
            GetRegA
Line 1080... Line 1103...
1080
 
1103
 
1081
        |IL.opMIN:
1104
        |IL.opMAX,IL.opMIN:
1082
            BinOp(reg1, reg2);
1105
            BinOp(reg1, reg2);
1083
            Op2(opCMP, reg2 * 256, reg1);
1106
            Op2(opCMP, reg2 * 256, reg1);
1084
            EmitWord(opJL + 1); (* jl L *)
-
 
1085
            MovRR(reg2, reg1);
1107
            IF opcode = IL.opMIN THEN
1086
                                (* L: *)
1108
                cc := opJL + 1
1087
            drop
-
 
1088
 
-
 
1089
 
1109
            ELSE
1090
        |IL.opMAX:
1110
                cc := opJGE + 1
1091
            BinOp(reg1, reg2);
-
 
1092
            Op2(opCMP, reg2 * 256, reg1);
1111
            END;
1093
            EmitWord(opJGE + 1); (* jge L *)
1112
            EmitWord(cc);        (* jge/jl L *)
1094
            MovRR(reg2, reg1);
1113
            MovRR(reg2, reg1);
1095
                                 (* L: *)
1114
                                 (* L: *)
Line 1096... Line 1115...
1096
            drop
1115
            drop
1097
 
1116
 
1098
        |IL.opMINC:
1117
        |IL.opMAXC, IL.opMINC:
1099
            UnOp(reg1);
1118
            UnOp(reg1);
1100
            Op2(opCMP, imm(param2), reg1);
-
 
1101
            L := NewLabel();
1119
            Op2(opCMP, imm(param2), reg1);
1102
            jcc(jl, L);
1120
            L := NewLabel();
1103
            Op2(opMOV, imm(param2), reg1);
-
 
1104
            EmitLabel(L)
1121
            IF opcode = IL.opMINC THEN
1105
 
1122
                cc := jl
1106
        |IL.opMAXC:
-
 
1107
            UnOp(reg1);
1123
            ELSE
1108
            Op2(opCMP, imm(param2), reg1);
1124
                cc := jge
1109
            L := NewLabel();
1125
            END;
1110
            jcc(jge, L);
1126
            jcc(cc, L);
Line 1111... Line 1127...
1111
            Op2(opMOV, imm(param2), reg1);
1127
            Op2(opMOV, imm(param2), reg1);
1112
            EmitLabel(L)
1128
            EmitLabel(L)
Line 1151... Line 1167...
1151
        |IL.opSBOOLC:
1167
        |IL.opSBOOLC:
1152
            UnOp(reg1);
1168
            UnOp(reg1);
1153
            Op2(opMOV + BW, imm(param2), dst_x(0, reg1));
1169
            Op2(opMOV + BW, imm(param2), dst_x(0, reg1));
1154
            drop
1170
            drop
Line 1155... Line -...
1155
 
-
 
1156
        |IL.opODD:
-
 
1157
            UnOp(reg1);
-
 
1158
            Op2(opAND, imm(1), reg1)
-
 
1159
 
1171
 
1160
        |IL.opEQS .. IL.opGES:
1172
        |IL.opEQS .. IL.opGES:
1161
            PushAll(4);
1173
            PushAll(4);
1162
            PushImm((opcode - IL.opEQS) * 12);
1174
            PushImm((opcode - IL.opEQS) * 12);
1163
            CallRTL(RTL._strcmp, 5);
1175
            CallRTL(RTL._strcmp, 5);
Line 1351... Line 1363...
1351
 
1363
 
1352
        |IL.opSAVES:
1364
        |IL.opSAVES:
1353
            UnOp(reg1);
1365
            UnOp(reg1);
1354
            PushAll_1;
1366
            PushAll_1;
-
 
1367
            Op1(opPUSH, PC, sINCR);
1355
            Op1(opPUSH, PC, sINCR);
1368
            INC(StkCnt);
1356
            EmitWord(param2);
1369
            EmitWord(param2);
1357
            Reloc(RDATA);
1370
            Reloc(RDATA);
1358
            Push(reg1);
1371
            Push(reg1);
1359
            drop;
1372
            drop;
Line 1430... Line 1443...
1430
            ELSIF opcode = IL.opNEP THEN
1443
            ELSIF opcode = IL.opNEP THEN
1431
                setcc(jne, reg1)
1444
                setcc(jne, reg1)
1432
            END
1445
            END
Line 1433... Line 1446...
1433
 
1446
 
1434
        |IL.opVADR_PARAM:
1447
        |IL.opVADR_PARAM:
1435
            Op1(opPUSH, BP, sIDX);
1448
            reg1 := GetAnyReg();
-
 
1449
            Op2(opMOV, LocalSrc(param2), reg1);
-
 
1450
            Push(reg1);
Line 1436... Line 1451...
1436
            EmitWord(param2 * 2)
1451
            drop
1437
 
1452
 
1438
        |IL.opNEW:
1453
        |IL.opNEW:
1439
            PushAll(1);
1454
            PushAll(1);
Line 1503... Line 1518...
1503
            PushAll(2);
1518
            PushAll(2);
1504
            CallRTL(RTL._excl, 2)
1519
            CallRTL(RTL._excl, 2)
Line 1505... Line 1520...
1505
 
1520
 
1506
        |IL.opLADR_INCL, IL.opLADR_EXCL:
1521
        |IL.opLADR_INCL, IL.opLADR_EXCL:
1507
            PushAll(1);
1522
            PushAll(1);
-
 
1523
            MovRR(SP, ACC);
-
 
1524
            n := LocalOffset(param2);
1508
            MovRR(BP, ACC);
1525
            IF n # 0 THEN
-
 
1526
                Op2(opADD, imm(n), ACC)
1509
            Op2(opADD, imm(param2 * 2), ACC);
1527
            END;
1510
            Push(ACC);
1528
            Push(ACC);
1511
            IF opcode = IL.opLADR_INCL THEN
1529
            IF opcode = IL.opLADR_INCL THEN
1512
                CallRTL(RTL._incl, 2)
1530
                CallRTL(RTL._incl, 2)
1513
            ELSIF opcode = IL.opLADR_EXCL THEN
1531
            ELSIF opcode = IL.opLADR_EXCL THEN
1514
                CallRTL(RTL._excl, 2)
1532
                CallRTL(RTL._excl, 2)
Line 1515... Line 1533...
1515
            END
1533
            END
1516
 
1534
 
Line 1517... Line 1535...
1517
        |IL.opLADR_INCLC:
1535
        |IL.opLADR_INCLC:
1518
            Op2(opBIS, imm(ORD({param2})), dst_x(param1 * 2, BP))
1536
            Op2(opBIS, imm(ORD({param2})), LocalDst(param1))
Line 1519... Line 1537...
1519
 
1537
 
Line 1520... Line 1538...
1520
        |IL.opLADR_EXCLC:
1538
        |IL.opLADR_EXCLC:
1521
            Op2(opBIC, imm(ORD({param2})), dst_x(param1 * 2, BP))
1539
            Op2(opBIC, imm(ORD({param2})), LocalDst(param1))
Line 1596... Line 1614...
1596
 
1614
 
1597
    RTL.Gen
1615
    RTL.Gen
Line 1598... Line -...
1598
END epilog;
-
 
1599
 
-
 
1600
 
-
 
1601
PROCEDURE hexdgt (n: BYTE): BYTE;
-
 
1602
BEGIN
-
 
1603
    IF n < 10 THEN
-
 
1604
        n := n + ORD("0")
-
 
1605
    ELSE
-
 
1606
        n := n - 10 + ORD("A")
-
 
1607
    END
-
 
1608
 
-
 
1609
    RETURN n
-
 
1610
END hexdgt;
-
 
1611
 
-
 
1612
 
-
 
1613
PROCEDURE WriteHexByte (file: FILES.FILE; byte: BYTE);
-
 
1614
BEGIN
-
 
1615
    WRITER.WriteByte(file, hexdgt(byte DIV 16));
-
 
1616
    WRITER.WriteByte(file, hexdgt(byte MOD 16));
-
 
1617
END WriteHexByte;
-
 
1618
 
-
 
1619
 
-
 
1620
PROCEDURE WriteHex (file: FILES.FILE; mem: ARRAY OF BYTE; idx, cnt: INTEGER);
-
 
1621
VAR
-
 
1622
    i, len, chksum: INTEGER;
-
 
1623
 
-
 
1624
BEGIN
-
 
1625
    WHILE cnt > 0 DO
-
 
1626
        len := MIN(cnt, 16);
-
 
1627
        chksum := len + idx DIV 256 + idx MOD 256;
-
 
1628
        WRITER.WriteByte(file, ORD(":"));
-
 
1629
        WriteHexByte(file, len);
-
 
1630
        WriteHexByte(file, idx DIV 256);
-
 
1631
        WriteHexByte(file, idx MOD 256);
-
 
1632
        WriteHexByte(file, 0);
-
 
1633
        FOR i := 1 TO len DO
-
 
1634
            WriteHexByte(file, mem[idx]);
-
 
1635
            INC(chksum, mem[idx]);
-
 
1636
            INC(idx)
-
 
1637
        END;
-
 
1638
        WriteHexByte(file, (-chksum) MOD 256);
-
 
1639
        DEC(cnt, len);
-
 
1640
        WRITER.WriteByte(file, 0DH);
-
 
1641
        WRITER.WriteByte(file, 0AH)
-
 
1642
    END
-
 
1643
END WriteHex;
1616
END epilog;
1644
 
1617
 
1645
 
1618
 
Line 1646... Line 1619...
1646
PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
1619
PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
Line 1647... Line 1620...
1647
VAR
1620
VAR
Line 1648... Line 1621...
1648
    i, adr, heap, stack, TextSize, TypesSize, bits, n: INTEGER;
1621
    i, adr, heap, stack, TextSize, TypesSize, bits, n: INTEGER;
Line 1649... Line 1622...
1649
 
1622
 
Line 1650... Line 1623...
1650
    Code, Data, Bss, Free: RECORD address, size: INTEGER END;
1623
    Code, Data, Bss, Free: RECORD address, size: INTEGER END;
1651
 
1624
 
1652
    ram, rom: INTEGER;
1625
    ram, rom: INTEGER;
Line 1692... Line 1665...
1692
 
1665
 
1693
    Code.address := 10000H - rom;
1666
    Code.address := 10000H - rom;
1694
    Code.size := Fixup(Code.address, IntVectorSize + TypesSize);
1667
    Code.size := Fixup(Code.address, IntVectorSize + TypesSize);
1695
    Data.address := Code.address + Code.size;
1668
    Data.address := Code.address + Code.size;
1696
    Data.size := CHL.Length(IL.codes.data);
1669
    Data.size := CHL.Length(IL.codes.data);
1697
    Data.size := Data.size + ORD(ODD(Data.size));
1670
    Data.size := Data.size + Data.size MOD 2;
Line 1698... Line 1671...
1698
    TextSize  := Code.size + Data.size;
1671
    TextSize  := Code.size + Data.size;
1699
 
1672
 
1700
    IF Code.address + TextSize + MAX(IL.codes.dmin - Data.size, IntVectorSize + TypesSize) > 10000H  THEN
1673
    IF Code.address + TextSize + MAX(IL.codes.dmin - Data.size, IntVectorSize + TypesSize) > 10000H  THEN
Line 1701... Line 1674...
1701
        ERRORS.Error(203)
1674
        ERRORS.Error(203)
1702
    END;
1675
    END;
1703
 
1676
 
1704
    Bss.address := RTL.ram + RTL.VarSize;
1677
    Bss.address := RTL.ram + RTL.VarSize;
1705
    Bss.size := IL.codes.bss + ORD(ODD(IL.codes.bss));
1678
    Bss.size := IL.codes.bss + IL.codes.bss MOD 2;
1706
    heap := Bss.address + Bss.size;
1679
    heap := Bss.address + Bss.size;
1707
    stack := RTL.ram + ram;
1680
    stack := RTL.ram + ram;
Line 1752... Line 1725...
1752
 
1725
 
1753
    PutWord(Free.address, adr);
1726
    PutWord(Free.address, adr);
1754
    PutWord(Free.size, adr);
1727
    PutWord(Free.size, adr);
1755
    PutWord(4130H, adr); (* RET *)
1728
    PutWord(4130H, adr); (* RET *)
-
 
1729
    PutWord(stack, adr);
Line 1756... Line 1730...
1756
    PutWord(stack, adr);
1730
    PutWord(0001H, adr); (* bsl signature (adr 0FFBEH) *)
1757
 
1731
 
1758
    FOR i := 0 TO LEN(IV) - 1 DO
1732
    FOR i := 0 TO LEN(IV) - 1 DO
Line 1759... Line 1733...
1759
        PutWord(LabelOffs(IV[i]) * 2, adr)
1733
        PutWord(LabelOffs(IV[i]) * 2, adr)
-
 
1734
    END;
1760
    END;
1735
 
1761
 
1736
    file := WR.Create(outname);
1762
    file := FILES.create(outname);
-
 
1763
    WriteHex(file, mem, Code.address, TextSize);
-
 
1764
    WriteHex(file, mem, 10000H - IntVectorSize - TypesSize, IntVectorSize + TypesSize);
-
 
1765
 
-
 
1766
    WRITER.WriteByte(file, ORD(":"));
-
 
1767
    WriteHexByte(file, 0);
1737
 
1768
    WriteHexByte(file, 0);
-
 
1769
    WriteHexByte(file, 0);
-
 
1770
    WriteHexByte(file, 1);
-
 
Line 1771... Line 1738...
1771
    WriteHexByte(file, 255);
1738
    HEX.Data(file, mem, Code.address, TextSize);
Line 1772... Line 1739...
1772
    WRITER.WriteByte(file, 0DH);
1739
    HEX.Data(file, mem, 10000H - IntVectorSize - TypesSize, IntVectorSize + TypesSize);
1773
    WRITER.WriteByte(file, 0AH);
1740
    HEX.End(file);
Line 1774... Line 1741...
1774
 
1741
 
Line 1782... Line 1749...
1782
    IF Free.size > 0 THEN
1749
    IF Free.size > 0 THEN
1783
        C.String(  "        "); C.Int(Free.size); C.String(" bytes free (0");
1750
        C.String(  "        "); C.Int(Free.size); C.String(" bytes free (0");
1784
            C.Hex(Free.address, 4); C.String("H..0"); C.Hex(Free.address + Free.size - 1, 4); C.StringLn("H)")
1751
            C.Hex(Free.address, 4); C.String("H..0"); C.Hex(Free.address + Free.size - 1, 4); C.StringLn("H)")
1785
    END;
1752
    END;
1786
    C.Ln;
1753
    C.Ln;
1787
    C.String(  "  ram:  "); C.Int(Bss.size); C.String(" of "); C.Int(ram); C.String("  ("); C.Int(Bss.size * 100 DIV ram); C.StringLn("%)");
1754
    C.String(  "  ram:  "); C.Int(Bss.size); C.String(" of "); C.Int(ram); C.String("  ("); C.Int(Bss.size * 100 DIV ram); C.StringLn("%)")
1788
    C.StringLn("--------------------------------------------")
-
 
Line 1789... Line 1755...
1789
 
1755
 
Line 1790... Line 1756...
1790
END CodeGen;
1756
END CodeGen;