Subversion Repositories Kolibri OS

Rev

Rev 7696 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7696 Rev 7983
1
(*
1
(*
2
    BSD 2-Clause License
2
    BSD 2-Clause License
3
 
3
 
4
    Copyright (c) 2018-2019, Anton Krotov
4
    Copyright (c) 2018-2020, Anton Krotov
5
    All rights reserved.
5
    All rights reserved.
6
*)
6
*)
7
 
7
 
8
MODULE X86;
8
MODULE X86;
9
 
9
 
10
IMPORT IL, REG, UTILS, LISTS, BIN, PE32, KOS, MSCOFF, ELF, PROG,
10
IMPORT IL, REG, UTILS, LISTS, BIN, PE32, KOS, MSCOFF, ELF, PROG,
11
       mConst := CONSTANTS, CHL := CHUNKLISTS, PATHS;
11
       CHL := CHUNKLISTS, PATHS, TARGETS;
12
 
12
 
13
 
13
 
14
CONST
14
CONST
15
 
15
 
16
    eax = REG.R0; ecx = REG.R1; edx = REG.R2;
16
    eax = REG.R0; ecx = REG.R1; edx = REG.R2;
17
 
17
 
18
    al = eax; cl = ecx; dl = edx; ah = 4;
18
    al = eax; cl = ecx; dl = edx; ah = 4;
19
 
19
 
20
    ax = eax; cx = ecx; dx = edx;
20
    ax = eax; cx = ecx; dx = edx;
21
 
21
 
22
    esp = 4;
22
    esp = 4;
23
    ebp = 5;
23
    ebp = 5;
24
 
24
 
25
    sete = 94H; setne = 95H; setl = 9CH; setge = 9DH; setle = 9EH; setg = 9FH; setc = 92H; setnc = 93H;
25
    sete = 94H; setne = 95H; setl = 9CH; setge = 9DH; setle = 9EH; setg = 9FH; setc = 92H; setnc = 93H;
26
 
26
 
27
    je = 84H; jne = 85H; jl = 8CH; jge = 8DH; jle = 8EH; jg = 8FH; jb = 82H; jnb = 83H;
27
    je = 84H; jne = 85H; jl = 8CH; jge = 8DH; jle = 8EH; jg = 8FH; jb = 82H; jnb = 83H;
28
 
28
 
29
 
29
 
30
    CODECHUNK = 8;
30
    CODECHUNK = 8;
31
 
31
 
32
 
32
 
33
TYPE
33
TYPE
34
 
34
 
35
    COMMAND = IL.COMMAND;
35
    COMMAND = IL.COMMAND;
36
 
36
 
37
 
37
 
38
    ANYCODE = POINTER TO RECORD (LISTS.ITEM)
38
    ANYCODE = POINTER TO RECORD (LISTS.ITEM)
39
 
39
 
40
        offset: INTEGER
40
        offset: INTEGER
41
 
41
 
42
    END;
42
    END;
43
 
43
 
44
    CODE = POINTER TO RECORD (ANYCODE)
44
    CODE = POINTER TO RECORD (ANYCODE)
45
 
45
 
46
        code:    ARRAY CODECHUNK OF BYTE;
46
        code:    ARRAY CODECHUNK OF BYTE;
47
        length:  INTEGER
47
        length:  INTEGER
48
 
48
 
49
    END;
49
    END;
50
 
50
 
51
    LABEL = POINTER TO RECORD (ANYCODE)
51
    LABEL = POINTER TO RECORD (ANYCODE)
52
 
52
 
53
        label: INTEGER
53
        label: INTEGER
54
 
54
 
55
    END;
55
    END;
56
 
56
 
57
    JUMP = POINTER TO RECORD (ANYCODE)
57
    JUMP = POINTER TO RECORD (ANYCODE)
58
 
58
 
59
        label, diff: INTEGER;
59
        label, diff: INTEGER;
60
        short: BOOLEAN
60
        short: BOOLEAN
61
 
61
 
62
    END;
62
    END;
63
 
63
 
64
    JMP = POINTER TO RECORD (JUMP)
64
    JMP = POINTER TO RECORD (JUMP)
65
 
65
 
66
    END;
66
    END;
67
 
67
 
68
    JCC = POINTER TO RECORD (JUMP)
68
    JCC = POINTER TO RECORD (JUMP)
69
 
69
 
70
        jmp: INTEGER
70
        jmp: INTEGER
71
 
71
 
72
    END;
72
    END;
73
 
73
 
74
    CALL = POINTER TO RECORD (JUMP)
74
    CALL = POINTER TO RECORD (JUMP)
75
 
75
 
76
    END;
76
    END;
77
 
77
 
78
    RELOC = POINTER TO RECORD (ANYCODE)
78
    RELOC = POINTER TO RECORD (ANYCODE)
79
 
79
 
80
        op, value: INTEGER
80
        op, value: INTEGER
81
 
81
 
82
    END;
82
    END;
83
 
83
 
84
 
84
 
85
VAR
85
VAR
86
 
86
 
87
    R: REG.REGS;
87
    R: REG.REGS;
88
 
88
 
89
    program: BIN.PROGRAM;
89
    program: BIN.PROGRAM;
90
 
90
 
91
    CodeList: LISTS.LIST;
91
    CodeList: LISTS.LIST;
92
 
92
 
93
    tcount: INTEGER;
93
    tcount: INTEGER;
94
 
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;
-
 
104
 
-
 
105
 
95
 
106
PROCEDURE OutByte* (n: BYTE);
96
PROCEDURE OutByte* (n: BYTE);
107
VAR
97
VAR
108
    c: CODE;
98
    c: CODE;
109
    last: ANYCODE;
99
    last: ANYCODE;
110
 
100
 
111
BEGIN
101
BEGIN
112
    last := CodeList.last(ANYCODE);
102
    last := CodeList.last(ANYCODE);
113
 
103
 
114
    IF (last IS CODE) & (last(CODE).length < CODECHUNK) THEN
104
    IF (last IS CODE) & (last(CODE).length < CODECHUNK) THEN
115
        c := last(CODE);
105
        c := last(CODE);
116
        c.code[c.length] := n;
106
        c.code[c.length] := n;
117
        INC(c.length)
107
        INC(c.length)
118
    ELSE
108
    ELSE
119
        NEW(c);
109
        NEW(c);
120
        c.code[0] := n;
110
        c.code[0] := n;
121
        c.length  := 1;
111
        c.length  := 1;
122
        LISTS.push(CodeList, c)
112
        LISTS.push(CodeList, c)
123
    END
113
    END
124
 
114
 
125
END OutByte;
115
END OutByte;
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));
133
    OutByte(UTILS.Byte(n, 3))
123
    OutByte(UTILS.Byte(n, 3))
134
END OutInt;
124
END OutInt;
135
 
125
 
136
 
126
 
137
PROCEDURE OutByte2 (a, b: BYTE);
127
PROCEDURE OutByte2 (a, b: BYTE);
138
BEGIN
128
BEGIN
139
    OutByte(a);
129
    OutByte(a);
140
    OutByte(b)
130
    OutByte(b)
141
END OutByte2;
131
END OutByte2;
142
 
132
 
143
 
133
 
144
PROCEDURE OutByte3 (a, b, c: BYTE);
134
PROCEDURE OutByte3 (a, b, c: BYTE);
145
BEGIN
135
BEGIN
146
    OutByte(a);
136
    OutByte(a);
147
    OutByte(b);
137
    OutByte(b);
148
    OutByte(c)
138
    OutByte(c)
149
END OutByte3;
139
END OutByte3;
150
 
140
 
151
 
141
 
152
PROCEDURE OutWord (n: INTEGER);
142
PROCEDURE OutWord (n: INTEGER);
153
BEGIN
143
BEGIN
154
    ASSERT((0 <= n) & (n <= 65535));
144
    ASSERT((0 <= n) & (n <= 65535));
155
    OutByte2(n MOD 256, n DIV 256)
145
    OutByte2(n MOD 256, n DIV 256)
156
END OutWord;
146
END OutWord;
157
 
147
 
158
 
148
 
159
PROCEDURE isByte (n: INTEGER): BOOLEAN;
149
PROCEDURE isByte (n: INTEGER): BOOLEAN;
160
    RETURN (-128 <= n) & (n <= 127)
150
    RETURN (-128 <= n) & (n <= 127)
161
END isByte;
151
END isByte;
162
 
152
 
163
 
153
 
164
PROCEDURE short (n: INTEGER): INTEGER;
154
PROCEDURE short (n: INTEGER): INTEGER;
165
    RETURN 2 * ORD(isByte(n))
155
    RETURN 2 * ORD(isByte(n))
166
END short;
156
END short;
167
 
157
 
168
 
158
 
169
PROCEDURE long (n: INTEGER): INTEGER;
159
PROCEDURE long (n: INTEGER): INTEGER;
170
    RETURN 40H * ORD(~isByte(n))
160
    RETURN 40H * ORD(~isByte(n))
171
END long;
161
END long;
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)
180
    END
170
    END
181
END OutIntByte;
171
END OutIntByte;
182
 
172
 
183
 
173
 
184
PROCEDURE shift* (op, reg: INTEGER);
174
PROCEDURE shift* (op, reg: INTEGER);
185
BEGIN
175
BEGIN
186
    CASE op OF
176
    CASE op OF
187
    |IL.opASR, IL.opASR1, IL.opASR2: OutByte(0F8H + reg)
177
    |IL.opASR, IL.opASR1, IL.opASR2: OutByte(0F8H + reg)
188
    |IL.opROR, IL.opROR1, IL.opROR2: OutByte(0C8H + reg)
178
    |IL.opROR, IL.opROR1, IL.opROR2: OutByte(0C8H + reg)
189
    |IL.opLSL, IL.opLSL1, IL.opLSL2: OutByte(0E0H + reg)
179
    |IL.opLSL, IL.opLSL1, IL.opLSL2: OutByte(0E0H + reg)
190
    |IL.opLSR, IL.opLSR1, IL.opLSR2: OutByte(0E8H + reg)
180
    |IL.opLSR, IL.opLSR1, IL.opLSR2: OutByte(0E8H + reg)
191
    END
181
    END
192
END shift;
182
END shift;
193
 
183
 
194
 
184
 
195
PROCEDURE mov (reg1, reg2: INTEGER);
185
PROCEDURE mov (reg1, reg2: INTEGER);
196
BEGIN
186
BEGIN
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
 
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
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
214
END xchg;
204
END xchg;
215
 
205
 
216
 
206
 
217
PROCEDURE pop (reg: INTEGER);
207
PROCEDURE pop (reg: INTEGER);
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
 
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
 
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 *)
232
    OutInt(n)
222
    OutInt(n)
233
END movrc;
223
END movrc;
234
 
224
 
235
 
225
 
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)
240
END pushc;
230
END pushc;
241
 
231
 
242
 
232
 
243
PROCEDURE test (reg: INTEGER);
233
PROCEDURE test (reg: INTEGER);
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
 
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
 
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;
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 *)
264
END add;
254
END add;
265
 
255
 
266
 
256
 
267
PROCEDURE andrc (reg, n: INTEGER);
257
PROCEDURE andrc (reg, n: INTEGER);
268
BEGIN
258
BEGIN
269
    OutByte2(81H + short(n), 0E0H + reg);  // and reg, n
259
    OutByte2(81H + short(n), 0E0H + reg);  (* and reg, n *)
270
    OutIntByte(n)
260
    OutIntByte(n)
271
END andrc;
261
END andrc;
272
 
262
 
273
 
263
 
274
PROCEDURE orrc (reg, n: INTEGER);
264
PROCEDURE orrc (reg, n: INTEGER);
275
BEGIN
265
BEGIN
276
    OutByte2(81H + short(n), 0C8H + reg);  // or reg, n
266
    OutByte2(81H + short(n), 0C8H + reg);  (* or reg, n *)
277
    OutIntByte(n)
267
    OutIntByte(n)
278
END orrc;
268
END orrc;
279
 
269
 
280
 
270
 
281
PROCEDURE addrc (reg, n: INTEGER);
271
PROCEDURE addrc (reg, n: INTEGER);
282
BEGIN
272
BEGIN
283
    OutByte2(81H + short(n), 0C0H + reg);  // add reg, n
273
    OutByte2(81H + short(n), 0C0H + reg);  (* add reg, n *)
284
    OutIntByte(n)
274
    OutIntByte(n)
285
END addrc;
275
END addrc;
286
 
276
 
287
 
277
 
288
PROCEDURE subrc (reg, n: INTEGER);
278
PROCEDURE subrc (reg, n: INTEGER);
289
BEGIN
279
BEGIN
290
    OutByte2(81H + short(n), 0E8H + reg);  // sub reg, n
280
    OutByte2(81H + short(n), 0E8H + reg);  (* sub reg, n *)
291
    OutIntByte(n)
281
    OutIntByte(n)
292
END subrc;
282
END subrc;
293
 
283
 
294
 
284
 
295
PROCEDURE cmprr (reg1, reg2: INTEGER);
285
PROCEDURE cmprr (reg1, reg2: INTEGER);
296
BEGIN
286
BEGIN
297
    OutByte2(39H, 0C0H + reg2 * 8 + reg1)  // cmp reg1, reg2
287
    OutByte2(39H, 0C0H + reg2 * 8 + reg1)  (* cmp reg1, reg2 *)
