Subversion Repositories Kolibri OS

Rev

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

Rev 7983 Rev 8097
Line 6... Line 6...
6
*)
6
*)
Line 7... Line 7...
7
 
7
 
Line 8... Line 8...
8
MODULE X86;
8
MODULE X86;
9
 
9
 
Line 10... Line 10...
10
IMPORT IL, REG, UTILS, LISTS, BIN, PE32, KOS, MSCOFF, ELF, PROG,
10
IMPORT IL, REG, UTILS, LISTS, BIN, PE32, KOS, MSCOFF, ELF, PROG,
Line 11... Line 11...
11
       CHL := CHUNKLISTS, PATHS, TARGETS;
11
       CHL := CHUNKLISTS, PATHS, TARGETS, ERRORS;
Line 20... Line 20...
20
    ax = eax; cx = ecx; dx = edx;
20
    ax = eax; cx = ecx; dx = edx;
Line 21... Line 21...
21
 
21
 
22
    esp = 4;
22
    esp = 4;
Line -... Line 23...
-
 
23
    ebp = 5;
-
 
24
 
23
    ebp = 5;
25
    MAX_FR = 7;
Line 24... Line 26...
24
 
26
 
Line 25... Line 27...
25
    sete = 94H; setne = 95H; setl = 9CH; setge = 9DH; setle = 9EH; setg = 9FH; setc = 92H; setnc = 93H;
27
    sete = 94H; setne = 95H; setl = 9CH; setge = 9DH; setle = 9EH; setg = 9FH; setc = 92H; setnc = 93H;
Line -... Line 28...
-
 
28
 
-
 
29
    je = 84H; jne = 85H; jl = 8CH; jge = 8DH; jle = 8EH; jg = 8FH; jb = 82H; jnb = 83H;
Line 26... Line 30...
26
 
30
 
Line 27... Line 31...
27
    je = 84H; jne = 85H; jl = 8CH; jge = 8DH; jle = 8EH; jg = 8FH; jb = 82H; jnb = 83H;
31
 
Line 90... Line 94...
90
 
94
 
Line 91... Line 95...
91
    CodeList: LISTS.LIST;
95
    CodeList: LISTS.LIST;
Line -... Line 96...
-
 
96
 
-
 
97
    tcount: INTEGER;
-
 
98
 
-
 
99
    FR: ARRAY 1000 OF INTEGER;
Line 92... Line 100...
92
 
100
 
93
    tcount: INTEGER;
101
    fname: PATHS.PATH;
94
 
102
 
95
 
103
 
Line 144... Line 152...
144
    ASSERT((0 <= n) & (n <= 65535));
152
    ASSERT((0 <= n) & (n <= 65535));
145
    OutByte2(n MOD 256, n DIV 256)
153
    OutByte2(n MOD 256, n DIV 256)
146
END OutWord;
154
END OutWord;
Line 147... Line 155...
147
 
155
 
148
 
156
 
149
PROCEDURE isByte (n: INTEGER): BOOLEAN;
157
PROCEDURE isByte* (n: INTEGER): BOOLEAN;
Line 150... Line 158...
150
    RETURN (-128 <= n) & (n <= 127)
158
    RETURN (-128 <= n) & (n <= 127)
Line 180... Line 188...
180
    |IL.opLSR, IL.opLSR1, IL.opLSR2: OutByte(0E8H + reg)
188
    |IL.opLSR, IL.opLSR1, IL.opLSR2: OutByte(0E8H + reg)
181
    END
189
    END
182
END shift;
190
END shift;
Line 183... Line 191...
183
 
191
 
184
 
192
 
185
PROCEDURE mov (reg1, reg2: INTEGER);
193
PROCEDURE oprr (op: BYTE; reg1, reg2: INTEGER); (* op reg1, reg2 *)
186
BEGIN
194
BEGIN
Line 187... Line 195...
187
    OutByte2(89H, 0C0H + reg2 * 8 + reg1)  (* mov reg1, reg2 *)
195
    OutByte2(op, 0C0H + 8 * reg2 + reg1)
188
END mov;
196
END oprr;
189
 
197
 
-
 
198
 
-
 
199
PROCEDURE mov (reg1, reg2: INTEGER); (* mov reg1, reg2 *)
Line -... Line 200...
-
 
200
BEGIN
190
 
201
    oprr(89H, reg1, reg2)
191
PROCEDURE xchg (reg1, reg2: INTEGER);
-
 
192
VAR
202
END mov;
193
    regs: SET;
203
 
194
 
204
 
195
BEGIN
-
 
196
    regs := {reg1, reg2};
205
PROCEDURE xchg (reg1, reg2: INTEGER); (* xchg reg1, reg2 *)
197
    IF regs = {eax, ecx} THEN
-
 
198
        OutByte(91H)                (* xchg eax, ecx *)
206
BEGIN
199
    ELSIF regs = {eax, edx} THEN
207
    IF eax IN {reg1, reg2} THEN
Line 200... Line 208...
200
        OutByte(92H)                (* xchg eax, edx *)
208
        OutByte(90H + reg1 + reg2)
Line 214... Line 222...
214
BEGIN
222
BEGIN
215
    OutByte(50H + reg) (* push reg *)
223
    OutByte(50H + reg) (* push reg *)
216
END push;
224
END push;
Line -... Line 225...
-
 
225
 
-
 
226
 
-
 
227
PROCEDURE xor (reg1, reg2: INTEGER); (* xor reg1, reg2 *)
-
 
228
BEGIN
-
 
229
    oprr(31H, reg1, reg2)
-
 
230
END xor;
217
 
231
 
218
 
232
 
-
 
233
PROCEDURE movrc (reg, n: INTEGER);
-
 
234
BEGIN
-
 
235
    IF n = 0 THEN
219
PROCEDURE movrc (reg, n: INTEGER);
236
        xor(reg, reg)
220
BEGIN
237
    ELSE
-
 
238
        OutByte(0B8H + reg); (* mov reg, n *)
221
    OutByte(0B8H + reg); (* mov reg, n *)
239
        OutInt(n)
Line 222... Line 240...
222
    OutInt(n)
240
    END
223
END movrc;
241
END movrc;
224
 
242
 
225
 
243
 
