Subversion Repositories Kolibri OS

Rev

Rev 8097 | Rev 9177 | 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) 2019-2020, Anton Krotov
4
    Copyright (c) 2019-2021, Anton Krotov
5
    All rights reserved.
5
    All rights reserved.
Line 6... Line 6...
6
*)
6
*)
Line 21... Line 21...
21
 
21
 
Line 22... Line 22...
22
    je = 0; jne = 1; jnb = 2; jb = 3; jge = 10; jl = 11; jg = 12; jle = 13;
22
    je = 0; jne = 1; jnb = 2; jb = 3; jge = 10; jl = 11; jg = 12; jle = 13;
Line 23... Line 23...
23
 
23
 
24
    inf = 7F800000H;
24
    inf = 7F800000H;
Line 25... Line 25...
25
 
25
 
Line -... Line 26...
-
 
26
    minROM* = 16; maxROM* = 65536;
-
 
27
    minRAM* = 4;  maxRAM* = 65536;
-
 
28
 
-
 
29
    maxIVT* = 1023;
-
 
30
 
-
 
31
    _THUMB2 = 0; _IT = 1; _SDIV = 2; _CBXZ = 3;
-
 
32
 
Line 26... Line 33...
26
    STM32_minROM* = 16; STM32_maxROM* = 65536;
33
    CortexM0  = {};
Line 27... Line 34...
27
    STM32_minRAM* = 4;  STM32_maxRAM* = 65536;
34
    CortexM1  = {};
Line 101... Line 108...
101
        FlashAdr,
108
        FlashAdr,
102
        SRAMAdr,
109
        SRAMAdr,
103
        IVTLen,
110
        IVTLen,
104
        MinStack,
111
        MinStack,
105
        Reserved: INTEGER;
112
        Reserved: INTEGER;
-
 
113
        InstrSet: SET;
106
        InstrSet: RECORD thumb2, it, cbxz, sdiv: BOOLEAN END
114
        isNXP: BOOLEAN
107
    END;
115
    END;
Line 108... Line 116...
108
 
116
 
Line 109... Line 117...
109
    IVT: ARRAY maxIVT + 1 OF INTEGER;
117
    IVT: ARRAY maxIVT + 1 OF INTEGER;
Line 473... Line 481...
473
END Cmp;
481
END Cmp;
Line 474... Line 482...
474
 
482
 
475
 
483
 