298
END cmprr;
288
END cmprr;
299
 
289
 
300
 
290
 
301
PROCEDURE cmprc (reg, n: INTEGER);
291
PROCEDURE cmprc (reg, n: INTEGER);
302
BEGIN
292
BEGIN
-
 
293
    IF n = 0 THEN
-
 
294
        test(reg)
-
 
295
    ELSE
303
    OutByte2(81H + short(n), 0F8H + reg);  // cmp reg, n
296
        OutByte2(81H + short(n), 0F8H + reg);  (* cmp reg, n *)
304
    OutIntByte(n)
297
        OutIntByte(n)
-
 
298
    END
305
END cmprc;
299
END cmprc;
306
 
300
 
307
 
301
 
308
PROCEDURE setcc (cond, reg: INTEGER);
302
PROCEDURE setcc (cond, reg: INTEGER);
309
BEGIN
303
BEGIN
310
    OutByte3(0FH, cond, 0C0H + reg)  // setcc reg
304
    OutByte3(0FH, cond, 0C0H + reg)  (* setcc reg *)
311
END setcc;
305
END setcc;
312
 
306
 
313
 
307
 
314
PROCEDURE xor (reg1, reg2: INTEGER);
308
PROCEDURE xor (reg1, reg2: INTEGER);
315
BEGIN
309
BEGIN
316
    OutByte2(31H, 0C0H + reg2 * 8 + reg1) // xor reg1, reg2
310
    OutByte2(31H, 0C0H + reg2 * 8 + reg1) (* xor reg1, reg2 *)
317
END xor;
311
END xor;
318
 
312
 
-
 
313
 
-
 
314
PROCEDURE ret*;
-
 
315
BEGIN
-
 
316
    OutByte(0C3H)
-
 
317
END ret;
-
 
318
 
319
 
319
 
320
PROCEDURE drop;
320
PROCEDURE drop;
321
BEGIN
321
BEGIN
322
    REG.Drop(R)
322
    REG.Drop(R)
323
END drop;
323
END drop;
324
 
324
 
325
 
325
 
326
PROCEDURE GetAnyReg (): INTEGER;
326
PROCEDURE GetAnyReg (): INTEGER;
327
    RETURN REG.GetAnyReg(R)
327
    RETURN REG.GetAnyReg(R)
328
END GetAnyReg;
328
END GetAnyReg;
329
 
329
 
330
 
330
 
331
PROCEDURE cond* (op: INTEGER): INTEGER;
331
PROCEDURE cond* (op: INTEGER): INTEGER;
332
VAR
332
VAR
333
    res: INTEGER;
333
    res: INTEGER;
334
 
334
 
335
BEGIN
335
BEGIN
336
    CASE op OF
336
    CASE op OF
337
    |IL.opGT, IL.opGTC: res := jg
337
    |IL.opGT, IL.opGTC: res := jg
338
    |IL.opGE, IL.opGEC: res := jge
338
    |IL.opGE, IL.opGEC: res := jge
339
    |IL.opLT, IL.opLTC: res := jl
339
    |IL.opLT, IL.opLTC: res := jl
340
    |IL.opLE, IL.opLEC: res := jle
340
    |IL.opLE, IL.opLEC: res := jle
341
    |IL.opEQ, IL.opEQC: res := je
341
    |IL.opEQ, IL.opEQC: res := je
342
    |IL.opNE, IL.opNEC: res := jne
342
    |IL.opNE, IL.opNEC: res := jne
343
    END
343
    END
344
 
344
 
345
    RETURN res
345
    RETURN res
346
END cond;
346
END cond;
347
 
347
 
348
 
348
 
349
PROCEDURE inv0* (op: INTEGER): INTEGER;
349
PROCEDURE inv0* (op: INTEGER): INTEGER;
350
    RETURN ORD(BITS(op) / {0})
350
    RETURN ORD(BITS(op) / {0})
351
END inv0;
351
END inv0;
352
 
352
 
353
 
353
 
354
PROCEDURE Reloc* (op, value: INTEGER);
354
PROCEDURE Reloc* (op, value: INTEGER);
355
VAR
355
VAR
356
    reloc: RELOC;
356
    reloc: RELOC;
357
 
357
 
358
BEGIN
358
BEGIN
359
    NEW(reloc);
359
    NEW(reloc);
360
    reloc.op := op;
360
    reloc.op := op;
361
    reloc.value := value;
361
    reloc.value := value;
362
    LISTS.push(CodeList, reloc)
362
    LISTS.push(CodeList, reloc)
363
END Reloc;
363
END Reloc;
364
 
364
 
365
 
365
 
366
PROCEDURE jcc* (cc, label: INTEGER);
366
PROCEDURE jcc* (cc, label: INTEGER);
367
VAR
367
VAR
368
    j: JCC;
368
    j: JCC;
369
 
369
 
370
BEGIN
370
BEGIN
371
    NEW(j);
371
    NEW(j);
372
    j.label := label;
372
    j.label := label;
373
    j.jmp   := cc;
373
    j.jmp   := cc;
374
    j.short := FALSE;
374
    j.short := FALSE;
375
    LISTS.push(CodeList, j)
375
    LISTS.push(CodeList, j)
376
END jcc;
376
END jcc;
377
 
377
 
378
 
378
 
379
PROCEDURE jmp* (label: INTEGER);
379
PROCEDURE jmp* (label: INTEGER);
380
VAR
380
VAR
381
    j: JMP;
381
    j: JMP;
382
 
382
 
383
BEGIN
383
BEGIN
384
    NEW(j);
384
    NEW(j);
385
    j.label := label;
385
    j.label := label;
386
    j.short := FALSE;
386
    j.short := FALSE;
387
    LISTS.push(CodeList, j)
387
    LISTS.push(CodeList, j)
388
END jmp;
388
END jmp;
389
 
389
 
390
 
390
 
391
PROCEDURE call* (label: INTEGER);
391
PROCEDURE call* (label: INTEGER);
392
VAR
392
VAR
393
    c: CALL;
393
    c: CALL;
394
 
394
 
395
BEGIN
395
BEGIN
396
    NEW(c);
396
    NEW(c);
397
    c.label := label;
397
    c.label := label;
398
    c.short := TRUE;
398
    c.short := TRUE;
399
    LISTS.push(CodeList, c)
399
    LISTS.push(CodeList, c)
400
END call;
400
END call;
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, ... *)
409
    Reloc(opcode, value)
409
    Reloc(opcode, value)
410
END Pic;
410
END Pic;
411
 
411
 
412
 
412
 
413
PROCEDURE CallRTL (pic: BOOLEAN; proc: INTEGER);
413
PROCEDURE CallRTL (pic: BOOLEAN; proc: INTEGER);
414
VAR
414
VAR
415
    label: INTEGER;
415
    label: INTEGER;
416
    reg1:  INTEGER;
416
    reg1:  INTEGER;
417
 
417
 
418
BEGIN
418
BEGIN
419
    label := IL.codes.rtl[proc];
419
    label := IL.codes.rtl[proc];
420
 
420
 
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
435
END CallRTL;
435
END CallRTL;
436
 
436
 
437
 
437
 
438
PROCEDURE SetLabel* (label: INTEGER);
438
PROCEDURE SetLabel* (label: INTEGER);
439
VAR
439
VAR
440
    L: LABEL;
440
    L: LABEL;
441
 
441
 
442
BEGIN
442
BEGIN
443
    NEW(L);
443
    NEW(L);
444
    L.label := label;
444
    L.label := label;
445
    LISTS.push(CodeList, L)
445
    LISTS.push(CodeList, L)
446
END SetLabel;
446
END SetLabel;
447
 
447
 
448
 
448
 
449
PROCEDURE fixup*;
449
PROCEDURE fixup*;
450
VAR
450
VAR
451
    code:      ANYCODE;
451
    code:      ANYCODE;
452
    count, i:  INTEGER;
452
    count, i:  INTEGER;
453
    shorted:   BOOLEAN;
453
    shorted:   BOOLEAN;
454
    jump:      JUMP;
454
    jump:      JUMP;
455
 
455
 
456
BEGIN
456
BEGIN
457
 
457
 
458
    REPEAT
458
    REPEAT
459
 
459
 
460
        shorted := FALSE;
460
        shorted := FALSE;
461
        count := 0;
461
        count := 0;
462
 
462
 
463
        code := CodeList.first(ANYCODE);
463
        code := CodeList.first(ANYCODE);
464
        WHILE code # NIL DO
464
        WHILE code # NIL DO
465
            code.offset := count;
465
            code.offset := count;
466
 
466
 
467
            CASE code OF
467
            CASE code OF
468
            |CODE:   INC(count, code.length)
468
            |CODE:   INC(count, code.length)
469
            |LABEL:  BIN.SetLabel(program, code.label, count)
469
            |LABEL:  BIN.SetLabel(program, code.label, count)
470
            |JMP:    IF code.short THEN INC(count, 2) ELSE INC(count, 5) END; code.offset := count
470
            |JMP:    IF code.short THEN INC(count, 2) ELSE INC(count, 5) END; code.offset := count
471
            |JCC:    IF code.short THEN INC(count, 2) ELSE INC(count, 6) END; code.offset := count
471
            |JCC:    IF code.short THEN INC(count, 2) ELSE INC(count, 6) END; code.offset := count
472
            |CALL:   INC(count, 5); code.offset := count
472
            |CALL:   INC(count, 5); code.offset := count
473
            |RELOC:  INC(count, 4)
473
            |RELOC:  INC(count, 4)
474
            END;
474
            END;
475
 
475
 
476
            code := code.next(ANYCODE)
476
            code := code.next(ANYCODE)
477
        END;
477
        END;
478
 
478
 
479
        code := CodeList.first(ANYCODE);
479
        code := CodeList.first(ANYCODE);
480
        WHILE code # NIL DO
480
        WHILE code # NIL DO
481
 
481
 
482
            IF code IS JUMP THEN
482
            IF code IS JUMP THEN
483
                jump := code(JUMP);
483
                jump := code(JUMP);
484
                jump.diff := BIN.GetLabel(program, jump.label) - code.offset;
484
                jump.diff := BIN.GetLabel(program, jump.label) - code.offset;
485
                IF ~jump.short & isByte(jump.diff) THEN
485
                IF ~jump.short & isByte(jump.diff) THEN
486
                    jump.short := TRUE;
486
                    jump.short := TRUE;
487
                    shorted := TRUE
487
                    shorted := TRUE
488
                END
488
                END
489
            END;
489
            END;
490
 
490
 
491
            code := code.next(ANYCODE)
491
            code := code.next(ANYCODE)
492
        END
492
        END
493
 
493
 
494
    UNTIL ~shorted;
494
    UNTIL ~shorted;
495
 
495
 
496
    code := CodeList.first(ANYCODE);
496
    code := CodeList.first(ANYCODE);
497
    WHILE code # NIL DO
497
    WHILE code # NIL DO
498
 
498
 
499
        CASE code OF
499
        CASE code OF
500
 
500
 
501
        |CODE:
501
        |CODE:
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
505
 
505
 
506
        |LABEL:
506
        |LABEL:
507
                BIN.SetLabel(program, code.label, code.offset)
-
 
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);
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);
524
                    BIN.PutCode(program, code.jmp);
523
                    BIN.PutCode(program, code.jmp);
525
                    BIN.PutCode32LE(program, code.diff)
524
                    BIN.PutCode32LE(program, code.diff)
526
                END
525
                END
527
 
526
 
528
        |CALL:
527
        |CALL:
529
                BIN.PutCode(program, 0E8H);
528
                BIN.PutCode(program, 0E8H);
530
                BIN.PutCode32LE(program, code.diff)
529
                BIN.PutCode32LE(program, code.diff)
531
 
530
 
532
        |RELOC:
531
        |RELOC:
533
                BIN.PutReloc(program, code.op);
532
                BIN.PutReloc(program, code.op);
534
                BIN.PutCode32LE(program, code.value)
533
                BIN.PutCode32LE(program, code.value)
535
 
534
 
536
        END;
535
        END;
537
 
536
 
538
        code := code.next(ANYCODE)
537
        code := code.next(ANYCODE)
539
    END
538
    END
540
 
539
 
541
END fixup;
540
END fixup;
542
 
541
 
543
 
542
 
544
PROCEDURE UnOp (VAR reg: INTEGER);
543
PROCEDURE UnOp (VAR reg: INTEGER);
545
BEGIN
544
BEGIN
546
    REG.UnOp(R, reg)
545
    REG.UnOp(R, reg)
547
END UnOp;
546
END UnOp;
548
 
547
 
549
 
548
 
550
PROCEDURE BinOp (VAR reg1, reg2: INTEGER);
549
PROCEDURE BinOp (VAR reg1, reg2: INTEGER);
551
BEGIN
550
BEGIN
552
    REG.BinOp(R, reg1, reg2)
551
    REG.BinOp(R, reg1, reg2)
553
END BinOp;
552
END BinOp;
554
 
553
 
555
 
554
 
556
PROCEDURE PushAll (NumberOfParameters: INTEGER);
555
PROCEDURE PushAll (NumberOfParameters: INTEGER);
557
BEGIN
556
BEGIN
558
    REG.PushAll(R);
557
    REG.PushAll(R);
559
    DEC(R.pushed, NumberOfParameters)