226
PROCEDURE pushc (n: INTEGER);
244
PROCEDURE pushc* (n: INTEGER);
Line 246... Line 264...
246
BEGIN
264
BEGIN
247
    OutByte2(0F7H, 0D0H + reg)  (* not reg *)
265
    OutByte2(0F7H, 0D0H + reg)  (* not reg *)
248
END not;
266
END not;
Line 249... Line 267...
249
 
267
 
250
 
268
 
251
PROCEDURE add (reg1, reg2: INTEGER);
269
PROCEDURE add (reg1, reg2: INTEGER); (* add reg1, reg2 *)
252
BEGIN
270
BEGIN
Line 253... Line 271...
253
    OutByte2(01H, 0C0H + reg2 * 8 + reg1)  (* add reg1, reg2 *)
271
    oprr(01H, reg1, reg2)
254
END add;
272
END add;
-
 
273
 
-
 
274
 
-
 
275
PROCEDURE oprc* (op, reg, n: INTEGER);
-
 
276
BEGIN
-
 
277
    IF (reg = eax) & ~isByte(n) THEN
-
 
278
        CASE op OF
-
 
279
        |0C0H: op := 05H (* add *)
-
 
280
        |0E8H: op := 2DH (* sub *)
-
 
281
        |0F8H: op := 3DH (* cmp *)
-
 
282
        |0E0H: op := 25H (* and *)
-
 
283
        |0C8H: op := 0DH (* or  *)
-
 
284
        |0F0H: op := 35H (* xor *)
255
 
285
        END;
256
 
286
        OutByte(op);
-
 
287
        OutInt(n)
-
 
288
    ELSE
-
 
289
        OutByte2(81H + short(n), op + reg MOD 8);
-
 
290
        OutIntByte(n)
-
 
291
    END
-
 
292
END oprc;
-
 
293
 
257
PROCEDURE andrc (reg, n: INTEGER);
294
 
Line 258... Line 295...
258
BEGIN
295
PROCEDURE andrc (reg, n: INTEGER); (* and reg, n *)
259
    OutByte2(81H + short(n), 0E0H + reg);  (* and reg, n *)
296
BEGIN
260
    OutIntByte(n)
-
 
261
END andrc;
297
    oprc(0E0H, reg, n)
262
 
298
END andrc;
Line 263... Line 299...
263
 
299
 
264
PROCEDURE orrc (reg, n: INTEGER);
300
 
265
BEGIN
-
 
266
    OutByte2(81H + short(n), 0C8H + reg);  (* or reg, n *)
301
PROCEDURE orrc (reg, n: INTEGER); (* or reg, n *)
267
    OutIntByte(n)
302
BEGIN
Line 268... Line 303...
268
END orrc;
303
    oprc(0C8H, reg, n)
269
 
304
END orrc;
270
 
-
 
271
PROCEDURE addrc (reg, n: INTEGER);
305
 
272
BEGIN
306
 
Line 273... Line 307...
273
    OutByte2(81H + short(n), 0C0H + reg);  (* add reg, n *)
307
PROCEDURE xorrc (reg, n: INTEGER); (* xor reg, n *)
274
    OutIntByte(n)
308
BEGIN
275
END addrc;
309
    oprc(0F0H, reg, n)
276
 
310
END xorrc;
Line 277... Line 311...
277
 
311
 
278
PROCEDURE subrc (reg, n: INTEGER);
312
 
279
BEGIN
313
PROCEDURE addrc (reg, n: INTEGER); (* add reg, n *)
280
    OutByte2(81H + short(n), 0E8H + reg);  (* sub reg, n *)
314
BEGIN
281
    OutIntByte(n)
315
    oprc(0C0H, reg, n)
282
END subrc;
-
 
283
 
316
END addrc;
284
 
317
 
285
PROCEDURE cmprr (reg1, reg2: INTEGER);
318
 
Line 286... Line 319...
286
BEGIN
319
PROCEDURE subrc (reg, n: INTEGER); (* sub reg, n *)
287
    OutByte2(39H, 0C0H + reg2 * 8 + reg1)  (* cmp reg1, reg2 *)
320
BEGIN
288
END cmprr;
321
    oprc(0E8H, reg, n)
289
 
322
END subrc;
Line 290... Line 323...
290
 
323
 
291
PROCEDURE cmprc (reg, n: INTEGER);
324
 
-
 
325
PROCEDURE cmprc (reg, n: INTEGER); (* cmp reg, n *)
-
 
326
BEGIN
-
 
327
    IF n = 0 THEN
292
BEGIN
328
        test(reg)
293
    IF n = 0 THEN
329
    ELSE
Line 294... Line 330...
294
        test(reg)
330
        oprc(0F8H, reg, n)
295
    ELSE
331
    END
296
        OutByte2(81H + short(n), 0F8H + reg);  (* cmp reg, n *)
332
END cmprc;
Line 576... Line 612...
576
BEGIN
612
BEGIN
577
    GetRegA;
613
    GetRegA;
578
    OutByte2(0DAH, 0E9H);       (* fucompp *)
614
    OutByte2(0DAH, 0E9H);       (* fucompp *)
579
    OutByte3(09BH, 0DFH, 0E0H); (* fstsw ax *)
615
    OutByte3(09BH, 0DFH, 0E0H); (* fstsw ax *)
580
    OutByte(09EH);              (* sahf *)
616
    OutByte(09EH);              (* sahf *)
581
    movrc(eax, 0)
617
    OutByte(0B8H); OutInt(0)    (* mov eax, 0 *)
582
END fcmp;
618
END fcmp;
Line 583... Line 619...
583
 
619
 
584
 
620
 
Line 692... Line 728...
692
 
728
 
693
PROCEDURE translate (pic: BOOLEAN; stroffs: INTEGER);
729
PROCEDURE translate (pic: BOOLEAN; stroffs: INTEGER);
694
VAR
730
VAR
Line 695... Line 731...
695
    cmd, next: COMMAND;
731
    cmd, next: COMMAND;
Line 696... Line 732...
696
 
732
 
Line 697... Line 733...
697
    reg1, reg2: INTEGER;
733
    reg1, reg2, fr: INTEGER;
Line 698... Line 734...
698
 
734
 
Line 699... Line 735...
699
    n, a, b, label, cc: INTEGER;
