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.>>=>=>>>=>>=>=>=>=>> |