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) 2018-2019, Anton Krotov
4
    Copyright (c) 2018-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 X86;
8
MODULE X86;
Line 9... Line 9...
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 91... Line 91...
91
    CodeList: LISTS.LIST;
91
    CodeList: LISTS.LIST;
Line 92... Line 92...
92
 
92
 
Line 93... Line -...
93
    tcount: INTEGER;
-
 
94
 
-
 
95
 
-
 
96
PROCEDURE Byte (n: INTEGER): BYTE;
-
 
97
    RETURN UTILS.Byte(n, 0)
-
 
98
END Byte;
-
 
99
 
-
 
100
 
-
 
101
PROCEDURE Word (n: INTEGER): INTEGER;
-
 
102
    RETURN UTILS.Byte(n, 0) + UTILS.Byte(n, 1) * 256
-
 
103
END Word;
93
    tcount: INTEGER;
104
 
94
 
105
 
95
 
106
PROCEDURE OutByte* (n: BYTE);
96
PROCEDURE OutByte* (n: BYTE);
Line 125... Line 115...
125
END OutByte;
115
END OutByte;
Line 126... Line 116...
126
 
116
 
127
 
117
 
128
PROCEDURE OutInt (n: INTEGER);
118
PROCEDURE OutInt (n: INTEGER);
129
BEGIN
119
BEGIN
130
    OutByte(UTILS.Byte(n, 0));
120
    OutByte(n MOD 256);
131
    OutByte(UTILS.Byte(n, 1));
121
    OutByte(UTILS.Byte(n, 1));
132
    OutByte(UTILS.Byte(n, 2));
122
    OutByte(UTILS.Byte(n, 2));
Line 172... Line 162...
172
 
162
 
173
 
163
 
174
PROCEDURE OutIntByte (n: INTEGER);
164
PROCEDURE OutIntByte (n: INTEGER);
175
BEGIN
165
BEGIN
176
    IF isByte(n) THEN
166
    IF isByte(n) THEN
177
        OutByte(Byte(n))
167
        OutByte(n MOD 256)
178
    ELSE
168
    ELSE
179
        OutInt(n)
169
        OutInt(n)
Line 192... Line 182...
192
END shift;
182
END shift;
Line 193... Line 183...
193
 
183
 
194
 
184
 
195
PROCEDURE mov (reg1, reg2: INTEGER);
185
PROCEDURE mov (reg1, reg2: INTEGER);
196
BEGIN
186
BEGIN
Line 197... Line 187...
197
    OutByte2(89H, 0C0H + reg2 * 8 + reg1)  // mov reg1, reg2
187
    OutByte2(89H, 0C0H + reg2 * 8 + reg1)  (* mov reg1, reg2 *)
198
END mov;
188
END mov;
199
 
189
 
Line 200... Line 190...
200
 
190
 
201
PROCEDURE xchg (reg1, reg2: INTEGER);
191
PROCEDURE xchg (reg1, reg2: INTEGER);
202
VAR
192
VAR
203
    regs: SET;
193
    regs: SET;
204
 
194
 
205
BEGIN
195
BEGIN
206
    regs := {reg1, reg2};
196
    regs := {reg1, reg2};
207
    IF regs = {eax, ecx} THEN
197
    IF regs = {eax, ecx} THEN
208
        OutByte(91H)                // xchg eax, ecx
198
        OutByte(91H)                (* xchg eax, ecx *)
209
    ELSIF regs = {eax, edx} THEN
199
    ELSIF regs = {eax, edx} THEN
Line 210... Line 200...
210
        OutByte(92H)                // xchg eax, edx
200
        OutByte(92H)                (* xchg eax, edx *)
211
    ELSIF regs = {ecx, edx} THEN
201
    ELSIF regs = {ecx, edx} THEN
212
        OutByte2(87H, 0D1H)         // xchg ecx, edx
202
        OutByte2(87H, 0D1H)         (* xchg ecx, edx *)
213
    END
203
    END
Line 214... Line 204...
214
END xchg;
204
END xchg;
215
 
205
 
216
 
206
 
217
PROCEDURE pop (reg: INTEGER);
207
PROCEDURE pop (reg: INTEGER);
Line 218... Line 208...
218
BEGIN
208
BEGIN
219
    OutByte(58H + reg) // pop reg
209
    OutByte(58H + reg) (* pop reg *)
220
END pop;
210
END pop;
221
 
211
 
222
 
212
 
Line 223... Line 213...
223
PROCEDURE push (reg: INTEGER);
213
PROCEDURE push (reg: INTEGER);
224
BEGIN
214
BEGIN
225
    OutByte(50H + reg) // push reg
215
    OutByte(50H + reg) (* push reg *)
226
END push;
216
END push;
227
 
217
 
Line 228... Line 218...
228
 
218
 
229
PROCEDURE movrc (reg, n: INTEGER);
219
PROCEDURE movrc (reg, n: INTEGER);
230
BEGIN
220
BEGIN
231
    OutByte(0B8H + reg); // mov reg, n
221
    OutByte(0B8H + reg); (* mov reg, n *)
Line 232... Line 222...
232
    OutInt(n)
222
    OutInt(n)
233
END movrc;
223
END movrc;
234
 
224
 
235
 
225
 
Line 236... Line 226...
236
PROCEDURE pushc (n: INTEGER);
226
PROCEDURE pushc (n: INTEGER);
237
BEGIN
227
BEGIN
238
    OutByte(68H + short(n)); // push n
228
    OutByte(68H + short(n)); (* push n *)
239
    OutIntByte(n)
229
    OutIntByte(n)
Line 240... Line 230...
240
END pushc;
230
END pushc;
241
 
231
 
242
 
232
 
243
PROCEDURE test (reg: INTEGER);
233
PROCEDURE test (reg: INTEGER);
Line 244... Line 234...
244
BEGIN
234
BEGIN
245
    OutByte2(85H, 0C0H + reg * 9)  // test reg, reg
235
    OutByte2(85H, 0C0H + reg * 9)  (* test reg, reg *)
246
END test;
236
END test;
247
 
237
 
248
 
238
 
Line 249... Line 239...
249
PROCEDURE neg (reg: INTEGER);
239
PROCEDURE neg (reg: INTEGER);
250
BEGIN
240
BEGIN
251
    OutByte2(0F7H, 0D8H + reg)  // neg reg
241
    OutByte2(0F7H, 0D8H + reg)  (* neg reg *)
252
END neg;
242
END neg;
253
 
243
 
Line 254... Line 244...
254
 
244
 
255
PROCEDURE not (reg: INTEGER);
245
PROCEDURE not (reg: INTEGER);
256
BEGIN
246
BEGIN
257
    OutByte2(0F7H, 0D0H + reg)  // not reg
247
    OutByte2(0F7H, 0D0H + reg)  (* not reg *)
258
END not;
248
END not;
Line 259... Line 249...
259
 
249
 
260
 
250
 
261
PROCEDURE add (reg1, reg2: INTEGER);
251
PROCEDURE add (reg1, reg2: INTEGER);
262
BEGIN
252
BEGIN
263
    OutByte2(01H, 0C0H + reg2 * 8 + reg1)  // add reg1, reg2
253
    OutByte2(01H, 0C0H + reg2 * 8 + reg1)  (* add reg1, reg2 *)
Line 264... Line 254...
264
END add;
254
END add;
265
 
255
 
266
 
256
 
267
PROCEDURE andrc (reg, n: INTEGER);
257
PROCEDURE andrc (reg, n: INTEGER);
Line 268... Line 258...
268
BEGIN
258
BEGIN
269
    OutByte2(81H + short(n), 0E0H + reg);  // and reg, n
259
    OutByte2(81H + short(n), 0E0H + reg);  (* and reg, n *)
-
 
260
    OutIntByte(n)
-
 
261
END andrc;
-
 
262
 
270
    OutIntByte(n)
263
 
271
END andrc;
264
PROCEDURE orrc (reg, n: INTEGER);
-
 
265
BEGIN
272
 
266
    OutByte2(81H + short(n), 0C8H + reg);  (* or reg, n *)
Line 273... Line 267...
273
 
267
    OutIntByte(n)
274
PROCEDURE orrc (reg, n: INTEGER);
268
END orrc;
275
BEGIN
269
 
276
    OutByte2(81H + short(n), 0C8H + reg);  // or reg, n
270
 
Line 277... Line 271...
277
    OutIntByte(n)
271
PROCEDURE addrc (reg, n: INTEGER);
278
END orrc;
272
BEGIN
279
 
273
    OutByte2(81H + short(n), 0C0H + reg);  (* add reg, n *)
280
 
274
    OutIntByte(n)
Line -... Line 275...
-
 
275
END addrc;
-
 
276
 
-
 
277
 
-
 
278
PROCEDURE subrc (reg, n: INTEGER);
-
 
279
BEGIN
-
 
280
    OutByte2(81H + short(n), 0E8H + reg);  (* sub reg, n *)
281
PROCEDURE addrc (reg, n: INTEGER);
281
    OutIntByte(n)
282
BEGIN
282
END subrc;
283
    OutByte2(81H + short(n), 0C0H + reg);  // add reg, n
283
 
284
    OutIntByte(n)
284
 
Line 400... Line 400...
400
END call;
400
END call;
Line 401... Line 401...
401
 
401
 
402
 
402
 
403
PROCEDURE Pic (reg, opcode, value: INTEGER);
403
PROCEDURE Pic (reg, opcode, value: INTEGER);
404
BEGIN
404
BEGIN
405
    OutByte(0E8H); OutInt(0); // call L
405
    OutByte(0E8H); OutInt(0); (* call L
406
                              // L:
406
                                 L: *)
407
    pop(reg);
407
    pop(reg);
408
    OutByte2(081H, 0C0H + reg);  // add reg, ...
408
    OutByte2(081H, 0C0H + reg);  (* add reg, ... *)
Line 409... Line 409...
409
    Reloc(opcode, value)
409
    Reloc(opcode, value)
Line 421... Line 421...
421
    IF label < 0 THEN
421
    IF label < 0 THEN
422
        label := -label;
422
        label := -label;
423
        IF pic THEN
423
        IF pic THEN
424
            reg1 := GetAnyReg();
424
            reg1 := GetAnyReg();
425
            Pic(reg1, BIN.PICIMP, label);
425
            Pic(reg1, BIN.PICIMP, label);
426
            OutByte2(0FFH, 010H + reg1);  // call dword[reg1]
426
            OutByte2(0FFH, 010H + reg1);  (* call dword[reg1] *)
427
            drop
427
            drop
428
        ELSE
428
        ELSE
429
            OutByte2(0FFH, 015H);  // call dword[label]
429
            OutByte2(0FFH, 015H);  (* call dword[label] *)
430
            Reloc(BIN.RIMP, label)
430
            Reloc(BIN.RIMP, label)
431
        END
431
        END
432
    ELSE
432
    ELSE
433
        call(label)
433
        call(label)
434
    END
434
    END
Line 502... Line 502...
502
                FOR i := 0 TO code.length - 1 DO
502
                FOR i := 0 TO code.length - 1 DO
503
                    BIN.PutCode(program, code.code[i])
503
                    BIN.PutCode(program, code.code[i])
504
                END
504
                END
Line 505... Line 505...
505
 
505
 
506
        |LABEL:
-
 
Line 507... Line 506...
507
                BIN.SetLabel(program, code.label, code.offset)
506
        |LABEL:
508
 
507
 
509
        |JMP:
508
        |JMP:
510
                IF code.short THEN
509
                IF code.short THEN
511
                    BIN.PutCode(program, 0EBH);
510
                    BIN.PutCode(program, 0EBH);
512
                    BIN.PutCode(program, Byte(code.diff))
511
                    BIN.PutCode(program, code.diff MOD 256)
513
                ELSE
512
                ELSE
514
                    BIN.PutCode(program, 0E9H);
513
                    BIN.PutCode(program, 0E9H);
Line 515... Line 514...
515
                    BIN.PutCode32LE(program, code.diff)
514
                    BIN.PutCode32LE(program, code.diff)
516
                END
515
                END
517
 
516
 
518
        |JCC:
517
        |JCC:
519
                IF code.short THEN
518
                IF code.short THEN
520
                    BIN.PutCode(program, code.jmp - 16);
519
                    BIN.PutCode(program, code.jmp - 16);
521
                    BIN.PutCode(program, Byte(code.diff))
520
                    BIN.PutCode(program, code.diff MOD 256)
522
                ELSE
521
                ELSE
523
                    BIN.PutCode(program, 0FH);
522
                    BIN.PutCode(program, 0FH);
Line 571... Line 570...
571
BEGIN
570
BEGIN
572
    ASSERT(REG.GetReg(R, eax))
571
    ASSERT(REG.GetReg(R, eax))
573
END GetRegA;
572
END GetRegA;
Line -... Line 573...
-
 
573
 
-
 
574
 
-
 
575
PROCEDURE fcmp;
-
 
576
BEGIN
-
 
577
    GetRegA;
-
 
578
    OutByte2(0DAH, 0E9H);       (* fucompp *)
-
 
579
    OutByte3(09BH, 0DFH, 0E0H); (* fstsw ax *)
-
 
580
    OutByte(09EH);              (* sahf *)
-
 
581
    movrc(eax, 0)
-
 
582
END fcmp;
-
 
583
 
-
 
584
 
-
 
585
PROCEDURE movzx* (reg1, reg2, offs: INTEGER; word: BOOLEAN); (* movzx reg1, byte/word[reg2 + offs] *)
-
 
586
VAR
-
 
587
    b: BYTE;
-
 
588
 
-
 
589
BEGIN
-
 
590
    OutByte2(0FH, 0B6H + ORD(word));
-
 