735
    n, a, b, label, cc: INTEGER;
700
 
736
 
Line -... Line 737...
-
 
737
    opcode, param1, param2: INTEGER;
-
 
738
 
701
    opcode, param1, param2: INTEGER;
739
    float: REAL;
Line 702... Line 740...
702
 
740
 
703
    float: REAL;
741
BEGIN
Line 736... Line 774...
736
            OutByte2(0FFH, 0D0H + reg1);  (* call reg1 *)
774
            OutByte2(0FFH, 0D0H + reg1);  (* call reg1 *)
737
            drop;
775
            drop;
738
            ASSERT(R.top = -1)
776
            ASSERT(R.top = -1)
Line 739... Line 777...
739
 
777
 
740
        |IL.opPRECALL:
778
        |IL.opPRECALL:
741
            n := param2;
779
            PushAll(0);
742
            IF (param1 # 0) & (n # 0) THEN
780
            IF (param2 # 0) & (fr >= 0) THEN
743
                subrc(esp, 8)
781
                subrc(esp, 8)
-
 
782
            END;
-
 
783
            INC(FR[0]);
744
            END;
784
            FR[FR[0]] := fr + 1;
745
            WHILE n > 0 DO
785
            WHILE fr >= 0 DO
746
                subrc(esp, 8);
786
                subrc(esp, 8);
747
                OutByte3(0DDH, 01CH, 024H); (* fstp qword[esp] *)
787
                OutByte3(0DDH, 01CH, 024H); (* fstp qword[esp] *)
748
                DEC(n)
788
                DEC(fr)
749
            END;
789
            END;
Line 750... Line 790...
750
            PushAll(0)
790
            ASSERT(fr = -1)
751
 
791
 
752
        |IL.opALIGN16:
792
        |IL.opALIGN16:
753
            ASSERT(eax IN R.regs);
793
            ASSERT(eax IN R.regs);
Line 757... Line 797...
757
            IF n > 0 THEN
797
            IF n > 0 THEN
758
                subrc(esp, n)
798
                subrc(esp, n)
759
            END;
799
            END;
760
            push(eax)
800
            push(eax)
Line 761... Line 801...
761
 
801
 
762
        |IL.opRES:
802
        |IL.opRESF, IL.opRES:
763
            ASSERT(R.top = -1);
-
 
764
            GetRegA;
-
 
765
            n := param2;
803
            ASSERT(R.top = -1);
766
            WHILE n > 0 DO
-
 
767
                OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *)
-
 
768
                addrc(esp, 8);
804
            ASSERT(fr = -1);
769
                DEC(n)
-
 
Line 770... Line 805...
770
            END
805
            n := FR[FR[0]]; DEC(FR[0]);
771
 
806
 
772
        |IL.opRESF:
807
            IF opcode = IL.opRESF THEN
773
            n := param2;
808
                INC(fr);
774
            IF n > 0 THEN
809
                IF n > 0 THEN
-
 
810
                    OutByte3(0DDH, 5CH + long(n * 8), 24H);
775
                OutByte3(0DDH, 5CH + long(n * 8), 24H);
811
                    OutIntByte(n * 8); (* fstp qword[esp + n*8] *)
776
                OutIntByte(n * 8); (* fstp qword[esp + n*8] *)
812
                    DEC(fr);
Line -... Line 813...
-
 
813
                    INC(n)
-
 
814
                END;
-
 
815
 
-
 
816
                IF fr + n > MAX_FR THEN
-
 
817
                    ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
-
 
818
                END
-
 
819
            ELSE
777
                INC(n)
820
                GetRegA
778
            END;
821
            END;
779
 
822
 
-
 
823
            WHILE n > 0 DO
780
            WHILE n > 0 DO
824
                OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *)
781
                OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *)
825
                addrc(esp, 8);
Line 782... Line 826...
782
                addrc(esp, 8);
826
                INC(fr);
783
                DEC(n)
827
                DEC(n)
Line 814... Line 858...
814
                drop
858
                drop
815
            END;
859
            END;
Line 816... Line 860...
816
 
860
 
Line -... Line 861...
-
 
861
            ASSERT(R.top = -1);
-
 
862
 
-
 
863
            IF opcode = IL.opLEAVEF THEN
-
 
864
                DEC(fr)
-
 
865
            END;
-
 
866
 
817
            ASSERT(R.top = -1);
867
            ASSERT(fr = -1);
818
 
868
 
819
            IF param1 > 0 THEN
869
            IF param1 > 0 THEN
Line 820... Line 870...
820
                mov(esp, ebp)
870
                mov(esp, ebp)
Line 847... Line 897...
847
                ASSERT(R.top + 1 <= n);
897
                ASSERT(R.top + 1 <= n);
848
                PushAll(n)
898
                PushAll(n)
849
            END
899
            END
Line 850... Line 900...
850
 
900
 
851
        |IL.opCLEANUP:
-
 
852
            n := param2 * 4;
901
        |IL.opCLEANUP:
853
            IF n # 0 THEN
902
            IF param2 # 0 THEN
854
                addrc(esp, n)
903
                addrc(esp, param2 * 4)
Line 855... Line 904...
855
            END
904
            END
856
 
905
 
Line 861... Line 910...
861
            movrc(GetAnyReg(), param2)
910
            movrc(GetAnyReg(), param2)
Line 862... Line 911...
862
 
911
 
863
        |IL.opLABEL:
912
        |IL.opLABEL:
Line 864... Line 913...
864
            SetLabel(param1) (* L: *)
913
            SetLabel(param1) (* L: *)
Line 865... Line 914...
865
 
914
 
-
 
915
        |IL.opNOP, IL.opAND, IL.opOR:
-
 
916
 
-
 
917
        |IL.opGADR:
-
 
918
            next := cmd.next(COMMAND);
-
 
919
            IF next.opcode = IL.opADDC THEN
866
        |IL.opNOP:
920
                INC(param2, next.param2);
867
 
921
                cmd := next
868
        |IL.opGADR:
922
            END;
869
            reg1 := GetAnyReg();
923
            reg1 := GetAnyReg();
870
            IF pic THEN
924
            IF pic THEN
871
                Pic(reg1, BIN.PICBSS, param2)
925
                Pic(reg1, BIN.PICBSS, param2)
872
            ELSE