558
    DEC(R.pushed, NumberOfParameters)
560
END PushAll;
559
END PushAll;
561
 
560
 
562
 
561
 
563
PROCEDURE NewLabel (): INTEGER;
562
PROCEDURE NewLabel (): INTEGER;
564
BEGIN
563
BEGIN
565
    BIN.NewLabel(program)
564
    BIN.NewLabel(program)
566
    RETURN IL.NewLabel()
565
    RETURN IL.NewLabel()
567
END NewLabel;
566
END NewLabel;
568
 
567
 
569
 
568
 
570
PROCEDURE GetRegA;
569
PROCEDURE GetRegA;
571
BEGIN
570
BEGIN
572
    ASSERT(REG.GetReg(R, eax))
571
    ASSERT(REG.GetReg(R, eax))
573
END GetRegA;
572
END GetRegA;
574
 
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;
-
 
691
 
575
 
692
 
576
PROCEDURE translate (pic: BOOLEAN; stroffs: INTEGER);
693
PROCEDURE translate (pic: BOOLEAN; stroffs: INTEGER);
577
VAR
694
VAR
578
    cmd: COMMAND;
695
    cmd, next: COMMAND;
579
 
696
 
580
    reg1, reg2: INTEGER;
697
    reg1, reg2: INTEGER;
581
 
698
 
582
    n, a, b, label, cc: INTEGER;
699
    n, a, b, label, cc: INTEGER;
583
 
700
 
584
    opcode, param1, param2: INTEGER;
701
    opcode, param1, param2: INTEGER;
585
 
702
 
586
    float: REAL;
703
    float: REAL;
587
 
704
 
588
BEGIN
705
BEGIN
589
    cmd := IL.codes.commands.first(COMMAND);
706
    cmd := IL.codes.commands.first(COMMAND);
590
 
707
 
591
    WHILE cmd # NIL DO
708
    WHILE cmd # NIL DO
592
 
709
 
593
        param1 := cmd.param1;
710
        param1 := cmd.param1;
594
        param2 := cmd.param2;
711
        param2 := cmd.param2;
595
 
712
 
596
        opcode := cmd.opcode;
713
        opcode := cmd.opcode;
597
 
714
 
598
        CASE opcode OF
715
        CASE opcode OF
599
 
716
 
600
        |IL.opJMP:
717
        |IL.opJMP:
601
            jmp(param1)
718
            jmp(param1)
602
 
719
 
603
        |IL.opCALL:
720
        |IL.opCALL:
604
            call(param1)
721
            call(param1)
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)
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 *)
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] *)
631
                DEC(n)
748
                DEC(n)
632
            END;
749
            END;
633
            PushAll(0)
750
            PushAll(0)
634
 
751
 
635
        |IL.opALIGN16:
752
        |IL.opALIGN16:
636
            ASSERT(eax IN R.regs);
753
            ASSERT(eax IN R.regs);
637
            mov(eax, esp);
754
            mov(eax, esp);
638
            andrc(esp, -16);
755
            andrc(esp, -16);
639
            n := (3 - param2 MOD 4) * 4;
756
            n := (3 - param2 MOD 4) * 4;
640
            IF n > 0 THEN
757
            IF n > 0 THEN
641
                subrc(esp, n)
758
                subrc(esp, n)
642
            END;
759
            END;
643
            push(eax)
760
            push(eax)
644
 
761
 
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
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)
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);
666
                DEC(n)
783
                DEC(n)
667
            END
784
            END
668
 
785
 
669
        |IL.opENTER:
786
        |IL.opENTER:
670
            ASSERT(R.top = -1);
787
            ASSERT(R.top = -1);
671
 
788
 
672
            SetLabel(param1);
789
            SetLabel(param1);
673
 
790
 
674
            push(ebp);
791
            push(ebp);
675
            mov(ebp, esp);
792
            mov(ebp, esp);
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)
686
                END
803
                END
687
            END
804
            END
688
 
805
 
689
        |IL.opLEAVE, IL.opLEAVER, IL.opLEAVEF:
806
        |IL.opLEAVE, IL.opLEAVER, IL.opLEAVEF:
690
            IF opcode = IL.opLEAVER THEN
807
            IF opcode = IL.opLEAVER THEN
691
                UnOp(reg1);
808
                UnOp(reg1);
692
                IF reg1 # eax THEN
809
                IF reg1 # eax THEN
693
                    GetRegA;
810
                    GetRegA;
694
                    ASSERT(REG.Exchange(R, reg1, eax));
811
                    ASSERT(REG.Exchange(R, reg1, eax));
695
                    drop
812
                    drop
696
                END;
813
                END;
697
                drop
814
                drop
698
            END;
815
            END;
699
 
816
 
700
            ASSERT(R.top = -1);
817
            ASSERT(R.top = -1);
701
 
818
 
702
            IF param1 > 0 THEN
819
            IF param1 > 0 THEN
703
                mov(esp, ebp)
820
                mov(esp, ebp)
704
            END;
821
            END;
705
 
822
 
706
            pop(ebp);
823
            pop(ebp);
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
714
            END
831
            END
715
 
832
 
716
        |IL.opPUSHC:
833
        |IL.opPUSHC:
717
            pushc(param2)
834
            pushc(param2)
-
 
835
 
-
 
836
        |IL.opONERR:
-
 
837
            pushc(param2);
-
 
838
            jmp(param1)
718
 
839
 
719
        |IL.opPARAM:
840
        |IL.opPARAM:
720
            n := param2;
841
            n := param2;
721
            IF n = 1 THEN
842
            IF n = 1 THEN
722
                UnOp(reg1);
843
                UnOp(reg1);
723
                push(reg1);
844
                push(reg1);
724
                drop
845
                drop
725
            ELSE
846
            ELSE
726
                ASSERT(R.top + 1 <= n);
847
                ASSERT(R.top + 1 <= n);
727
                PushAll(n)
848
                PushAll(n)
728
            END
849
            END
729
 
850
 
730
        |IL.opCLEANUP:
851
        |IL.opCLEANUP:
731
            n := param2 * 4;
852
            n := param2 * 4;
732
            IF n # 0 THEN
853
            IF n # 0 THEN
733
                addrc(esp, n)
854
                addrc(esp, n)
734
            END
855
            END
735
 
856
 
736
        |IL.opPOPSP:
857
        |IL.opPOPSP:
737
            pop(esp)
858
            pop(esp)
738
 
859
 
739
        |IL.opCONST:
860
        |IL.opCONST:
740
            movrc(GetAnyReg(), param2)
861
            movrc(GetAnyReg(), param2)
741
 
862
 
742
        |IL.opLABEL:
863
        |IL.opLABEL:
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)
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
755
 
876
 
756
        |IL.opLADR:
877
        |IL.opLADR:
757
            n := param2 * 4;
878
            n := param2 * 4;
758
            OutByte2(8DH, 45H + GetAnyReg() * 8 + long(n));  // lea reg1, dword[ebp + n]
879
            OutByte2(8DH, 45H + GetAnyReg() * 8 + long(n));  (* lea reg1, dword[ebp + n] *)
759
            OutIntByte(n)
880
            OutIntByte(n)
760
 
881
 
761
        |IL.opVADR:
882
        |IL.opVADR, IL.opLLOAD32:
762
            n := param2 * 4;
-
 
763
            OutByte2(8BH, 45H + GetAnyReg() * 8 + long(n));  // mov reg1, dword[ebp + n]
-
 
764
            OutIntByte(n)
883
            movrm(GetAnyReg(), ebp, param2 * 4)
765
 
884
 
766
        |IL.opSADR:
885
        |IL.opSADR:
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
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
 
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
779
 
898
 
780
        |IL.opSAVE8C:
899
        |IL.opSAVE8C:
781
            UnOp(reg1);
900
            UnOp(reg1);
782
            OutByte3(0C6H, reg1, Byte(param2));  // mov byte[reg1], param2
901
            OutByte3(0C6H, reg1, param2 MOD 256);  (* mov byte[reg1], param2 *)
783
            drop
902
            drop
784
 
903
 
785
        |IL.opSAVE16C:
904
        |IL.opSAVE16C:
786
            UnOp(reg1);
905
            UnOp(reg1);
787
            OutByte3(66H, 0C7H, reg1); OutWord(Word(param2));  // mov word[reg1], param2
906
            OutByte3(66H, 0C7H, reg1); OutWord(param2 MOD 65536);  (* mov word[reg1], param2 *)
788
            drop
907
            drop
789
 
908
 
790
        |IL.opVLOAD32:
909
        |IL.opVLOAD32:
791
            n := param2 * 4;
910
            n := param2 * 4;
792
            reg1 := GetAnyReg();
911
            reg1 := GetAnyReg();
793
            OutByte2(8BH, 45H + reg1 * 8 + long(n));  // mov reg1, dword[ebp + n]
-
 
794
            OutIntByte(n);
912
            movrm(reg1, ebp, param2 * 4);
795
            OutByte2(8BH, reg1 * 9)  // mov reg1, dword[reg1]
913
            movrm(reg1, reg1, 0)
796
 
914
 
797
        |IL.opGLOAD32:
915
        |IL.opGLOAD32:
798
            reg1 := GetAnyReg();
916
            reg1 := GetAnyReg();
799
            IF pic THEN
917
            IF pic THEN
800
                Pic(reg1, BIN.PICBSS, param2);
918
                Pic(reg1, BIN.PICBSS, param2);
801
                OutByte2(8BH, reg1 * 9)       // mov reg1, dword[reg1]
919
                movrm(reg1, reg1, 0)
802
            ELSE
920
            ELSE
803
                OutByte2(08BH, 05H + reg1 * 8);  // mov reg1, dword[_bss + param2]
921
                OutByte2(08BH, 05H + reg1 * 8);  (* mov reg1, dword[_bss + param2] *)
804
                Reloc(BIN.RBSS, param2)
922
                Reloc(BIN.RBSS, param2)
805
            END
923
            END
806
 
-
 
807
        |IL.opLLOAD32:
-
 
808
            n := param2 * 4;
-
 
809
            OutByte2(8BH, 45H + GetAnyReg() * 8 + long(n));  // mov reg1, dword[ebp + n]
-
 
810
            OutIntByte(n)
-
 
811
 
924
 
812
        |IL.opLOAD32:
925
        |IL.opLOAD32:
813
            UnOp(reg1);
926
            UnOp(reg1);
814
            OutByte2(8BH, reg1 * 9)  // mov reg1, dword[reg1]
927
            movrm(reg1, reg1, 0)
815
 
-
 
816
        |IL.opVLOAD8:
928
 
817
            n := param2 * 4;
-
 
818
            reg1 := GetAnyReg();
929
        |IL.opVLOAD8:
819
            OutByte2(8BH, 45H + reg1 * 8 + long(n)); // mov reg1, dword[ebp + n]
930
            reg1 := GetAnyReg();
820
            OutIntByte(n);
931
            movrm(reg1, ebp, param2 * 4);
821
            OutByte3(0FH, 0B6H, reg1 * 9) // movzx reg1, byte[reg1]
932
            movzx(reg1, reg1, 0, FALSE)
822
 
933
 
823
        |IL.opGLOAD8:
934
        |IL.opGLOAD8:
824
            reg1 := GetAnyReg();
935
            reg1 := GetAnyReg();
825
            IF pic THEN
936
            IF pic THEN
826
                Pic(reg1, BIN.PICBSS, param2);
937
                Pic(reg1, BIN.PICBSS, param2);
827
                OutByte3(0FH, 0B6H, reg1 * 9) // movzx reg1, byte[reg1]
938
                movzx(reg1, reg1, 0, FALSE)
828
            ELSE
939
            ELSE
829
                OutByte3(00FH, 0B6H, 05H + reg1 * 8);  // movzx reg1, byte[_bss + param2]
940
                OutByte3(00FH, 0B6H, 05H + reg1 * 8); (* movzx reg1, byte[_bss + param2] *)
830
                Reloc(BIN.RBSS, param2)
941
                Reloc(BIN.RBSS, param2)
831
            END
942
            END
832
 
943
 
833
        |IL.opLLOAD8:
944
        |IL.opLLOAD8:
834
            n := param2 * 4;
945
            movzx(GetAnyReg(), ebp, param2 * 4, FALSE)
835
            OutByte3(0FH, 0B6H, 45H + GetAnyReg() * 8 + long(n)); // movzx reg1, byte[ebp + n]
-
 
836
            OutIntByte(n)
-
 
837
 
946
 
838
        |IL.opLOAD8:
947
        |IL.opLOAD8:
839
            UnOp(reg1);
948
            UnOp(reg1);
840
            OutByte3(0FH, 0B6H, reg1 * 9) // movzx reg1, byte[reg1]
949
            movzx(reg1, reg1, 0, FALSE)
841
 
950
 
842
        |IL.opVLOAD16:
-
 
843
            n := param2 * 4;
951
        |IL.opVLOAD16:
844
            reg1 := GetAnyReg();
-
 
845
            OutByte2(8BH, 45H + reg1 * 8 + long(n)); // mov reg1, dword[ebp + n]
952
            reg1 := GetAnyReg();
846
            OutIntByte(n);
953
            movrm(reg1, ebp, param2 * 4);
847
            OutByte3(0FH, 0B7H, reg1 * 9) // movzx reg1, word[reg1]