476
PROCEDURE Tst (r: INTEGER);
484
PROCEDURE Tst (r: INTEGER);
477
BEGIN
485
BEGIN
Line 478... Line 486...
478
    gen3(1, r, 0) (* cmp r, #0 *)
486
    gen3(1, r, 0) (* cmp r, 0 *)
479
END Tst;
487
END Tst;
Line 531... Line 539...
531
    code:    ANYCODE;
539
    code:    ANYCODE;
532
    count:   INTEGER;
540
    count:   INTEGER;
533
    shorted: BOOLEAN;
541
    shorted: BOOLEAN;
534
    jump:    JUMP;
542
    jump:    JUMP;
Line 535... Line -...
535
 
-
 
536
    first, second: INTEGER;
-
 
537
 
543
 
Line 538... Line 544...
538
    reloc, i, diff, len: INTEGER;
544
    reloc, i, diff, len: INTEGER;
Line 553... Line 559...
553
        ASSERT(srange(offset, 11))
559
        ASSERT(srange(offset, 11))
554
        RETURN 0E000H + offset MOD 2048
560
        RETURN 0E000H + offset MOD 2048
555
    END genjmp;
561
    END genjmp;
Line 556... Line -...
556
 
-
 
557
 
-
 
558
    PROCEDURE genlongjmp (offset: INTEGER; VAR first, second: INTEGER);
-
 
559
    BEGIN
-
 
560
        ASSERT(srange(offset, 22));
-
 
561
        first  := 0F000H + ASR(offset, 11) MOD 2048;
-
 
562
        second := 0F800H + offset MOD 2048
-
 
563
    END genlongjmp;
-
 
564
 
562
 
565
 
563
 
566
    PROCEDURE movwt (r, imm16, t: INTEGER; VAR code: RELOCCODE);
564
    PROCEDURE movwt (r, imm16, t: INTEGER; VAR code: RELOCCODE);
Line 567... Line 565...
567
    VAR
565
    VAR
Line 574... Line 572...
574
    END movwt;
572
    END movwt;
Line 575... Line 573...
575
 
573
 
576
 
574
 
577
    PROCEDURE genmovimm32 (r, value: INTEGER; VAR code: RELOCCODE);
575
    PROCEDURE genmovimm32 (r, value: INTEGER; VAR code: RELOCCODE);
578
    BEGIN
576
    BEGIN
579
        IF Target.InstrSet.thumb2 THEN
577
        IF _THUMB2 IN Target.InstrSet THEN
580
            movwt(r, low(value), 0, code);
578
            movwt(r, low(value), 0, code);
581
            movwt(r, high(value), 1, code)
579
            movwt(r, high(value), 1, code)
582
        ELSE
580
        ELSE
583
            code[0] := 2000H + r * 256 + UTILS.Byte(value, 3);  (* mov r, #imm8 *)
581
            code[0] := 2000H + r * 256 + UTILS.Byte(value, 3);  (* movs r, imm8 *)
584
            code[1] := 0200H + r * 9;                           (* lsl r, r, #8 *)
582
            code[1] := 0200H + r * 9;                           (* lsls r, 8    *)
585
            code[2] := 3000H + r * 256 + UTILS.Byte(value, 2);  (* add r, #imm8 *)
583
            code[2] := 3000H + r * 256 + UTILS.Byte(value, 2);  (* adds r, imm8 *)
586
            code[3] := code[1];                                 (* lsl r, r, #8 *)
584
            code[3] := code[1];                                 (* lsls r, 8    *)
587
            code[4] := 3000H + r * 256 + UTILS.Byte(value, 1);  (* add r, #imm8 *)
585
            code[4] := 3000H + r * 256 + UTILS.Byte(value, 1);  (* adds r, imm8 *)
588
            code[5] := code[1];                                 (* lsl r, r, #8 *)
586
            code[5] := code[1];                                 (* lsls r, 8    *)
589
            code[6] := 3000H + r * 256 + UTILS.Byte(value, 0)   (* add r, #imm8 *)
587
            code[6] := 3000H + r * 256 + UTILS.Byte(value, 0)   (* adds r, imm8 *)
Line 590... Line 588...
590
        END
588
        END
591
    END genmovimm32;
589
    END genmovimm32;
592
 
590
 
593
 
591
 
Line 594... Line 592...
594
    PROCEDURE PutCode (code: INTEGER);
592
    PROCEDURE PutCode (code: INTEGER);
595
    BEGIN
593
    BEGIN
596
        BIN.PutCode16LE(program, code)
594
        BIN.PutCode16LE(program, code)
-
 
595
    END PutCode;
-
 
596
 
-
 
597
 
Line -... Line 598...
-
 
598
    PROCEDURE genlongjmp (offset: INTEGER);
-
 
599
    BEGIN
597
    END PutCode;
600
        ASSERT(srange(offset, 22));
598
 
601
        PutCode(0F000H + ASR(offset, 11) MOD 2048);
599
 
602
        PutCode(0F800H + offset MOD 2048)
600
    PROCEDURE genbc (code: JUMP);
603
    END genlongjmp;
601
    VAR
604
 
602
        first, second: INTEGER;
605
 
603
 
606
    PROCEDURE genbc (code: JUMP);
604
    BEGIN
-
 
605
        CASE code.len OF
-
 
606
        |1: PutCode(genjcc(code.cond, code.diff))
607
    BEGIN
607
        |2: PutCode(genjcc(inv0(code.cond), 0));
608
        CASE code.len OF
Line 608... Line 609...
608
            PutCode(genjmp(code.diff))
609
        |1: PutCode(genjcc(code.cond, code.diff))
Line 645... Line 646...
645
 
646
 
646
            CASE code OF
647
            CASE code OF
647
            |CODE:  INC(count)
648
            |CODE:  INC(count)
648
            |LABEL: BIN.SetLabel(program, code.label, count)
649
            |LABEL: BIN.SetLabel(program, code.label, count)
649
            |JUMP:  INC(count, code.len); code.offset := count + ORD(code.short)
650
            |JUMP:  INC(count, code.len); code.offset := count + ORD(code.short)
650
            |RELOC: INC(count, 7 - ORD(Target.InstrSet.thumb2) * 3 + code.rel MOD 2)
651
            |RELOC: INC(count, 7 - ORD(_THUMB2 IN Target.InstrSet) * 3 + code.rel MOD 2)
Line 651... Line 652...
651
            END;
652
            END;
652
 
653
 
Line 712... Line 713...
712
 
713
 
713
        |JMP:
714
        |JMP:
714
                IF code.len = 1 THEN
715
                IF code.len = 1 THEN
715
                    PutCode(genjmp(code.diff))
716
                    PutCode(genjmp(code.diff))
716
                ELSE
717
                ELSE
717
                    genlongjmp(code.diff, first, second);
-
 
718
                    PutCode(first);
-
 
719
                    PutCode(second)
718
                    genlongjmp(code.diff)
Line 720... Line 719...
720
                END
719
                END
Line 721... Line 720...
721
 
720
 
722
        |JCC:   genbc(code)
721
        |JCC:   genbc(code)
723
 
722
 
724
        |CBXZ:
723
        |CBXZ:
725
                IF code.len > 1 THEN
724
                IF code.len > 1 THEN
726
                    PutCode(2800H + code.reg * 256); (* cmp code.reg, #0 *)
725
                    PutCode(2800H + code.reg * 256); (* cmp code.reg, 0 *)
727
                    DEC(code.len);
726
                    DEC(code.len);
728
                    genbc(code)
727
                    genbc(code)
729
                ELSE
728
                ELSE
Line 730... Line -...
730
                    (* cb(n)z code.reg, L *)
-
 
731
                    PutCode(0B100H + 800H * ORD(code.cond = jne) + 200H * ORD(code.diff >= 32) + (code.diff MOD 32) * 8 + code.reg)
729
                    (* cb(n)z code.reg, L *)
732
                END
-
 
733
 
-
 
Line 734... Line 730...
734
        |CALL:
730
                    PutCode(0B100H + 800H * ORD(code.cond = jne) + 200H * (code.diff DIV 32) + (code.diff MOD 32) * 8 + code.reg)
735
                genlongjmp(code.diff, first, second);
731
                END
736
                PutCode(first);
732
 
737
                PutCode(second)
733
        |CALL:  genlongjmp(code.diff)
738
 
734
 
739
        |RELOC:
735
        |RELOC:
740
                CASE code.rel OF
736
                CASE code.rel OF
741
                |BIN.RCODE, BIN.PICCODE: reloc := BIN.GetLabel(program, code.value) * 2 + CodeAdr
737
                |BIN.RCODE, BIN.PICCODE: reloc := BIN.GetLabel(program, code.value) * 2 + CodeAdr
742
                |BIN.RDATA, BIN.PICDATA: reloc := code.value + DataAdr
738
                |BIN.RDATA, BIN.PICDATA: reloc := code.value + DataAdr
743
                |BIN.RBSS,  BIN.PICBSS:  reloc := code.value + BssAdr
739
                |BIN.RBSS,  BIN.PICBSS:  reloc := code.value + BssAdr
744
                END;
740
                END;
745
                IF code.rel IN {BIN.PICCODE, BIN.PICDATA, BIN.PICBSS} THEN
741
                IF code.rel IN {BIN.PICCODE, BIN.PICDATA, BIN.PICBSS} THEN
746
                    DEC(reloc, CodeAdr + 2 * (code.offset - 3 * ORD(Target.InstrSet.thumb2) + 9))
742
                    DEC(reloc, CodeAdr + 2 * (code.offset - 3 * ORD(_THUMB2 IN Target.InstrSet) + 9))
747
                END;
743
                END;
748
                genmovimm32(code.reg, reloc, RelocCode);
744
                genmovimm32(code.reg, reloc, RelocCode);
749
                FOR i := 0 TO 6 - 3 * ORD(Target.InstrSet.thumb2) DO
745
                FOR i := 0 TO 6 - 3 * ORD(_THUMB2 IN Target.InstrSet) DO
750
                    PutCode(RelocCode[i])
746
                    PutCode(RelocCode[i])
Line 751... Line 747...
751
                END;
747
                END;
752
                IF code.rel IN {BIN.PICCODE, BIN.PICDATA, BIN.PICBSS} THEN
748
                IF code.rel IN {BIN.PICCODE, BIN.PICDATA, BIN.PICBSS} THEN
Line 856... Line 852...
856
        LslImm(r, UTILS.Log2(c))
852
        LslImm(r, UTILS.Log2(c))
857
    ELSIF c = UTILS.min32 THEN
853
    ELSIF c = UTILS.min32 THEN
858
        MovImm8(r, 1);
854
        MovImm8(r, 1);
859
        LslImm(r, 31)
855
        LslImm(r, 31)
860
    ELSE
856
    ELSE
861
        IF Target.InstrSet.thumb2 THEN
857
        IF _THUMB2 IN Target.InstrSet THEN
862
            movwt(r, low(c), 0);
858
            movwt(r, low(c), 0);
863
            IF (c < 0) OR (c > 65535) THEN
859
            IF (c < 0) OR (c > 65535) THEN
864
                movwt(r, high(c), 1)
860
                movwt(r, high(c), 1)
865
            END
861
            END
866
        ELSE
862
        ELSE
Line 895... Line 891...
895
PROCEDURE SetCC (cc, r: INTEGER);
891
PROCEDURE SetCC (cc, r: INTEGER);
896
VAR
892
VAR
897
    L1, L2: INTEGER;
893
    L1, L2: INTEGER;
Line 898... Line 894...
898
 
894
 
899
BEGIN
895
BEGIN
900
    IF Target.InstrSet.it THEN
896
    IF _IT IN Target.InstrSet THEN
901
        Code(0BF00H + cc * 16 + ((cc + 1) MOD 2) * 8 + 4); (* ite cc *)
897
        Code(0BF00H + cc * 16 + ((cc + 1) MOD 2) * 8 + 4); (* ite cc *)
902
        MovConst(r, 1);
898
        MovConst(r, 1);
903
        MovConst(r, 0)
899
        MovConst(r, 0)
904
    ELSE
900
    ELSE
Line 936... Line 932...
936
            IF n > 0 THEN
932
            IF n > 0 THEN
937
                AddImm8(r, n)
933
                AddImm8(r, n)
938
            ELSE
934
            ELSE
939
                SubImm8(r, -n)
935
                SubImm8(r, -n)
940
            END
936
            END
941
        ELSIF Target.InstrSet.thumb2 & (-4095 <= n) & (n <= 4095) THEN
937
        ELSIF (_THUMB2 IN Target.InstrSet) & (-4095 <= n) & (n <= 4095) THEN
942
            IF n > 0 THEN
-
 
943
                AddSubImm12(r, n, FALSE)
-
 
944
            ELSE
-
 
945
                AddSubImm12(r, -n, TRUE)
938
            AddSubImm12(r, ABS(n), n < 0)
946
            END
-
 
947
        ELSE
939
        ELSE
948
            r2 := GetAnyReg();
940
            r2 := GetAnyReg();
949
            ASSERT(r2 # r);
941
            ASSERT(r2 # r);
950
            IF n > 0 THEN
942
            IF n > 0 THEN
951
                MovConst(r2, n);
943
                MovConst(r2, n);
Line 980... Line 972...
980
        DEC(StkCount, n)
972
        DEC(StkCount, n)
981
    END
973
    END
982
END AddSP;
974
END AddSP;
Line 983... Line 975...
983
 
975
 
984
 
976
 
985
PROCEDURE cbz (r, label: INTEGER);
977
PROCEDURE cbxz2 (c, r, label: INTEGER);
986
BEGIN
978
BEGIN
987
    IF Target.InstrSet.cbxz THEN
979
    IF _CBXZ IN Target.InstrSet THEN
988
        cbxz(je, r, label)
980
        cbxz(c, r, label)
989
    ELSE
981
    ELSE
990
        Tst(r);
982
        Tst(r);
-
 
983
        jcc(c, label)
-
 
984
    END
-
 
985
END cbxz2;
-
 
986
 
-
 
987
 
-
 
988
PROCEDURE cbz (r, label: INTEGER);
991
        jcc(je, label)
989
BEGIN
Line 992... Line 990...
992
    END
990
    cbxz2(je, r, label)
993
END cbz;
991
END cbz;
994
 
-
 
995
 
992
 
996
PROCEDURE cbnz (r, label: INTEGER);
-
 
997
BEGIN
-
 
998
    IF Target.InstrSet.cbxz THEN
-
 
999
        cbxz(jne, r, label)
-
 
1000
    ELSE
993
 
Line 1001... Line 994...
1001
        Tst(r);
994
PROCEDURE cbnz (r, label: INTEGER);
1002
        jcc(jne, label)
995
BEGIN
Line 1051... Line 1044...
1051
    call(sdivProc);
1044
    call(sdivProc);
1052
    AddSP(2)
1045
    AddSP(2)
1053
END divmod;
1046
END divmod;
Line -... Line 1047...
-
 
1047
 
-
 
1048
 
-
 
1049
PROCEDURE cpsid_i;
-
 
1050
BEGIN
-
 
1051
    Code(0B672H)  (*  cpsid i  *)
-
 
1052
END cpsid_i;
-
 
1053
 
-
 
1054
 
-
 
1055
PROCEDURE cpsie_i;
-
 
1056
BEGIN
-
 
1057
    Code(0B662H)  (*  cpsie i  *)
-
 
1058
END cpsie_i;
1054
 
1059
 
1055
 
1060
 
1056
PROCEDURE translate (pic, stroffs: INTEGER);
1061
PROCEDURE translate (pic, stroffs: INTEGER);
1057
VAR
1062
VAR
Line 1101... Line 1106...
1101
        |IL.opENTER:
1106
        |IL.opENTER:
1102
            ASSERT(R.top = -1);
1107
            ASSERT(R.top = -1);
Line 1103... Line 1108...
1103
 
1108
 
Line 1104... Line 1109...
1104
            Label(param1);
1109
            Label(param1);
Line 1105... Line 1110...
1105
 
1110
 
1106
            gen14(FALSE, TRUE, {}); (* push LR *)
1111
            gen14(FALSE, TRUE, {}); (* push {lr} *)
1107
 
1112
 
1108
            n := param2;
1113
            n := param2;
Line 1126... Line 1131...
1126
 
1131
 
1127
        |IL.opLEAVE, IL.opLEAVER, IL.opLEAVEF:
1132
        |IL.opLEAVE, IL.opLEAVER, IL.opLEAVEF:
1128
            IF opcode # IL.opLEAVE THEN
1133
            IF opcode # IL.opLEAVE THEN
1129
                UnOp(r1);
1134
                UnOp(r1);
1130
                IF r1 # ACC THEN
-
 
1131
                    GetRegA;
-
 
1132
                    ASSERT(REG.Exchange(R, r1, ACC));
1135
                IF r1 # ACC THEN
1133
                    drop
1136
                    mov(ACC, r1)
1134
                END;
1137
                END;
1135
                drop
1138
                drop
Line 1136... Line 1139...
1136
            END;
1139
            END;
1137
 
1140
 
Line 1138... Line 1141...
1138
            ASSERT(R.top = -1);
1141
            ASSERT(R.top = -1);
1139
            ASSERT(StkCount = param1);
1142
            ASSERT(StkCount = param1);
Line 1140... Line 1143...
1140
 
1143
 
1141
            AddSP(param1);
1144
            AddSP(param1);
Line 1142... Line 1145...
1142
            gen14(TRUE, TRUE, {}) (* pop PC *)
1145
            gen14(TRUE, TRUE, {}) (* pop {pc} *)
1143
 
1146
 
Line 1144... Line 1147...
1144
        |IL.opLEAVEC:
1147
        |IL.opLEAVEC:
Line 1167... Line 1170...
1167
 
1170
 
1168
        |IL.opPUSHC:
1171
        |IL.opPUSHC:
Line 1169... Line 1172...
1169
            PushConst(param2)
1172
            PushConst(param2)
-
 
1173
 
1170
 
1174
        |IL.opONERR:
1171
        |IL.opONERR:
1175
            cpsid_i;
1172
            MovConst(R0, param2);
1176
            MovConst(R0, param2);
1173
            push(R0);
1177
            push(R0);
Line 1201... Line 1205...
1201
        |IL.opGLOAD8:
1205
        |IL.opGLOAD8:
1202
            r1 := GetAnyReg();
1206
            r1 := GetAnyReg();
1203
            reloc(r1, BIN.RBSS + pic, param2);
1207
            reloc(r1, BIN.RBSS + pic, param2);
1204
            Ldr8(r1, r1)
1208
            Ldr8(r1, r1)
Line -... Line 1209...
-
 
1209
 
-
 
1210
        |IL.opLADR_SAVE:
-
 
1211
            UnOp(r1);
-
 
1212
            n := LocalOffset(param2);
-
 
1213
            IF n <= 255 THEN
-
 
1214
                gen11(FALSE, r1, n)  (* str r1, [sp, n*4] *)
-
 
1215
            ELSE
-
 
1216
                LocAdr(param2);
-
 
1217
                BinOp(r1, r2);
-
 
1218
                Str32(r1, r2);
-
 
1219
                drop
-
 
1220
            END;
-
 
1221
            drop
-
 
1222
 
-
 
1223
        |IL.opLADR_INCC:
-
 
1224
            n := LocalOffset(param1);
-
 
1225
            IF n <= 255 THEN
-
 
1226
                r1 := GetAnyReg();
-
 
1227
                LdrSp(r1, n);
-
 
1228
                AddConst(r1, param2);
-
 
1229
                gen11(FALSE, r1, n)  (* str r1, [sp, n*4] *)
-
 
1230
            ELSE
-
 
1231
                LocAdr(param1);
-
 
1232
                r1 := GetAnyReg();
-
 
1233
                BinOp(r2, r1);
-
 
1234
                Ldr32(r1, r2);
-
 
1235
                AddConst(r1, param2);
-
 
1236
                BinOp(r2, r1);
-
 
1237
                Str32(r1, r2);
-
 
1238
                drop
-
 
1239
            END;
-
 
1240
            drop
1205
 
1241
 
1206
        |IL.opLLOAD32, IL.opVADR, IL.opVLOAD32:
1242
        |IL.opLLOAD32, IL.opVADR, IL.opVLOAD32:
1207
            r1 := GetAnyReg();
1243
            r1 := GetAnyReg();
1208
            n := LocalOffset(param2);
1244
            n := LocalOffset(param2);
1209
            IF n <= 255 THEN
1245
            IF n <= 255 THEN
Line 1400... Line 1436...
1400
            drop
1436
            drop
Line 1401... Line 1437...
1401
 
1437
 
1402
        |IL.opCASELR:
1438
        |IL.opCASELR:
1403
            GetRegA;
1439
            GetRegA;
-
 
1440
            CmpConst(ACC, param1);
-
 
1441
            IF param2 = cmd.param3 THEN
-
 
1442
                jcc(jne, param2)
1404
            CmpConst(ACC, param1);
1443
            ELSE
1405
            jcc(jl, param2);
1444
                jcc(jl, param2);
-
 
1445
                jcc(jg, cmd.param3)
1406
            jcc(jg, cmd.param3);
1446
            END;
Line 1407... Line 1447...
1407
            drop
1447
            drop
1408
 
1448
 
Line 1547... Line 1587...
1547
            Tst(r1);
1587
            Tst(r1);
1548
            SetCC(jne, r1)
1588
            SetCC(jne, r1)
Line 1549... Line 1589...
1549
 
1589
 
1550
        |IL.opCHR:
1590
        |IL.opCHR:
1551
            UnOp(r1);
1591
            UnOp(r1);
Line 1552... Line 1592...
1552
            Code(0B2C0H + r1 * 9) (* uxtb r1 *)
1592
            Code(0B2C0H + r1 * 9) (* uxtb r1, r1 *)
1553
 
1593
 
1554
        |IL.opWCHR:
1594
        |IL.opWCHR:
Line 1555... Line 1595...
1555
            UnOp(r1);
1595
            UnOp(r1);
1556
            Code(0B280H + r1 * 9) (* uxth r1 *)
1596
            Code(0B280H + r1 * 9) (* uxth r1, r1 *)
1557
 
1597
 
1558
        |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR:
1598
        |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR:
Line 1613... Line 1653...
1613
            END;
1653
            END;
Line 1614... Line 1654...
1614
 
1654
 
1615
            INCL(R.regs, r1);
1655
            INCL(R.regs, r1);
Line 1616... Line -...
1616
            ASSERT(REG.GetReg(R, r1))
-
 
1617
 
-
 
1618
        |IL.opLOOP, IL.opENDLOOP:
1656
            ASSERT(REG.GetReg(R, r1))
1619
 
1657
 
Line 1620... Line 1658...
1620
        |IL.opINF:
1658
        |IL.opINF:
1621
            MovConst(GetAnyReg(), inf)
1659
            MovConst(GetAnyReg(), inf)
Line 1718... Line 1756...
1718
            MovConst(r1, param2);
1756
            MovConst(r1, param2);
1719
            Label(L)
1757
            Label(L)
Line 1720... Line 1758...
1720
 
1758
 
1721
        |IL.opMULS:
1759
        |IL.opMULS:
1722
            BinOp(r1, r2);
1760
            BinOp(r1, r2);
1723
            gen4(0, r2, r1); (* and r1, r2 *)
1761
            gen4(0, r2, r1); (* ands r1, r2 *)
Line 1724... Line 1762...
1724
            drop
1762
            drop
1725
 
1763
 
1726
        |IL.opMULSC:
1764
        |IL.opMULSC:
1727
            MovConst(GetAnyReg(), param2);
1765
            MovConst(GetAnyReg(), param2);
1728
            BinOp(r1, r2);
1766
            BinOp(r1, r2);
Line 1729... Line 1767...
1729
            gen4(0, r2, r1); (* and r1, r2 *)
1767
            gen4(0, r2, r1); (* ands r1, r2 *)
1730
            drop
1768
            drop
1731
 
1769
 
1732
        |IL.opDIVS:
1770
        |IL.opDIVS:
Line 1733... Line 1771...
1733
            BinOp(r1, r2);
1771
            BinOp(r1, r2);
1734
            gen4(1, r2, r1); (* eor r1, r2 *)
1772
            gen4(1, r2, r1); (* eors r1, r2 *)
1735
            drop
1773
            drop
1736
 
1774
 
1737
        |IL.opDIVSC:
1775
        |IL.opDIVSC:
Line 1738... Line 1776...
1738
            MovConst(GetAnyReg(), param2);
1776
            MovConst(GetAnyReg(), param2);
1739
            BinOp(r1, r2);
1777
            BinOp(r1, r2);
1740
            gen4(1, r2, r1); (* eor r1, r2 *)
1778
            gen4(1, r2, r1); (* eors r1, r2 *)
1741
            drop
1779
            drop
Line 1742... Line 1780...
1742
 
1780
 
1743
        |IL.opADDS:
1781
        |IL.opADDS:
1744
            BinOp(r1, r2);
1782
            BinOp(r1, r2);
1745
            gen4(12, r2, r1); (* orr r1, r2 *)
1783
            gen4(12, r2, r1); (* orrs r1, r2 *)
Line 1746... Line 1784...
1746
            drop
1784
            drop
1747
 
1785
 
1748
        |IL.opSUBS:
1786
        |IL.opSUBS:
1749
            BinOp(r1, r2);
1787
            BinOp(r1, r2);
1750
            gen4(14, r2, r1); (* bic r1, r2 *)
1788
            gen4(14, r2, r1); (* bics r1, r2 *)
Line 1751... Line 1789...
1751
            drop
1789
            drop
1752
 
1790
 
1753
        |IL.opADDSC:
1791
        |IL.opADDSC:
1754
            MovConst(GetAnyReg(), param2);
1792
            MovConst(GetAnyReg(), param2);
1755
            BinOp(r1, r2);
1793
            BinOp(r1, r2);
1756
            gen4(12, r2, r1); (* orr r1, r2 *)
1794
            gen4(12, r2, r1); (* orrs r1, r2 *)
1757
            drop
1795
            drop
Line 1758... Line 1796...
1758
 
1796
 
1759
        |IL.opSUBSL:
1797
        |IL.opSUBSL:
1760
            MovConst(GetAnyReg(), param2);
1798
            MovConst(GetAnyReg(), param2);
1761
            BinOp(r1, r2);
1799
            BinOp(r1, r2);
1762
            gen4(14, r1, r2); (* bic r2, r1 *)
1800
            gen4(14, r1, r2); (* bics r2, r1 *)
Line 1763... Line 1801...
1763
            INCL(R.regs, r1);
1801
            INCL(R.regs, r1);
1764
            DEC(R.top);
1802
            DEC(R.top);
1765
            R.stk[R.top] := r2
1803
            R.stk[R.top] := r2
Line 1766... Line 1804...
1766
 
1804
 
1767
        |IL.opSUBSR:
1805
        |IL.opSUBSR:
1768
            MovConst(GetAnyReg(), param2);
1806
            MovConst(GetAnyReg(), param2);
1769
            BinOp(r1, r2);
1807
            BinOp(r1, r2);
1770
            gen4(14, r2, r1); (* bic r1, r2 *)
1808
            gen4(14, r2, r1); (* bics r1, r2 *)
1771
            drop
1809
            drop
1772
 
1810
 
1773
        |IL.opUMINS:
1811
        |IL.opUMINS:
1774
            UnOp(r1);
1812
            UnOp(r1);
1775
            gen4(15, r1, r1) (* mvn r1, r1 *)
1813
            gen4(15, r1, r1) (* mvns r1, r1 *)
1776
 
1814
 
1777
        |IL.opINCL, IL.opEXCL:
1815
        |IL.opINCL, IL.opEXCL:
1778
            BinOp(r1, r2);
1816
            BinOp(r1, r2);
1779
            r3 := GetAnyReg();
1817
            r3 := GetAnyReg();
1780
            MovConst(r3, 1);
1818
            MovConst(r3, 1);
1781
            CmpConst(r1, 32);
1819
            CmpConst(r1, 32);
1782
            L := NewLabel();
1820
            L := NewLabel();
1783
            jcc(jnb, L);
1821
            jcc(jnb, L);
Line 1800... Line 1838...
1800
            r3 := GetAnyReg();
1838
            r3 := GetAnyReg();
1801
            MovConst(r3, 1);
1839
            MovConst(r3, 1);
1802
            LslImm(r3, param2);
1840
            LslImm(r3, param2);
1803
            Ldr32(r1, r2);
1841
            Ldr32(r1, r2);
1804
            IF opcode = IL.opINCLC THEN
1842
            IF opcode = IL.opINCLC THEN
1805
                gen4(12, r3, r1) (* orr r1, r3 *)
1843
                gen4(12, r3, r1) (* orrs r1, r3 *)
1806
            ELSE
1844
            ELSE
1807
                gen4(14, r3, r1) (* bic r1, r3 *)
1845
                gen4(14, r3, r1) (* bics r1, r3 *)
1808
            END;
1846
            END;
1809
            Str32(r1, r2);
1847
            Str32(r1, r2);
1810
            drop;
1848
            drop;
1811
            drop;
1849
            drop;
1812
            drop
1850
            drop
Line 1900... Line 1938...
1900
        |IL.opMODR:
1938
        |IL.opMODR:
1901
            n := UTILS.Log2(param2);
1939
            n := UTILS.Log2(param2);
1902
            IF n > 0 THEN
1940
            IF n > 0 THEN
1903
                UnOp(r1);
1941
                UnOp(r1);
1904
                IF n = 8 THEN
1942
                IF n = 8 THEN
1905
                    Code(0B2C0H + r1 * 9) (* uxtb r1 *)
1943
                    Code(0B2C0H + r1 * 9) (* uxtb r1, r1 *)
1906
                ELSIF n = 16 THEN
1944
                ELSIF n = 16 THEN
1907
                    Code(0B280H + r1 * 9) (* uxth r1 *)
1945
                    Code(0B280H + r1 * 9) (* uxth r1, r1 *)
1908
                ELSE
1946
                ELSE
1909
                    LslImm(r1, 32 - n);
1947
                    LslImm(r1, 32 - n);
1910
                    LsrImm(r1, 32 - n)
1948
                    LsrImm(r1, 32 - n)
1911
                END
1949
                END
1912
            ELSIF n < 0 THEN
1950
            ELSIF n < 0 THEN
Line 1944... Line 1982...
1944
            MovConst(r1, 0);
1982
            MovConst(r1, 0);
1945
            jmp(L2);
1983
            jmp(L2);
1946
            Label(L);
1984
            Label(L);
1947
            MovConst(r3, 1);
1985
            MovConst(r3, 1);
1948
            Shift(IL.opLSL, r3, r1);
1986
            Shift(IL.opLSL, r3, r1);
1949
            gen4(0, r3, r2); (* and r2, r3 *)
1987
            gen4(0, r3, r2); (* ands r2, r3 *)
1950
            SetCC(jne, r1);
1988
            SetCC(jne, r1);
1951
            Label(L2);
1989
            Label(L2);
1952
            drop;
1990
            drop;
1953
            drop
1991
            drop
Line 1954... Line 1992...
1954
 
1992
 
1955
        |IL.opINL:
1993
        |IL.opINL:
1956
            UnOp(r1);
1994
            UnOp(r1);
1957
            r2 := GetAnyReg();
1995
            r2 := GetAnyReg();
1958
            MovConst(r2, LSL(1, param2));
1996
            MovConst(r2, LSL(1, param2));
1959
            gen4(0, r2, r1); (* and r1, r2 *)
1997
            gen4(0, r2, r1); (* ands r1, r2 *)
1960
            SetCC(jne, r1);
1998
            SetCC(jne, r1);
Line 1961... Line 1999...
1961
            drop
1999
            drop
1962
 
2000
 
Line 2037... Line 2075...
2037
        |IL.opUMINF:
2075
        |IL.opUMINF:
2038
            UnOp(r1);
2076
            UnOp(r1);
2039
            r2 := GetAnyReg();
2077
            r2 := GetAnyReg();
2040
            MovConst(r2, 1);
2078
            MovConst(r2, 1);
2041
            LslImm(r2, 31);
2079
            LslImm(r2, 31);
2042
            gen4(1, r2, r1); (* eor r1, r2 *)
2080
            gen4(1, r2, r1); (* eors r1, r2 *)
2043
            drop
2081
            drop
Line 2044... Line 2082...
2044
 
2082
 
2045
        |IL.opFABS:
2083
        |IL.opFABS:
2046
            UnOp(r1);
2084
            UnOp(r1);
2047
            r2 := GetAnyReg();
2085
            r2 := GetAnyReg();
2048
            MovConst(r2, 1);
2086
            MovConst(r2, 1);
2049
            LslImm(r2, 31);
2087
            LslImm(r2, 31);
2050
            gen4(14, r2, r1); (* bic r1, r2 *)
2088
            gen4(14, r2, r1); (* bics r1, r2 *)
Line 2051... Line 2089...
2051
            drop
2089
            drop
-
 
2090
 
2052
 
2091
        |IL.opNEW:
2053
        |IL.opNEW:
2092
            cpsid_i;
2054
            PushAll(1);
2093
            PushAll(1);
2055
            n := param2 + 8;
2094
            n := param2 + 4;
2056
            ASSERT(UTILS.Align(n, 32));
2095
            ASSERT(UTILS.Align(n, 4));
2057
            PushConst(n);
2096
            PushConst(n);
-
 
2097
            PushConst(param1);
Line 2058... Line 2098...
2058
            PushConst(param1);
2098
            CallRTL(IL._new, 3);
2059
            CallRTL(IL._new, 3)
2099
            cpsie_i
2060
 
2100
 
2061
        |IL.opTYPEGP:
2101
        |IL.opTYPEGP:
Line 2130... Line 2170...
2130
    ASSERT(R.pushed = 0);
2170
    ASSERT(R.pushed = 0);
2131
    ASSERT(R.top = -1)
2171
    ASSERT(R.top = -1)
2132
END translate;
2172
END translate;
Line 2133... Line 2173...
2133
 
2173
 
2134
 
2174
 
2135
PROCEDURE prolog (GlobSize, tcount, pic, FlashAdr, sp, ivt_len: INTEGER);
2175
PROCEDURE prolog (GlobSize, tcount, pic, sp, ivt_len: INTEGER);
Line 2136... Line 2176...
2136
VAR
2176
VAR
2137
    r1, r2, i, dcount: INTEGER;
2177
    r1, r2, i, dcount: INTEGER;
Line 2156... Line 2196...
2156
        Code(low(IVT[i]));
2196
        Code(low(IVT[i]));
2157
        Code(high(IVT[i]))
2197
        Code(high(IVT[i]))
2158
    END;
2198
    END;
Line 2159... Line 2199...
2159
 
2199
 
-
 
2200
    Label(entry);
Line 2160... Line 2201...
2160
    Label(entry);
2201
    cpsie_i;
2161
 
2202
 
2162
    r1 := GetAnyReg();
2203
    r1 := GetAnyReg();
Line 2199... Line 2240...
2199
PROCEDURE epilog;
2240
PROCEDURE epilog;
2200
VAR
2241
VAR
2201
    L1, L2, L3, L4: INTEGER;
2242
    L1, L2, L3, L4: INTEGER;
Line 2202... Line 2243...
2202
 
2243
 
2203
BEGIN
2244
BEGIN
2204
    Code(0BF30H);  (* L2: wfi *)
2245
                   (* L2:  *)
Line 2205... Line 2246...
2205
    Code(0E7FDH);  (* b L2    *)
2246
    Code(0E7FEH);  (* b L2 *)
2206
 
2247
 
2207
    Label(genInt);
2248
    Label(genInt);
2208
    Code(0F3EFH); Code(08105H);  (* mrs r1, ipsr  *)
2249
    Code(0F3EFH); Code(08005H);  (* mrs r0, ipsr  *)
2209
    gen14(FALSE, TRUE, {R1});    (* push {LR, R1} *)
2250
    gen14(FALSE, TRUE, {R0});    (* push {lr, r0} *)
Line 2210... Line 2251...
2210
    call(int0);
2251
    call(int0);
2211
    gen14(TRUE, TRUE, {R1});     (* pop {PC, R1}  *)
2252
    gen14(TRUE, TRUE, {R0});     (* pop {pc, r0}  *)
Line 2212... Line 2253...
2212
 
2253
 
2213
    Label(emptyProc);
2254
    Label(emptyProc);
2214
    Code(04770H);  (* bx lr *)
2255
    Code(04770H);  (* bx lr *)
Line 2215... Line 2256...
2215
 
2256
 
2216
    Label(genTrap);
2257
    Label(genTrap);
2217
    call(trap);
2258
    call(trap);
2218
    call(entry);
2259
    call(entry);
2219
 
2260
 
2220
    Label(sdivProc);
2261
    Label(sdivProc);
2221
    IF Target.InstrSet.sdiv THEN
2262
    IF _SDIV IN Target.InstrSet THEN
2222
        Code(09800H);  (* ldr  r0, [sp + #0] *)
2263
        Code(09800H);  (* ldr  r0, [sp]    *)
2223
        Code(09901H);  (* ldr  r1, [sp + #4] *)
2264
        Code(09901H);  (* ldr  r1, [sp, 4] *)
2224
        Code(0FB91H);  (* sdiv r2, r1, r0    *)
2265
        Code(0FB91H);  (* sdiv r2, r1, r0  *)
2225
        Code(0F2F0H);
2266
        Code(0F2F0H);
2226
        Code(00013H);  (* mov  r3, r2        *)
2267
        Code(00013H);  (* movs r3, r2      *)
2227
        Code(04343H);  (* mul  r3, r0        *)
2268
        Code(04343H);  (* muls r3, r0, r3  *)
2228
        Code(01AC9H);  (* sub  r1, r3        *)
2269
        Code(01AC9H);  (* subs r1, r1, r3  *)
2229
        Code(0DA01H);  (* bge  L             *)
2270
        Code(0DA01H);  (* bge  L           *)
2230
        Code(04401H);  (* add  r1, r0        *)
2271
        Code(01809H);  (* adds r1, r1, r0  *)
2231
        Code(03A01H);  (* sub  r2, #1        *)
2272
        Code(03A01H);  (* subs r2, 1       *)
2232
                       (* L:                 *)
2273
                       (* L:               *)
2233
        Code(00010H);  (* mov  r0, r2        *)
2274
        Code(00010H);  (* movs r0, r2      *)
Line 2301... Line 2342...
2301
    END
2342
    END
Line 2302... Line 2343...
2302
 
2343
 
Line 2303... Line 2344...
2303
END epilog;
2344
END epilog;
2304
 
2345
 
2305
 
2346
 
2306
PROCEDURE CortexM3;
2347
PROCEDURE SetTarget (FlashStart, SRAMStart: INTEGER; InstrSet: SET; isNXP: BOOLEAN);
-
 
2348
BEGIN
-
 
2349
    Target.FlashAdr := FlashStart;
-
 
2350
    Target.SRAMAdr  := SRAMStart;
2307
BEGIN
2351
    Target.InstrSet := InstrSet;
2308
    Target.FlashAdr := 08000000H;
2352
    Target.isNXP    := isNXP;
2309
    Target.SRAMAdr  := 20000000H;
2353
 
2310
    Target.IVTLen   := 256;
-
 
2311
    Target.Reserved := 0;
-
 
2312
    Target.MinStack := 512;
-
 
2313
    Target.InstrSet.thumb2 := TRUE;
-
 
2314
    Target.InstrSet.it     := TRUE;
2354
    Target.IVTLen   := 256; (* >= 192 *)
Line 2315... Line 2355...
2315
    Target.InstrSet.sdiv   := TRUE;
2355
    Target.Reserved := 0;
2316
    Target.InstrSet.cbxz   := TRUE
2356
    Target.MinStack := 512;
2317
END CortexM3;
2357
END SetTarget;
Line 2318... Line 2358...
2318
 
2358
 
Line 2319... Line 2359...
2319
 
2359
 
Line 2320... Line 2360...
2320
PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
2360
PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
-
 
2361
VAR
-
 
2362
    opt: PROG.OPTIONS;
-
 
2363
 
2321
VAR
2364
    ram, rom, i, j: INTEGER;
2322
    opt: PROG.OPTIONS;
2365
 
2323
 
2366
    DataAdr, BssAdr, DataSize, BssSize, CodeSize: INTEGER;
Line 2324... Line -...
2324
    ram, rom: INTEGER;
-
 
2325
 
-
 
2326
    DataAdr, BssAdr, DataSize, BssSize, CodeSize: INTEGER;
-
 
2327
 
2367
 
Line 2328... Line 2368...
2328
BEGIN
2368
BEGIN
2329
    IF target = TARGETS.STM32CM3 THEN
2369
    ram := MIN(MAX(options.ram, minRAM), maxRAM) * 1024;
Line 2330... Line 2370...
2330
        CortexM3
2370
    rom := MIN(MAX(options.rom, minROM), maxROM) * 1024;
Line 2331... Line 2371...
2331
    END;
2371
 
Line 2332... Line 2372...
2332
 
2372
    IF target = TARGETS.STM32CM3 THEN
Line 2333... Line 2373...
2333
    ram := MIN(MAX(options.ram, STM32_minRAM), STM32_maxRAM) * 1024;
2373
        SetTarget(08000000H, 20000000H, CortexM3, FALSE)
2334
    rom := MIN(MAX(options.rom, STM32_minROM), STM32_maxROM) * 1024;
2374
    END;
Line 2355... Line 2395...
2355
    IL.set_bss(MAX(IL.codes.bss, MAX(IL.codes.dmin - CHL.Length(IL.codes.data), 4)));
2395
    IL.set_bss(MAX(IL.codes.bss, MAX(IL.codes.dmin - CHL.Length(IL.codes.data), 4)));
Line 2356... Line 2396...
2356
 
2396
 
2357
    BssSize := IL.codes.bss;
2397
    BssSize := IL.codes.bss;
Line 2358... Line 2398...
2358
    ASSERT(UTILS.Align(BssSize, 4));
2398
    ASSERT(UTILS.Align(BssSize, 4));
2359
 
2399
 
2360
    prolog(BssSize, tcount, ORD(opt.pic), Target.FlashAdr, Target.SRAMAdr + ram, Target.IVTLen);
2400
    prolog(BssSize, tcount, ORD(opt.pic), Target.SRAMAdr + ram, Target.IVTLen);
Line 2361... Line 2401...
2361
    translate(ORD(opt.pic), tcount * 4);
2401
    translate(ORD(opt.pic), tcount * 4);
Line 2372... Line 2412...
2372
 
2412
 
2373
    IF DataSize > ram - Target.MinStack THEN
2413
    IF DataSize > ram - Target.MinStack THEN
2374
        ERRORS.Error(204)
2414
        ERRORS.Error(204)
Line -... Line 2415...
-
 
2415
    END;
-
 
2416
 
-
 
2417
    IF Target.isNXP THEN
-
 
2418
        BIN.put32le(program.code, 2FCH, 0H); (* code read protection (CRP) *)
-
 
2419
        (* NXP checksum *)
-
 
2420
        j := 0;
-
 
2421
        FOR i := 0 TO 6 DO
-
 
2422
            INC(j, BIN.get32le(program.code, i * 4))
-
 
2423
        END;
-
 
2424
        BIN.put32le(program.code, 1CH, -j)
2375
    END;
2425
    END;
Line 2376... Line 2426...
2376
 
2426
 
2377
    WR.Create(outname);
2427
    WR.Create(outname);
Line 2378... Line 2428...
2378
 
2428
 
Line 2379... Line 2429...
2379
    HEX.Data2(program.code, 0, CodeSize, high(Target.FlashAdr));
2429
    HEX.Data2(program.code, 0, CodeSize, high(Target.FlashAdr));
2380
    HEX.End;
2430
    HEX.End;
2381
 
2431
 
2382
    WR.Close;
2432
    WR.Close;
2383
 
-
 
2384
    C.StringLn("--------------------------------------------");
2433
 
Line 2385... Line 2434...
2385
    C.String(  "  rom:  "); C.Int(CodeSize); C.String(" of "); C.Int(rom); C.String("  ("); C.Int(CodeSize * 100 DIV rom); C.StringLn("%)");
2434
    C.Dashes;
2386
    C.Ln;
2435
    C.String(  "  rom:  "); C.Int(CodeSize); C.String(" of "); C.Int(rom); C.String("  ("); C.Int(CodeSize * 100 DIV rom); C.StringLn("%)");