926
            ELSE
Line 873... Line 927...
873
                OutByte(0B8H + reg1);  (* mov reg1, _bss + param2 *)
927
                OutByte(0B8H + reg1);  (* mov reg1, _bss + param2 *)
-
 
928
                Reloc(BIN.RBSS, param2)
874
                Reloc(BIN.RBSS, param2)
929
            END
-
 
930
 
-
 
931
        |IL.opLADR:
-
 
932
            next := cmd.next(COMMAND);
-
 
933
            n := param2 * 4;
875
            END
934
            IF next.opcode = IL.opADDC THEN
876
 
935
                INC(n, next.param2);
Line 877... Line 936...
877
        |IL.opLADR:
936
                cmd := next
878
            n := param2 * 4;
937
            END;
Line 905... Line 964...
905
            UnOp(reg1);
964
            UnOp(reg1);
906
            OutByte3(66H, 0C7H, reg1); OutWord(param2 MOD 65536);  (* mov word[reg1], param2 *)
965
            OutByte3(66H, 0C7H, reg1); OutWord(param2 MOD 65536);  (* mov word[reg1], param2 *)
907
            drop
966
            drop
Line 908... Line 967...
908
 
967
 
909
        |IL.opVLOAD32:
-
 
910
            n := param2 * 4;
968
        |IL.opVLOAD32:
911
            reg1 := GetAnyReg();
969
            reg1 := GetAnyReg();
912
            movrm(reg1, ebp, param2 * 4);
970
            movrm(reg1, ebp, param2 * 4);
Line 913... Line 971...
913
            movrm(reg1, reg1, 0)
971
            movrm(reg1, reg1, 0)
Line 977... Line 1035...
977
        |IL.opADD:
1035
        |IL.opADD:
978
            BinOp(reg1, reg2);
1036
            BinOp(reg1, reg2);
979
            add(reg1, reg2);
1037
            add(reg1, reg2);
980
            drop
1038
            drop
Line 981... Line 1039...
981
 
1039
 
982
        |IL.opADDL, IL.opADDR:
1040
        |IL.opADDC:
983
            IF param2 # 0 THEN
1041
            IF param2 # 0 THEN
984
                UnOp(reg1);
1042
                UnOp(reg1);
985
                next := cmd.next(COMMAND);
1043
                next := cmd.next(COMMAND);
986
                CASE next.opcode OF
1044
                CASE next.opcode OF
Line 1008... Line 1066...
1008
                END
1066
                END
1009
            END
1067
            END
Line 1010... Line 1068...
1010
 
1068
 
1011
        |IL.opSUB:
1069
        |IL.opSUB:
1012
            BinOp(reg1, reg2);
1070
            BinOp(reg1, reg2);
1013
            OutByte2(29H, 0C0H + reg2 * 8 + reg1); (* sub reg1, reg2 *)
1071
            oprr(29H, reg1, reg2); (* sub reg1, reg2 *)
Line 1014... Line 1072...
1014
            drop
1072
            drop
1015
 
1073
 
1016
        |IL.opSUBR, IL.opSUBL:
-
 
1017
            UnOp(reg1);
1074
        |IL.opSUBR, IL.opSUBL:
1018
            n := param2;
1075
            UnOp(reg1);
1019
            IF n = 1 THEN
1076
            IF param2 = 1 THEN
1020
                OutByte(48H + reg1) (* dec reg1 *)
1077
                OutByte(48H + reg1) (* dec reg1 *)
1021
            ELSIF n = -1 THEN
1078
            ELSIF param2 = -1 THEN
1022
                OutByte(40H + reg1) (* inc reg1 *)
1079
                OutByte(40H + reg1) (* inc reg1 *)
1023
            ELSIF n # 0 THEN
1080
            ELSIF param2 # 0 THEN
1024
                subrc(reg1, n)
1081
                subrc(reg1, param2)
1025
            END;
1082
            END;
1026
            IF opcode = IL.opSUBL THEN
1083
            IF opcode = IL.opSUBL THEN
Line 1177... Line 1234...
1177
 
1234
 
1178
            drop;
1235
            drop;
1179
            cc := cond(opcode);
1236
            cc := cond(opcode);
Line 1180... Line 1237...
1180
            next := cmd.next(COMMAND);
1237
            next := cmd.next(COMMAND);
1181
 
1238
 
1182
            IF next.opcode = IL.opJE THEN
1239
            IF next.opcode = IL.opJNZ THEN
1183
                jcc(cc, next.param1);
1240
                jcc(cc, next.param1);
1184
                cmd := next
1241
                cmd := next
1185
            ELSIF next.opcode = IL.opJNE THEN
1242
            ELSIF next.opcode = IL.opJZ THEN
1186
                jcc(inv0(cc), next.param1);
1243
                jcc(inv0(cc), next.param1);
1187
                cmd := next
1244
                cmd := next
1188
            ELSE
1245
            ELSE
Line 1210... Line 1267...
1210
            ELSE
1267
            ELSE
1211
                setcc(setne, reg1)
1268
                setcc(setne, reg1)
1212
            END;
1269
            END;
1213
            andrc(reg1, 1)
1270
            andrc(reg1, 1)
Line 1214... Line -...
1214
 
-
 
1215
        |IL.opACC:
-
 