954
            movzx(reg1, reg1, 0, TRUE)
848
 
955
 
849
        |IL.opGLOAD16:
956
        |IL.opGLOAD16:
850
            reg1 := GetAnyReg();
957
            reg1 := GetAnyReg();
851
            IF pic THEN
958
            IF pic THEN
852
                Pic(reg1, BIN.PICBSS, param2);
959
                Pic(reg1, BIN.PICBSS, param2);
853
                OutByte3(0FH, 0B7H, reg1 * 9) // movzx reg1, word[reg1]
960
                movzx(reg1, reg1, 0, TRUE)
854
            ELSE
961
            ELSE
855
                OutByte3(00FH, 0B7H, 05H + reg1 * 8);  // movzx reg1, word[_bss + param2]
962
                OutByte3(00FH, 0B7H, 05H + reg1 * 8);  (* movzx reg1, word[_bss + param2] *)
856
                Reloc(BIN.RBSS, param2)
963
                Reloc(BIN.RBSS, param2)
857
            END
964
            END
858
 
965
 
859
        |IL.opLLOAD16:
966
        |IL.opLLOAD16:
860
            n := param2 * 4;
967
            movzx(GetAnyReg(), ebp, param2 * 4, TRUE)
861
            OutByte3(0FH, 0B7H, 45H + GetAnyReg() * 8 + long(n)); // movzx reg1, word[ebp + n]
-
 
862
            OutIntByte(n)
-
 
863
 
968
 
864
        |IL.opLOAD16:
969
        |IL.opLOAD16:
865
            UnOp(reg1);
970
            UnOp(reg1);
866
            OutByte3(0FH, 0B7H, reg1 * 9) // movzx reg1, word[reg1]
971
            movzx(reg1, reg1, 0, TRUE)
867
 
972
 
868
        |IL.opUMINUS:
973
        |IL.opUMINUS:
869
            UnOp(reg1);
974
            UnOp(reg1);
870
            neg(reg1)
975
            neg(reg1)
871
 
976
 
872
        |IL.opADD:
977
        |IL.opADD:
873
            BinOp(reg1, reg2);
978
            BinOp(reg1, reg2);
874
            add(reg1, reg2);
979
            add(reg1, reg2);
875
            drop
980
            drop
876
 
981
 
877
        |IL.opADDL, IL.opADDR:
982
        |IL.opADDL, IL.opADDR:
878
            IF param2 # 0 THEN
983
            IF param2 # 0 THEN
879
                UnOp(reg1);
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
-
 
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
887
            END
1008
                END
-
 
1009
            END
888
 
1010
 
889
        |IL.opSUB:
1011
        |IL.opSUB:
890
            BinOp(reg1, reg2);
1012
            BinOp(reg1, reg2);
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;
904
            IF opcode = IL.opSUBL THEN
1026
            IF opcode = IL.opSUBL THEN
905
                neg(reg1)
1027
                neg(reg1)
906
            END
1028
            END
907
 
1029
 
908
        |IL.opMULC:
1030
        |IL.opMULC:
-
 
1031
            IF (cmd.next(COMMAND).opcode = IL.opADD) & ((param2 = 2) OR (param2 = 4) OR (param2 = 8)) THEN
-
 
1032
                BinOp(reg1, reg2);
-
 
1033
                OutByte3(8DH, 04H + reg1 * 8, reg1 + reg2 * 8 + 40H * UTILS.Log2(param2)); (* lea reg1, [reg1 + reg2 * param2] *)
-
 
1034
                drop;
-
 
1035
                cmd := cmd.next(COMMAND)
-
 
1036
            ELSE
909
            UnOp(reg1);
1037
                UnOp(reg1);
910
 
1038
 
911
            a := param2;
1039
                a := param2;
912
            IF a > 1 THEN
1040
                IF a > 1 THEN
913
                n := UTILS.Log2(a)
1041
                    n := UTILS.Log2(a)
914
            ELSIF a < -1 THEN
1042
                ELSIF a < -1 THEN
915
                n := UTILS.Log2(-a)
1043
                    n := UTILS.Log2(-a)
916
            ELSE
1044
                ELSE
917
                n := -1
1045
                    n := -1
918
            END;
1046
                END;
919
 
1047
 
920
            IF a = 1 THEN
1048
                IF a = 1 THEN
921
 
1049
 
922
            ELSIF a = -1 THEN
1050
                ELSIF a = -1 THEN
923
                neg(reg1)
1051
                    neg(reg1)
924
            ELSIF a = 0 THEN
1052
                ELSIF a = 0 THEN
925
                xor(reg1, reg1)
1053
                    xor(reg1, reg1)
926
            ELSE
1054
                ELSE
927
                IF n > 0 THEN
1055
                    IF n > 0 THEN
928
                    IF a < 0 THEN
1056
                        IF a < 0 THEN
929
                        neg(reg1)
1057
                            neg(reg1)
930
                    END;
1058
                        END;
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
941
            END
1069
                END
-
 
1070
            END
942
 
1071
 
943
        |IL.opMUL:
1072
        |IL.opMUL:
944
            BinOp(reg1, reg2);
1073
            BinOp(reg1, reg2);
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);
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:
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
 
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);
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] *)
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
 
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
 
1003
        |IL.opPUSHIP:
1132
        |IL.opPUSHIP:
1004
            reg1 := GetAnyReg();
1133
            reg1 := GetAnyReg();
1005
            IF pic THEN
1134
            IF pic THEN
1006
                Pic(reg1, BIN.PICIMP, param2);
1135
                Pic(reg1, BIN.PICIMP, param2);
1007
                OutByte2(08BH, reg1 * 9)         // mov reg1, dword[reg1]
1136
                movrm(reg1, reg1, 0)
1008
            ELSE
1137
            ELSE
1009
                OutByte2(08BH, 05H + reg1 * 8);  // mov reg1, dword[L]
1138
                OutByte2(08BH, 05H + reg1 * 8);  (* mov reg1, dword[L] *)
1010
                Reloc(BIN.RIMP, param2)
1139
                Reloc(BIN.RIMP, param2)
1011
            END
1140
            END
1012
 
1141
 
1013
        |IL.opNOT:
1142
        |IL.opNOT:
1014
            UnOp(reg1);
1143
            UnOp(reg1);
1015
            test(reg1);
1144
            test(reg1);
1016
            setcc(sete, reg1);
1145
            setcc(sete, reg1);
1017
            andrc(reg1, 1)
1146
            andrc(reg1, 1)
1018
 
1147
 
1019
        |IL.opORD:
1148
        |IL.opORD:
1020
            UnOp(reg1);
1149
            UnOp(reg1);
1021
            test(reg1);
1150
            test(reg1);
1022
            setcc(setne, reg1);
1151
            setcc(setne, reg1);
1023
            andrc(reg1, 1)
1152
            andrc(reg1, 1)
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;
1030
            drop
1159
            drop
1031
 
1160
 
1032
        |IL.opSBOOLC:
1161
        |IL.opSBOOLC:
1033
            UnOp(reg1);
1162
            UnOp(reg1);
1034
            OutByte3(0C6H, reg1, ORD(param2 # 0)); // mov byte[reg1], 0/1
1163
            OutByte3(0C6H, reg1, ORD(param2 # 0)); (* mov byte[reg1], 0/1 *)
1035
            drop
1164
            drop
1036
 
-
 
1037
        |IL.opODD:
-
 
1038
            UnOp(reg1);
-
 
1039
            andrc(reg1, 1)
-
 
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);
1171
                cmprr(reg1, reg2);
1047
                drop
1172
                drop
1048
            ELSE
1173
            ELSE
1049
                UnOp(reg1);
1174
                UnOp(reg1);
1050
                IF param2 = 0 THEN
-
 
1051
                    test(reg1)
-
 
1052
                ELSE
-
 
1053
                    cmprc(reg1, param2)
1175
                cmprc(reg1, param2)
1054
                END
-
 
1055
            END;
1176
            END;
1056
 
1177
 
1057
            drop;
1178
            drop;
1058
            cc := cond(opcode);
1179
            cc := cond(opcode);
-
 
1180
            next := cmd.next(COMMAND);
1059
 
1181
 
1060
            IF cmd.next(COMMAND).opcode = IL.opJE THEN
-
 
1061
                label := cmd.next(COMMAND).param1;
1182
            IF next.opcode = IL.opJE THEN
1062
                jcc(cc, label);
1183
                jcc(cc, next.param1);
1063
                cmd := cmd.next(COMMAND)
-
 
1064
 
1184
                cmd := next
1065
            ELSIF cmd.next(COMMAND).opcode = IL.opJNE THEN
-
 
1066
                label := cmd.next(COMMAND).param1;
1185
            ELSIF next.opcode = IL.opJNE THEN
1067
                jcc(inv0(cc), label);
1186
                jcc(inv0(cc), next.param1);
1068
                cmd := cmd.next(COMMAND)
-
 
1069
 
1187
                cmd := next
1070
            ELSE
1188
            ELSE
1071
                reg1 := GetAnyReg();
1189
                reg1 := GetAnyReg();
1072
                setcc(cc + 16, reg1);
1190
                setcc(cc + 16, reg1);
1073
                andrc(reg1, 1)
1191
                andrc(reg1, 1)
1074
            END
1192
            END
1075
 
1193
 
1076
        |IL.opEQB, IL.opNEB:
1194
        |IL.opEQB, IL.opNEB:
1077
            BinOp(reg1, reg2);
1195
            BinOp(reg1, reg2);
1078
            drop;
1196
            drop;
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
1087
                               // @@:
1205
                                  @@: *)
1088
 
1206
 
1089
            cmprr(reg1, reg2);
1207
            cmprr(reg1, reg2);
1090
            IF opcode = IL.opEQB THEN
1208
            IF opcode = IL.opEQB THEN
1091
                setcc(sete, reg1)
1209
                setcc(sete, reg1)
1092
            ELSE
1210
            ELSE
1093
                setcc(setne, reg1)
1211
                setcc(setne, reg1)
1094
            END;
1212
            END;
1095
            andrc(reg1, 1)
1213
            andrc(reg1, 1)
1096
 
1214
 
1097
        |IL.opACC:
1215
        |IL.opACC:
1098
            IF (R.top # 0) OR (R.stk[0] # eax) THEN
1216
            IF (R.top # 0) OR (R.stk[0] # eax) THEN
1099
                PushAll(0);
1217
                PushAll(0);
1100
                GetRegA;
1218
                GetRegA;
1101
                pop(eax);
1219
                pop(eax);
1102
                DEC(R.pushed)
1220
                DEC(R.pushed)
1103
            END
1221
            END
1104
 
1222
 
1105
        |IL.opDROP:
1223
        |IL.opDROP:
1106
            UnOp(reg1);
1224
            UnOp(reg1);
1107
            drop
1225
            drop
1108
 
1226
 
1109
        |IL.opJNZ:
1227
        |IL.opJNZ:
1110
            UnOp(reg1);
1228
            UnOp(reg1);
1111
            test(reg1);
1229
            test(reg1);
1112
            jcc(jne, param1)
1230
            jcc(jne, param1)
1113
 
1231
 
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)
-
 
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);
1123
            drop
1246
            drop
1124
 
1247
 
1125
        |IL.opJNE:
1248
        |IL.opJNE:
1126
            UnOp(reg1);
1249
            UnOp(reg1);
1127
            test(reg1);
1250
            test(reg1);
1128
            jcc(je, param1);
1251
            jcc(je, param1);
1129
            drop
1252
            drop
1130
 
1253
 
1131
        |IL.opSWITCH:
1254
        |IL.opSWITCH:
1132
            UnOp(reg1);
1255
            UnOp(reg1);
1133
            IF param2 = 0 THEN
1256
            IF param2 = 0 THEN
1134
                reg2 := eax
1257
                reg2 := eax
1135
            ELSE
1258
            ELSE
1136
                reg2 := ecx
1259
                reg2 := ecx
1137
            END;
1260
            END;
1138
            IF reg1 # reg2 THEN
1261
            IF reg1 # reg2 THEN
1139
                ASSERT(REG.GetReg(R, reg2));
1262
                ASSERT(REG.GetReg(R, reg2));
1140
                ASSERT(REG.Exchange(R, reg1, reg2));
1263
                ASSERT(REG.Exchange(R, reg1, reg2));
1141
                drop
1264
                drop
1142
            END;
1265
            END;
1143
            drop
1266
            drop
1144
 
1267
 
1145
        |IL.opENDSW:
1268
        |IL.opENDSW:
1146
 
1269
 
1147
        |IL.opCASEL:
1270
        |IL.opCASEL:
1148
            cmprc(eax, param1);
1271
            cmprc(eax, param1);
1149
            jcc(jl, param2)
1272
            jcc(jl, param2)
1150
 
1273
 
1151
        |IL.opCASER:
1274
        |IL.opCASER:
1152
            cmprc(eax, param1);
1275
            cmprc(eax, param1);
1153
            jcc(jg, param2)
1276
            jcc(jg, param2)
1154
 
1277
 
1155
        |IL.opCASELR:
1278
        |IL.opCASELR:
1156
            cmprc(eax, param1);
1279
            cmprc(eax, param1);
1157
            jcc(jl, param2);
1280
            jcc(jl, param2);
1158
            jcc(jg, cmd.param3)
1281
            jcc(jg, cmd.param3)
1159
 
1282
 
1160
        |IL.opCODE:
1283
        |IL.opCODE:
1161
            OutByte(param2)
1284
            OutByte(param2)
1162
 
1285
 
1163
        |IL.opGET, IL.opGETC:
1286
        |IL.opGET, IL.opGETC:
1164
            IF opcode = IL.opGET THEN
1287
            IF opcode = IL.opGET THEN
1165
                BinOp(reg1, reg2)
1288
                BinOp(reg1, reg2)
1166
            ELSIF opcode = IL.opGETC THEN
1289
            ELSIF opcode = IL.opGETC THEN
1167
                UnOp(reg2);
1290
                UnOp(reg2);
1168
                reg1 := GetAnyReg();
1291
                reg1 := GetAnyReg();
1169
                movrc(reg1, param1)
1292
                movrc(reg1, param1)
1170
            END;
1293
            END;
1171
            drop;
1294
            drop;
1172
            drop;
1295
            drop;
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)
1305
                CallRTL(pic, IL._move)
1193
 
-
 
1194
            END
1306
            END
1195
 
1307
 
1196
        |IL.opSAVES:
1308
        |IL.opSAVES:
1197
            UnOp(reg2);
1309
            UnOp(reg2);
1198
            REG.PushAll_1(R);
1310
            REG.PushAll_1(R);
1199
 
1311
 
1200
            IF pic THEN
1312
            IF pic THEN
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;
1209
 
1321
 
1210
            push(reg2);
1322
            push(reg2);
1211
            drop;
1323
            drop;
1212
            pushc(param1);
1324
            pushc(param1);
1213
            CallRTL(pic, IL._move)
1325
            CallRTL(pic, IL._move)
1214
 
1326
 
1215
        |IL.opCHKBYTE:
1327
        |IL.opCHKBYTE:
1216
            BinOp(reg1, reg2);
1328
            BinOp(reg1, reg2);
1217
            cmprc(reg1, 256);
1329
            cmprc(reg1, 256);
1218
            jcc(jb, param1)
1330
            jcc(jb, param1)
1219
 
1331
 
1220
        |IL.opCHKIDX:
1332
        |IL.opCHKIDX:
1221
            UnOp(reg1);
1333
            UnOp(reg1);
1222
            cmprc(reg1, param2);
1334
            cmprc(reg1, param2);
1223
            jcc(jb, param1)
1335
            jcc(jb, param1)
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);
1340
                cmprr(reg2, reg1);