591
    IF (offs = 0) & (reg2 # ebp) THEN
-
 
592
        b := 0
-
 
593
    ELSE
-
 
594
        b := 40H + long(offs)
-
 
595
    END;
-
 
596
    OutByte(b + (reg1 MOD 8) * 8 + reg2 MOD 8);
-
 
597
    IF reg2 = esp THEN
-
 
598
        OutByte(24H)
-
 
599
    END;
-
 
600
    IF b # 0 THEN
-
 
601
        OutIntByte(offs)
-
 
602
    END
-
 
603
END movzx;
-
 
604
 
-
 
605
 
-
 
606
PROCEDURE _movrm* (reg1, reg2, offs, size: INTEGER; mr: BOOLEAN);
-
 
607
VAR
-
 
608
    b: BYTE;
-
 
609
 
-
 
610
BEGIN
-
 
611
    IF size = 16 THEN
-
 
612
        OutByte(66H)
-
 
613
    END;
-
 
614
    IF (reg1 >= 8) OR (reg2 >= 8) OR (size = 64) THEN
-
 
615
        OutByte(40H + reg2 DIV 8 + 4 * (reg1 DIV 8) + 8 * ORD(size = 64))
-
 
616
    END;
-
 
617
    OutByte(8BH - 2 * ORD(mr) - ORD(size = 8));
-
 
618
    IF (offs = 0) & (reg2 # ebp) THEN
-
 
619
        b := 0
-
 
620
    ELSE
-
 
621
        b := 40H + long(offs)
-
 
622
    END;
-
 
623
    OutByte(b + (reg1 MOD 8) * 8 + reg2 MOD 8);
-
 
624
    IF reg2 = esp THEN
-
 
625
        OutByte(24H)
-
 
626
    END;
-
 
627
    IF b # 0 THEN
-
 
628
        OutIntByte(offs)
-
 
629
    END
-
 
630
END _movrm;
-
 
631
 
-
 
632
 
-
 
633
PROCEDURE movmr (reg1, offs, reg2: INTEGER); (* mov dword[reg1+offs], reg2_8 *)
-
 
634
BEGIN
-
 
635
    _movrm(reg2, reg1, offs, 32, TRUE)
-
 
636
END movmr;
-
 
637
 
-
 
638
 
-
 
639
PROCEDURE movrm (reg1, reg2, offs: INTEGER); (* mov reg1, dword[reg2 + offs] *)
-
 
640
BEGIN
-
 
641
    _movrm(reg1, reg2, offs, 32, FALSE)
-
 
642
END movrm;
-
 
643
 
-
 
644
 
-
 
645
PROCEDURE movmr8* (reg1, offs, reg2: INTEGER); (* mov byte[reg1+offs], reg2_8 *)
-
 
646
BEGIN
-
 
647
    _movrm(reg2, reg1, offs, 8, TRUE)
-
 
648
END movmr8;
-
 
649
 
-
 
650
 
-
 
651
PROCEDURE movrm8* (reg1, reg2, offs: INTEGER); (* mov reg1_8, byte[reg2+offs] *)
-
 
652
BEGIN
-
 
653
    _movrm(reg1, reg2, offs, 8, FALSE)
-
 
654
END movrm8;
-
 
655
 
-
 
656
 
-
 
657
PROCEDURE movmr16* (reg1, offs, reg2: INTEGER); (* mov word[reg1+offs], reg2_16 *)
-
 
658
BEGIN
-
 
659
    _movrm(reg2, reg1, offs, 16, TRUE)
-
 
660
END movmr16;
-
 
661
 
-
 
662
 
-
 
663
PROCEDURE movrm16* (reg1, reg2, offs: INTEGER); (* mov reg1_16, word[reg2+offs] *)
-
 
664
BEGIN
-
 
665
    _movrm(reg1, reg2, offs, 16, FALSE)
-
 
666
END movrm16;
-
 
667
 
-
 
668
 
-
 
669
PROCEDURE pushm* (reg, offs: INTEGER); (* push qword[reg+offs] *)
-
 
670
VAR
-
 
671
    b: BYTE;
-
 
672
 
-
 
673
BEGIN
-
 
674
    IF reg >= 8 THEN
-
 
675
        OutByte(41H)
-
 
676
    END;
-
 
677
    OutByte(0FFH);
-
 
678
    IF (offs = 0) & (reg # ebp) THEN
-
 
679
        b := 30H
-
 
680
    ELSE
-
 
681
        b := 70H + long(offs)
-
 
682
    END;
-
 
683
    OutByte(b + reg MOD 8);
-
 
684
    IF reg = esp THEN
-
 
685
        OutByte(24H)
-
 
686
    END;
-
 
687
    IF b # 30H THEN
-
 
688
        OutIntByte(offs)
-
 
689
    END
-
 
690
END pushm;
574
 
691
 
575
 
692
 
576
PROCEDURE translate (pic: BOOLEAN; stroffs: INTEGER);
693
PROCEDURE translate (pic: BOOLEAN; stroffs: INTEGER);
Line 577... Line 694...
577
VAR
694
VAR
Line 578... Line 695...
578
    cmd: COMMAND;
695
    cmd, next: COMMAND;
Line 605... Line 722...
605
 
722
 
606
        |IL.opCALLI:
723
        |IL.opCALLI:
607
            IF pic THEN
724
            IF pic THEN
608
                reg1 := GetAnyReg();
725
                reg1 := GetAnyReg();
609
                Pic(reg1, BIN.PICIMP, param1);
726
                Pic(reg1, BIN.PICIMP, param1);
610
                OutByte2(0FFH, 010H + reg1);  // call dword[reg1]
727
                OutByte2(0FFH, 010H + reg1);  (* call dword[reg1] *)
611
                drop
728
                drop
612
            ELSE
729
            ELSE
613
                OutByte2(0FFH, 015H);  // call dword[L]
730
                OutByte2(0FFH, 015H);  (* call dword[L] *)
614
                Reloc(BIN.RIMP, param1)
731
                Reloc(BIN.RIMP, param1)
Line 615... Line 732...
615
            END
732
            END
616
 
733
 
617
        |IL.opCALLP:
734
        |IL.opCALLP:
618
            UnOp(reg1);
735
            UnOp(reg1);
619
            OutByte2(0FFH, 0D0H + reg1);    // call reg1
736
            OutByte2(0FFH, 0D0H + reg1);  (* call reg1 *)
Line 620... Line 737...
620
            drop;
737
            drop;
621
            ASSERT(R.top = -1)
738
            ASSERT(R.top = -1)
622
 
739
 
623
        |IL.opPRECALL:
740
        |IL.opPRECALL:
624
            n := param2;
741
            n := param2;
625
            IF (param1 # 0) & (n # 0) THEN
742
            IF (param1 # 0) & (n # 0) THEN
626
                subrc(esp, 8)
743
                subrc(esp, 8)
627
            END;
744
            END;
628
            WHILE n > 0 DO
745
            WHILE n > 0 DO
629
                subrc(esp, 8);
746
                subrc(esp, 8);
630
                OutByte3(0DDH, 01CH, 024H); // fstp qword[esp]
747
                OutByte3(0DDH, 01CH, 024H); (* fstp qword[esp] *)
Line 631... Line 748...
631
                DEC(n)
748
                DEC(n)
Line 645... Line 762...
645
        |IL.opRES:
762
        |IL.opRES:
646
            ASSERT(R.top = -1);
763
            ASSERT(R.top = -1);
647
            GetRegA;
764
            GetRegA;
648
            n := param2;
765
            n := param2;
649
            WHILE n > 0 DO
766
            WHILE n > 0 DO
650
                OutByte3(0DDH, 004H, 024H); // fld qword[esp]
767
                OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *)
651
                addrc(esp, 8);
768
                addrc(esp, 8);
652
                DEC(n)
769
                DEC(n)
653
            END
770
            END
Line 654... Line 771...
654
 
771
 
655
        |IL.opRESF:
772
        |IL.opRESF:
656
            n := param2;
773
            n := param2;
657
            IF n > 0 THEN
774
            IF n > 0 THEN
658
                OutByte3(0DDH, 5CH + long(n * 8), 24H);
775
                OutByte3(0DDH, 5CH + long(n * 8), 24H);
659
                OutIntByte(n * 8); // fstp qword[esp + n*8]
776
                OutIntByte(n * 8); (* fstp qword[esp + n*8] *)
660
                INC(n)
777
                INC(n)
Line 661... Line 778...
661
            END;
778
            END;
662
 
779
 
663
            WHILE n > 0 DO
780
            WHILE n > 0 DO
664
                OutByte3(0DDH, 004H, 024H); // fld qword[esp]
781
                OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *)
665
                addrc(esp, 8);
782
                addrc(esp, 8);
Line 666... Line 783...
666
                DEC(n)
783
                DEC(n)
Line 675... Line 792...
675
            mov(ebp, esp);
792
            mov(ebp, esp);
Line 676... Line 793...
676
 
793
 
677
            n := param2;
794
            n := param2;
678
            IF n > 4 THEN
795
            IF n > 4 THEN
679
                movrc(ecx, n);
796
                movrc(ecx, n);
680
                pushc(0);             // @@: push 0
797
                pushc(0);             (* L: push 0 *)
681
                OutByte2(0E2H, 0FCH)  // loop @b
798
                OutByte2(0E2H, 0FCH)  (* loop L    *)
682
            ELSE
799
            ELSE
683
                WHILE n > 0 DO
800
                WHILE n > 0 DO
684
                    pushc(0);
801
                    pushc(0);
685
                    DEC(n)
802
                    DEC(n)
Line 706... Line 823...
706
            pop(ebp);
823
            pop(ebp);
Line 707... Line 824...
707
 
824
 
708
            n := param2;
825
            n := param2;
709
            IF n > 0 THEN
826
            IF n > 0 THEN
710
                n := n * 4;
827
                n := n * 4;
711
                OutByte(0C2H); OutWord(Word(n)) // ret n
828
                OutByte(0C2H); OutWord(n MOD 65536) (* ret n *)
712
            ELSE
829
            ELSE
713
                OutByte(0C3H) // ret
830
                ret
Line 714... Line 831...
714
            END
831
            END
715
 
832
 
Line -... Line 833...
-
 
833
        |IL.opPUSHC:
-
 
834
            pushc(param2)
-
 
835
 
-
 
836
        |IL.opONERR:
716
        |IL.opPUSHC:
837
            pushc(param2);
717
            pushc(param2)
838
            jmp(param1)
718
 
839
 
719
        |IL.opPARAM:
840
        |IL.opPARAM:
720
            n := param2;
841
            n := param2;
Line 738... Line 859...
738
 
859
 
739
        |IL.opCONST:
860
        |IL.opCONST:
Line 740... Line 861...
740
            movrc(GetAnyReg(), param2)
861
            movrc(GetAnyReg(), param2)
741
 
862
 
Line 742... Line 863...
742
        |IL.opLABEL:
863
        |IL.opLABEL:
Line 743... Line 864...
743
            SetLabel(param1) // L:
864
            SetLabel(param1) (* L: *)
744
 
865
 
745
        |IL.opNOP:
866
        |IL.opNOP:
746
 
867
 
747
        |IL.opGADR:
868
        |IL.opGADR:
748
            reg1 := GetAnyReg();
869
            reg1 := GetAnyReg();
749
            IF pic THEN
870
            IF pic THEN
750
                Pic(reg1, BIN.PICBSS, param2)
871
                Pic(reg1, BIN.PICBSS, param2)
Line 751... Line 872...
751
            ELSE
872
            ELSE
752
                OutByte(0B8H + reg1);  // mov reg1, _bss + param2
873
                OutByte(0B8H + reg1);  (* mov reg1, _bss + param2 *)
753
                Reloc(BIN.RBSS, param2)
874
                Reloc(BIN.RBSS, param2)
754
            END
875
            END
Line 755... Line 876...
755
 
876
 
756
        |IL.opLADR:
877
        |IL.opLADR:
757
            n := param2 * 4;
-
 
758
            OutByte2(8DH, 45H + GetAnyReg() * 8 + long(n));  // lea reg1, dword[ebp + n]
-
 
Line 759... Line 878...
759
            OutIntByte(n)
878
            n := param2 * 4;
760
 
879
            OutByte2(8DH, 45H + GetAnyReg() * 8 + long(n));  (* lea reg1, dword[ebp + n] *)
761
        |IL.opVADR:
880
            OutIntByte(n)
762
            n := param2 * 4;
881
 
763
            OutByte2(8BH, 45H + GetAnyReg() * 8 + long(n));  // mov reg1, dword[ebp + n]
882
        |IL.opVADR, IL.opLLOAD32:
764
            OutIntByte(n)
883
            movrm(GetAnyReg(), ebp, param2 * 4)
765
 
884
 
766
        |IL.opSADR:
885
        |IL.opSADR:
Line 767... Line 886...
767
            reg1 := GetAnyReg();
886
            reg1 := GetAnyReg();
768
            IF pic THEN
887
            IF pic THEN
769
                Pic(reg1, BIN.PICDATA, stroffs + param2);
888
                Pic(reg1, BIN.PICDATA, stroffs + param2);
770
            ELSE
889
            ELSE
Line 771... Line 890...
771
                OutByte(0B8H + reg1);  // mov reg1, _data + stroffs + param2
890
                OutByte(0B8H + reg1);  (* mov reg1, _data + stroffs + param2 *)
772
                Reloc(BIN.RDATA, stroffs + param2)
891
                Reloc(BIN.RDATA, stroffs + param2)
773
            END
892
            END
774
 
893
 
Line 775... Line 894...
775
        |IL.opSAVEC:
894
        |IL.opSAVEC:
776
            UnOp(reg1);
895
            UnOp(reg1);
777
            OutByte2(0C7H, reg1); OutInt(param2);  // mov dword[reg1], param2
896
            OutByte2(0C7H, reg1); OutInt(param2);  (* mov dword[reg1], param2 *)
778
            drop
897
            drop
Line 779... Line 898...
779
 
898
 
780
        |IL.opSAVE8C:
899
        |IL.opSAVE8C:
781
            UnOp(reg1);
900
            UnOp(reg1);
782
            OutByte3(0C6H, reg1, Byte(param2));  // mov byte[reg1], param2
-
 
783
            drop
901
            OutByte3(0C6H, reg1, param2 MOD 256);  (* mov byte[reg1], param2 *)
784
 
902
            drop
Line 785... Line 903...
785
        |IL.opSAVE16C:
903
 
786
            UnOp(reg1);
904
        |IL.opSAVE16C:
787
            OutByte3(66H, 0C7H, reg1); OutWord(Word(param2));  // mov word[reg1], param2
905
            UnOp(reg1);
788
            drop
906
            OutByte3(66H, 0C7H, reg1); OutWord(param2 MOD 65536);  (* mov word[reg1], param2 *)
789
 
907
            drop
790
        |IL.opVLOAD32:
908
 
791
            n := param2 * 4;
909
        |IL.opVLOAD32:
792
            reg1 := GetAnyReg();
910
            n := param2 * 4;
793
            OutByte2(8BH, 45H + reg1 * 8 + long(n));  // mov reg1, dword[ebp + n]
911
            reg1 := GetAnyReg();
Line 794... Line -...
794
            OutIntByte(n);
-
 
795
            OutByte2(8BH, reg1 * 9)  // mov reg1, dword[reg1]
-
 
796
 
-
 
797
        |IL.opGLOAD32:
-
 
798
            reg1 := GetAnyReg();
-
 
799
            IF pic THEN
912
            movrm(reg1, ebp, param2 * 4);
800
                Pic(reg1, BIN.PICBSS, param2);
913
            movrm(reg1, reg1, 0)
801
                OutByte2(8BH, reg1 * 9)       // mov reg1, dword[reg1]
914
 
Line 802... Line 915...
802
            ELSE
915
        |IL.opGLOAD32:
803
                OutByte2(08BH, 05H + reg1 * 8);  // mov reg1, dword[_bss + param2]
-
 
804
                Reloc(BIN.RBSS, param2)
916
            reg1 := GetAnyReg();
805
            END
-
 
806
 
917
            IF pic THEN
807
        |IL.opLLOAD32:
918
                Pic(reg1, BIN.PICBSS, param2);
Line 808... Line 919...
808
            n := param2 * 4;
919
                movrm(reg1, reg1, 0)
809
            OutByte2(8BH, 45H + GetAnyReg() * 8 + long(n));  // mov reg1, dword[ebp + n]
920
            ELSE
810
            OutIntByte(n)
921
                OutByte2(08BH, 05H + reg1 * 8);  (* mov reg1, dword[_bss + param2] *)
811
 
922
                Reloc(BIN.RBSS, param2)
812
        |IL.opLOAD32:
923
            END
813
            UnOp(reg1);
924
 
814
            OutByte2(8BH, reg1 * 9)  // mov reg1, dword[reg1]
925
        |IL.opLOAD32:
815
 
926
            UnOp(reg1);
816
        |IL.opVLOAD8:
927
            movrm(reg1, reg1, 0)
Line 817... Line 928...
817
            n := param2 * 4;
928
 
818
            reg1 := GetAnyReg();
929
        |IL.opVLOAD8:
819
            OutByte2(8BH, 45H + reg1 * 8 + long(n)); // mov reg1, dword[ebp + n]
-
 
820
            OutIntByte(n);
-
 
Line 821... Line 930...
821
            OutByte3(0FH, 0B6H, reg1 * 9) // movzx reg1, byte[reg1]
930
            reg1 := GetAnyReg();
822
 
931
            movrm(reg1, ebp, param2 * 4);
823
        |IL.opGLOAD8:
932
            movzx(reg1, reg1, 0, FALSE)
Line 824... Line 933...
824
            reg1 := GetAnyReg();
933
 
825
            IF pic THEN
-
 
826
                Pic(reg1, BIN.PICBSS, param2);
934
        |IL.opGLOAD8:
827
                OutByte3(0FH, 0B6H, reg1 * 9) // movzx reg1, byte[reg1]
-
 
828
            ELSE
935
            reg1 := GetAnyReg();
829
                OutByte3(00FH, 0B6H, 05H + reg1 * 8);  // movzx reg1, byte[_bss + param2]
936
            IF pic THEN
Line 830... Line 937...
830
                Reloc(BIN.RBSS, param2)
937
                Pic(reg1, BIN.PICBSS, param2);
831
            END
938
                movzx(reg1, reg1, 0, FALSE)
832
 
939
            ELSE
833
        |IL.opLLOAD8:
940
                OutByte3(00FH, 0B6H, 05H + reg1 * 8); (* movzx reg1, byte[_bss + param2] *)
834
            n := param2 * 4;
941
                Reloc(BIN.RBSS, param2)
835
            OutByte3(0FH, 0B6H, 45H + GetAnyReg() * 8 + long(n)); // movzx reg1, byte[ebp + n]
942
            END
836
            OutIntByte(n)
943
 
837
 
944
        |IL.opLLOAD8:
838
        |IL.opLOAD8:
945
            movzx(GetAnyReg(), ebp, param2 * 4, FALSE)
Line 839... Line 946...
839
            UnOp(reg1);
946
 
840
            OutByte3(0FH, 0B6H, reg1 * 9) // movzx reg1, byte[reg1]
947
        |IL.opLOAD8:
841
 
-
 
842
        |IL.opVLOAD16:
-
 
Line 843... Line 948...
843
            n := param2 * 4;
948
            UnOp(reg1);
844
            reg1 := GetAnyReg();
949
            movzx(reg1, reg1, 0, FALSE)
845
            OutByte2(8BH, 45H + reg1 * 8 + long(n)); // mov reg1, dword[ebp + n]
950
 
Line 846... Line 951...
846
            OutIntByte(n);
951
        |IL.opVLOAD16:
847
            OutByte3(0FH, 0B7H, reg1 * 9) // movzx reg1, word[reg1]
952
            reg1 := GetAnyReg();
848
 
953
            movrm(reg1, ebp, param2 * 4);
Line 875... Line 980...
875
            drop
980
            drop
Line 876... Line 981...
876
 
981
 
877
        |IL.opADDL, IL.opADDR:
982
        |IL.opADDL, IL.opADDR:
878
            IF param2 # 0 THEN
983
            IF param2 # 0 THEN
-
 
984
                UnOp(reg1);
-
 
985
                next := cmd.next(COMMAND);
-
 
986
                CASE next.opcode OF
-
 
987
                |IL.opLOAD32:
-
 
988
                    movrm(reg1, reg1, param2);
-
 
989
                    cmd := next
-
 
990
                |IL.opLOAD16:
-
 
991
                    movzx(reg1, reg1, param2, TRUE);
-
 
992
                    cmd := next
-
 
993
                |IL.opLOAD8:
-
 
994
                    movzx(reg1, reg1, param2, FALSE);
-
 
995
                    cmd := next
-
 
996
                |IL.opLOAD32_PARAM:
-
 
997
                    pushm(reg1, param2);
-
 
998
                    drop;
-
 
999
                    cmd := next
879
                UnOp(reg1);
1000
                ELSE
880
                IF param2 = 1 THEN
1001
                    IF param2 = 1 THEN
881
                    OutByte(40H + reg1) // inc reg1
1002
                        OutByte(40H + reg1) (* inc reg1 *)
882
                ELSIF param2 = -1 THEN
1003
                    ELSIF param2 = -1 THEN
883
                    OutByte(48H + reg1) // dec reg1
1004
                        OutByte(48H + reg1) (* dec reg1 *)
884
                ELSE
1005
                    ELSE
885
                    addrc(reg1, param2)
1006
                        addrc(reg1, param2)
886
                END
1007
                    END
-
 
1008
                END
Line 887... Line 1009...
887
            END
1009
            END
888
 
1010
 
889
        |IL.opSUB:
1011
        |IL.opSUB:
890
            BinOp(reg1, reg2);
1012
            BinOp(reg1, reg2);
Line 891... Line 1013...
891
            OutByte2(29H, 0C0H + reg2 * 8 + reg1); // sub reg1, reg2
1013
            OutByte2(29H, 0C0H + reg2 * 8 + reg1); (* sub reg1, reg2 *)
892
            drop
1014
            drop
893
 
1015
 
894
        |IL.opSUBR, IL.opSUBL:
1016
        |IL.opSUBR, IL.opSUBL:
895
            UnOp(reg1);
1017
            UnOp(reg1);
896
            n := param2;
1018
            n := param2;
897
            IF n = 1 THEN
1019
            IF n = 1 THEN
898
                OutByte(48H + reg1) // dec reg1
1020
                OutByte(48H + reg1) (* dec reg1 *)
899
            ELSIF n = -1 THEN
1021
            ELSIF n = -1 THEN
900
                OutByte(40H + reg1) // inc reg1
1022
                OutByte(40H + reg1) (* inc reg1 *)
901
            ELSIF n # 0 THEN
1023
            ELSIF n # 0 THEN
902
                subrc(reg1, n)
1024
                subrc(reg1, n)
903
            END;
1025
            END;
Line 904... Line 1026...
904
            IF opcode = IL.opSUBL THEN
1026
            IF opcode = IL.opSUBL THEN
-
 
1027
                neg(reg1)
-
 
1028
            END
-
 
1029
 
-
 
1030
        |IL.opMULC:
-
 
1031
            IF (cmd.next(COMMAND).opcode = IL.opADD) & ((param2 = 2) OR (param2 = 4) OR (param2 = 8)) THEN
-
 
1032
                BinOp(reg1, reg2);
905
                neg(reg1)
1033
                OutByte3(8DH, 04H + reg1 * 8, reg1 + reg2 * 8 + 40H * UTILS.Log2(param2)); (* lea reg1, [reg1 + reg2 * param2] *)
Line 906... Line 1034...
906
            END
1034
                drop;
907
 
1035
                cmd := cmd.next(COMMAND)
908
        |IL.opMULC:
1036
            ELSE
Line 928... Line 1056...
928
                    IF a < 0 THEN
1056
                        IF a < 0 THEN
929
                        neg(reg1)
1057
                            neg(reg1)
930
                    END;
1058
                        END;
Line 931... Line 1059...
931
 
1059
 
932
                    IF n # 1 THEN
1060
                        IF n # 1 THEN
933
                        OutByte3(0C1H, 0E0H + reg1, n)   // shl reg1, n
1061
                            OutByte3(0C1H, 0E0H + reg1, n)   (* shl reg1, n *)
934
                    ELSE
1062
                        ELSE
935
                        OutByte2(0D1H, 0E0H + reg1)      // shl reg1, 1
1063
                            OutByte2(0D1H, 0E0H + reg1)      (* shl reg1, 1 *)
936
                    END
1064
                        END
937
                ELSE
1065
                    ELSE
938
                    OutByte2(69H + short(a), 0C0H + reg1 * 9); // imul reg1, a
1066
                        OutByte2(69H + short(a), 0C0H + reg1 * 9); (* imul reg1, a *)
939
                    OutIntByte(a)
1067
                        OutIntByte(a)
940
                END
1068
                    END
-
 
1069
                END
Line 941... Line 1070...
941
            END
1070
            END
942
 
1071
 
943
        |IL.opMUL:
1072
        |IL.opMUL:
944
            BinOp(reg1, reg2);
1073
            BinOp(reg1, reg2);
Line 945... Line 1074...
945
            OutByte3(0FH, 0AFH, 0C0H + reg1 * 8 + reg2); // imul reg1, reg2
1074
            OutByte3(0FH, 0AFH, 0C0H + reg1 * 8 + reg2); (* imul reg1, reg2 *)
946
            drop
1075
            drop
947
 
1076
 
948
        |IL.opSAVE, IL.opSAVE32:
1077
        |IL.opSAVE, IL.opSAVE32:
949
            BinOp(reg2, reg1);
1078
            BinOp(reg2, reg1);
Line 950... Line 1079...
950
            OutByte2(89H, reg2 * 8 + reg1); // mov dword[reg1], reg2
1079
            movmr(reg1, 0, reg2);
951
            drop;
1080
            drop;
952
            drop
1081
            drop
953
 
1082
 
954
        |IL.opSAVE8:
1083
        |IL.opSAVE8:
Line 955... Line 1084...
955
            BinOp(reg2, reg1);
1084
            BinOp(reg2, reg1);
956
            OutByte2(88H, reg2 * 8 + reg1); // mov byte[reg1], reg2
1085
            movmr8(reg1, 0, reg2);
957
            drop;
1086
            drop;
958
            drop
1087
            drop
959
 
1088
 
Line 960... Line 1089...
960
        |IL.opSAVE16:
1089
        |IL.opSAVE16:
961
            BinOp(reg2, reg1);
1090
            BinOp(reg2, reg1);
962
            OutByte3(66H, 89H, reg2 * 8 + reg1); // mov word[reg1], reg2
1091
            movmr16(reg1, 0, reg2);
963
            drop;
1092
            drop;
964
            drop
1093
            drop
965
 
1094
 
966
        |IL.opSAVEP:
1095
        |IL.opSAVEP:
967
            UnOp(reg1);
1096
            UnOp(reg1);
968
            IF pic THEN
1097
            IF pic THEN
969
                reg2 := GetAnyReg();
1098
                reg2 := GetAnyReg();
970
                Pic(reg2, BIN.PICCODE, param2);
1099
                Pic(reg2, BIN.PICCODE, param2);
971
                OutByte2(089H, reg2 * 8 + reg1); // mov dword[reg1], reg2
1100
                movmr(reg1, 0, reg2);
Line 972... Line 1101...
972
                drop
1101
                drop
973
            ELSE
1102
            ELSE
974
                OutByte2(0C7H, reg1);  // mov dword[reg1], L
1103
                OutByte2(0C7H, reg1);  (* mov dword[reg1], L *)
975
                Reloc(BIN.RCODE, param2)
1104
                Reloc(BIN.RCODE, param2)
976
            END;
1105
            END;
977
            drop
1106
            drop
978
 
1107
 
979
        |IL.opSAVEIP:
1108
        |IL.opSAVEIP:
980
            UnOp(reg1);
1109
            UnOp(reg1);
981
            IF pic THEN
1110
            IF pic THEN
982
                reg2 := GetAnyReg();
1111
                reg2 := GetAnyReg();
983
                Pic(reg2, BIN.PICIMP, param2);
1112
                Pic(reg2, BIN.PICIMP, param2);
984
                OutByte2(0FFH, 30H + reg2);   // push dword[reg2]
1113
                pushm(reg2, 0);
985
                OutByte2(08FH, reg1);         // pop dword[reg1]
1114
                OutByte2(08FH, reg1);         (* pop  dword[reg1] *)
Line 986... Line 1115...
986
                drop
1115
                drop
987
            ELSE
1116
            ELSE
988
                OutByte2(0FFH, 035H);  // push dword[L]
1117
                OutByte2(0FFH, 035H);  (* push dword[L] *)
989
                Reloc(BIN.RIMP, param2);
1118
                Reloc(BIN.RIMP, param2);
990
                OutByte2(08FH, reg1)   // pop dword[reg1]
1119
                OutByte2(08FH, reg1)   (* pop dword[reg1] *)
991
            END;
1120
            END;
992
            drop
1121
            drop
993
 
1122
 
Line 994... Line 1123...
994
        |IL.opPUSHP:
1123
        |IL.opPUSHP:
995
            reg1 := GetAnyReg();
1124
            reg1 := GetAnyReg();
996
            IF pic THEN
1125
            IF pic THEN
997
                Pic(reg1, BIN.PICCODE, param2)
1126
                Pic(reg1, BIN.PICCODE, param2)
998
            ELSE
1127
            ELSE
999
                OutByte(0B8H + reg1);  // mov reg1, L
1128
                OutByte(0B8H + reg1);  (* mov reg1, L *)
1000
                Reloc(BIN.RCODE, param2)
1129
                Reloc(BIN.RCODE, param2)
1001
            END
1130
            END
1002
 
1131
 
Line 1003... Line 1132...
1003
        |IL.opPUSHIP:
1132
        |IL.opPUSHIP:
1004
            reg1 := GetAnyReg();
1133
            reg1 := GetAnyReg();
Line 1023... Line 1152...
1023
            andrc(reg1, 1)
1152
            andrc(reg1, 1)
Line 1024... Line 1153...
1024
 
1153
 
1025
        |IL.opSBOOL:
1154
        |IL.opSBOOL:
1026
            BinOp(reg2, reg1);
1155
            BinOp(reg2, reg1);
1027
            test(reg2);
1156
            test(reg2);
1028
            OutByte3(0FH, 95H, reg1); // setne byte[reg1]
1157
            OutByte3(0FH, 95H, reg1); (* setne byte[reg1] *)
1029
            drop;
1158
            drop;
Line 1030... Line 1159...
1030
            drop
1159
            drop
1031
 
1160
 
1032
        |IL.opSBOOLC:
1161
        |IL.opSBOOLC:
1033
            UnOp(reg1);
1162
            UnOp(reg1);
Line 1034... Line -...
1034
            OutByte3(0C6H, reg1, ORD(param2 # 0)); // mov byte[reg1], 0/1
-
 
1035
            drop
-
 
1036
 
-
 
1037
        |IL.opODD:
-
 
1038
            UnOp(reg1);
1163
            OutByte3(0C6H, reg1, ORD(param2 # 0)); (* mov byte[reg1], 0/1 *)
1039
            andrc(reg1, 1)
1164
            drop
Line 1040... Line 1165...
1040
 
1165
 
1041
        |IL.opEQ..IL.opGE,
1166
        |IL.opEQ..IL.opGE,
1042
         IL.opEQC..IL.opGEC:
1167
         IL.opEQC..IL.opGEC:
1043
 
1168
 
1044
            IF (IL.opEQ <= opcode) & (opcode <= IL.opGE) THEN
1169
            IF (IL.opEQ <= opcode) & (opcode <= IL.opGE) THEN
1045
                BinOp(reg1, reg2);
1170
                BinOp(reg1, reg2);
1046
                cmprr(reg1, reg2);
-
 
1047
                drop
-
 
1048
            ELSE
-
 
1049
                UnOp(reg1);
1171
                cmprr(reg1, reg2);
1050
                IF param2 = 0 THEN
-
 
1051
                    test(reg1)
1172
                drop
Line 1052... Line 1173...
1052
                ELSE
1173
            ELSE
1053
                    cmprc(reg1, param2)
1174
                UnOp(reg1);
-
 
1175
                cmprc(reg1, param2)
Line 1054... Line 1176...
1054
                END
1176
            END;
1055
            END;
-
 
1056
 
1177
 
1057
            drop;
1178
            drop;
1058
            cc := cond(opcode);
-
 
1059
 
1179
            cc := cond(opcode);
1060
            IF cmd.next(COMMAND).opcode = IL.opJE THEN
-
 
1061
                label := cmd.next(COMMAND).param1;
1180
            next := cmd.next(COMMAND);
1062
                jcc(cc, label);
1181
 
1063
                cmd := cmd.next(COMMAND)
-
 
1064
 
1182
            IF next.opcode = IL.opJE THEN
1065
            ELSIF cmd.next(COMMAND).opcode = IL.opJNE THEN
1183
                jcc(cc, next.param1);
1066
                label := cmd.next(COMMAND).param1;
1184
                cmd := next
1067
                jcc(inv0(cc), label);
1185
            ELSIF next.opcode = IL.opJNE THEN
1068
                cmd := cmd.next(COMMAND)
1186
                jcc(inv0(cc), next.param1);
Line 1076... Line 1194...
1076
        |IL.opEQB, IL.opNEB:
1194
        |IL.opEQB, IL.opNEB:
1077
            BinOp(reg1, reg2);
1195
            BinOp(reg1, reg2);
1078
            drop;
1196
            drop;
Line 1079... Line 1197...
1079
 
1197
 
1080
            test(reg1);
1198
            test(reg1);
1081
            OutByte2(74H, 5);  // je @f
1199
            OutByte2(74H, 5);  (* je @f *)
1082
            movrc(reg1, 1);    // mov reg1, 1
1200
            movrc(reg1, 1);    (* mov reg1, 1
1083
                               // @@:
1201
                                  @@: *)
1084
            test(reg2);
1202
            test(reg2);
1085
            OutByte2(74H, 5);  // je @f
1203
            OutByte2(74H, 5);  (* je @f *)
1086
            movrc(reg2, 1);    // mov reg2, 1
1204
            movrc(reg2, 1);    (* mov reg2, 1
Line 1087... Line 1205...
1087
                               // @@:
1205
                                  @@: *)
1088
 
1206
 
1089
            cmprr(reg1, reg2);
1207
            cmprr(reg1, reg2);
1090
            IF opcode = IL.opEQB THEN
1208
            IF opcode = IL.opEQB THEN
Line 1114... Line 1232...
1114
        |IL.opJZ:
1232
        |IL.opJZ:
1115
            UnOp(reg1);
1233
            UnOp(reg1);
1116
            test(reg1);
1234
            test(reg1);
1117
            jcc(je, param1)
1235
            jcc(je, param1)
Line -... Line 1236...
-
 
1236
 
-
 
1237
        |IL.opJG:
-
 
1238
            UnOp(reg1);
-
 
1239
            test(reg1);
-
 
1240
            jcc(jg, param1)
1118
 
1241
 
1119
        |IL.opJE:
1242
        |IL.opJE:
1120
            UnOp(reg1);
1243
            UnOp(reg1);
1121
            test(reg1);
1244
            test(reg1);
1122
            jcc(jne, param1);
1245
            jcc(jne, param1);
Line 1169... Line 1292...
1169
                movrc(reg1, param1)
1292
                movrc(reg1, param1)
1170
            END;
1293
            END;
1171
            drop;
1294
            drop;
1172
            drop;
1295
            drop;
Line 1173... Line 1296...
1173
 
1296
 
1174
            CASE param2 OF
-
 
1175
            |1:
1297
            IF param2 # 8 THEN
1176
                OutByte2(8AH, reg1 * 9);       // mov reg1, byte[reg1]
1298
                _movrm(reg1, reg1, 0, param2 * 8, FALSE);
1177
                OutByte2(88H, reg1 * 8 + reg2) // mov byte[reg2], reg1
-
 
1178
 
-
 
1179
            |2:
-
 
1180
                OutByte3(66H, 8BH, reg1 * 9);       // mov reg1, word[reg1]
-
 
1181
                OutByte3(66H, 89H, reg1 * 8 + reg2) // mov word[reg2], reg1
-
 
1182
 
-
 
1183
            |4:
-
 
1184
                OutByte2(8BH, reg1 * 9);        // mov reg1, dword[reg1]
-
 
1185
                OutByte2(89H, reg1 * 8 + reg2)  // mov dword[reg2], reg1
-
 
1186
 
1299
                _movrm(reg1, reg2, 0, param2 * 8, TRUE)
1187
            |8:
1300
            ELSE
1188
                PushAll(0);
1301
                PushAll(0);
1189
                push(reg1);
1302
                push(reg1);
1190
                push(reg2);
1303
                push(reg2);
1191
                pushc(8);
1304
                pushc(8);
1192
                CallRTL(pic, IL._move)
-
 
1193
 
1305
                CallRTL(pic, IL._move)
Line 1194... Line 1306...
1194
            END
1306
            END
1195
 
1307
 
1196
        |IL.opSAVES:
1308
        |IL.opSAVES:
Line 1201... Line 1313...
1201
                reg1 := GetAnyReg();
1313
                reg1 := GetAnyReg();
1202
                Pic(reg1, BIN.PICDATA, stroffs + param2);
1314
                Pic(reg1, BIN.PICDATA, stroffs + param2);
1203
                push(reg1);
1315
                push(reg1);
1204
                drop
1316
                drop
1205
            ELSE
1317
            ELSE
1206
                OutByte(068H);  // push _data + stroffs + param2
1318
                OutByte(068H);  (* push _data + stroffs + param2 *)
1207
                Reloc(BIN.RDATA, stroffs + param2);
1319
                Reloc(BIN.RDATA, stroffs + param2);
1208
            END;
1320
            END;
Line 1209... Line 1321...
1209
 
1321
 
1210
            push(reg2);
1322
            push(reg2);
Line 1224... Line 1336...
1224
 
1336
 
1225
        |IL.opCHKIDX2:
1337
        |IL.opCHKIDX2:
1226
            BinOp(reg1, reg2);
1338
            BinOp(reg1, reg2);
1227
            IF param2 # -1 THEN
1339
            IF param2 # -1 THEN
1228
                cmprr(reg2, reg1);
-
 
1229
                mov(reg1, reg2);
-
 
1230
                drop;
1340
                cmprr(reg2, reg1);
1231
                jcc(jb, param1)
1341
                jcc(jb, param1)
1232
            ELSE
1342
            END;
1233
                INCL(R.regs, reg1);
1343
            INCL(R.regs, reg1);
1234
                DEC(R.top);
1344
            DEC(R.top);
1235
                R.stk[R.top] := reg2
-
 
Line 1236... Line 1345...
1236
            END
1345
            R.stk[R.top] := reg2
1237
 
1346
 
1238
        |IL.opLEN:
1347
        |IL.opLEN:
1239
            n := param2;
1348
            n := param2;
Line 1250... Line 1359...
1250
            INCL(R.regs, reg1);
1359
            INCL(R.regs, reg1);
1251
            ASSERT(REG.GetReg(R, reg1))
1360
            ASSERT(REG.GetReg(R, reg1))
Line 1252... Line 1361...
1252
 
1361
 
1253
        |IL.opINCC:
1362
        |IL.opINCC:
-
 
1363
            UnOp(reg1);
-
 
1364
            IF param2 = 1 THEN
-
 
1365
                OutByte2(0FFH, reg1) (* inc dword[reg1] *)
-
 
1366
            ELSIF param2 = -1 THEN
-
 
1367
                OutByte2(0FFH, reg1 + 8) (* dec dword[reg1] *)
1254
            UnOp(reg1);
1368
            ELSE
-
 
1369
                OutByte2(81H + short(param2), reg1); OutIntByte(param2) (* add dword[reg1], param2 *)
1255
            OutByte2(81H + short(param2), reg1); OutIntByte(param2); // add dword[reg1], param2
1370
            END;
Line 1256... Line 1371...
1256
            drop
1371
            drop
1257
 
1372
 
1258
        |IL.opINC, IL.opDEC:
1373
        |IL.opINC, IL.opDEC:
1259
            BinOp(reg1, reg2);
1374
            BinOp(reg1, reg2);
1260
            OutByte2(01H + 28H * ORD(opcode = IL.opDEC), reg1 * 8 + reg2); // add/sub dword[reg2], reg1
1375
            OutByte2(01H + 28H * ORD(opcode = IL.opDEC), reg1 * 8 + reg2); (* add/sub dword[reg2], reg1 *)
Line 1261... Line 1376...
1261
            drop;
1376
            drop;
1262
            drop
1377
            drop
1263
 
1378
 
1264
        |IL.opINCCB, IL.opDECCB:
1379
        |IL.opINCCB, IL.opDECCB:
Line 1265... Line 1380...
1265
            UnOp(reg1);
1380
            UnOp(reg1);
1266
            OutByte3(80H, 28H * ORD(opcode = IL.opDECCB) + reg1, Byte(param2)); // add/sub byte[reg1], n
1381
            OutByte3(80H, 28H * ORD(opcode = IL.opDECCB) + reg1, param2 MOD 256); (* add/sub byte[reg1], n *)
1267
            drop
1382
            drop
1268
 
1383
 
1269
        |IL.opINCB, IL.opDECB:
1384
        |IL.opINCB, IL.opDECB:
Line 1270... Line 1385...
1270
            BinOp(reg1, reg2);
1385
            BinOp(reg1, reg2);
1271
            OutByte2(28H * ORD(opcode = IL.opDECB), reg1 * 8 + reg2); // add/sub byte[reg2], reg1
1386
            OutByte2(28H * ORD(opcode = IL.opDECB), reg1 * 8 + reg2); (* add/sub byte[reg2], reg1 *)
1272
            drop;
1387
            drop;
1273
            drop
1388
            drop
Line 1274... Line 1389...
1274
 
1389
 
1275
        |IL.opMULS:
1390
        |IL.opMULS:
1276
            BinOp(reg1, reg2);
1391
            BinOp(reg1, reg2);
Line 1286... Line 1401...
1286
            xor(reg1, reg2);
1401
            xor(reg1, reg2);
1287
            drop
1402
            drop
Line 1288... Line 1403...
1288
 
1403
 
1289
        |IL.opDIVSC:
1404
        |IL.opDIVSC:
1290
            UnOp(reg1);
1405
            UnOp(reg1);
1291
            OutByte2(81H + short(param2), 0F0H + reg1);  // xor reg1, n
1406
            OutByte2(81H + short(param2), 0F0H + reg1);  (* xor reg1, n *)
Line 1292... Line 1407...
1292
            OutIntByte(param2)
1407
            OutIntByte(param2)
1293
 
1408
 
1294
        |IL.opADDS:
1409
        |IL.opADDS:
1295
            BinOp(reg1, reg2);
1410
            BinOp(reg1, reg2);
Line 1296... Line 1411...
1296
            OutByte2(9H, 0C0H + reg2 * 8 + reg1); // or reg1, reg2
1411
            OutByte2(9H, 0C0H + reg2 * 8 + reg1); (* or reg1, reg2 *)
1297
            drop
1412
            drop
1298
 
1413
 
1299
        |IL.opSUBS:
1414
        |IL.opSUBS:
1300
            BinOp(reg1, reg2);
1415
            BinOp(reg1, reg2);
Line 1301... Line 1416...
1301
            not(reg2);
1416
            not(reg2);
1302
            OutByte2(21H, 0C0H + reg2 * 8 + reg1); // and reg1, reg2
1417
            OutByte2(21H, 0C0H + reg2 * 8 + reg1); (* and reg1, reg2 *)
1303
            drop
1418
            drop
Line 1346... Line 1461...
1346
            END;
1461
            END;
Line 1347... Line 1462...
1347
 
1462
 
1348
            BinOp(reg1, reg2);
1463
            BinOp(reg1, reg2);
1349
            ASSERT(reg2 = ecx);
1464
            ASSERT(reg2 = ecx);
1350
            OutByte(0D3H);
1465
            OutByte(0D3H);
1351
            shift(opcode, reg1); // shift reg1, cl
1466
            shift(opcode, reg1); (* shift reg1, cl *)
Line 1352... Line 1467...
1352
            drop
1467
            drop
1353
 
1468
 
1354
        |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1:
1469
        |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1:
Line 1362... Line 1477...
1362
            reg1 := GetAnyReg();
1477
            reg1 := GetAnyReg();
1363
            movrc(reg1, param2);
1478
            movrc(reg1, param2);
1364
            BinOp(reg1, reg2);
1479
            BinOp(reg1, reg2);
1365
            ASSERT(reg1 = ecx);
1480
            ASSERT(reg1 = ecx);
1366
            OutByte(0D3H);
1481
            OutByte(0D3H);
1367
            shift(opcode, reg2); // shift reg2, cl
1482
            shift(opcode, reg2); (* shift reg2, cl *)
1368
            drop;
1483
            drop;
1369
            drop;
1484
            drop;
1370
            ASSERT(REG.GetReg(R, reg2))
1485
            ASSERT(REG.GetReg(R, reg2))
Line 1371... Line 1486...
1371
 
1486
 
Line 1375... Line 1490...
1375
            IF n # 1 THEN
1490
            IF n # 1 THEN
1376
                OutByte(0C1H)
1491
                OutByte(0C1H)
1377
            ELSE
1492
            ELSE
1378
                OutByte(0D1H)
1493
                OutByte(0D1H)
1379
            END;
1494
            END;
1380
            shift(opcode, reg1); // shift reg1, n
1495
            shift(opcode, reg1); (* shift reg1, n *)
1381
            IF n # 1 THEN
1496
            IF n # 1 THEN
1382
                OutByte(n)
1497
                OutByte(n)
1383
            END
1498
            END
Line 1384... Line 1499...
1384
 
1499
 
1385
        |IL.opMIN:
-
 
1386
            BinOp(reg1, reg2);
-
 
1387
            cmprr(reg1, reg2);
-
 
1388
            OutByte2(07EH, 002H);  // jle @f
-
 
1389
            mov(reg1, reg2);       // mov reg1, reg2
-
 
1390
                                   // @@:
-
 
1391
            drop
-
 
1392
 
-
 
1393
        |IL.opMAX:
1500
        |IL.opMAX, IL.opMIN:
1394
            BinOp(reg1, reg2);
1501
            BinOp(reg1, reg2);
1395
            cmprr(reg1, reg2);
1502
            cmprr(reg1, reg2);
1396
            OutByte2(07DH, 002H);  // jge @f
1503
            OutByte2(07DH + ORD(opcode = IL.opMIN), 2);  (* jge/jle L *)
1397
            mov(reg1, reg2);       // mov reg1, reg2
1504
            mov(reg1, reg2);
1398
                                   // @@:
1505
            (* L: *)
Line 1399... Line 1506...
1399
            drop
1506
            drop
1400
 
1507
 
1401
        |IL.opMINC:
1508
        |IL.opMAXC, IL.opMINC:
1402
            UnOp(reg1);
1509
            UnOp(reg1);
1403
            cmprc(reg1, param2);
1510
            cmprc(reg1, param2);
1404
            OutByte2(07EH, 005H);    // jle @f
1511
            OutByte2(07DH + ORD(opcode = IL.opMINC), 5);  (* jge/jle L *)
Line 1405... Line 1512...
1405
            movrc(reg1, param2)      // mov reg1, param2
1512
            movrc(reg1, param2)
1406
                                     // @@:
1513
            (* L: *)
1407
 
1514
 
1408
        |IL.opMAXC:
-
 
1409
            UnOp(reg1);
1515
        |IL.opIN, IL.opINR:
1410
            cmprc(reg1, param2);
-
 
1411
            OutByte2(07DH, 005H);    // jge @f
-
 
1412
            movrc(reg1, param2)      // mov reg1, param2
1516
            IF opcode = IL.opINR THEN
1413
                                     // @@:
1517
                reg2 := GetAnyReg();
1414
 
1518
                movrc(reg2, param2)
1415
        |IL.opIN:
1519
            END;
1416
            label := NewLabel();
1520
            label := NewLabel();
1417
            BinOp(reg1, reg2);
-
 
1418
            cmprc(reg1, 32);
-
 
1419
            OutByte2(72H, 4); // jb L
-
 
1420
            xor(reg1, reg1);
-
 
1421
            jmp(label);
-
 
1422
            //L:
-
 
1423
            OutByte3(0FH, 0A3H, 0C0H + reg2 + 8 * reg1); // bt reg2, reg1
-
 
1424
            setcc(setc, reg1);
-
 
1425
            andrc(reg1, 1);
-
 
1426
            SetLabel(label);
-
 
1427
            drop
-
 
1428
 
-
 
1429
        |IL.opINR:
-
 
1430
            label := NewLabel();
-
 
1431
            UnOp(reg1);
-
 
1432
            reg2 := GetAnyReg();
1521
            BinOp(reg1, reg2);
1433
            cmprc(reg1, 32);
1522
            cmprc(reg1, 32);
1434
            OutByte2(72H, 4); // jb L
1523
            OutByte2(72H, 4); (* jb L *)
1435
            xor(reg1, reg1);
-
 
1436
            jmp(label);
1524
            xor(reg1, reg1);
1437
            //L:
1525
            jmp(label);
1438
            movrc(reg2, param2);
1526
            (* L: *)
1439
            OutByte3(0FH, 0A3H, 0C0H + reg2 + 8 * reg1); // bt reg2, reg1
1527
            OutByte3(0FH, 0A3H, 0C0H + reg2 + 8 * reg1); (* bt reg2, reg1 *)
1440
            setcc(setc, reg1);
1528
            setcc(setc, reg1);
Line 1441... Line 1529...
1441
            andrc(reg1, 1);
1529
            andrc(reg1, 1);
1442
            SetLabel(label);
1530
            SetLabel(label);
1443
            drop
1531
            drop
1444
 
1532
 
1445
        |IL.opINL:
1533
        |IL.opINL:
Line 1446... Line 1534...
1446
            UnOp(reg1);
1534
            UnOp(reg1);
1447
            OutByte3(0FH, 0BAH, 0E0H + reg1); OutByte(param2); // bt reg1, param2
1535
            OutByte3(0FH, 0BAH, 0E0H + reg1); OutByte(param2); (* bt reg1, param2 *)
Line 1474... Line 1562...
1474
            GetRegA
1562
            GetRegA
Line 1475... Line 1563...
1475
 
1563
 
1476
        |IL.opINCL, IL.opEXCL:
1564
        |IL.opINCL, IL.opEXCL:
1477
            BinOp(reg1, reg2);
1565
            BinOp(reg1, reg2);
1478
            cmprc(reg1, 32);
1566
            cmprc(reg1, 32);
1479
            OutByte2(73H, 03H); // jnb L
1567
            OutByte2(73H, 03H); (* jnb L *)
1480
            OutByte(0FH);
1568
            OutByte(0FH);
1481
            IF opcode = IL.opINCL THEN
1569
            IF opcode = IL.opINCL THEN
1482
                OutByte(0ABH) // bts dword[reg2], reg1
1570
                OutByte(0ABH) (* bts dword[reg2], reg1 *)
1483
            ELSE
1571
            ELSE
1484
                OutByte(0B3H) // btr dword[reg2], reg1
1572
                OutByte(0B3H) (* btr dword[reg2], reg1 *)
1485
            END;
1573
            END;
1486
            OutByte(reg2 + 8 * reg1);
1574
            OutByte(reg2 + 8 * reg1);
1487
            //L:
1575
            (* L: *)
1488
            drop;
1576
            drop;
Line 1489... Line 1577...
1489
            drop
1577
            drop
1490
 
1578
 
1491
        |IL.opINCLC:
1579
        |IL.opINCLC:
1492
            UnOp(reg1);
1580
            UnOp(reg1);
Line 1493... Line 1581...
1493
            OutByte3(0FH, 0BAH, 28H + reg1); OutByte(param2); //bts dword[reg1],param2
1581
            OutByte3(0FH, 0BAH, 28H + reg1); OutByte(param2); (* bts dword[reg1], param2 *)
1494
            drop
1582
            drop
1495
 
1583
 
1496
        |IL.opEXCLC:
1584
        |IL.opEXCLC:
Line 1497... Line 1585...
1497
            UnOp(reg1);
1585
            UnOp(reg1);
1498
            OutByte3(0FH, 0BAH, 30H + reg1); OutByte(param2); //btr dword[reg1],param2
1586
            OutByte3(0FH, 0BAH, 30H + reg1); OutByte(param2); (* btr dword[reg1], param2 *)
1499
            drop
1587
            drop
1500
 
1588
 
Line 1501... Line 1589...
1501
        |IL.opDIV:
1589
        |IL.opDIV:
1502
            PushAll(2);
-
 
1503
            CallRTL(pic, IL._divmod);
-
 
1504
            GetRegA
-
 
1505
 
-
 
1506
        |IL.opDIVR:
1590
            PushAll(2);
1507
            a := param2;
-
 
1508
            IF a > 1 THEN
-
 
1509
                n := UTILS.Log2(a)
-
 
1510
            ELSIF a < -1 THEN
-
 
1511
                n := UTILS.Log2(-a)
-
 
1512
            ELSE
-
 
1513
                n := -1
-
 
1514
            END;
-
 
1515
 
-
 
1516
            IF a = 1 THEN
-
 
1517
 
1591
            CallRTL(pic, IL._divmod);
1518
            ELSIF a = -1 THEN
1592
            GetRegA
1519
                UnOp(reg1);
-
 
1520
                neg(reg1)
-
 
1521
            ELSE
-
 
1522
                IF n > 0 THEN
-
 
1523
                    UnOp(reg1);
1593
 
1524
 
1594
        |IL.opDIVR:
1525
                    IF a < 0 THEN
1595
            n := UTILS.Log2(param2);
1526
                        reg2 := GetAnyReg();
1596
            IF n > 0 THEN
1527
                        mov(reg2, reg1);
-
 
1528
                        IF n # 1 THEN
-
 
1529
                            OutByte3(0C1H, 0F8H + reg1, n)     // sar reg1, n
-
 
1530
                        ELSE
-
 
1531
                            OutByte2(0D1H, 0F8H + reg1)        // sar reg1, 1
-
 
1532
                        END;
-
 
1533
                        OutByte2(29H, 0C0H + reg2 * 8 + reg1); // sub reg1, reg2
-
 
1534
                        drop
-
 
1535
                    ELSE
-
 
1536
                        IF n # 1 THEN
1597
                UnOp(reg1);
1537
                            OutByte3(0C1H, 0F8H + reg1, n)     // sar reg1, n
-
 
1538
                        ELSE
1598
                IF n # 1 THEN
1539
                            OutByte2(0D1H, 0F8H + reg1)        // sar reg1, 1
1599
                    OutByte3(0C1H, 0F8H + reg1, n) (* sar reg1, n *)
1540
                        END
1600
                ELSE
1541
                    END
1601
                    OutByte2(0D1H, 0F8H + reg1)    (* sar reg1, 1 *)
1542
 
1602
                END
1543
                ELSE
1603
            ELSIF n < 0 THEN
1544
                    PushAll(1);
-
 
Line 1545... Line 1604...
1545
                    pushc(param2);
1604
                PushAll(1);
1546
                    CallRTL(pic, IL._divmod);
1605
                pushc(param2);
1547
                    GetRegA
1606
                CallRTL(pic, IL._divmod);
1548
                END
1607
                GetRegA
Line 1562... Line 1621...
1562
            CallRTL(pic, IL._divmod);
1621
            CallRTL(pic, IL._divmod);
1563
            mov(eax, edx);
1622
            mov(eax, edx);
1564
            GetRegA
1623
            GetRegA
Line 1565... Line 1624...
1565
 
1624
 
1566
        |IL.opMODR:
-
 
1567
            a := param2;
-
 
1568
            IF a > 1 THEN
-
 
1569
                n := UTILS.Log2(a)
-
 
1570
            ELSIF a < -1 THEN
1625
        |IL.opMODR:
1571
                n := UTILS.Log2(-a)
-
 
1572
            ELSE
-
 
1573
                n := -1
-
 
1574
            END;
-
 
1575
 
-
 
1576
            IF ABS(a) = 1 THEN
-
 
1577
                UnOp(reg1);
-
 
1578
                xor(reg1, reg1)
-
 
1579
            ELSE
1626
            n := UTILS.Log2(param2);
1580
                IF n > 0 THEN
1627
            IF n > 0 THEN
1581
                    UnOp(reg1);
1628
                UnOp(reg1);
1582
                    andrc(reg1, ABS(a) - 1);
-
 
1583
 
1629
                andrc(reg1, param2 - 1);
1584
                    IF a < 0 THEN
-
 
1585
                        test(reg1);
-
 
1586
                        OutByte(74H);      // je @f
-
 
1587
                        IF isByte(a) THEN
-
 
1588
                            OutByte(3)
-
 
1589
                        ELSE
-
 
1590
                            OutByte(6)
-
 
1591
                        END;
-
 
1592
                        addrc(reg1, a)
-
 
1593
                                           // @@:
-
 
1594
                    END
-
 
1595
 
-
 
1596
                ELSE
1630
            ELSIF n < 0 THEN
1597
                    PushAll(1);
1631
                PushAll(1);
1598
                    pushc(param2);
1632
                pushc(param2);
1599
                    CallRTL(pic, IL._divmod);
1633
                CallRTL(pic, IL._divmod);
1600
                    mov(eax, edx);
1634
                mov(eax, edx);
1601
                    GetRegA
1635
                GetRegA
-
 
1636
            ELSE
-
 
1637
                UnOp(reg1);
1602
                END
1638
                xor(reg1, reg1)
Line 1603... Line 1639...
1603
            END
1639
            END
1604
 
1640
 
1605
        |IL.opMODL:
1641
        |IL.opMODL:
Line 1616... Line 1652...
1616
            CallRTL(pic, IL._error)
1652
            CallRTL(pic, IL._error)
Line 1617... Line 1653...
1617
 
1653
 
1618
        |IL.opABS:
1654
        |IL.opABS:
1619
            UnOp(reg1);
1655
            UnOp(reg1);
1620
            test(reg1);
1656
            test(reg1);
1621
            OutByte2(07DH, 002H); // jge @f
1657
            OutByte2(07DH, 002H); (* jge L *)
1622
            neg(reg1)             // neg reg1
1658
            neg(reg1)             (* neg reg1
Line 1623... Line 1659...
1623
                                  // @@:
1659
                                     L: *)
1624
 
1660
 
1625
        |IL.opCOPY:
1661
        |IL.opCOPY:
1626
            PushAll(2);
1662
            PushAll(2);
Line 1680... Line 1716...
1680
                    reg2 := GetAnyReg();
1716
                    reg2 := GetAnyReg();
1681
                    Pic(reg2, BIN.PICCODE, param1);
1717
                    Pic(reg2, BIN.PICCODE, param1);
1682
                    cmprr(reg1, reg2);
1718
                    cmprr(reg1, reg2);
1683
                    drop
1719
                    drop
1684
                ELSE
1720
                ELSE
1685
                    OutByte2(081H, 0F8H + reg1);  // cmp reg1, L
1721
                    OutByte2(081H, 0F8H + reg1);  (* cmp reg1, L *)
1686
                    Reloc(BIN.RCODE, param1)
1722
                    Reloc(BIN.RCODE, param1)
1687
                END
1723
                END
Line 1688... Line 1724...
1688
 
1724
 
1689
            |IL.opEQIP, IL.opNEIP:
1725
            |IL.opEQIP, IL.opNEIP:
1690
                IF pic THEN
1726
                IF pic THEN
1691
                    reg2 := GetAnyReg();
1727
                    reg2 := GetAnyReg();
1692
                    Pic(reg2, BIN.PICIMP, param1);
1728
                    Pic(reg2, BIN.PICIMP, param1);
1693
                    OutByte2(03BH, reg1 * 8 + reg2);  //cmp reg1, dword [reg2]
1729
                    OutByte2(03BH, reg1 * 8 + reg2);  (* cmp reg1, dword [reg2] *)
1694
                    drop
1730
                    drop
1695
                ELSE
1731
                ELSE
1696
                    OutByte2(3BH, 05H + reg1 * 8);    // cmp reg1, dword[L]
1732
                    OutByte2(3BH, 05H + reg1 * 8);    (* cmp reg1, dword[L] *)
1697
                    Reloc(BIN.RIMP, param1)
1733
                    Reloc(BIN.RIMP, param1)
Line 1698... Line 1734...
1698
                END
1734
                END
1699
 
1735
 
Line 1708... Line 1744...
1708
 
1744
 
Line 1709... Line 1745...
1709
            andrc(reg1, 1)
1745
            andrc(reg1, 1)
1710
 
1746
 
1711
        |IL.opPUSHT:
1747
        |IL.opPUSHT:
1712
            UnOp(reg1);
-
 
Line 1713... Line 1748...
1713
            reg2 := GetAnyReg();
1748
            UnOp(reg1);
1714
            OutByte3(8BH, 40H + reg2 * 8 + reg1, 0FCH)  // mov reg2, dword[reg1 - 4]
1749
            movrm(GetAnyReg(), reg1, -4)
1715
 
1750
 
1716
        |IL.opISREC:
1751
        |IL.opISREC:
Line 1740... Line 1775...
1740
            GetRegA
1775
            GetRegA
Line 1741... Line 1776...
1741
 
1776
 
1742
        |IL.opTYPEGD:
1777
        |IL.opTYPEGD:
1743
            UnOp(reg1);
1778
            UnOp(reg1);
1744
            PushAll(0);
1779
            PushAll(0);
1745
            OutByte3(0FFH, 070H + reg1, 0FCH);  // push dword[reg1 - 4]
1780
            pushm(reg1, -4);
1746
            pushc(param2 * tcount);
1781
            pushc(param2 * tcount);
1747
            CallRTL(pic, IL._guardrec);
1782
            CallRTL(pic, IL._guardrec);
Line 1748... Line 1783...
1748
            GetRegA
1783
            GetRegA
Line 1757... Line 1792...
1757
            jcc(jne, param1)
1792
            jcc(jne, param1)
Line 1758... Line 1793...
1758
 
1793
 
1759
        |IL.opPACK:
1794
        |IL.opPACK:
1760
            BinOp(reg1, reg2);
1795
            BinOp(reg1, reg2);
1761
            push(reg2);
1796
            push(reg2);
1762
            OutByte3(0DBH, 004H, 024H);   // fild dword[esp]
1797
            OutByte3(0DBH, 004H, 024H);   (* fild dword[esp]  *)
1763
            OutByte2(0DDH, reg1);         // fld qword[reg1]
1798
            OutByte2(0DDH, reg1);         (* fld qword[reg1]  *)
1764
            OutByte2(0D9H, 0FDH);         // fscale
1799
            OutByte2(0D9H, 0FDH);         (* fscale           *)
1765
            OutByte2(0DDH, 018H + reg1);  // fstp qword[reg1]
1800
            OutByte2(0DDH, 018H + reg1);  (* fstp qword[reg1] *)
1766
            OutByte3(0DBH, 01CH, 024H);   // fistp dword[esp]
1801
            OutByte3(0DBH, 01CH, 024H);   (* fistp dword[esp] *)
1767
            pop(reg2);
1802
            pop(reg2);
1768
            drop;
1803
            drop;
Line 1769... Line 1804...
1769
            drop
1804
            drop
1770
 
1805
 
1771
        |IL.opPACKC:
1806
        |IL.opPACKC:
1772
            UnOp(reg1);
1807
            UnOp(reg1);
1773
            pushc(param2);
1808
            pushc(param2);
1774
            OutByte3(0DBH, 004H, 024H);   // fild dword[esp]
1809
            OutByte3(0DBH, 004H, 024H);   (* fild dword[esp]  *)
1775
            OutByte2(0DDH, reg1);         // fld qword[reg1]
1810
            OutByte2(0DDH, reg1);         (* fld qword[reg1]  *)
1776
            OutByte2(0D9H, 0FDH);         // fscale
1811
            OutByte2(0D9H, 0FDH);         (* fscale           *)
1777
            OutByte2(0DDH, 018H + reg1);  // fstp qword[reg1]
1812
            OutByte2(0DDH, 018H + reg1);  (* fstp qword[reg1] *)
1778
            OutByte3(0DBH, 01CH, 024H);   // fistp dword[esp]
1813
            OutByte3(0DBH, 01CH, 024H);   (* fistp dword[esp] *)
Line 1779... Line 1814...
1779
            pop(reg1);
1814
            pop(reg1);
1780
            drop
1815
            drop
1781
 
1816
 
1782
        |IL.opUNPK:
1817
        |IL.opUNPK:
1783
            BinOp(reg1, reg2);
1818
            BinOp(reg1, reg2);
1784
            OutByte2(0DDH, reg1);         // fld qword[reg1]
1819
            OutByte2(0DDH, reg1);         (* fld qword[reg1]   *)
1785
            OutByte2(0D9H, 0F4H);         // fxtract
1820
            OutByte2(0D9H, 0F4H);         (* fxtract           *)
1786
            OutByte2(0DDH, 018H + reg1);  // fstp qword[reg1]
1821
            OutByte2(0DDH, 018H + reg1);  (* fstp qword[reg1]  *)
Line 1787... Line 1822...
1787
            OutByte2(0DBH, 018H + reg2);  // fistp dword[reg2]
1822
            OutByte2(0DBH, 018H + reg2);  (* fistp dword[reg2] *)
1788
            drop;
1823
            drop;
1789
            drop
1824
            drop
Line 1790... Line 1825...
1790
 
1825
 
1791
        |IL.opPUSHF:
1826
        |IL.opPUSHF:
1792
            subrc(esp, 8);
1827
            subrc(esp, 8);
1793
            OutByte3(0DDH, 01CH, 024H)    // fstp qword[esp]
1828
            OutByte3(0DDH, 01CH, 024H)    (* fstp qword[esp] *)
Line 1794... Line 1829...
1794
 
1829
 
1795
        |IL.opLOADF:
1830
        |IL.opLOADF:
1796
            UnOp(reg1);
1831
            UnOp(reg1);
1797
            OutByte2(0DDH, reg1);         // fld qword[reg1]
1832
            OutByte2(0DDH, reg1);         (* fld qword[reg1] *)
1798
            drop
1833
            drop
1799
 
1834
 
1800
        |IL.opCONSTF:
1835
        |IL.opCONSTF:
1801
            float := cmd.float;
1836
            float := cmd.float;
1802
            IF float = 0.0 THEN
1837
            IF float = 0.0 THEN
1803
                OutByte2(0D9H, 0EEH)      // fldz
1838
                OutByte2(0D9H, 0EEH)      (* fldz *)
1804
            ELSIF float = 1.0 THEN
1839
            ELSIF float = 1.0 THEN
1805
                OutByte2(0D9H, 0E8H)      // fld1
1840
                OutByte2(0D9H, 0E8H)      (* fld1 *)
1806
            ELSIF float = -1.0 THEN
1841
            ELSIF float = -1.0 THEN
1807
                OutByte2(0D9H, 0E8H);     // fld1
1842
                OutByte2(0D9H, 0E8H);     (* fld1 *)
1808
                OutByte2(0D9H, 0E0H)      // fchs
1843
                OutByte2(0D9H, 0E0H)      (* fchs *)
1809
            ELSE
1844
            ELSE
Line 1810... Line 1845...
1810
                n := UTILS.splitf(float, a, b);
1845
                n := UTILS.splitf(float, a, b);
1811
                pushc(b);
1846
                pushc(b);
1812
                pushc(a);
1847
                pushc(a);
1813
                OutByte3(0DDH, 004H, 024H); // fld qword[esp]
1848
                OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *)
Line 1814... Line 1849...
1814
                addrc(esp, 8)
1849
                addrc(esp, 8)
1815
            END
1850
            END
Line 1816... Line 1851...
1816
 
1851
 
1817
        |IL.opSAVEF:
1852
        |IL.opSAVEF, IL.opSAVEFI:
Line 1818... Line 1853...
1818
            UnOp(reg1);
1853
            UnOp(reg1);
1819
            OutByte2(0DDH, 018H + reg1); // fstp qword[reg1]
1854
            OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *)
Line 1820... Line 1855...
1820
            drop
1855
            drop
1821
 
1856
 
Line 1822... Line 1857...
1822
        |IL.opADDF, IL.opADDFI:
1857
        |IL.opADDF, IL.opADDFI:
1823
            OutByte2(0DEH, 0C1H)  // faddp st1, st
1858
            OutByte2(0DEH, 0C1H)  (* faddp st1, st *)
Line 1824... Line 1859...
1824
 
1859
 
1825
        |IL.opSUBF:
1860
        |IL.opSUBF:
Line 1826... Line 1861...
1826
            OutByte2(0DEH, 0E9H)  // fsubp st1, st
1861
            OutByte2(0DEH, 0E9H)  (* fsubp st1, st *)
1827
 
1862
 
Line 1828... Line 1863...
1828
        |IL.opSUBFI:
1863
        |IL.opSUBFI:
1829
            OutByte2(0DEH, 0E1H)  // fsubrp st1, st
1864
            OutByte2(0DEH, 0E1H)  (* fsubrp st1, st *)
Line 1830... Line 1865...
1830
 
1865
 
1831
        |IL.opMULF:
1866
        |IL.opMULF:
1832
            OutByte2(0DEH, 0C9H)  // fmulp st1, st
1867
            OutByte2(0DEH, 0C9H)  (* fmulp st1, st *)
1833
 
1868
 
1834
        |IL.opDIVF:
1869
        |IL.opDIVF:
1835
            OutByte2(0DEH, 0F9H)  // fdivp st1, st
1870
            OutByte2(0DEH, 0F9H)  (* fdivp st1, st *)
Line 1836... Line 1871...
1836
 
1871
 
1837
        |IL.opDIVFI:
1872
        |IL.opDIVFI:
1838
            OutByte2(0DEH, 0F1H)  // fdivrp st1, st
1873
            OutByte2(0DEH, 0F1H)  (* fdivrp st1, st *)
1839
 
1874
 
1840
        |IL.opUMINF:
1875
        |IL.opUMINF:
1841
            OutByte2(0D9H, 0E0H)  // fchs
1876
            OutByte2(0D9H, 0E0H)  (* fchs *)
1842
 
1877
 
1843
        |IL.opFABS:
1878
        |IL.opFABS:
1844
            OutByte2(0D9H, 0E1H)  // fabs
1879
            OutByte2(0D9H, 0E1H)  (* fabs *)
1845
 
1880
 
1846
        |IL.opFLT:
1881
        |IL.opFLT:
1847
            UnOp(reg1);
1882
            UnOp(reg1);
Line 1848... Line 1883...
1848
            push(reg1);
1883
            push(reg1);
1849
            OutByte3(0DBH, 004H, 024H); // fild dword[esp]
1884
            OutByte3(0DBH, 004H, 024H); (* fild dword[esp] *)
1850
            pop(reg1);
-
 
1851
            drop
-
 
1852
 
-
 
1853
        |IL.opFLOOR:
-
 
1854
            subrc(esp, 8);
1885
            pop(reg1);
1855
            OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 004H);                   // fstcw word[esp+4]
1886
            drop
1856
            OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 006H);                   // fstcw word[esp+6]
1887
 
Line 1857... Line 1888...
1857
            OutByte2(066H, 081H); OutByte3(064H, 024H, 004H); OutWord(0F3FFH);  // and word[esp+4], 1111001111111111b
1888
        |IL.opFLOOR:
1858
            OutByte2(066H, 081H); OutByte3(04CH, 024H, 004H); OutWord(00400H);  // or  word[esp+4], 0000010000000000b
1889
            subrc(esp, 8);
1859
            OutByte2(0D9H, 06CH); OutByte2(024H, 004H);                         // fldcw word[esp+4]
-
 
1860
            OutByte2(0D9H, 0FCH);                                               // frndint
-
 
1861
            OutByte3(0DBH, 01CH, 024H);                                         // fistp dword[esp]
-
 
1862
            pop(GetAnyReg());
-
 
1863
            OutByte2(0D9H, 06CH); OutByte2(024H, 002H);                         // fldcw word[esp+2]
1890
            OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 004H);                   (* fstcw word[esp+4]                    *)
1864
            addrc(esp, 4)
1891
            OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 006H);                   (* fstcw word[esp+6]                    *)
1865
 
1892
            OutByte2(066H, 081H); OutByte3(064H, 024H, 004H); OutWord(0F3FFH);  (* and   word[esp+4], 1111001111111111b *)
Line 1866... Line 1893...
1866
        |IL.opEQF:
1893
            OutByte2(066H, 081H); OutByte3(04CH, 024H, 004H); OutWord(00400H);  (* or    word[esp+4], 0000010000000000b *)
1867
            GetRegA;
1894
            OutByte2(0D9H, 06CH); OutByte2(024H, 004H);                         (* fldcw word[esp+4]                    *)
1868
            OutByte2(0DAH, 0E9H);       // fucompp
-
 
1869
            OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
-
 
1870
            OutByte(09EH);              // sahf
-
 
1871
            movrc(eax, 0);
-
 
1872
            OutByte2(07AH, 003H);       // jp L
1895
            OutByte2(0D9H, 0FCH);                                               (* frndint                              *)
1873
            setcc(sete, al)
1896
            OutByte3(0DBH, 01CH, 024H);                                         (* fistp dword[esp]                     *)
1874
                                        // L:
1897
            pop(GetAnyReg());
1875
 
1898
            OutByte2(0D9H, 06CH); OutByte2(024H, 002H);                         (* fldcw word[esp+2]                    *)
1876
        |IL.opNEF:
1899
            addrc(esp, 4)
1877
            GetRegA;
1900
 
1878
            OutByte2(0DAH, 0E9H);       // fucompp
1901
        |IL.opEQF:
Line 1879... Line 1902...
1879
            OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
1902
            fcmp;
1880
            OutByte(09EH);              // sahf
1903
            OutByte2(07AH, 003H);       (* jp L *)
1881
            movrc(eax, 0);
-
 
1882
            OutByte2(07AH, 003H);       // jp L
-
 
1883
            setcc(setne, al)
-
 
1884
                                        // L:
-
 
1885
 
1904
            setcc(sete, al)
1886
        |IL.opLTF:
1905
                                        (* L: *)
1887
            GetRegA;
1906
 
1888
            OutByte2(0DAH, 0E9H);       // fucompp
1907
        |IL.opNEF:
1889
            OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
1908
            fcmp;
1890
            OutByte(09EH);              // sahf
1909
            OutByte2(07AH, 003H);       (* jp L *)
1891
            movrc(eax, 0);
1910
            setcc(setne, al)
Line 1892... Line 1911...
1892
            OutByte2(07AH, 00EH);       // jp L
1911
                                        (* L: *)
1893
            setcc(setc, al);
1912
 
1894
            setcc(sete, ah);
-
 
1895
            test(eax);
-
 
1896
            setcc(sete, al);
-
 
1897
            andrc(eax, 1)
-
 
1898
                                        // L:
1913
        |IL.opLTF:
1899
 
1914
            fcmp;
1900
        |IL.opGTF:
1915
            OutByte2(07AH, 00EH);       (* jp L *)
Line 1901... Line 1916...
1901
            GetRegA;
1916
            setcc(setc, al);
1902
            OutByte2(0DAH, 0E9H);       // fucompp
1917
            setcc(sete, ah);
1903
            OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
-
 
1904
            OutByte(09EH);              // sahf
-
 
1905
            movrc(eax, 0);
-
 
1906
            OutByte2(07AH, 00FH);       // jp L
-
 
1907
            setcc(setc, al);
1918
            test(eax);
1908
            setcc(sete, ah);
1919
            setcc(sete, al);
1909
            cmprc(eax, 1);
1920
            andrc(eax, 1)
1910
            setcc(sete, al);
1921
                                        (* L: *)
1911
            andrc(eax, 1)
1922
 
1912
                                        // L:
1923
        |IL.opGTF:
1913
 
1924
            fcmp;
1914
        |IL.opLEF:
1925
            OutByte2(07AH, 00FH);       (* jp L *)
Line 1915... Line 1926...
1915
            GetRegA;
1926
            setcc(setc, al);
1916
            OutByte2(0DAH, 0E9H);       // fucompp
1927
            setcc(sete, ah);
1917
            OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
1928
            cmprc(eax, 1);
1918
            OutByte(09EH);              // sahf
1929
            setcc(sete, al);
1919
            movrc(eax, 0);
1930
            andrc(eax, 1)
Line 1920... Line 1931...
1920
            OutByte2(07AH, 003H);       // jp L
1931
                                        (* L: *)
1921
            setcc(setnc, al)
1932
 
1922
                                        // L:
1933
        |IL.opLEF:
1923
 
1934
            fcmp;
1924
        |IL.opGEF:
1935
            OutByte2(07AH, 003H);       (* jp L *)
1925
            GetRegA;
1936
            setcc(setnc, al)
1926
            OutByte2(0DAH, 0E9H);       // fucompp
1937
                                        (* L: *)
1927
            OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
1938
 
1928
            OutByte(09EH);              // sahf
1939
        |IL.opGEF:
1929
            movrc(eax, 0);
1940
            fcmp;
1930
            OutByte2(07AH, 010H);       // jp L
1941
            OutByte2(07AH, 010H);       (* jp L *)
1931
            setcc(setc, al);
1942
            setcc(setc, al);
Line 1932... Line 1943...
1932
            setcc(sete, ah);
1943
            setcc(sete, ah);
1933
            OutByte2(000H, 0E0H);       // add al,ah
1944
            OutByte2(000H, 0E0H);       (* add al, ah *)
1934
            OutByte2(03CH, 001H);       // cmp al,1
1945
            OutByte2(03CH, 001H);       (* cmp al, 1 *)
1935
            setcc(sete, al);
1946
            setcc(sete, al);
1936
            andrc(eax, 1)
1947
            andrc(eax, 1)
1937
                                        // L:
1948
                                        (* L: *)
1938
 
1949
 
1939
        |IL.opINF:
1950
        |IL.opINF:
1940
            pushc(7FF00000H);
1951
            pushc(7FF00000H);
1941
            pushc(0);
1952
            pushc(0);
Line 1942... Line 1953...
1942
            OutByte3(0DDH, 004H, 024H);  // fld qword[esp]
1953
            OutByte3(0DDH, 004H, 024H);  (* fld qword[esp] *)
1943
            addrc(esp, 8)
1954
            addrc(esp, 8)
1944
 
-
 
1945
        |IL.opLADR_UNPK:
-
 
Line 1946... Line 1955...
1946
            n := param2 * 4;
1955
 
1947
            reg1 := GetAnyReg();
1956
        |IL.opLADR_UNPK:
Line 1948... Line 1957...
1948
            OutByte2(8DH, 45H + reg1 * 8 + long(n));  // lea reg1, dword[ebp + n]
1957
            n := param2 * 4;
1949
            OutIntByte(n);
1958
            reg1 := GetAnyReg();
1950
            BinOp(reg1, reg2);
1959
            OutByte2(8DH, 45H + reg1 * 8 + long(n));  (* lea reg1, dword[ebp + n] *)
1951
            OutByte2(0DDH, reg1);         // fld qword[reg1]
1960
            OutIntByte(n);
1952
            OutByte2(0D9H, 0F4H);         // fxtract
1961
            BinOp(reg1, reg2);
1953
            OutByte2(0DDH, 018H + reg1);  // fstp qword[reg1]
1962
            OutByte2(0DDH, reg1);         (* fld qword[reg1]   *)
1954
            OutByte2(0DBH, 018H + reg2);  // fistp dword[reg2]
1963
            OutByte2(0D9H, 0F4H);         (* fxtract           *)
1955
            drop;
1964
            OutByte2(0DDH, 018H + reg1);  (* fstp qword[reg1]  *)
1956
            drop
1965
            OutByte2(0DBH, 018H + reg2);  (* fistp dword[reg2] *)
1957
 
1966
            drop;
Line 1958... Line -...
1958
        |IL.opSADR_PARAM:
-
 
1959
            IF pic THEN
-
 
1960
                reg1 := GetAnyReg();
-
 
1961
                Pic(reg1, BIN.PICDATA, stroffs + param2);
-
 
1962
                push(reg1);
-
 
1963
                drop
1967
            drop
1964
            ELSE
1968
 
1965
                OutByte(068H);  // push _data + stroffs + param2
1969
        |IL.opSADR_PARAM:
1966
                Reloc(BIN.RDATA, stroffs + param2)
1970
            IF pic THEN
Line 1967... Line 1971...
1967
            END
1971
                reg1 := GetAnyReg();
1968
 
1972
                Pic(reg1, BIN.PICDATA, stroffs + param2);
1969
        |IL.opVADR_PARAM:
1973
                push(reg1);
1970
            n := param2 * 4;
1974
                drop
1971
            OutByte2(0FFH, 75H + long(n));  // push dword[ebp + n]
1975
            ELSE
1972
            OutIntByte(n)
1976
                OutByte(068H);  (* push _data + stroffs + param2 *)
1973
 
1977
                Reloc(BIN.RDATA, stroffs + param2)
1974
        |IL.opCONST_PARAM:
1978
            END
1975
            pushc(param2)
1979
 
1976
 
1980
        |IL.opVADR_PARAM, IL.opLLOAD32_PARAM:
1977
        |IL.opGLOAD32_PARAM:
1981
            pushm(ebp, param2 * 4)
1978
            IF pic THEN
1982
 
Line 1979... Line 1983...
1979
                reg1 := GetAnyReg();
1983
        |IL.opCONST_PARAM:
1980
                Pic(reg1, BIN.PICBSS, param2);
1984
            pushc(param2)
1981
                OutByte2(0FFH, 30H + reg1);   // push dword[reg1]
1985
 
1982
                drop
1986
        |IL.opGLOAD32_PARAM:
1983
            ELSE
1987
            IF pic THEN
Line 1984... Line 1988...
1984
                OutByte2(0FFH, 035H);  // push dword[_bss + param2]
1988
                reg1 := GetAnyReg();
1985
                Reloc(BIN.RBSS, param2)
-
 
1986
            END
1989
                Pic(reg1, BIN.PICBSS, param2);
1987
 
-
 
1988
        |IL.opLLOAD32_PARAM:
1990
                pushm(reg1, 0);
1989
            n := param2 * 4;
1991
                drop
Line 1990... Line 1992...
1990
            OutByte2(0FFH, 75H + long(n));  // push dword[ebp + n]
1992
            ELSE
1991
            OutIntByte(n)
1993
                OutByte2(0FFH, 035H);  (* push dword[_bss + param2] *)
1992
 
1994
                Reloc(BIN.RBSS, param2)
1993
        |IL.opLOAD32_PARAM:
1995
            END
1994
            UnOp(reg1);
1996
 
1995
            OutByte2(0FFH, 30H + reg1);  // push dword[reg1]
1997
        |IL.opLOAD32_PARAM:
1996
            drop
1998
            UnOp(reg1);
1997
 
1999
            pushm(reg1, 0);
1998
        |IL.opGADR_SAVEC:
2000
            drop
1999
            IF pic THEN
2001
 
Line 2000... Line 2002...
2000
                reg1 := GetAnyReg();
2002
        |IL.opGADR_SAVEC:
2001
                Pic(reg1, BIN.PICBSS, param1);
2003
            IF pic THEN
2002
                OutByte2(0C7H, reg1);  // mov dword[reg1], param2
2004
                reg1 := GetAnyReg();
2003
                OutInt(param2);
2005
                Pic(reg1, BIN.PICBSS, param1);
2004
                drop
2006
                OutByte2(0C7H, reg1);  (* mov dword[reg1], param2 *)
2005
            ELSE
2007
                OutInt(param2);
2006
                OutByte2(0C7H, 05H);  // mov dword[_bss + param1], param2
2008
                drop
2007
                Reloc(BIN.RBSS, param1);
2009
            ELSE
2008
                OutInt(param2)
2010
                OutByte2(0C7H, 05H);  (* mov dword[_bss + param1], param2 *)
2009
            END
2011
                Reloc(BIN.RBSS, param1);
Line 2010... Line 2012...
2010
 
2012
                OutInt(param2)
2011
        |IL.opLADR_SAVEC:
2013
            END
2012
            n := param1 * 4;
2014
 
2013
            OutByte2(0C7H, 45H + long(n));  // mov dword[ebp + n], param2
2015
        |IL.opLADR_SAVEC:
2014
            OutIntByte(n);
2016
            n := param1 * 4;
2015
            OutInt(param2)
2017
            OutByte2(0C7H, 45H + long(n));  (* mov dword[ebp + n], param2 *)
Line 2016... Line 2018...
2016
 
2018
            OutIntByte(n);
2017
        |IL.opLADR_SAVE:
2019
            OutInt(param2)
2018
            n := param2 * 4;
2020
 
2019
            UnOp(reg1);
2021
        |IL.opLADR_SAVE:
2020
            OutByte2(89H, 45H + reg1 * 8 + long(n));  // mov dword[ebp + n], reg1
2022
            UnOp(reg1);
2021
            OutIntByte(n);
2023
            movmr(ebp, param2 * 4, reg1);
Line 2022... Line 2024...
2022
            drop
2024
            drop
2023
 
2025
 
2024
        |IL.opLADR_INCC:
2026
        |IL.opLADR_INCC:
2025
            n := param1 * 4;
2027
            n := param1 * 4;
2026
            IF ABS(param2) = 1 THEN
2028
            IF ABS(param2) = 1 THEN
2027
                OutByte2(0FFH, 45H + 8 * ORD(param2 = -1) + long(n));  // inc/dec dword[ebp + n]
2029
                OutByte2(0FFH, 45H + 8 * ORD(param2 = -1) + long(n));  (* inc/dec dword[ebp + n] *)
2028
                OutIntByte(n)
2030
                OutIntByte(n)
2029
            ELSE
2031
            ELSE
2030
                OutByte2(81H + short(param2), 45H + long(n)); // add dword[ebp + n], param2
2032
                OutByte2(81H + short(param2), 45H + long(n)); (* add dword[ebp + n], param2 *)
2031
                OutIntByte(n);
2033
                OutIntByte(n);
Line 2032... Line 2034...
2032
                OutIntByte(param2)
2034
                OutIntByte(param2)
2033
            END
2035
            END
2034
 
2036
 
2035
        |IL.opLADR_INCCB, IL.opLADR_DECCB:
2037
        |IL.opLADR_INCCB, IL.opLADR_DECCB:
2036
            n := param1 * 4;
2038
            n := param1 * 4;
Line 2037... Line 2039...
2037
            IF param2 = 1 THEN
2039
            IF param2 = 1 THEN
Line 2094... Line 2096...
2094
BEGIN
2096
BEGIN
Line 2095... Line 2097...
2095
 
2097
 
2096
    entry := NewLabel();
2098
    entry := NewLabel();
Line 2097... Line 2099...
2097
    SetLabel(entry);
2099
    SetLabel(entry);
2098
 
2100
 
2099
    IF target = mConst.Target_iDLL THEN
2101
    IF target = TARGETS.Win32DLL THEN
2100
        push(ebp);
2102
        push(ebp);
2101
        mov(ebp, esp);
2103
        mov(ebp, esp);
2102
        OutByte3(0FFH, 75H, 16);  // push dword[ebp+16]
2104
        pushm(ebp, 16);
2103
        OutByte3(0FFH, 75H, 12);  // push dword[ebp+12]
2105
        pushm(ebp, 12);
2104
        OutByte3(0FFH, 75H, 8);   // push dword[ebp+8]
2106
        pushm(ebp, 8);
2105
        CallRTL(pic, IL._dllentry);
2107
        CallRTL(pic, IL._dllentry);
2106
        test(eax);
2108
        test(eax);
2107
        jcc(je, dllret)
2109
        jcc(je, dllret)
2108
    ELSIF target = mConst.Target_iObject THEN
2110
    ELSIF target = TARGETS.KolibriOSDLL THEN
Line 2109... Line 2111...
2109
        SetLabel(dllinit)
2111
        SetLabel(dllinit)
2110
    END;
2112
    END;
2111
 
2113
 
2112
    IF target = mConst.Target_iKolibri THEN
2114
    IF target = TARGETS.KolibriOS THEN
2113
        reg1 := GetAnyReg();
2115
        reg1 := GetAnyReg();
2114
        Pic(reg1, BIN.IMPTAB, 0);
2116
        Pic(reg1, BIN.IMPTAB, 0);
2115
        push(reg1);    // push IMPORT
2117
        push(reg1);    (* push IMPORT *)
2116
        drop
2118
        drop
2117
    ELSIF target = mConst.Target_iObject THEN
2119
    ELSIF target = TARGETS.KolibriOSDLL THEN
2118
        OutByte(68H);  // push IMPORT
2120
        OutByte(68H);  (* push IMPORT *)
2119
        Reloc(BIN.IMPTAB, 0)
2121
        Reloc(BIN.IMPTAB, 0)
2120
    ELSIF target = mConst.Target_iELF32 THEN
2122
    ELSIF target = TARGETS.Linux32 THEN
2121
        push(esp)
2123
        push(esp)
Line 2122... Line 2124...
2122
    ELSE
2124
    ELSE
2123
        pushc(0)
2125
        pushc(0)
2124
    END;
2126
    END;
2125
 
2127
 
2126
    IF pic THEN
2128
    IF pic THEN
2127
        reg1 := GetAnyReg();
2129
        reg1 := GetAnyReg();
2128
        Pic(reg1, BIN.PICCODE, entry);
2130
        Pic(reg1, BIN.PICCODE, entry);
2129
        push(reg1);     // push CODE
2131
        push(reg1);     (* push CODE *)
2130
        drop
2132
        drop
Line 2131... Line 2133...
2131
    ELSE
2133
    ELSE
2132
        OutByte(68H);  // push CODE
2134
        OutByte(68H);  (* push CODE *)
2133
        Reloc(BIN.RCODE, entry)
2135
        Reloc(BIN.RCODE, entry)
2134
    END;
2136
    END;
2135
 
2137
 
2136
    IF pic THEN
2138
    IF pic THEN
2137
        reg1 := GetAnyReg();
2139
        reg1 := GetAnyReg();
2138
        Pic(reg1, BIN.PICDATA, 0);
2140
        Pic(reg1, BIN.PICDATA, 0);
2139
        push(reg1);    // push _data
2141
        push(reg1);    (* push _data *)
Line 2140... Line 2142...
2140
        drop
2142
        drop
Line 2141... Line 2143...
2141
    ELSE
2143
    ELSE
Line 2142... Line 2144...
2142
        OutByte(68H);  // push _data
2144
        OutByte(68H);  (* push _data *)
2143
        Reloc(BIN.RDATA, 0)
2145
        Reloc(BIN.RDATA, 0)
2144
    END;
2146
    END;
2145
 
2147
 
2146
    dcount := CHL.Length(IL.codes.data);
2148
    dcount := CHL.Length(IL.codes.data);
2147
 
2149
 
2148
    pushc(tcount);
2150
    pushc(tcount);
2149
 
2151
 
2150
    IF pic THEN
2152
    IF pic THEN
Line 2151... Line 2153...
2151
        reg1 := GetAnyReg();
2153
        reg1 := GetAnyReg();
Line 2152... Line 2154...
2152
        Pic(reg1, BIN.PICDATA, tcount * 4 + dcount);
2154
        Pic(reg1, BIN.PICDATA, tcount * 4 + dcount);
2153
        push(reg1);    // push _data + tcount * 4 + dcount
2155
        push(reg1);    (* push _data + tcount * 4 + dcount *)
2154
        drop
2156
        drop
2155
    ELSE
2157
    ELSE
2156
        OutByte(68H);  // push _data
2158
        OutByte(68H);  (* push _data *)
2157
        Reloc(BIN.RDATA, tcount * 4 + dcount)
2159
        Reloc(BIN.RDATA, tcount * 4 + dcount)
Line 2205... Line 2207...
2205
    END import;
2207
    END import;
Line 2206... Line 2208...
2206
 
2208
 
Line 2207... Line 2209...
2207
 
2209
 
2208
BEGIN
2210
BEGIN
2209
 
2211
 
2210
    IF target IN {mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iKolibri, mConst.Target_iELF32} THEN
2212
    IF target IN {TARGETS.Win32C, TARGETS.Win32GUI, TARGETS.KolibriOS, TARGETS.Linux32} THEN
2211
        pushc(0);
2213
        pushc(0);
2212
        CallRTL(pic, IL._exit);
2214
        CallRTL(pic, IL._exit);
2213
    ELSIF target = mConst.Target_iDLL THEN
2215
    ELSIF target = TARGETS.Win32DLL THEN
2214
        SetLabel(dllret);
2216
        SetLabel(dllret);
2215
        movrc(eax, 1);
2217
        movrc(eax, 1);
2216
        OutByte(0C9H); // leave
2218
        OutByte(0C9H); (* leave *)
2217
        OutByte3(0C2H, 0CH, 0) // ret 12
2219
        OutByte3(0C2H, 0CH, 0) (* ret 12 *)
2218
    ELSIF target = mConst.Target_iObject THEN
2220
    ELSIF target = TARGETS.KolibriOSDLL THEN
2219
        movrc(eax, 1);
2221
        movrc(eax, 1);
2220
        OutByte(0C3H)  // ret
2222
        ret
2221
    ELSIF target = mConst.Target_iELFSO32 THEN
2223
    ELSIF target = TARGETS.Linux32SO THEN
2222
        OutByte(0C3H);  // ret
2224
        ret;
2223
        SetLabel(sofinit);
2225
        SetLabel(sofinit);
Line 2224... Line 2226...
2224
        CallRTL(pic, IL._sofinit);
2226
        CallRTL(pic, IL._sofinit);
Line 2225... Line 2227...
2225
        OutByte(0C3H)   // ret
2227
        ret
Line 2242... Line 2244...
2242
    PATHS.split(modname, path, name, ext);
2244
    PATHS.split(modname, path, name, ext);
2243
    BIN.PutDataStr(program, name);
2245
    BIN.PutDataStr(program, name);
2244
    BIN.PutDataStr(program, ext);
2246
    BIN.PutDataStr(program, ext);
2245
    BIN.PutData(program, 0);
2247
    BIN.PutData(program, 0);
Line 2246... Line 2248...
2246
 
2248
 
2247
    IF target = mConst.Target_iObject THEN
2249
    IF target = TARGETS.KolibriOSDLL THEN
2248
        BIN.Export(program, "lib_init", dllinit);
2250
        BIN.Export(program, "lib_init", dllinit);
Line 2249... Line 2251...
2249
    END;
2251
    END;
2250
 
2252
 
Line 2278... Line 2280...
2278
 
2280
 
2279
    dllinit := NewLabel();
2281
    dllinit := NewLabel();
2280
    dllret  := NewLabel();
2282
    dllret  := NewLabel();
Line 2281... Line 2283...
2281
    sofinit := NewLabel();
2283
    sofinit := NewLabel();
2282
 
2284
 
2283
    IF target = mConst.Target_iObject THEN
2285
    IF target = TARGETS.KolibriOSDLL THEN
Line 2284... Line 2286...
2284
        opt.pic := FALSE
2286
        opt.pic := FALSE
2285
    END;
2287
    END;
2286
 
2288
 
Line 2287... Line 2289...
2287
    IF target IN {mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL, mConst.Target_iELF32, mConst.Target_iELFSO32} THEN
2289
    IF TARGETS.OS IN {TARGETS.osWIN32, TARGETS.osLINUX32} THEN
Line 2294... Line 2296...
2294
    translate(opt.pic, tcount * 4);
2296
    translate(opt.pic, tcount * 4);
2295
    epilog(opt.pic, outname, target, opt.stack, opt.version, dllinit, dllret, sofinit);
2297
    epilog(opt.pic, outname, target, opt.stack, opt.version, dllinit, dllret, sofinit);
Line 2296... Line 2298...
2296
 
2298
 
Line 2297... Line 2299...
2297
    BIN.fixup(program);
2299
    BIN.fixup(program);
2298
 
2300
 
2299
    IF target IN {mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL} THEN
2301
    IF TARGETS.OS = TARGETS.osWIN32 THEN
2300
        PE32.write(program, outname, target = mConst.Target_iConsole, target = mConst.Target_iDLL, FALSE)
2302
        PE32.write(program, outname, target = TARGETS.Win32C, target = TARGETS.Win32DLL, FALSE)
2301
    ELSIF target = mConst.Target_iKolibri THEN
2303
    ELSIF target = TARGETS.KolibriOS THEN
2302
        KOS.write(program, outname)
2304
        KOS.write(program, outname)
2303
    ELSIF target = mConst.Target_iObject THEN
2305
    ELSIF target = TARGETS.KolibriOSDLL THEN
2304
        MSCOFF.write(program, outname, opt.version)
2306
        MSCOFF.write(program, outname, opt.version)
2305
    ELSIF target IN {mConst.Target_iELF32, mConst.Target_iELFSO32} THEN
2307
    ELSIF TARGETS.OS = TARGETS.osLINUX32 THEN
Line 2306... Line 2308...
2306
        ELF.write(program, outname, sofinit, target = mConst.Target_iELFSO32, FALSE)
2308
        ELF.write(program, outname, sofinit, target = TARGETS.Linux32SO, FALSE)