1216
            IF (R.top # 0) OR (R.stk[0] # eax) THEN
-
 
1217
                PushAll(0);
-
 
1218
                GetRegA;
-
 
1219
                pop(eax);
-
 
1220
                DEC(R.pushed)
-
 
1221
            END
-
 
1222
 
1271
 
1223
        |IL.opDROP:
1272
        |IL.opDROP:
1224
            UnOp(reg1);
1273
            UnOp(reg1);
Line 1225... Line 1274...
1225
            drop
1274
            drop
1226
 
1275
 
1227
        |IL.opJNZ:
1276
        |IL.opJNZ1:
1228
            UnOp(reg1);
1277
            UnOp(reg1);
Line 1229... Line -...
1229
            test(reg1);
-
 
1230
            jcc(jne, param1)
-
 
1231
 
-
 
1232
        |IL.opJZ:
-
 
1233
            UnOp(reg1);
-
 
1234
            test(reg1);
1278
            test(reg1);
1235
            jcc(je, param1)
1279
            jcc(jne, param1)
1236
 
1280
 
1237
        |IL.opJG:
1281
        |IL.opJG:
Line 1238... Line 1282...
1238
            UnOp(reg1);
1282
            UnOp(reg1);
1239
            test(reg1);
1283
            test(reg1);
1240
            jcc(jg, param1)
1284
            jcc(jg, param1)
1241
 
1285
 
1242
        |IL.opJE:
1286
        |IL.opJNZ:
Line 1243... Line 1287...
1243
            UnOp(reg1);
1287
            UnOp(reg1);
1244
            test(reg1);
1288
            test(reg1);
1245
            jcc(jne, param1);
1289
            jcc(jne, param1);
1246
            drop
1290
            drop
1247
 
1291
 
Line 1387... Line 1431...
1387
            drop;
1431
            drop;
1388
            drop
1432
            drop
Line 1389... Line 1433...
1389
 
1433
 
1390
        |IL.opMULS:
1434
        |IL.opMULS:
1391
            BinOp(reg1, reg2);
1435
            BinOp(reg1, reg2);
1392
            OutByte2(21H, 0C0H + reg2 * 8 + reg1); (* and reg1, reg2 *)
1436
            oprr(21H, reg1, reg2); (* and reg1, reg2 *)
Line 1393... Line 1437...
1393
            drop
1437
            drop
1394
 
1438
 
1395
        |IL.opMULSC:
1439
        |IL.opMULSC:
Line 1401... Line 1445...
1401
            xor(reg1, reg2);
1445
            xor(reg1, reg2);
1402
            drop
1446
            drop
Line 1403... Line 1447...
1403
 
1447
 
1404
        |IL.opDIVSC:
1448
        |IL.opDIVSC:
1405
            UnOp(reg1);
-
 
1406
            OutByte2(81H + short(param2), 0F0H + reg1);  (* xor reg1, n *)
1449
            UnOp(reg1);
Line 1407... Line 1450...
1407
            OutIntByte(param2)
1450
            xorrc(reg1, param2)
1408
 
1451
 
1409
        |IL.opADDS:
1452
        |IL.opADDS:
1410
            BinOp(reg1, reg2);
1453
            BinOp(reg1, reg2);
Line 1411... Line 1454...
1411
            OutByte2(9H, 0C0H + reg2 * 8 + reg1); (* or reg1, reg2 *)
1454
            oprr(9H, reg1, reg2); (* or reg1, reg2 *)
1412
            drop
1455
            drop
1413
 
1456
 
1414
        |IL.opSUBS:
1457
        |IL.opSUBS:
1415
            BinOp(reg1, reg2);
1458
            BinOp(reg1, reg2);
Line 1416... Line 1459...
1416
            not(reg2);
1459
            not(reg2);
1417
            OutByte2(21H, 0C0H + reg2 * 8 + reg1); (* and reg1, reg2 *)
1460
            oprr(21H, reg1, reg2); (* and reg1, reg2 *)
1418
            drop
1461
            drop
Line 1419... Line 1462...
1419
 
1462
 
1420
        |IL.opADDSL, IL.opADDSR:
1463
        |IL.opADDSC:
Line 1506... Line 1549...
1506
            drop
1549
            drop
Line 1507... Line 1550...
1507
 
1550
 
1508
        |IL.opMAXC, IL.opMINC:
1551
        |IL.opMAXC, IL.opMINC:
1509
            UnOp(reg1);
1552
            UnOp(reg1);
-
 
1553
            cmprc(reg1, param2);
1510
            cmprc(reg1, param2);
1554
            label := NewLabel();
-
 
1555
            IF opcode = IL.opMINC THEN
-
 
1556
                cc := jle
-
 
1557
            ELSE
-
 
1558
                cc := jge
-
 
1559
            END;
1511
            OutByte2(07DH + ORD(opcode = IL.opMINC), 5);  (* jge/jle L *)
1560
            jcc(cc, label);
1512
            movrc(reg1, param2)
1561
            movrc(reg1, param2);
Line 1513... Line 1562...
1513
            (* L: *)
1562
            SetLabel(label)
1514
 
1563
 
1515
        |IL.opIN, IL.opINR:
1564
        |IL.opIN, IL.opINR:
1516
            IF opcode = IL.opINR THEN
1565
            IF opcode = IL.opINR THEN
Line 1822... Line 1871...
1822
            OutByte2(0DBH, 018H + reg2);  (* fistp dword[reg2] *)
1871
            OutByte2(0DBH, 018H + reg2);  (* fistp dword[reg2] *)
1823
            drop;
1872
            drop;
1824
            drop
1873
            drop
Line 1825... Line 1874...
1825
 
1874
 
-
 
1875
        |IL.opPUSHF:
-
 
1876
            ASSERT(fr >= 0);
1826
        |IL.opPUSHF:
1877
            DEC(fr);
1827
            subrc(esp, 8);
1878
            subrc(esp, 8);
Line 1828... Line 1879...
1828
            OutByte3(0DDH, 01CH, 024H)    (* fstp qword[esp] *)
1879
            OutByte3(0DDH, 01CH, 024H)    (* fstp qword[esp] *)
-
 
1880
 
-
 
1881
        |IL.opLOADF:
-
 
1882
            INC(fr);
-
 
1883
            IF fr > MAX_FR THEN
1829
 
1884
                ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
1830
        |IL.opLOADF:
1885
            END;
1831
            UnOp(reg1);
1886
            UnOp(reg1);
Line 1832... Line 1887...
1832
            OutByte2(0DDH, reg1);         (* fld qword[reg1] *)
1887
            OutByte2(0DDH, reg1);         (* fld qword[reg1] *)
-
 
1888
            drop
-
 
1889
 
-
 
1890
        |IL.opCONSTF:
-
 
1891
            INC(fr);
1833
            drop
1892
            IF fr > MAX_FR THEN
1834
 
1893
                ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
1835
        |IL.opCONSTF:
1894
            END;
1836
            float := cmd.float;
1895
            float := cmd.float;
1837
            IF float = 0.0 THEN
1896
            IF float = 0.0 THEN
Line 1848... Line 1907...
1848
                OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *)
1907
                OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *)
1849
                addrc(esp, 8)
1908
                addrc(esp, 8)
1850
            END
1909
            END