1229
                mov(reg1, reg2);
-
 
1230
                drop;
-
 
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
1345
            R.stk[R.top] := reg2
1236
            END
-
 
1237
 
1346
 
1238
        |IL.opLEN:
1347
        |IL.opLEN:
1239
            n := param2;
1348
            n := param2;
1240
            UnOp(reg1);
1349
            UnOp(reg1);
1241
            drop;
1350
            drop;
1242
            EXCL(R.regs, reg1);
1351
            EXCL(R.regs, reg1);
1243
 
1352
 
1244
            WHILE n > 0 DO
1353
            WHILE n > 0 DO
1245
                UnOp(reg2);
1354
                UnOp(reg2);
1246
                drop;
1355
                drop;
1247
                DEC(n)
1356
                DEC(n)
1248
            END;
1357
            END;
1249
 
1358
 
1250
            INCL(R.regs, reg1);
1359
            INCL(R.regs, reg1);
1251
            ASSERT(REG.GetReg(R, reg1))
1360
            ASSERT(REG.GetReg(R, reg1))
1252
 
1361
 
1253
        |IL.opINCC:
1362
        |IL.opINCC:
1254
            UnOp(reg1);
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] *)
-
 
1368
            ELSE
1255
            OutByte2(81H + short(param2), reg1); OutIntByte(param2); // add dword[reg1], param2
1369
                OutByte2(81H + short(param2), reg1); OutIntByte(param2) (* add dword[reg1], param2 *)
-
 
1370
            END;
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 *)
1261
            drop;
1376
            drop;
1262
            drop
1377
            drop
1263
 
1378
 
1264
        |IL.opINCCB, IL.opDECCB:
1379
        |IL.opINCCB, IL.opDECCB:
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:
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
1274
 
1389
 
1275
        |IL.opMULS:
1390
        |IL.opMULS:
1276
            BinOp(reg1, reg2);
1391
            BinOp(reg1, reg2);
1277
            OutByte2(21H, 0C0H + reg2 * 8 + reg1); // and reg1, reg2
1392
            OutByte2(21H, 0C0H + reg2 * 8 + reg1); (* and reg1, reg2 *)
1278
            drop
1393
            drop
1279
 
1394
 
1280
        |IL.opMULSC:
1395
        |IL.opMULSC:
1281
            UnOp(reg1);
1396
            UnOp(reg1);
1282
            andrc(reg1, param2)
1397
            andrc(reg1, param2)
1283
 
1398
 
1284
        |IL.opDIVS:
1399
        |IL.opDIVS:
1285
            BinOp(reg1, reg2);
1400
            BinOp(reg1, reg2);
1286
            xor(reg1, reg2);
1401
            xor(reg1, reg2);
1287
            drop
1402
            drop
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 *)
1292
            OutIntByte(param2)
1407
            OutIntByte(param2)
1293
 
1408
 
1294
        |IL.opADDS:
1409
        |IL.opADDS:
1295
            BinOp(reg1, reg2);
1410
            BinOp(reg1, reg2);
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);
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
1304
 
1419
 
1305
        |IL.opADDSL, IL.opADDSR:
1420
        |IL.opADDSL, IL.opADDSR:
1306
            UnOp(reg1);
1421
            UnOp(reg1);
1307
            orrc(reg1, param2)
1422
            orrc(reg1, param2)
1308
 
1423
 
1309
        |IL.opSUBSL:
1424
        |IL.opSUBSL:
1310
            UnOp(reg1);
1425
            UnOp(reg1);
1311
            not(reg1);
1426
            not(reg1);
1312
            andrc(reg1, param2)
1427
            andrc(reg1, param2)
1313
 
1428
 
1314
        |IL.opSUBSR:
1429
        |IL.opSUBSR:
1315
            UnOp(reg1);
1430
            UnOp(reg1);
1316
            andrc(reg1, ORD(-BITS(param2)))
1431
            andrc(reg1, ORD(-BITS(param2)))
1317
 
1432
 
1318
        |IL.opUMINS:
1433
        |IL.opUMINS:
1319
            UnOp(reg1);
1434
            UnOp(reg1);
1320
            not(reg1)
1435
            not(reg1)
1321
 
1436
 
1322
        |IL.opLENGTH:
1437
        |IL.opLENGTH:
1323
            PushAll(2);
1438
            PushAll(2);
1324
            CallRTL(pic, IL._length);
1439
            CallRTL(pic, IL._length);
1325
            GetRegA
1440
            GetRegA
1326
 
1441
 
1327
        |IL.opLENGTHW:
1442
        |IL.opLENGTHW:
1328
            PushAll(2);
1443
            PushAll(2);
1329
            CallRTL(pic, IL._lengthw);
1444
            CallRTL(pic, IL._lengthw);
1330
            GetRegA
1445
            GetRegA
1331
 
1446
 
1332
        |IL.opCHR:
1447
        |IL.opCHR:
1333
            UnOp(reg1);
1448
            UnOp(reg1);
1334
            andrc(reg1, 255)
1449
            andrc(reg1, 255)
1335
 
1450
 
1336
        |IL.opWCHR:
1451
        |IL.opWCHR:
1337
            UnOp(reg1);
1452
            UnOp(reg1);
1338
            andrc(reg1, 65535)
1453
            andrc(reg1, 65535)
1339
 
1454
 
1340
        |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR:
1455
        |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR:
1341
            UnOp(reg1);
1456
            UnOp(reg1);
1342
            IF reg1 # ecx THEN
1457
            IF reg1 # ecx THEN
1343
                ASSERT(REG.GetReg(R, ecx));
1458
                ASSERT(REG.GetReg(R, ecx));
1344
                ASSERT(REG.Exchange(R, reg1, ecx));
1459
                ASSERT(REG.Exchange(R, reg1, ecx));
1345
                drop
1460
                drop
1346
            END;
1461
            END;
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 *)
1352
            drop
1467
            drop
1353
 
1468
 
1354
        |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1:
1469
        |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1:
1355
            UnOp(reg1);
1470
            UnOp(reg1);
1356
            IF reg1 # ecx THEN
1471
            IF reg1 # ecx THEN
1357
                ASSERT(REG.GetReg(R, ecx));
1472
                ASSERT(REG.GetReg(R, ecx));
1358
                ASSERT(REG.Exchange(R, reg1, ecx));
1473
                ASSERT(REG.Exchange(R, reg1, ecx));
1359
                drop
1474
                drop
1360
            END;
1475
            END;
1361
 
1476
 
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))
1371
 
1486
 
1372
        |IL.opASR2, IL.opROR2, IL.opLSL2, IL.opLSR2:
1487
        |IL.opASR2, IL.opROR2, IL.opLSL2, IL.opLSR2:
1373
            UnOp(reg1);
1488
            UnOp(reg1);
1374
            n := param2 MOD 32;
1489
            n := param2 MOD 32;
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
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: *)
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 *)
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);
1521
            BinOp(reg1, reg2);
1418
            cmprc(reg1, 32);
1522
            cmprc(reg1, 32);
1419
            OutByte2(72H, 4); // jb L
1523
            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();
-
 
1433
            cmprc(reg1, 32);
-
 
1434
            OutByte2(72H, 4); // jb L
-
 
1435
            xor(reg1, reg1);
1524
            xor(reg1, reg1);
1436
            jmp(label);
1525
            jmp(label);
1437
            //L:
1526
            (* L: *)
1438
            movrc(reg2, param2);
-
 
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);
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:
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 *)
1448
            setcc(setc, reg1);
1536
            setcc(setc, reg1);
1449
            andrc(reg1, 1)
1537
            andrc(reg1, 1)
1450
 
1538
 
1451
        |IL.opRSET:
1539
        |IL.opRSET:
1452
            PushAll(2);
1540
            PushAll(2);
1453
            CallRTL(pic, IL._set);
1541
            CallRTL(pic, IL._set);
1454
            GetRegA
1542
            GetRegA
1455
 
1543
 
1456
        |IL.opRSETR:
1544
        |IL.opRSETR:
1457
            PushAll(1);
1545
            PushAll(1);
1458
            pushc(param2);
1546
            pushc(param2);
1459
            CallRTL(pic, IL._set);
1547
            CallRTL(pic, IL._set);
1460
            GetRegA
1548
            GetRegA
1461
 
1549
 
1462
        |IL.opRSETL:
1550
        |IL.opRSETL:
1463
            UnOp(reg1);
1551
            UnOp(reg1);
1464
            REG.PushAll_1(R);
1552
            REG.PushAll_1(R);
1465
            pushc(param2);
1553
            pushc(param2);
1466
            push(reg1);
1554
            push(reg1);
1467
            drop;
1555
            drop;
1468
            CallRTL(pic, IL._set);
1556
            CallRTL(pic, IL._set);
1469
            GetRegA
1557
            GetRegA
1470
 
1558
 
1471
        |IL.opRSET1:
1559
        |IL.opRSET1:
1472
            PushAll(1);
1560
            PushAll(1);
1473
            CallRTL(pic, IL._set1);
1561
            CallRTL(pic, IL._set1);
1474
            GetRegA
1562
            GetRegA
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;
1489
            drop
1577
            drop
1490
 
1578
 
1491
        |IL.opINCLC:
1579
        |IL.opINCLC:
1492
            UnOp(reg1);
1580
            UnOp(reg1);
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:
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
 
1501
        |IL.opDIV:
1589
        |IL.opDIV:
1502
            PushAll(2);
1590
            PushAll(2);
1503
            CallRTL(pic, IL._divmod);
1591
            CallRTL(pic, IL._divmod);
1504
            GetRegA
1592
            GetRegA
1505
 
1593
 
1506
        |IL.opDIVR:
1594
        |IL.opDIVR:
1507
            a := param2;
-
 
1508
            IF a > 1 THEN
-
 
1509
                n := UTILS.Log2(a)
-
 
1510
            ELSIF a < -1 THEN
-
 
1511
                n := UTILS.Log2(-a)
1595
            n := UTILS.Log2(param2);
1512
            ELSE
-
 
1513
                n := -1
-
 
1514
            END;
-
 
1515
 
-
 
1516
            IF a = 1 THEN
-
 
1517
 
-
 
1518
            ELSIF a = -1 THEN
-
 
1519
                UnOp(reg1);
-
 
1520
                neg(reg1)
-
 
1521
            ELSE
-
 
1522
                IF n > 0 THEN
1596
            IF n > 0 THEN
1523
                    UnOp(reg1);
1597
                UnOp(reg1);
1524
 
-
 
1525
                    IF a < 0 THEN
-
 
1526
                        reg2 := GetAnyReg();
-
 
1527
                        mov(reg2, reg1);
-
 
1528
                        IF n # 1 THEN
1598
                IF n # 1 THEN
1529
                            OutByte3(0C1H, 0F8H + reg1, n)     // sar reg1, n
1599
                    OutByte3(0C1H, 0F8H + reg1, n) (* sar reg1, n *)