Line 1851... Line 1910...
1851
 
1910
 
-
 
1911
        |IL.opSAVEF, IL.opSAVEFI:
-
 
1912
            ASSERT(fr >= 0);
1852
        |IL.opSAVEF, IL.opSAVEFI:
1913
            DEC(fr);
1853
            UnOp(reg1);
1914
            UnOp(reg1);
1854
            OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *)
1915
            OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *)
Line 1855... Line 1916...
1855
            drop
1916
            drop
-
 
1917
 
-
 
1918
        |IL.opADDF:
1856
 
1919
            ASSERT(fr >= 1);
Line 1857... Line 1920...
1857
        |IL.opADDF, IL.opADDFI:
1920
            DEC(fr);
-
 
1921
            OutByte2(0DEH, 0C1H)  (* faddp st1, st *)
-
 
1922
 
1858
            OutByte2(0DEH, 0C1H)  (* faddp st1, st *)
1923
        |IL.opSUBF:
Line 1859... Line 1924...
1859
 
1924
            ASSERT(fr >= 1);
-
 
1925
            DEC(fr);
-
 
1926
            OutByte2(0DEH, 0E9H)  (* fsubp st1, st *)
1860
        |IL.opSUBF:
1927
 
Line 1861... Line 1928...
1861
            OutByte2(0DEH, 0E9H)  (* fsubp st1, st *)
1928
        |IL.opSUBFI:
-
 
1929
            ASSERT(fr >= 1);
-
 
1930
            DEC(fr);
1862
 
1931
            OutByte2(0DEH, 0E1H)  (* fsubrp st1, st *)
Line 1863... Line 1932...
1863
        |IL.opSUBFI:
1932
 
-
 
1933
        |IL.opMULF:
-
 
1934
            ASSERT(fr >= 1);
1864
            OutByte2(0DEH, 0E1H)  (* fsubrp st1, st *)
1935
            DEC(fr);
Line 1865... Line 1936...
1865
 
1936
            OutByte2(0DEH, 0C9H)  (* fmulp st1, st *)
-
 
1937
 
-
 
1938
        |IL.opDIVF:
1866
        |IL.opMULF:
1939
            ASSERT(fr >= 1);
Line 1867... Line 1940...
1867
            OutByte2(0DEH, 0C9H)  (* fmulp st1, st *)
1940
            DEC(fr);
-
 
1941
            OutByte2(0DEH, 0F9H)  (* fdivp st1, st *)
1868
 
1942
 
Line 1869... Line 1943...
1869
        |IL.opDIVF:
1943
        |IL.opDIVFI:
-
 
1944
            ASSERT(fr >= 1);
1870
            OutByte2(0DEH, 0F9H)  (* fdivp st1, st *)
1945
            DEC(fr);
Line 1871... Line 1946...
1871
 
1946
            OutByte2(0DEH, 0F1H)  (* fdivrp st1, st *)
-
 
1947
 
-
 
1948
        |IL.opUMINF:
-
 
1949
            ASSERT(fr >= 0);
-
 
1950
            OutByte2(0D9H, 0E0H)  (* fchs *)
1872
        |IL.opDIVFI:
1951
 
1873
            OutByte2(0DEH, 0F1H)  (* fdivrp st1, st *)
1952
        |IL.opFABS:
1874
 
1953
            ASSERT(fr >= 0);
1875
        |IL.opUMINF:
1954
            OutByte2(0D9H, 0E1H)  (* fabs *)
1876
            OutByte2(0D9H, 0E0H)  (* fchs *)
1955
 
Line 1877... Line 1956...
1877
 
1956
        |IL.opFLT:
-
 
1957
            INC(fr);
-
 
1958
            IF fr > MAX_FR THEN
1878
        |IL.opFABS:
1959
                ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
1879
            OutByte2(0D9H, 0E1H)  (* fabs *)
1960
            END;
1880
 
1961
            UnOp(reg1);
1881
        |IL.opFLT:
1962
            push(reg1);
1882
            UnOp(reg1);
1963
            OutByte3(0DBH, 004H, 024H); (* fild dword[esp] *)
Line 1897... Line 1978...
1897
            pop(GetAnyReg());
1978
            pop(GetAnyReg());
1898
            OutByte2(0D9H, 06CH); OutByte2(024H, 002H);                         (* fldcw word[esp+2]                    *)
1979
            OutByte2(0D9H, 06CH); OutByte2(024H, 002H);                         (* fldcw word[esp+2]                    *)
1899
            addrc(esp, 4)
1980
            addrc(esp, 4)
Line 1900... Line 1981...
1900
 
1981
 
-
 
1982
        |IL.opEQF:
-
 
1983
            ASSERT(fr >= 1);
1901
        |IL.opEQF:
1984
            DEC(fr, 2);
1902
            fcmp;
1985
            fcmp;
1903
            OutByte2(07AH, 003H);       (* jp L *)
1986
            OutByte2(07AH, 003H);       (* jp L *)
1904
            setcc(sete, al)
1987
            setcc(sete, al)
Line 1905... Line 1988...
1905
                                        (* L: *)
1988
                                        (* L: *)
-
 
1989
 
-
 
1990
        |IL.opNEF:
1906
 
1991
            ASSERT(fr >= 1);
1907
        |IL.opNEF:
1992
            DEC(fr, 2);
1908
            fcmp;
1993
            fcmp;
1909
            OutByte2(07AH, 003H);       (* jp L *)
1994
            OutByte2(07AH, 003H);       (* jp L *)
Line 1910... Line 1995...
1910
            setcc(setne, al)
1995
            setcc(setne, al)
-
 
1996
                                        (* L: *)
-
 
1997
 
1911
                                        (* L: *)
1998
        |IL.opLTF:
1912
 
1999
            ASSERT(fr >= 1);
1913
        |IL.opLTF:
2000
            DEC(fr, 2);
1914
            fcmp;
2001
            fcmp;
1915
            OutByte2(07AH, 00EH);       (* jp L *)
2002
            OutByte2(07AH, 00EH);       (* jp L *)
1916
            setcc(setc, al);
2003
            setcc(setc, al);
1917
            setcc(sete, ah);
2004
            setcc(sete, ah);
1918
            test(eax);
2005
            test(eax);
Line 1919... Line 2006...
1919
            setcc(sete, al);
2006
            setcc(sete, al);
-
 
2007
            andrc(eax, 1)
-
 
2008
                                        (* L: *)
1920
            andrc(eax, 1)
2009
 
1921
                                        (* L: *)
2010
        |IL.opGTF:
1922
 
2011
            ASSERT(fr >= 1);
1923
        |IL.opGTF:
2012
            DEC(fr, 2);
1924
            fcmp;
2013
            fcmp;
1925
            OutByte2(07AH, 00FH);       (* jp L *)
2014
            OutByte2(07AH, 00FH);       (* jp L *)
1926
            setcc(setc, al);
2015
            setcc(setc, al);
1927
            setcc(sete, ah);
2016
            setcc(sete, ah);
Line 1928... Line 2017...
1928
            cmprc(eax, 1);
2017
            cmprc(eax, 1);
-
 
2018
            setcc(sete, al);
-
 
2019
            andrc(eax, 1)
1929
            setcc(sete, al);
2020
                                        (* L: *)
1930
            andrc(eax, 1)
2021
 
1931
                                        (* L: *)
2022
        |IL.opLEF:
1932
 
2023
            ASSERT(fr >= 1);
Line 1933... Line 2024...
1933
        |IL.opLEF:
2024
            DEC(fr, 2);
-
 
2025
            fcmp;
-
 
2026
            OutByte2(07AH, 003H);       (* jp L *)
1934
            fcmp;
2027
            setcc(setnc, al)
1935
            OutByte2(07AH, 003H);       (* jp L *)
2028
                                        (* L: *)
1936
            setcc(setnc, al)
2029
 
1937
                                        (* L: *)
2030
        |IL.opGEF:
1938
 
2031
            ASSERT(fr >= 1);
Line 1946... Line 2039...
1946
            setcc(sete, al);
2039
            setcc(sete, al);
1947
            andrc(eax, 1)
2040
            andrc(eax, 1)
1948
                                        (* L: *)
2041
                                        (* L: *)
Line 1949... Line 2042...
1949
 
2042
 
-
 
2043
        |IL.opINF:
-
 
2044
            INC(fr);
-
 
2045
            IF fr > MAX_FR THEN
-
 
2046
                ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
1950
        |IL.opINF:
2047
            END;
1951
            pushc(7FF00000H);
2048
            pushc(7FF00000H);
1952
            pushc(0);
2049
            pushc(0);
1953
            OutByte3(0DDH, 004H, 024H);  (* fld qword[esp] *)
2050
            OutByte3(0DDH, 004H, 024H);  (* fld qword[esp] *)
Line 2074... Line 2171...
2074
            n := param1 * 4;
2171
            n := param1 * 4;
2075
            OutByte3(0FH, 0BAH, 6DH + long(n) + 8 * ORD(opcode = IL.opLADR_EXCLC)); (* bts(r) dword[ebp + n], param2 *)
2172
            OutByte3(0FH, 0BAH, 6DH + long(n) + 8 * ORD(opcode = IL.opLADR_EXCLC)); (* bts(r) dword[ebp + n], param2 *)
2076
            OutIntByte(n);
2173
            OutIntByte(n);
2077
            OutByte(param2)
2174
            OutByte(param2)
Line -... Line 2175...
-
 
2175
 
-
 
2176
        |IL.opFNAME:
-
 
2177
            fname := cmd(IL.FNAMECMD).fname
2078
 
2178
 
Line 2079... Line 2179...
2079
        |IL.opLOOP, IL.opENDLOOP:
2179
        |IL.opLOOP, IL.opENDLOOP:
Line 2080... Line 2180...
2080
 
2180
 
2081
        END;
2181
        END;
Line 2082... Line 2182...
2082
 
2182
 
2083
        cmd := cmd.next(COMMAND)
2183
        cmd := cmd.next(COMMAND)
2084
    END;
-
 
-
 
2184
    END;
2085
 
2185
 
Line 2086... Line 2186...
2086
    ASSERT(R.pushed = 0);
2186
    ASSERT(R.pushed = 0);
2087
    ASSERT(R.top = -1)
2187
    ASSERT(R.top = -1);
2088
 
2188
    ASSERT(fr = -1)
Line 2089... Line 2189...
2089
END translate;
2189
END translate;
2090
 
-
 
2091
 
2190
 
2092
PROCEDURE prolog (pic: BOOLEAN; target, stack, dllinit, dllret: INTEGER);
2191
 
-
 
2192
PROCEDURE prolog (pic: BOOLEAN; target, stack, dllinit, dllret: INTEGER);
Line 2093... Line 2193...
2093
VAR
2193
VAR
2094
    reg1, entry, L, dcount: INTEGER;
2194
    reg1, entry, L, dcount: INTEGER;
2095
 
2195
 
2096
BEGIN
2196
BEGIN
2097
 
2197
    entry := NewLabel();
2098
    entry := NewLabel();
2198
    SetLabel(entry);
2099
    SetLabel(entry);
2199
    dcount := CHL.Length(IL.codes.data);
2100
 
2200
 
2101
    IF target = TARGETS.Win32DLL THEN
2201
    IF target = TARGETS.Win32DLL THEN
-
 
2202
        push(ebp);
2102
        push(ebp);
2203
        mov(ebp, esp);
2103
        mov(ebp, esp);
2204
        pushm(ebp, 16);
-
 
2205
        pushm(ebp, 12);
2104
        pushm(ebp, 16);
2206
        pushm(ebp, 8);
2105
        pushm(ebp, 12);
-
 
2106
        pushm(ebp, 8);
2207
        CallRTL(pic, IL._dllentry);
2107
        CallRTL(pic, IL._dllentry);
2208
        test(eax);
2108
        test(eax);
2209
        jcc(je, dllret);
2109
        jcc(je, dllret)
2210
        pushc(0)
2110
    ELSIF target = TARGETS.KolibriOSDLL THEN
2211
    ELSIF target = TARGETS.KolibriOSDLL THEN
2111
        SetLabel(dllinit)
-
 
2112
    END;
-
 
2113
 
-
 
2114
    IF target = TARGETS.KolibriOS THEN
2212
        SetLabel(dllinit);
2115
        reg1 := GetAnyReg();