1530
                        ELSE
1600
                ELSE
1531
                            OutByte2(0D1H, 0F8H + reg1)        // sar reg1, 1
1601
                    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
-
 
1537
                            OutByte3(0C1H, 0F8H + reg1, n)     // sar reg1, n
-
 
1538
                        ELSE
-
 
1539
                            OutByte2(0D1H, 0F8H + reg1)        // sar reg1, 1
-
 
1540
                        END
-
 
1541
                    END
1602
                END
1542
 
-
 
1543
                ELSE
1603
            ELSIF n < 0 THEN
1544
                    PushAll(1);
1604
                PushAll(1);
1545
                    pushc(param2);
1605
                pushc(param2);
1546
                    CallRTL(pic, IL._divmod);
1606
                CallRTL(pic, IL._divmod);
1547
                    GetRegA
1607
                GetRegA
1548
                END
1608
            END
1549
            END
-
 
1550
 
1609
 
1551
        |IL.opDIVL:
1610
        |IL.opDIVL:
1552
            UnOp(reg1);
1611
            UnOp(reg1);
1553
            REG.PushAll_1(R);
1612
            REG.PushAll_1(R);
1554
            pushc(param2);
1613
            pushc(param2);
1555
            push(reg1);
1614
            push(reg1);
1556
            drop;
1615
            drop;
1557
            CallRTL(pic, IL._divmod);
1616
            CallRTL(pic, IL._divmod);
1558
            GetRegA
1617
            GetRegA
1559
 
1618
 
1560
        |IL.opMOD:
1619
        |IL.opMOD:
1561
            PushAll(2);
1620
            PushAll(2);
1562
            CallRTL(pic, IL._divmod);
1621
            CallRTL(pic, IL._divmod);
1563
            mov(eax, edx);
1622
            mov(eax, edx);
1564
            GetRegA
1623
            GetRegA
1565
 
1624
 
1566
        |IL.opMODR:
1625
        |IL.opMODR:
1567
            a := param2;
-
 
1568
            IF a > 1 THEN
-
 
1569
                n := UTILS.Log2(a)
-
 
1570
            ELSIF a < -1 THEN
-
 
1571
                n := UTILS.Log2(-a)
1626
            n := UTILS.Log2(param2);
1572
            ELSE
-
 
1573
                n := -1
-
 
1574
            END;
-
 
1575
 
-
 
1576
            IF ABS(a) = 1 THEN
-
 
1577
                UnOp(reg1);
-
 
1578
                xor(reg1, reg1)
-
 
1579
            ELSE
-
 
1580
                IF n > 0 THEN
1627
            IF n > 0 THEN
1581
                    UnOp(reg1);
1628
                UnOp(reg1);
1582
                    andrc(reg1, ABS(a) - 1);
1629
                andrc(reg1, param2 - 1);
1583
 
-
 
1584
                    IF a < 0 THEN
1630
            ELSIF n < 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
-
 
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
1602
                END
1636
            ELSE
-
 
1637
                UnOp(reg1);
-
 
1638
                xor(reg1, reg1)
1603
            END
1639
            END
1604
 
1640
 
1605
        |IL.opMODL:
1641
        |IL.opMODL:
1606
            UnOp(reg1);
1642
            UnOp(reg1);
1607
            REG.PushAll_1(R);
1643
            REG.PushAll_1(R);
1608
            pushc(param2);
1644
            pushc(param2);
1609
            push(reg1);
1645
            push(reg1);
1610
            drop;
1646
            drop;
1611
            CallRTL(pic, IL._divmod);
1647
            CallRTL(pic, IL._divmod);
1612
            mov(eax, edx);
1648
            mov(eax, edx);
1613
            GetRegA
1649
            GetRegA
1614
 
1650
 
1615
        |IL.opERR:
1651
        |IL.opERR:
1616
            CallRTL(pic, IL._error)
1652
            CallRTL(pic, IL._error)
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
1623
                                  // @@:
1659
                                     L: *)
1624
 
1660
 
1625
        |IL.opCOPY:
1661
        |IL.opCOPY:
1626
            PushAll(2);
1662
            PushAll(2);
1627
            pushc(param2);
1663
            pushc(param2);
1628
            CallRTL(pic, IL._move)
1664
            CallRTL(pic, IL._move)
1629
 
1665
 
1630
        |IL.opMOVE:
1666
        |IL.opMOVE:
1631
            PushAll(3);
1667
            PushAll(3);
1632
            CallRTL(pic, IL._move)
1668
            CallRTL(pic, IL._move)
1633
 
1669
 
1634
        |IL.opCOPYA:
1670
        |IL.opCOPYA:
1635
            PushAll(4);
1671
            PushAll(4);
1636
            pushc(param2);
1672
            pushc(param2);
1637
            CallRTL(pic, IL._arrcpy);
1673
            CallRTL(pic, IL._arrcpy);
1638
            GetRegA
1674
            GetRegA
1639
 
1675
 
1640
        |IL.opCOPYS:
1676
        |IL.opCOPYS:
1641
            PushAll(4);
1677
            PushAll(4);
1642
            pushc(param2);
1678
            pushc(param2);
1643
            CallRTL(pic, IL._strcpy)
1679
            CallRTL(pic, IL._strcpy)
1644
 
1680
 
1645
        |IL.opROT:
1681
        |IL.opROT:
1646
            PushAll(0);
1682
            PushAll(0);
1647
            push(esp);
1683
            push(esp);
1648
            pushc(param2);
1684
            pushc(param2);
1649
            CallRTL(pic, IL._rot)
1685
            CallRTL(pic, IL._rot)
1650
 
1686
 
1651
        |IL.opNEW:
1687
        |IL.opNEW:
1652
            PushAll(1);
1688
            PushAll(1);
1653
            n := param2 + 8;
1689
            n := param2 + 8;
1654
            ASSERT(UTILS.Align(n, 32));
1690
            ASSERT(UTILS.Align(n, 32));
1655
            pushc(n);
1691
            pushc(n);
1656
            pushc(param1);
1692
            pushc(param1);
1657
            CallRTL(pic, IL._new)
1693
            CallRTL(pic, IL._new)
1658
 
1694
 
1659
        |IL.opDISP:
1695
        |IL.opDISP:
1660
            PushAll(1);
1696
            PushAll(1);
1661
            CallRTL(pic, IL._dispose)
1697
            CallRTL(pic, IL._dispose)
1662
 
1698
 
1663
        |IL.opEQS .. IL.opGES:
1699
        |IL.opEQS .. IL.opGES:
1664
            PushAll(4);
1700
            PushAll(4);
1665
            pushc(opcode - IL.opEQS);
1701
            pushc(opcode - IL.opEQS);
1666
            CallRTL(pic, IL._strcmp);
1702
            CallRTL(pic, IL._strcmp);
1667
            GetRegA
1703
            GetRegA
1668
 
1704
 
1669
        |IL.opEQSW .. IL.opGESW:
1705
        |IL.opEQSW .. IL.opGESW:
1670
            PushAll(4);
1706
            PushAll(4);
1671
            pushc(opcode - IL.opEQSW);
1707
            pushc(opcode - IL.opEQSW);
1672
            CallRTL(pic, IL._strcmpw);
1708
            CallRTL(pic, IL._strcmpw);
1673
            GetRegA
1709
            GetRegA
1674
 
1710
 
1675
        |IL.opEQP, IL.opNEP, IL.opEQIP, IL.opNEIP:
1711
        |IL.opEQP, IL.opNEP, IL.opEQIP, IL.opNEIP:
1676
            UnOp(reg1);
1712
            UnOp(reg1);
1677
            CASE opcode OF
1713
            CASE opcode OF
1678
            |IL.opEQP, IL.opNEP:
1714
            |IL.opEQP, IL.opNEP:
1679
                IF pic THEN
1715
                IF pic THEN
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
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)
1698
                END
1734
                END
1699
 
1735
 
1700
            END;
1736
            END;
1701
            drop;
1737
            drop;
1702
            reg1 := GetAnyReg();
1738
            reg1 := GetAnyReg();
1703
 
1739
 
1704
            CASE opcode OF
1740
            CASE opcode OF
1705
            |IL.opEQP, IL.opEQIP: setcc(sete,  reg1)
1741
            |IL.opEQP, IL.opEQIP: setcc(sete,  reg1)
1706
            |IL.opNEP, IL.opNEIP: setcc(setne, reg1)
1742
            |IL.opNEP, IL.opNEIP: setcc(setne, reg1)
1707
            END;
1743
            END;
1708
 
1744
 
1709
            andrc(reg1, 1)
1745
            andrc(reg1, 1)
1710
 
1746
 
1711
        |IL.opPUSHT:
1747
        |IL.opPUSHT:
1712
            UnOp(reg1);
1748
            UnOp(reg1);
1713
            reg2 := GetAnyReg();
1749
            movrm(GetAnyReg(), reg1, -4)
1714
            OutByte3(8BH, 40H + reg2 * 8 + reg1, 0FCH)  // mov reg2, dword[reg1 - 4]
-
 
1715
 
1750
 
1716
        |IL.opISREC:
1751
        |IL.opISREC:
1717
            PushAll(2);
1752
            PushAll(2);
1718
            pushc(param2 * tcount);
1753
            pushc(param2 * tcount);
1719
            CallRTL(pic, IL._isrec);
1754
            CallRTL(pic, IL._isrec);
1720
            GetRegA
1755
            GetRegA
1721
 
1756
 
1722
        |IL.opIS:
1757
        |IL.opIS:
1723
            PushAll(1);
1758
            PushAll(1);
1724
            pushc(param2 * tcount);
1759
            pushc(param2 * tcount);
1725
            CallRTL(pic, IL._is);
1760
            CallRTL(pic, IL._is);
1726
            GetRegA
1761
            GetRegA
1727
 
1762
 
1728
        |IL.opTYPEGR:
1763
        |IL.opTYPEGR:
1729
            PushAll(1);
1764
            PushAll(1);
1730
            pushc(param2 * tcount);
1765
            pushc(param2 * tcount);
1731
            CallRTL(pic, IL._guardrec);
1766
            CallRTL(pic, IL._guardrec);
1732
            GetRegA
1767
            GetRegA
1733
 
1768
 
1734
        |IL.opTYPEGP:
1769
        |IL.opTYPEGP:
1735
            UnOp(reg1);
1770
            UnOp(reg1);
1736
            PushAll(0);
1771
            PushAll(0);
1737
            push(reg1);
1772
            push(reg1);
1738
            pushc(param2 * tcount);
1773
            pushc(param2 * tcount);
1739
            CallRTL(pic, IL._guard);
1774
            CallRTL(pic, IL._guard);
1740
            GetRegA
1775
            GetRegA
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);
1748
            GetRegA
1783
            GetRegA
1749
 
1784
 
1750
        |IL.opCASET:
1785
        |IL.opCASET:
1751
            push(ecx);
1786
            push(ecx);
1752
            push(ecx);
1787
            push(ecx);
1753
            pushc(param2 * tcount);
1788
            pushc(param2 * tcount);
1754
            CallRTL(pic, IL._guardrec);
1789
            CallRTL(pic, IL._guardrec);
1755
            pop(ecx);
1790
            pop(ecx);
1756
            test(eax);
1791
            test(eax);
1757
            jcc(jne, param1)
1792
            jcc(jne, param1)
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;
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] *)
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]  *)
1787
            OutByte2(0DBH, 018H + reg2);  // fistp dword[reg2]
1822
            OutByte2(0DBH, 018H + reg2);  (* fistp dword[reg2] *)
1788
            drop;
1823
            drop;
1789
            drop
1824
            drop
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] *)
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
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] *)
1814
                addrc(esp, 8)
1849
                addrc(esp, 8)
1815
            END
1850
            END
1816
 
1851
 
1817
        |IL.opSAVEF:
1852
        |IL.opSAVEF, IL.opSAVEFI:
1818
            UnOp(reg1);
1853
            UnOp(reg1);
1819
            OutByte2(0DDH, 018H + reg1); // fstp qword[reg1]
1854
            OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *)
1820
            drop
1855
            drop
1821
 
1856
 
1822
        |IL.opADDF, IL.opADDFI:
1857
        |IL.opADDF, IL.opADDFI:
1823
            OutByte2(0DEH, 0C1H)  // faddp st1, st
1858
            OutByte2(0DEH, 0C1H)  (* faddp st1, st *)
1824
 
1859
 
1825
        |IL.opSUBF:
1860
        |IL.opSUBF:
1826
            OutByte2(0DEH, 0E9H)  // fsubp st1, st
1861
            OutByte2(0DEH, 0E9H)  (* fsubp st1, st *)
1827
 
1862
 
1828
        |IL.opSUBFI:
1863
        |IL.opSUBFI:
1829
            OutByte2(0DEH, 0E1H)  // fsubrp st1, st
1864
            OutByte2(0DEH, 0E1H)  (* fsubrp st1, st *)
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 *)
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);
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);
1885
            pop(reg1);
1851
            drop
1886
            drop
1852
 
1887
 
1853
        |IL.opFLOOR:
1888
        |IL.opFLOOR:
1854
            subrc(esp, 8);
1889
            subrc(esp, 8);
1855
            OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 004H);                   // fstcw word[esp+4]
1890
            OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 004H);                   (* fstcw word[esp+4]                    *)