2213
        OutByte(68H);  (* push IMPORT *)
2116
        Pic(reg1, BIN.IMPTAB, 0);
2214
        Reloc(BIN.IMPTAB, 0)
2117
        push(reg1);    (* push IMPORT *)
2215
    ELSIF target = TARGETS.KolibriOS THEN
2118
        drop
2216
        reg1 := GetAnyReg();
Line 2119... Line 2217...
2119
    ELSIF target = TARGETS.KolibriOSDLL THEN
2217
        Pic(reg1, BIN.IMPTAB, 0);
2120
        OutByte(68H);  (* push IMPORT *)
2218
        push(reg1);    (* push IMPORT *)
2121
        Reloc(BIN.IMPTAB, 0)
2219
        drop
2122
    ELSIF target = TARGETS.Linux32 THEN
2220
    ELSIF target = TARGETS.Linux32 THEN
2123
        push(esp)
-
 
2124
    ELSE
-
 
2125
        pushc(0)
-
 
2126
    END;
-
 
2127
 
-
 
2128
    IF pic THEN
-
 
2129
        reg1 := GetAnyReg();
-
 
2130
        Pic(reg1, BIN.PICCODE, entry);
-
 
2131
        push(reg1);     (* push CODE *)
2221
        push(esp)
2132
        drop
2222
    ELSE
2133
    ELSE
-
 
2134
        OutByte(68H);  (* push CODE *)
-
 
2135
        Reloc(BIN.RCODE, entry)
-
 
2136
    END;
-
 
2137
 
-
 
2138
    IF pic THEN
-
 
2139
        reg1 := GetAnyReg();
-
 
2140
        Pic(reg1, BIN.PICDATA, 0);
-
 
2141
        push(reg1);    (* push _data *)
2223
        pushc(0)
2142
        drop
-
 
2143
    ELSE
-
 
2144
        OutByte(68H);  (* push _data *)
-
 
2145
        Reloc(BIN.RDATA, 0)
2224
    END;
2146
    END;
2225
 
2147
 
2226
    IF pic THEN
2148
    dcount := CHL.Length(IL.codes.data);
2227
        reg1 := GetAnyReg();
-
 
2228
        Pic(reg1, BIN.PICCODE, entry);
-
 
2229
        push(reg1);    (* push CODE *)
2149
 
2230
        Pic(reg1, BIN.PICDATA, 0);
-
 
2231
        push(reg1);    (* push _data *)
-
 
2232
        pushc(tcount);
-
 
2233
        Pic(reg1, BIN.PICDATA, tcount * 4 + dcount);
2150
    pushc(tcount);
2234
        push(reg1);    (* push _data + tcount * 4 + dcount *)
2151
 
2235
        drop
Line 2152... Line 2236...
2152
    IF pic THEN
2236
    ELSE
Line 2153... Line 2237...
2153
        reg1 := GetAnyReg();
2237
        OutByte(68H);  (* push CODE *)
2154
        Pic(reg1, BIN.PICDATA, tcount * 4 + dcount);
2238
        Reloc(BIN.RCODE, entry);
2155
        push(reg1);    (* push _data + tcount * 4 + dcount *)
2239
        OutByte(68H);  (* push _data *)
2156
        drop
2240
        Reloc(BIN.RDATA, 0);
2157
    ELSE
2241
        pushc(tcount);
2158
        OutByte(68H);  (* push _data *)
2242
        OutByte(68H);  (* push _data + tcount * 4 + dcount *)
Line 2184... Line 2268...
2184
    path, name, ext: PATHS.PATH;
2268
    path, name, ext: PATHS.PATH;
Line 2185... Line 2269...
2185
 
2269
 
Line 2186... Line 2270...
2186
    dcount, i: INTEGER;
2270
    dcount, i: INTEGER;
2187
 
2271
 
2188
 
2272
 
2189
    PROCEDURE import (imp: LISTS.LIST);
2273
    PROCEDURE _import (imp: LISTS.LIST);
Line 2190... Line 2274...
2190
    VAR
2274
    VAR
Line 2202... Line 2286...
2202
                proc := proc.next(IL.IMPORT_PROC)
2286
                proc := proc.next(IL.IMPORT_PROC)
2203
            END;
2287
            END;
2204
            lib := lib.next(IL.IMPORT_LIB)
2288
            lib := lib.next(IL.IMPORT_LIB)
2205
        END
2289
        END
Line 2206... Line 2290...
2206
 
2290
 
Line 2207... Line 2291...
2207
    END import;
2291
    END _import;
Line 2208... Line 2292...
2208
 
2292
 
Line 2254... Line 2338...
2254
    WHILE exp # NIL DO
2338
    WHILE exp # NIL DO
2255
        BIN.Export(program, exp.name, exp.label);
2339
        BIN.Export(program, exp.name, exp.label);
2256
        exp := exp.next(IL.EXPORT_PROC)
2340
        exp := exp.next(IL.EXPORT_PROC)
2257
    END;
2341
    END;
Line 2258... Line 2342...
2258
 
2342
 
Line 2259... Line 2343...
2259
    import(IL.codes.import);
2343
    _import(IL.codes._import);
Line 2260... Line 2344...
2260
 
2344
 
2261
    IL.set_bss(MAX(IL.codes.bss, MAX(IL.codes.dmin - CHL.Length(IL.codes.data), 4)));
-
 
2262
 
2345
    IL.set_bss(MAX(IL.codes.bss, MAX(IL.codes.dmin - CHL.Length(IL.codes.data), 4)));
Line 2263... Line 2346...
2263
    BIN.SetParams(program, IL.codes.bss, stack * (1024 * 1024), WCHR(ver DIV 65536), WCHR(ver MOD 65536));
2346
 
2264
 
2347
    BIN.SetParams(program, IL.codes.bss, stack * (1024 * 1024), WCHR(ver DIV 65536), WCHR(ver MOD 65536))
2265
END epilog;
2348
END epilog;
2266
 
2349
 
Line 2267... Line 2350...
2267
 
2350
 
-
 
2351
PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
2268
PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
2352
VAR
Line 2269... Line 2353...
2269
VAR
2353
    dllret, dllinit, sofinit: INTEGER;
2270
    dllret, dllinit, sofinit: INTEGER;
2354
    opt: PROG.OPTIONS;