1856
            OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 006H);                   // fstcw word[esp+6]
1891
            OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 006H);                   (* fstcw word[esp+6]                    *)
1857
            OutByte2(066H, 081H); OutByte3(064H, 024H, 004H); OutWord(0F3FFH);  // and word[esp+4], 1111001111111111b
1892
            OutByte2(066H, 081H); OutByte3(064H, 024H, 004H); OutWord(0F3FFH);  (* and   word[esp+4], 1111001111111111b *)
1858
            OutByte2(066H, 081H); OutByte3(04CH, 024H, 004H); OutWord(00400H);  // or  word[esp+4], 0000010000000000b
1893
            OutByte2(066H, 081H); OutByte3(04CH, 024H, 004H); OutWord(00400H);  (* or    word[esp+4], 0000010000000000b *)
1859
            OutByte2(0D9H, 06CH); OutByte2(024H, 004H);                         // fldcw word[esp+4]
1894
            OutByte2(0D9H, 06CH); OutByte2(024H, 004H);                         (* fldcw word[esp+4]                    *)
1860
            OutByte2(0D9H, 0FCH);                                               // frndint
1895
            OutByte2(0D9H, 0FCH);                                               (* frndint                              *)
1861
            OutByte3(0DBH, 01CH, 024H);                                         // fistp dword[esp]
1896
            OutByte3(0DBH, 01CH, 024H);                                         (* fistp dword[esp]                     *)
1862
            pop(GetAnyReg());
1897
            pop(GetAnyReg());
1863
            OutByte2(0D9H, 06CH); OutByte2(024H, 002H);                         // fldcw word[esp+2]
1898
            OutByte2(0D9H, 06CH); OutByte2(024H, 002H);                         (* fldcw word[esp+2]                    *)
1864
            addrc(esp, 4)
1899
            addrc(esp, 4)
1865
 
1900
 
1866
        |IL.opEQF:
1901
        |IL.opEQF:
1867
            GetRegA;
1902
            fcmp;
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
1903
            OutByte2(07AH, 003H);       (* jp L *)
1873
            setcc(sete, al)
1904
            setcc(sete, al)
1874
                                        // L:
1905
                                        (* L: *)
1875
 
1906
 
1876
        |IL.opNEF:
1907
        |IL.opNEF:
1877
            GetRegA;
-
 
1878
            OutByte2(0DAH, 0E9H);       // fucompp
-
 
1879
            OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
-
 
1880
            OutByte(09EH);              // sahf
-
 
1881
            movrc(eax, 0);
1908
            fcmp;
1882
            OutByte2(07AH, 003H);       // jp L
1909
            OutByte2(07AH, 003H);       (* jp L *)
1883
            setcc(setne, al)
1910
            setcc(setne, al)
1884
                                        // L:
1911
                                        (* L: *)
1885
 
1912
 
1886
        |IL.opLTF:
-
 
1887
            GetRegA;
-
 
1888
            OutByte2(0DAH, 0E9H);       // fucompp
-
 
1889
            OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
-
 
1890
            OutByte(09EH);              // sahf
1913
        |IL.opLTF:
1891
            movrc(eax, 0);
1914
            fcmp;
1892
            OutByte2(07AH, 00EH);       // jp L
1915
            OutByte2(07AH, 00EH);       (* jp L *)
1893
            setcc(setc, al);
1916
            setcc(setc, al);
1894
            setcc(sete, ah);
1917
            setcc(sete, ah);
1895
            test(eax);
1918
            test(eax);
1896
            setcc(sete, al);
1919
            setcc(sete, al);
1897
            andrc(eax, 1)
1920
            andrc(eax, 1)
1898
                                        // L:
1921
                                        (* L: *)
1899
 
1922
 
1900
        |IL.opGTF:
1923
        |IL.opGTF:
1901
            GetRegA;
-
 
1902
            OutByte2(0DAH, 0E9H);       // fucompp
-
 
1903
            OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
-
 
1904
            OutByte(09EH);              // sahf
-
 
1905
            movrc(eax, 0);
1924
            fcmp;
1906
            OutByte2(07AH, 00FH);       // jp L
1925
            OutByte2(07AH, 00FH);       (* jp L *)
1907
            setcc(setc, al);
1926
            setcc(setc, al);
1908
            setcc(sete, ah);
1927
            setcc(sete, ah);
1909
            cmprc(eax, 1);
1928
            cmprc(eax, 1);
1910
            setcc(sete, al);
1929
            setcc(sete, al);
1911
            andrc(eax, 1)
1930
            andrc(eax, 1)
1912
                                        // L:
1931
                                        (* L: *)
1913
 
1932
 
1914
        |IL.opLEF:
1933
        |IL.opLEF:
1915
            GetRegA;
-
 
1916
            OutByte2(0DAH, 0E9H);       // fucompp
-
 
1917
            OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
-
 
1918
            OutByte(09EH);              // sahf
-
 
1919
            movrc(eax, 0);
1934
            fcmp;
1920
            OutByte2(07AH, 003H);       // jp L
1935
            OutByte2(07AH, 003H);       (* jp L *)
1921
            setcc(setnc, al)
1936
            setcc(setnc, al)
1922
                                        // L:
1937
                                        (* L: *)
1923
 
1938
 
1924
        |IL.opGEF:
-
 
1925
            GetRegA;
-
 
1926
            OutByte2(0DAH, 0E9H);       // fucompp
-
 
1927
            OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
-
 
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);
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);
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
 
1955
 
1945
        |IL.opLADR_UNPK:
1956
        |IL.opLADR_UNPK:
1946
            n := param2 * 4;
1957
            n := param2 * 4;
1947
            reg1 := GetAnyReg();
1958
            reg1 := GetAnyReg();
1948
            OutByte2(8DH, 45H + reg1 * 8 + long(n));  // lea reg1, dword[ebp + n]
1959
            OutByte2(8DH, 45H + reg1 * 8 + long(n));  (* lea reg1, dword[ebp + n] *)
1949
            OutIntByte(n);
1960
            OutIntByte(n);
1950
            BinOp(reg1, reg2);
1961
            BinOp(reg1, reg2);
1951
            OutByte2(0DDH, reg1);         // fld qword[reg1]
1962
            OutByte2(0DDH, reg1);         (* fld qword[reg1]   *)
1952
            OutByte2(0D9H, 0F4H);         // fxtract
1963
            OutByte2(0D9H, 0F4H);         (* fxtract           *)
1953
            OutByte2(0DDH, 018H + reg1);  // fstp qword[reg1]
1964
            OutByte2(0DDH, 018H + reg1);  (* fstp qword[reg1]  *)
1954
            OutByte2(0DBH, 018H + reg2);  // fistp dword[reg2]
1965
            OutByte2(0DBH, 018H + reg2);  (* fistp dword[reg2] *)
1955
            drop;
1966
            drop;
1956
            drop
1967
            drop
1957
 
1968
 
1958
        |IL.opSADR_PARAM:
1969
        |IL.opSADR_PARAM:
1959
            IF pic THEN
1970
            IF pic THEN
1960
                reg1 := GetAnyReg();
1971
                reg1 := GetAnyReg();
1961
                Pic(reg1, BIN.PICDATA, stroffs + param2);
1972
                Pic(reg1, BIN.PICDATA, stroffs + param2);
1962
                push(reg1);
1973
                push(reg1);
1963
                drop
1974
                drop
1964
            ELSE
1975
            ELSE
1965
                OutByte(068H);  // push _data + stroffs + param2
1976
                OutByte(068H);  (* push _data + stroffs + param2 *)
1966
                Reloc(BIN.RDATA, stroffs + param2)
1977
                Reloc(BIN.RDATA, stroffs + param2)
1967
            END
1978
            END
1968
 
1979
 
1969
        |IL.opVADR_PARAM:
1980
        |IL.opVADR_PARAM, IL.opLLOAD32_PARAM:
1970
            n := param2 * 4;
-
 
1971
            OutByte2(0FFH, 75H + long(n));  // push dword[ebp + n]
-
 
1972
            OutIntByte(n)
1981
            pushm(ebp, param2 * 4)
1973
 
1982
 
1974
        |IL.opCONST_PARAM:
1983
        |IL.opCONST_PARAM:
1975
            pushc(param2)
1984
            pushc(param2)
1976
 
1985
 
1977
        |IL.opGLOAD32_PARAM:
1986
        |IL.opGLOAD32_PARAM:
1978
            IF pic THEN
1987
            IF pic THEN
1979
                reg1 := GetAnyReg();
1988
                reg1 := GetAnyReg();
1980
                Pic(reg1, BIN.PICBSS, param2);
1989
                Pic(reg1, BIN.PICBSS, param2);
1981
                OutByte2(0FFH, 30H + reg1);   // push dword[reg1]
1990
                pushm(reg1, 0);
1982
                drop
1991
                drop
1983
            ELSE
1992
            ELSE
1984
                OutByte2(0FFH, 035H);  // push dword[_bss + param2]
1993
                OutByte2(0FFH, 035H);  (* push dword[_bss + param2] *)
1985
                Reloc(BIN.RBSS, param2)
1994
                Reloc(BIN.RBSS, param2)
1986
            END
1995
            END
1987
 
-
 
1988
        |IL.opLLOAD32_PARAM:
-
 
1989
            n := param2 * 4;
-
 
1990
            OutByte2(0FFH, 75H + long(n));  // push dword[ebp + n]
-
 
1991
            OutIntByte(n)
-
 
1992
 
1996
 
1993
        |IL.opLOAD32_PARAM:
1997
        |IL.opLOAD32_PARAM:
1994
            UnOp(reg1);
1998
            UnOp(reg1);
1995
            OutByte2(0FFH, 30H + reg1);  // push dword[reg1]
1999
            pushm(reg1, 0);
1996
            drop
2000
            drop
1997
 
2001
 
1998
        |IL.opGADR_SAVEC:
2002
        |IL.opGADR_SAVEC:
1999
            IF pic THEN
2003
            IF pic THEN
2000
                reg1 := GetAnyReg();
2004
                reg1 := GetAnyReg();
2001
                Pic(reg1, BIN.PICBSS, param1);
2005
                Pic(reg1, BIN.PICBSS, param1);
2002
                OutByte2(0C7H, reg1);  // mov dword[reg1], param2
2006
                OutByte2(0C7H, reg1);  (* mov dword[reg1], param2 *)
2003
                OutInt(param2);
2007
                OutInt(param2);
2004
                drop
2008
                drop
2005
            ELSE
2009
            ELSE
2006
                OutByte2(0C7H, 05H);  // mov dword[_bss + param1], param2
2010
                OutByte2(0C7H, 05H);  (* mov dword[_bss + param1], param2 *)
2007
                Reloc(BIN.RBSS, param1);
2011
                Reloc(BIN.RBSS, param1);
2008
                OutInt(param2)
2012
                OutInt(param2)
2009
            END
2013
            END
2010
 
2014
 
2011
        |IL.opLADR_SAVEC:
2015
        |IL.opLADR_SAVEC:
2012
            n := param1 * 4;
2016
            n := param1 * 4;
2013
            OutByte2(0C7H, 45H + long(n));  // mov dword[ebp + n], param2
2017
            OutByte2(0C7H, 45H + long(n));  (* mov dword[ebp + n], param2 *)
2014
            OutIntByte(n);
2018
            OutIntByte(n);
2015
            OutInt(param2)
2019
            OutInt(param2)
2016
 
2020
 
2017
        |IL.opLADR_SAVE:
2021
        |IL.opLADR_SAVE:
2018
            n := param2 * 4;
-
 
2019
            UnOp(reg1);
2022
            UnOp(reg1);
2020
            OutByte2(89H, 45H + reg1 * 8 + long(n));  // mov dword[ebp + n], reg1
-
 
2021
            OutIntByte(n);
2023
            movmr(ebp, param2 * 4, reg1);
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);
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;
2037
            IF param2 = 1 THEN
2039
            IF param2 = 1 THEN
2038
                OutByte2(0FEH, 45H + 8 * ORD(opcode = IL.opLADR_DECCB) + long(n));  // inc/dec byte[ebp + n]
2040
                OutByte2(0FEH, 45H + 8 * ORD(opcode = IL.opLADR_DECCB) + long(n));  (* inc/dec byte[ebp + n] *)
2039
                OutIntByte(n)
2041
                OutIntByte(n)
2040
            ELSE
2042
            ELSE
2041
                OutByte2(80H, 45H + 28H * ORD(opcode = IL.opLADR_DECCB) + long(n)); // add/sub byte[ebp + n], param2
2043
                OutByte2(80H, 45H + 28H * ORD(opcode = IL.opLADR_DECCB) + long(n)); (* add/sub byte[ebp + n], param2 *)
2042
                OutIntByte(n);
2044
                OutIntByte(n);
2043
                OutByte(param2 MOD 256)
2045
                OutByte(param2 MOD 256)
2044
            END
2046
            END
2045
 
2047
 
2046
        |IL.opLADR_INC, IL.opLADR_DEC:
2048
        |IL.opLADR_INC, IL.opLADR_DEC:
2047
            n := param2 * 4;
2049
            n := param2 * 4;
2048
            UnOp(reg1);
2050
            UnOp(reg1);
2049
            OutByte2(01H + 28H * ORD(opcode = IL.opLADR_DEC), 45H + long(n) + reg1 * 8); // add/sub dword[ebp + n], reg1
2051
            OutByte2(01H + 28H * ORD(opcode = IL.opLADR_DEC), 45H + long(n) + reg1 * 8); (* add/sub dword[ebp + n], reg1 *)
2050
            OutIntByte(n);
2052
            OutIntByte(n);
2051
            drop
2053
            drop
2052
 
2054
 
2053
        |IL.opLADR_INCB, IL.opLADR_DECB:
2055
        |IL.opLADR_INCB, IL.opLADR_DECB:
2054
            n := param2 * 4;
2056
            n := param2 * 4;
2055
            UnOp(reg1);
2057
            UnOp(reg1);
2056
            OutByte2(28H * ORD(opcode = IL.opLADR_DECB), 45H + long(n) + reg1 * 8); // add/sub byte[ebp + n], reg1
2058
            OutByte2(28H * ORD(opcode = IL.opLADR_DECB), 45H + long(n) + reg1 * 8); (* add/sub byte[ebp + n], reg1 *)
2057
            OutIntByte(n);
2059
            OutIntByte(n);
2058
            drop
2060
            drop
2059
 
2061
 
2060
        |IL.opLADR_INCL, IL.opLADR_EXCL:
2062
        |IL.opLADR_INCL, IL.opLADR_EXCL:
2061
            n := param2 * 4;
2063
            n := param2 * 4;
2062
            UnOp(reg1);
2064
            UnOp(reg1);
2063
            cmprc(reg1, 32);
2065
            cmprc(reg1, 32);
2064
            label := NewLabel();
2066
            label := NewLabel();
2065
            jcc(jnb, label);
2067
            jcc(jnb, label);
2066
            OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), 45H + long(n) + reg1 * 8); // bts(r) dword[ebp + n], reg1
2068
            OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), 45H + long(n) + reg1 * 8); (* bts(r) dword[ebp + n], reg1 *)
2067
            OutIntByte(n);
2069
            OutIntByte(n);
2068
            SetLabel(label);
2070
            SetLabel(label);
2069
            drop
2071
            drop
2070
 
2072
 
2071
        |IL.opLADR_INCLC, IL.opLADR_EXCLC:
2073
        |IL.opLADR_INCLC, IL.opLADR_EXCLC:
2072
            n := param1 * 4;
2074
            n := param1 * 4;
2073
            OutByte3(0FH, 0BAH, 6DH + long(n) + 8 * ORD(opcode = IL.opLADR_EXCLC)); // bts(r) dword[ebp + n], param2
2075
            OutByte3(0FH, 0BAH, 6DH + long(n) + 8 * ORD(opcode = IL.opLADR_EXCLC)); (* bts(r) dword[ebp + n], param2 *)
2074
            OutIntByte(n);
2076
            OutIntByte(n);
2075
            OutByte(param2)
2077
            OutByte(param2)
2076
 
2078
 
2077
        |IL.opLOOP, IL.opENDLOOP:
2079
        |IL.opLOOP, IL.opENDLOOP:
2078
 
2080
 
2079
        END;
2081
        END;
2080
 
2082
 
2081
        cmd := cmd.next(COMMAND)
2083
        cmd := cmd.next(COMMAND)
2082
    END;
2084
    END;
2083
 
2085
 
2084
    ASSERT(R.pushed = 0);
2086
    ASSERT(R.pushed = 0);
2085
    ASSERT(R.top = -1)
2087
    ASSERT(R.top = -1)
2086
 
2088
 
2087
END translate;
2089
END translate;
2088
 
2090
 
2089
 
2091
 
2090
PROCEDURE prolog (pic: BOOLEAN; target, stack, dllinit, dllret: INTEGER);
2092
PROCEDURE prolog (pic: BOOLEAN; target, stack, dllinit, dllret: INTEGER);
2091
VAR
2093
VAR
2092
    reg1, entry, L, dcount: INTEGER;
2094
    reg1, entry, L, dcount: INTEGER;
2093
 
2095
 
2094
BEGIN
2096
BEGIN
2095
 
2097
 
2096
    entry := NewLabel();
2098
    entry := NewLabel();
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
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)
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
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 *)
2140
        drop
2142
        drop
2141
    ELSE
2143
    ELSE
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
2151
        reg1 := GetAnyReg();
2153
        reg1 := GetAnyReg();
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)
2158
    END;
2160
    END;
2159
 
2161
 
2160
    CallRTL(pic, IL._init);
2162
    CallRTL(pic, IL._init);
2161
 
2163
 
2162
    IF target = mConst.Target_iELF32 THEN
2164
    IF target = TARGETS.Linux32 THEN
2163
        L := NewLabel();
2165
        L := NewLabel();
2164
        pushc(0);
2166
        pushc(0);
2165
        push(esp);
2167
        push(esp);
2166
        pushc(1024 * 1024 * stack);
2168
        pushc(1024 * 1024 * stack);
2167
        pushc(0);
2169
        pushc(0);
2168
        CallRTL(pic, IL._new);
2170
        CallRTL(pic, IL._new);
2169
        pop(eax);
2171
        pop(eax);
2170
        test(eax);
2172
        test(eax);
2171
        jcc(je, L);
2173
        jcc(je, L);
2172
        addrc(eax, 1024 * 1024 * stack - 4);
2174
        addrc(eax, 1024 * 1024 * stack - 4);
2173
        mov(esp, eax);
2175
        mov(esp, eax);
2174
        SetLabel(L)
2176
        SetLabel(L)
2175
    END
2177
    END
2176
END prolog;
2178
END prolog;
2177
 
2179
 
2178
 
2180
 
2179
PROCEDURE epilog (pic: BOOLEAN; modname: ARRAY OF CHAR; target, stack, ver, dllinit, dllret, sofinit: INTEGER);
2181
PROCEDURE epilog (pic: BOOLEAN; modname: ARRAY OF CHAR; target, stack, ver, dllinit, dllret, sofinit: INTEGER);
2180
VAR
2182
VAR
2181
    exp:  IL.EXPORT_PROC;
2183
    exp:  IL.EXPORT_PROC;
2182
    path, name, ext: PATHS.PATH;
2184
    path, name, ext: PATHS.PATH;
2183
 
2185
 
2184
    dcount, i: INTEGER;
2186
    dcount, i: INTEGER;
2185
 
2187
 
2186
 
2188
 
2187
    PROCEDURE import (imp: LISTS.LIST);
2189
    PROCEDURE import (imp: LISTS.LIST);
2188
    VAR
2190
    VAR
2189
        lib:  IL.IMPORT_LIB;
2191
        lib:  IL.IMPORT_LIB;
2190
        proc: IL.IMPORT_PROC;
2192
        proc: IL.IMPORT_PROC;
2191
 
2193
 
2192
    BEGIN
2194
    BEGIN
2193
 
2195
 
2194
        lib := imp.first(IL.IMPORT_LIB);
2196
        lib := imp.first(IL.IMPORT_LIB);
2195
        WHILE lib # NIL DO
2197
        WHILE lib # NIL DO
2196
            BIN.Import(program, lib.name, 0);
2198
            BIN.Import(program, lib.name, 0);
2197
            proc := lib.procs.first(IL.IMPORT_PROC);
2199
            proc := lib.procs.first(IL.IMPORT_PROC);
2198
            WHILE proc # NIL DO
2200
            WHILE proc # NIL DO
2199
                BIN.Import(program, proc.name, proc.label);
2201
                BIN.Import(program, proc.name, proc.label);
2200
                proc := proc.next(IL.IMPORT_PROC)
2202
                proc := proc.next(IL.IMPORT_PROC)
2201
            END;
2203
            END;
2202
            lib := lib.next(IL.IMPORT_LIB)
2204
            lib := lib.next(IL.IMPORT_LIB)
2203
        END
2205
        END
2204
 
2206
 
2205
    END import;
2207
    END import;
2206
 
2208
 
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);
2224
        CallRTL(pic, IL._sofinit);
2226
        CallRTL(pic, IL._sofinit);
2225
        OutByte(0C3H)   // ret
2227
        ret
2226
    END;
2228
    END;
2227
 
2229
 
2228
    fixup;
2230
    fixup;
2229
 
2231
 
2230
    dcount := CHL.Length(IL.codes.data);
2232
    dcount := CHL.Length(IL.codes.data);
2231
 
2233
 
2232
    FOR i := 0 TO tcount - 1 DO
2234
    FOR i := 0 TO tcount - 1 DO
2233
        BIN.PutData32LE(program, CHL.GetInt(IL.codes.types, i))
2235
        BIN.PutData32LE(program, CHL.GetInt(IL.codes.types, i))
2234
    END;
2236
    END;
2235
 
2237
 
2236
    FOR i := 0 TO dcount - 1 DO
2238
    FOR i := 0 TO dcount - 1 DO
2237
        BIN.PutData(program, CHL.GetByte(IL.codes.data, i))
2239
        BIN.PutData(program, CHL.GetByte(IL.codes.data, i))
2238
    END;
2240
    END;
2239
 
2241
 
2240
    program.modname := CHL.Length(program.data);
2242
    program.modname := CHL.Length(program.data);
2241
 
2243
 
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);
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);
2249
    END;
2251
    END;
2250
 
2252
 
2251
    exp := IL.codes.export.first(IL.EXPORT_PROC);
2253
    exp := IL.codes.export.first(IL.EXPORT_PROC);
2252
    WHILE exp # NIL DO
2254
    WHILE exp # NIL DO
2253
        BIN.Export(program, exp.name, exp.label);
2255
        BIN.Export(program, exp.name, exp.label);
2254
        exp := exp.next(IL.EXPORT_PROC)
2256
        exp := exp.next(IL.EXPORT_PROC)
2255
    END;
2257
    END;
2256
 
2258
 
2257
    import(IL.codes.import);
2259
    import(IL.codes.import);
2258
 
2260
 
2259
    IL.set_bss(MAX(IL.codes.bss, MAX(IL.codes.dmin - CHL.Length(IL.codes.data), 4)));
2261
    IL.set_bss(MAX(IL.codes.bss, MAX(IL.codes.dmin - CHL.Length(IL.codes.data), 4)));
2260
 
2262
 
2261
    BIN.SetParams(program, IL.codes.bss, stack * (1024 * 1024), WCHR(ver DIV 65536), WCHR(ver MOD 65536));
2263
    BIN.SetParams(program, IL.codes.bss, stack * (1024 * 1024), WCHR(ver DIV 65536), WCHR(ver MOD 65536));
2262
 
2264
 
2263
END epilog;
2265
END epilog;
2264
 
2266
 
2265
 
2267
 
2266
PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
2268
PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
2267
VAR
2269
VAR
2268
    dllret, dllinit, sofinit: INTEGER;
2270
    dllret, dllinit, sofinit: INTEGER;
2269
    opt: PROG.OPTIONS;
2271
    opt: PROG.OPTIONS;
2270
 
2272
 
2271
BEGIN
2273
BEGIN
2272
    tcount := CHL.Length(IL.codes.types);
2274
    tcount := CHL.Length(IL.codes.types);
2273
 
2275
 
2274
    opt := options;
2276
    opt := options;
2275
    CodeList := LISTS.create(NIL);
2277
    CodeList := LISTS.create(NIL);
2276
 
2278
 
2277
    program := BIN.create(IL.codes.lcount);
2279
    program := BIN.create(IL.codes.lcount);
2278
 
2280
 
2279
    dllinit := NewLabel();
2281
    dllinit := NewLabel();
2280
    dllret  := NewLabel();
2282
    dllret  := NewLabel();
2281
    sofinit := NewLabel();
2283
    sofinit := NewLabel();
2282
 
2284
 
2283
    IF target = mConst.Target_iObject THEN
2285
    IF target = TARGETS.KolibriOSDLL THEN
2284
        opt.pic := FALSE
2286
        opt.pic := FALSE
2285
    END;
2287
    END;
2286
 
2288
 
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
2288
        opt.pic := TRUE
2290
        opt.pic := TRUE
2289
    END;
2291
    END;
2290
 
2292
 
2291
    REG.Init(R, push, pop, mov, xchg, NIL, NIL, {eax, ecx, edx}, {});
2293
    REG.Init(R, push, pop, mov, xchg, NIL, NIL, {eax, ecx, edx}, {});
2292
 
2294
 
2293
    prolog(opt.pic, target, opt.stack, dllinit, dllret);
2295
    prolog(opt.pic, target, opt.stack, dllinit, dllret);
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);
2296
 
2298
 
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
2306
        ELF.write(program, outname, sofinit, target = mConst.Target_iELFSO32, FALSE)
2308
        ELF.write(program, outname, sofinit, target = TARGETS.Linux32SO, FALSE)
2307
    END
2309
    END
2308
 
2310
 
2309
END CodeGen;
2311
END CodeGen;
2310
 
2312
 
2311
 
2313
 
2312
PROCEDURE SetProgram* (prog: BIN.PROGRAM);
2314
PROCEDURE SetProgram* (prog: BIN.PROGRAM);
2313
BEGIN
2315
BEGIN
2314
    program := prog;
2316
    program := prog;
2315
    CodeList := LISTS.create(NIL)
2317
    CodeList := LISTS.create(NIL)
2316
END SetProgram;
2318
END SetProgram;
2317
 
2319
 
2318
 
2320
 
2319
END X86.
2321
END X86.