Rev 9847 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
7983 | leency | 1 | (* |
7597 | akron1 | 2 | BSD 2-Clause License |
6613 | leency | 3 | |
9847 | akron1 | 4 | Copyright (c) 2018-2022, Anton Krotov |
7597 | akron1 | 5 | All rights reserved. |
6613 | leency | 6 | *) |
7 | |||
8 | MODULE X86; |
||
9 | |||
7693 | akron1 | 10 | IMPORT IL, REG, UTILS, LISTS, BIN, PE32, KOS, MSCOFF, ELF, PROG, |
8097 | maxcodehac | 11 | CHL := CHUNKLISTS, PATHS, TARGETS, ERRORS; |
6613 | leency | 12 | |
7597 | akron1 | 13 | |
6613 | leency | 14 | CONST |
15 | |||
7597 | akron1 | 16 | eax = REG.R0; ecx = REG.R1; edx = REG.R2; |
6613 | leency | 17 | |
7597 | akron1 | 18 | al = eax; cl = ecx; dl = edx; ah = 4; |
6613 | leency | 19 | |
7597 | akron1 | 20 | ax = eax; cx = ecx; dx = edx; |
6613 | leency | 21 | |
7597 | akron1 | 22 | esp = 4; |
23 | ebp = 5; |
||
6613 | leency | 24 | |
8097 | maxcodehac | 25 | MAX_FR = 7; |
26 | |||
7597 | akron1 | 27 | sete = 94H; setne = 95H; setl = 9CH; setge = 9DH; setle = 9EH; setg = 9FH; setc = 92H; setnc = 93H; |
6613 | leency | 28 | |
7597 | akron1 | 29 | je = 84H; jne = 85H; jl = 8CH; jge = 8DH; jle = 8EH; jg = 8FH; jb = 82H; jnb = 83H; |
6613 | leency | 30 | |
31 | |||
7597 | akron1 | 32 | CODECHUNK = 8; |
6613 | leency | 33 | |
8097 | maxcodehac | 34 | FPR_ERR = 41; |
6613 | leency | 35 | |
8097 | maxcodehac | 36 | |
6613 | leency | 37 | TYPE |
38 | |||
7693 | akron1 | 39 | COMMAND = IL.COMMAND; |
6613 | leency | 40 | |
41 | |||
7597 | akron1 | 42 | ANYCODE = POINTER TO RECORD (LISTS.ITEM) |
6613 | leency | 43 | |
7597 | akron1 | 44 | offset: INTEGER |
6613 | leency | 45 | |
7597 | akron1 | 46 | END; |
6613 | leency | 47 | |
7693 | akron1 | 48 | CODE = POINTER TO RECORD (ANYCODE) |
6613 | leency | 49 | |
7597 | akron1 | 50 | code: ARRAY CODECHUNK OF BYTE; |
51 | length: INTEGER |
||
6613 | leency | 52 | |
7597 | akron1 | 53 | END; |
6613 | leency | 54 | |
7597 | akron1 | 55 | LABEL = POINTER TO RECORD (ANYCODE) |
6613 | leency | 56 | |
7597 | akron1 | 57 | label: INTEGER |
6613 | leency | 58 | |
7597 | akron1 | 59 | END; |
6613 | leency | 60 | |
7597 | akron1 | 61 | JUMP = POINTER TO RECORD (ANYCODE) |
7209 | akron1 | 62 | |
7597 | akron1 | 63 | label, diff: INTEGER; |
64 | short: BOOLEAN |
||
6613 | leency | 65 | |
7597 | akron1 | 66 | END; |
6613 | leency | 67 | |
7597 | akron1 | 68 | JMP = POINTER TO RECORD (JUMP) |
6613 | leency | 69 | |
7597 | akron1 | 70 | END; |
6613 | leency | 71 | |
7597 | akron1 | 72 | JCC = POINTER TO RECORD (JUMP) |
6613 | leency | 73 | |
7597 | akron1 | 74 | jmp: INTEGER |
6613 | leency | 75 | |
76 | END; |
||
77 | |||
7597 | akron1 | 78 | CALL = POINTER TO RECORD (JUMP) |
6613 | leency | 79 | |
7597 | akron1 | 80 | END; |
6613 | leency | 81 | |
7597 | akron1 | 82 | RELOC = POINTER TO RECORD (ANYCODE) |
6613 | leency | 83 | |
7597 | akron1 | 84 | op, value: INTEGER |
6613 | leency | 85 | |
7597 | akron1 | 86 | END; |
6613 | leency | 87 | |
88 | |||
7597 | akron1 | 89 | VAR |
6613 | leency | 90 | |
7597 | akron1 | 91 | R: REG.REGS; |
6613 | leency | 92 | |
7597 | akron1 | 93 | program: BIN.PROGRAM; |
6613 | leency | 94 | |
7597 | akron1 | 95 | CodeList: LISTS.LIST; |
6613 | leency | 96 | |
9873 | akron1 | 97 | tcount, LocVarSize, mainLocVarSize: INTEGER; |
6613 | leency | 98 | |
8097 | maxcodehac | 99 | FR: ARRAY 1000 OF INTEGER; |
7693 | akron1 | 100 | |
8097 | maxcodehac | 101 | fname: PATHS.PATH; |
102 | |||
9873 | akron1 | 103 | FltConstLabel, mainFltConstLabel: LABEL; |
8097 | maxcodehac | 104 | |
9873 | akron1 | 105 | |
7597 | akron1 | 106 | PROCEDURE OutByte* (n: BYTE); |
107 | VAR |
||
7693 | akron1 | 108 | c: CODE; |
7597 | akron1 | 109 | last: ANYCODE; |
6613 | leency | 110 | |
7597 | akron1 | 111 | BEGIN |
112 | last := CodeList.last(ANYCODE); |
||
6613 | leency | 113 | |
7693 | akron1 | 114 | IF (last IS CODE) & (last(CODE).length < CODECHUNK) THEN |
115 | c := last(CODE); |
||
7597 | akron1 | 116 | c.code[c.length] := n; |
117 | INC(c.length) |
||
118 | ELSE |
||
119 | NEW(c); |
||
120 | c.code[0] := n; |
||
121 | c.length := 1; |
||
122 | LISTS.push(CodeList, c) |
||
123 | END |
||
6613 | leency | 124 | |
7597 | akron1 | 125 | END OutByte; |
6613 | leency | 126 | |
127 | |||
7597 | akron1 | 128 | PROCEDURE OutInt (n: INTEGER); |
6613 | leency | 129 | BEGIN |
7983 | leency | 130 | OutByte(n MOD 256); |
7693 | akron1 | 131 | OutByte(UTILS.Byte(n, 1)); |
132 | OutByte(UTILS.Byte(n, 2)); |
||
133 | OutByte(UTILS.Byte(n, 3)) |
||
7597 | akron1 | 134 | END OutInt; |
6613 | leency | 135 | |
136 | |||
7597 | akron1 | 137 | PROCEDURE OutByte2 (a, b: BYTE); |
6613 | leency | 138 | BEGIN |
7597 | akron1 | 139 | OutByte(a); |
140 | OutByte(b) |
||
141 | END OutByte2; |
||
6613 | leency | 142 | |
143 | |||
7597 | akron1 | 144 | PROCEDURE OutByte3 (a, b, c: BYTE); |
6613 | leency | 145 | BEGIN |
7597 | akron1 | 146 | OutByte(a); |
147 | OutByte(b); |
||
148 | OutByte(c) |
||
149 | END OutByte3; |
||
6613 | leency | 150 | |
151 | |||
7597 | akron1 | 152 | PROCEDURE OutWord (n: INTEGER); |
6613 | leency | 153 | BEGIN |
7597 | akron1 | 154 | ASSERT((0 <= n) & (n <= 65535)); |
155 | OutByte2(n MOD 256, n DIV 256) |
||
156 | END OutWord; |
||
6613 | leency | 157 | |
158 | |||
8097 | maxcodehac | 159 | PROCEDURE isByte* (n: INTEGER): BOOLEAN; |
7597 | akron1 | 160 | RETURN (-128 <= n) & (n <= 127) |
161 | END isByte; |
||
162 | |||
163 | |||
164 | PROCEDURE short (n: INTEGER): INTEGER; |
||
165 | RETURN 2 * ORD(isByte(n)) |
||
166 | END short; |
||
167 | |||
168 | |||
169 | PROCEDURE long (n: INTEGER): INTEGER; |
||
170 | RETURN 40H * ORD(~isByte(n)) |
||
171 | END long; |
||
172 | |||
173 | |||
174 | PROCEDURE OutIntByte (n: INTEGER); |
||
6613 | leency | 175 | BEGIN |
7597 | akron1 | 176 | IF isByte(n) THEN |
7983 | leency | 177 | OutByte(n MOD 256) |
7597 | akron1 | 178 | ELSE |
179 | OutInt(n) |
||
180 | END |
||
181 | END OutIntByte; |
||
6613 | leency | 182 | |
7597 | akron1 | 183 | |
184 | PROCEDURE shift* (op, reg: INTEGER); |
||
6613 | leency | 185 | BEGIN |
7597 | akron1 | 186 | CASE op OF |
7693 | akron1 | 187 | |IL.opASR, IL.opASR1, IL.opASR2: OutByte(0F8H + reg) |
188 | |IL.opROR, IL.opROR1, IL.opROR2: OutByte(0C8H + reg) |
||
189 | |IL.opLSL, IL.opLSL1, IL.opLSL2: OutByte(0E0H + reg) |
||
190 | |IL.opLSR, IL.opLSR1, IL.opLSR2: OutByte(0E8H + reg) |
||
7597 | akron1 | 191 | END |
192 | END shift; |
||
6613 | leency | 193 | |
7597 | akron1 | 194 | |
8097 | maxcodehac | 195 | PROCEDURE oprr (op: BYTE; reg1, reg2: INTEGER); (* op reg1, reg2 *) |
6613 | leency | 196 | BEGIN |
8097 | maxcodehac | 197 | OutByte2(op, 0C0H + 8 * reg2 + reg1) |
198 | END oprr; |
||
199 | |||
200 | |||
201 | PROCEDURE mov (reg1, reg2: INTEGER); (* mov reg1, reg2 *) |
||
202 | BEGIN |
||
203 | oprr(89H, reg1, reg2) |
||
7597 | akron1 | 204 | END mov; |
6613 | leency | 205 | |
7597 | akron1 | 206 | |
8097 | maxcodehac | 207 | PROCEDURE xchg (reg1, reg2: INTEGER); (* xchg reg1, reg2 *) |
6613 | leency | 208 | BEGIN |
8097 | maxcodehac | 209 | IF eax IN {reg1, reg2} THEN |
210 | OutByte(90H + reg1 + reg2) |
||
211 | ELSE |
||
212 | oprr(87H, reg1, reg2) |
||
7597 | akron1 | 213 | END |
214 | END xchg; |
||
6613 | leency | 215 | |
7597 | akron1 | 216 | |
217 | PROCEDURE pop (reg: INTEGER); |
||
6613 | leency | 218 | BEGIN |
7983 | leency | 219 | OutByte(58H + reg) (* pop reg *) |
7597 | akron1 | 220 | END pop; |
6613 | leency | 221 | |
7597 | akron1 | 222 | |
223 | PROCEDURE push (reg: INTEGER); |
||
6613 | leency | 224 | BEGIN |
7983 | leency | 225 | OutByte(50H + reg) (* push reg *) |
7597 | akron1 | 226 | END push; |
6613 | leency | 227 | |
7597 | akron1 | 228 | |
8097 | maxcodehac | 229 | PROCEDURE xor (reg1, reg2: INTEGER); (* xor reg1, reg2 *) |
230 | BEGIN |
||
231 | oprr(31H, reg1, reg2) |
||
232 | END xor; |
||
233 | |||
234 | |||
7597 | akron1 | 235 | PROCEDURE movrc (reg, n: INTEGER); |
6613 | leency | 236 | BEGIN |
8097 | maxcodehac | 237 | IF n = 0 THEN |
238 | xor(reg, reg) |
||
239 | ELSE |
||
240 | OutByte(0B8H + reg); (* mov reg, n *) |
||
241 | OutInt(n) |
||
242 | END |
||
7597 | akron1 | 243 | END movrc; |
6613 | leency | 244 | |
7597 | akron1 | 245 | |
8097 | maxcodehac | 246 | PROCEDURE pushc* (n: INTEGER); |
6613 | leency | 247 | BEGIN |
7983 | leency | 248 | OutByte(68H + short(n)); (* push n *) |
7597 | akron1 | 249 | OutIntByte(n) |
250 | END pushc; |
||
6613 | leency | 251 | |
7597 | akron1 | 252 | |
253 | PROCEDURE test (reg: INTEGER); |
||
6613 | leency | 254 | BEGIN |
7983 | leency | 255 | OutByte2(85H, 0C0H + reg * 9) (* test reg, reg *) |
7597 | akron1 | 256 | END test; |
6613 | leency | 257 | |
7597 | akron1 | 258 | |
259 | PROCEDURE neg (reg: INTEGER); |
||
6613 | leency | 260 | BEGIN |
7983 | leency | 261 | OutByte2(0F7H, 0D8H + reg) (* neg reg *) |
7597 | akron1 | 262 | END neg; |
6613 | leency | 263 | |
7597 | akron1 | 264 | |
265 | PROCEDURE not (reg: INTEGER); |
||
6613 | leency | 266 | BEGIN |
7983 | leency | 267 | OutByte2(0F7H, 0D0H + reg) (* not reg *) |
7597 | akron1 | 268 | END not; |
6613 | leency | 269 | |
7597 | akron1 | 270 | |
8097 | maxcodehac | 271 | PROCEDURE add (reg1, reg2: INTEGER); (* add reg1, reg2 *) |
6613 | leency | 272 | BEGIN |
8097 | maxcodehac | 273 | oprr(01H, reg1, reg2) |
7597 | akron1 | 274 | END add; |
6613 | leency | 275 | |
7597 | akron1 | 276 | |
8097 | maxcodehac | 277 | PROCEDURE oprc* (op, reg, n: INTEGER); |
6613 | leency | 278 | BEGIN |
8097 | maxcodehac | 279 | IF (reg = eax) & ~isByte(n) THEN |
280 | CASE op OF |
||
281 | |0C0H: op := 05H (* add *) |
||
282 | |0E8H: op := 2DH (* sub *) |
||
283 | |0F8H: op := 3DH (* cmp *) |
||
284 | |0E0H: op := 25H (* and *) |
||
285 | |0C8H: op := 0DH (* or *) |
||
286 | |0F0H: op := 35H (* xor *) |
||
287 | END; |
||
288 | OutByte(op); |
||
289 | OutInt(n) |
||
290 | ELSE |
||
291 | OutByte2(81H + short(n), op + reg MOD 8); |
||
292 | OutIntByte(n) |
||
293 | END |
||
294 | END oprc; |
||
295 | |||
296 | |||
297 | PROCEDURE andrc (reg, n: INTEGER); (* and reg, n *) |
||
298 | BEGIN |
||
299 | oprc(0E0H, reg, n) |
||
7597 | akron1 | 300 | END andrc; |
6613 | leency | 301 | |
7597 | akron1 | 302 | |
8097 | maxcodehac | 303 | PROCEDURE orrc (reg, n: INTEGER); (* or reg, n *) |
6613 | leency | 304 | BEGIN |
8097 | maxcodehac | 305 | oprc(0C8H, reg, n) |
7597 | akron1 | 306 | END orrc; |
6613 | leency | 307 | |
7597 | akron1 | 308 | |
8097 | maxcodehac | 309 | PROCEDURE xorrc (reg, n: INTEGER); (* xor reg, n *) |
6613 | leency | 310 | BEGIN |
8097 | maxcodehac | 311 | oprc(0F0H, reg, n) |
312 | END xorrc; |
||
6613 | leency | 313 | |
7597 | akron1 | 314 | |
8097 | maxcodehac | 315 | PROCEDURE addrc (reg, n: INTEGER); (* add reg, n *) |
6613 | leency | 316 | BEGIN |
8097 | maxcodehac | 317 | oprc(0C0H, reg, n) |
318 | END addrc; |
||
6613 | leency | 319 | |
7597 | akron1 | 320 | |
8097 | maxcodehac | 321 | PROCEDURE subrc (reg, n: INTEGER); (* sub reg, n *) |
6613 | leency | 322 | BEGIN |
8097 | maxcodehac | 323 | oprc(0E8H, reg, n) |
324 | END subrc; |
||
6613 | leency | 325 | |
7597 | akron1 | 326 | |
8097 | maxcodehac | 327 | PROCEDURE cmprc (reg, n: INTEGER); (* cmp reg, n *) |
6613 | leency | 328 | BEGIN |
7983 | leency | 329 | IF n = 0 THEN |
330 | test(reg) |
||
331 | ELSE |
||
8097 | maxcodehac | 332 | oprc(0F8H, reg, n) |
7983 | leency | 333 | END |
7597 | akron1 | 334 | END cmprc; |
6613 | leency | 335 | |
7597 | akron1 | 336 | |
8097 | maxcodehac | 337 | PROCEDURE cmprr (reg1, reg2: INTEGER); (* cmp reg1, reg2 *) |
6613 | leency | 338 | BEGIN |
8097 | maxcodehac | 339 | oprr(39H, reg1, reg2) |
340 | END cmprr; |
||
6613 | leency | 341 | |
7597 | akron1 | 342 | |
8097 | maxcodehac | 343 | PROCEDURE setcc* (cc, reg: INTEGER); (* setcc reg *) |
7667 | akron1 | 344 | BEGIN |
8097 | maxcodehac | 345 | IF reg >= 8 THEN |
346 | OutByte(41H) |
||
347 | END; |
||
348 | OutByte3(0FH, cc, 0C0H + reg MOD 8) |
||
349 | END setcc; |
||
7667 | akron1 | 350 | |
351 | |||
7983 | leency | 352 | PROCEDURE ret*; |
353 | BEGIN |
||
354 | OutByte(0C3H) |
||
355 | END ret; |
||
356 | |||
357 | |||
7597 | akron1 | 358 | PROCEDURE drop; |
6613 | leency | 359 | BEGIN |
7597 | akron1 | 360 | REG.Drop(R) |
361 | END drop; |
||
6613 | leency | 362 | |
7597 | akron1 | 363 | |
7693 | akron1 | 364 | PROCEDURE GetAnyReg (): INTEGER; |
365 | RETURN REG.GetAnyReg(R) |
||
366 | END GetAnyReg; |
||
7597 | akron1 | 367 | |
6613 | leency | 368 | |
7597 | akron1 | 369 | PROCEDURE cond* (op: INTEGER): INTEGER; |
370 | VAR |
||
371 | res: INTEGER; |
||
6613 | leency | 372 | |
373 | BEGIN |
||
7597 | akron1 | 374 | CASE op OF |
7693 | akron1 | 375 | |IL.opGT, IL.opGTC: res := jg |
376 | |IL.opGE, IL.opGEC: res := jge |
||
377 | |IL.opLT, IL.opLTC: res := jl |
||
378 | |IL.opLE, IL.opLEC: res := jle |
||
379 | |IL.opEQ, IL.opEQC: res := je |
||
380 | |IL.opNE, IL.opNEC: res := jne |
||
7597 | akron1 | 381 | END |
6613 | leency | 382 | |
7597 | akron1 | 383 | RETURN res |
384 | END cond; |
||
385 | |||
386 | |||
7693 | akron1 | 387 | PROCEDURE inv0* (op: INTEGER): INTEGER; |
388 | RETURN ORD(BITS(op) / {0}) |
||
389 | END inv0; |
||
6613 | leency | 390 | |
391 | |||
7597 | akron1 | 392 | PROCEDURE Reloc* (op, value: INTEGER); |
393 | VAR |
||
394 | reloc: RELOC; |
||
6613 | leency | 395 | |
396 | BEGIN |
||
7597 | akron1 | 397 | NEW(reloc); |
398 | reloc.op := op; |
||
399 | reloc.value := value; |
||
400 | LISTS.push(CodeList, reloc) |
||
401 | END Reloc; |
||
6613 | leency | 402 | |
403 | |||
9873 | akron1 | 404 | PROCEDURE PushFlt (label: LABEL; value: REAL); |
405 | VAR |
||
406 | a, b, n: INTEGER; |
||
407 | |||
408 | |||
409 | PROCEDURE pushImm (label: LABEL; value: INTEGER); |
||
410 | VAR |
||
411 | c: CODE; |
||
412 | i: INTEGER; |
||
413 | |||
414 | BEGIN |
||
415 | NEW(c); |
||
416 | IF isByte(value) THEN |
||
417 | c.code[0] := 6AH; |
||
418 | c.code[1] := value MOD 256; |
||
419 | c.length := 2 |
||
420 | ELSE |
||
421 | c.code[0] := 68H; |
||
422 | FOR i := 1 TO 4 DO |
||
423 | c.code[i] := UTILS.Byte(value, i - 1) |
||
424 | END; |
||
425 | c.length := 5 |
||
426 | END; |
||
427 | LISTS.insertL(CodeList, label, c) |
||
428 | END pushImm; |
||
429 | |||
430 | |||
431 | BEGIN |
||
432 | n := UTILS.splitf(value, a, b); |
||
433 | pushImm(label, b); |
||
434 | pushImm(label, a) |
||
435 | END PushFlt; |
||
436 | |||
437 | |||
7597 | akron1 | 438 | PROCEDURE jcc* (cc, label: INTEGER); |
439 | VAR |
||
440 | j: JCC; |
||
6613 | leency | 441 | |
442 | BEGIN |
||
7597 | akron1 | 443 | NEW(j); |
444 | j.label := label; |
||
445 | j.jmp := cc; |
||
446 | j.short := FALSE; |
||
447 | LISTS.push(CodeList, j) |
||
448 | END jcc; |
||
6613 | leency | 449 | |
450 | |||
7597 | akron1 | 451 | PROCEDURE jmp* (label: INTEGER); |
452 | VAR |
||
453 | j: JMP; |
||
6613 | leency | 454 | |
455 | BEGIN |
||
7597 | akron1 | 456 | NEW(j); |
457 | j.label := label; |
||
458 | j.short := FALSE; |
||
459 | LISTS.push(CodeList, j) |
||
460 | END jmp; |
||
6613 | leency | 461 | |
462 | |||
7597 | akron1 | 463 | PROCEDURE call* (label: INTEGER); |
464 | VAR |
||
465 | c: CALL; |
||
6613 | leency | 466 | |
467 | BEGIN |
||
7597 | akron1 | 468 | NEW(c); |
469 | c.label := label; |
||
470 | c.short := TRUE; |
||
471 | LISTS.push(CodeList, c) |
||
472 | END call; |
||
6613 | leency | 473 | |
474 | |||
7597 | akron1 | 475 | PROCEDURE Pic (reg, opcode, value: INTEGER); |
6613 | leency | 476 | BEGIN |
7983 | leency | 477 | OutByte(0E8H); OutInt(0); (* call L |
478 | L: *) |
||
7597 | akron1 | 479 | pop(reg); |
7983 | leency | 480 | OutByte2(081H, 0C0H + reg); (* add reg, ... *) |
7597 | akron1 | 481 | Reloc(opcode, value) |
482 | END Pic; |
||
6613 | leency | 483 | |
484 | |||
7597 | akron1 | 485 | PROCEDURE CallRTL (pic: BOOLEAN; proc: INTEGER); |
486 | VAR |
||
487 | label: INTEGER; |
||
488 | reg1: INTEGER; |
||
6613 | leency | 489 | |
490 | BEGIN |
||
7693 | akron1 | 491 | label := IL.codes.rtl[proc]; |
6613 | leency | 492 | |
7597 | akron1 | 493 | IF label < 0 THEN |
494 | label := -label; |
||
495 | IF pic THEN |
||
7693 | akron1 | 496 | reg1 := GetAnyReg(); |
7597 | akron1 | 497 | Pic(reg1, BIN.PICIMP, label); |
7983 | leency | 498 | OutByte2(0FFH, 010H + reg1); (* call dword[reg1] *) |
7597 | akron1 | 499 | drop |
500 | ELSE |
||
7983 | leency | 501 | OutByte2(0FFH, 015H); (* call dword[label] *) |
7597 | akron1 | 502 | Reloc(BIN.RIMP, label) |
503 | END |
||
504 | ELSE |
||
505 | call(label) |
||
506 | END |
||
507 | END CallRTL; |
||
6613 | leency | 508 | |
509 | |||
7597 | akron1 | 510 | PROCEDURE SetLabel* (label: INTEGER); |
511 | VAR |
||
512 | L: LABEL; |
||
6613 | leency | 513 | |
514 | BEGIN |
||
7597 | akron1 | 515 | NEW(L); |
516 | L.label := label; |
||
517 | LISTS.push(CodeList, L) |
||
518 | END SetLabel; |
||
6613 | leency | 519 | |
520 | |||
7597 | akron1 | 521 | PROCEDURE fixup*; |
522 | VAR |
||
523 | code: ANYCODE; |
||
524 | count, i: INTEGER; |
||
525 | shorted: BOOLEAN; |
||
526 | jump: JUMP; |
||
6613 | leency | 527 | |
528 | BEGIN |
||
529 | |||
7597 | akron1 | 530 | REPEAT |
6613 | leency | 531 | |
7597 | akron1 | 532 | shorted := FALSE; |
533 | count := 0; |
||
6613 | leency | 534 | |
7597 | akron1 | 535 | code := CodeList.first(ANYCODE); |
536 | WHILE code # NIL DO |
||
537 | code.offset := count; |
||
6613 | leency | 538 | |
7597 | akron1 | 539 | CASE code OF |
7693 | akron1 | 540 | |CODE: INC(count, code.length) |
7597 | akron1 | 541 | |LABEL: BIN.SetLabel(program, code.label, count) |
542 | |JMP: IF code.short THEN INC(count, 2) ELSE INC(count, 5) END; code.offset := count |
||
543 | |JCC: IF code.short THEN INC(count, 2) ELSE INC(count, 6) END; code.offset := count |
||
544 | |CALL: INC(count, 5); code.offset := count |
||
545 | |RELOC: INC(count, 4) |
||
546 | END; |
||
6613 | leency | 547 | |
7597 | akron1 | 548 | code := code.next(ANYCODE) |
549 | END; |
||
6613 | leency | 550 | |
7597 | akron1 | 551 | code := CodeList.first(ANYCODE); |
552 | WHILE code # NIL DO |
||
6613 | leency | 553 | |
7597 | akron1 | 554 | IF code IS JUMP THEN |
555 | jump := code(JUMP); |
||
556 | jump.diff := BIN.GetLabel(program, jump.label) - code.offset; |
||
557 | IF ~jump.short & isByte(jump.diff) THEN |
||
558 | jump.short := TRUE; |
||
559 | shorted := TRUE |
||
560 | END |
||
561 | END; |
||
6613 | leency | 562 | |
7597 | akron1 | 563 | code := code.next(ANYCODE) |
564 | END |
||
6613 | leency | 565 | |
7597 | akron1 | 566 | UNTIL ~shorted; |
6613 | leency | 567 | |
7597 | akron1 | 568 | code := CodeList.first(ANYCODE); |
569 | WHILE code # NIL DO |
||
6613 | leency | 570 | |
7597 | akron1 | 571 | CASE code OF |
6613 | leency | 572 | |
7693 | akron1 | 573 | |CODE: |
7597 | akron1 | 574 | FOR i := 0 TO code.length - 1 DO |
575 | BIN.PutCode(program, code.code[i]) |
||
576 | END |
||
6613 | leency | 577 | |
7597 | akron1 | 578 | |LABEL: |
6613 | leency | 579 | |
7597 | akron1 | 580 | |JMP: |
581 | IF code.short THEN |
||
582 | BIN.PutCode(program, 0EBH); |
||
7983 | leency | 583 | BIN.PutCode(program, code.diff MOD 256) |
7597 | akron1 | 584 | ELSE |
585 | BIN.PutCode(program, 0E9H); |
||
586 | BIN.PutCode32LE(program, code.diff) |
||
587 | END |
||
6613 | leency | 588 | |
7597 | akron1 | 589 | |JCC: |
590 | IF code.short THEN |
||
591 | BIN.PutCode(program, code.jmp - 16); |
||
7983 | leency | 592 | BIN.PutCode(program, code.diff MOD 256) |
7597 | akron1 | 593 | ELSE |
594 | BIN.PutCode(program, 0FH); |
||
595 | BIN.PutCode(program, code.jmp); |
||
596 | BIN.PutCode32LE(program, code.diff) |
||
597 | END |
||
6613 | leency | 598 | |
7597 | akron1 | 599 | |CALL: |
600 | BIN.PutCode(program, 0E8H); |
||
601 | BIN.PutCode32LE(program, code.diff) |
||
6613 | leency | 602 | |
7597 | akron1 | 603 | |RELOC: |
604 | BIN.PutReloc(program, code.op); |
||
605 | BIN.PutCode32LE(program, code.value) |
||
6613 | leency | 606 | |
7597 | akron1 | 607 | END; |
608 | |||
609 | code := code.next(ANYCODE) |
||
6613 | leency | 610 | END |
611 | |||
7597 | akron1 | 612 | END fixup; |
6613 | leency | 613 | |
614 | |||
7597 | akron1 | 615 | PROCEDURE UnOp (VAR reg: INTEGER); |
6613 | leency | 616 | BEGIN |
7597 | akron1 | 617 | REG.UnOp(R, reg) |
618 | END UnOp; |
||
6613 | leency | 619 | |
620 | |||
7597 | akron1 | 621 | PROCEDURE BinOp (VAR reg1, reg2: INTEGER); |
6613 | leency | 622 | BEGIN |
7597 | akron1 | 623 | REG.BinOp(R, reg1, reg2) |
624 | END BinOp; |
||
6613 | leency | 625 | |
626 | |||
7597 | akron1 | 627 | PROCEDURE PushAll (NumberOfParameters: INTEGER); |
6613 | leency | 628 | BEGIN |
7597 | akron1 | 629 | REG.PushAll(R); |
7693 | akron1 | 630 | DEC(R.pushed, NumberOfParameters) |
7597 | akron1 | 631 | END PushAll; |
6613 | leency | 632 | |
633 | |||
7597 | akron1 | 634 | PROCEDURE NewLabel (): INTEGER; |
6613 | leency | 635 | BEGIN |
7597 | akron1 | 636 | BIN.NewLabel(program) |
7693 | akron1 | 637 | RETURN IL.NewLabel() |
7597 | akron1 | 638 | END NewLabel; |
6613 | leency | 639 | |
640 | |||
7597 | akron1 | 641 | PROCEDURE GetRegA; |
6613 | leency | 642 | BEGIN |
7597 | akron1 | 643 | ASSERT(REG.GetReg(R, eax)) |
644 | END GetRegA; |
||
6613 | leency | 645 | |
646 | |||
7983 | leency | 647 | PROCEDURE fcmp; |
648 | BEGIN |
||
649 | GetRegA; |
||
650 | OutByte2(0DAH, 0E9H); (* fucompp *) |
||
651 | OutByte3(09BH, 0DFH, 0E0H); (* fstsw ax *) |
||
652 | OutByte(09EH); (* sahf *) |
||
8097 | maxcodehac | 653 | OutByte(0B8H); OutInt(0) (* mov eax, 0 *) |
7983 | leency | 654 | END fcmp; |
655 | |||
656 | |||
657 | PROCEDURE movzx* (reg1, reg2, offs: INTEGER; word: BOOLEAN); (* movzx reg1, byte/word[reg2 + offs] *) |
||
658 | VAR |
||
659 | b: BYTE; |
||
660 | |||
661 | BEGIN |
||
662 | OutByte2(0FH, 0B6H + ORD(word)); |
||
663 | IF (offs = 0) & (reg2 # ebp) THEN |
||
664 | b := 0 |
||
665 | ELSE |
||
666 | b := 40H + long(offs) |
||
667 | END; |
||
668 | OutByte(b + (reg1 MOD 8) * 8 + reg2 MOD 8); |
||
669 | IF reg2 = esp THEN |
||
670 | OutByte(24H) |
||
671 | END; |
||
672 | IF b # 0 THEN |
||
673 | OutIntByte(offs) |
||
674 | END |
||
675 | END movzx; |
||
676 | |||
677 | |||
678 | PROCEDURE _movrm* (reg1, reg2, offs, size: INTEGER; mr: BOOLEAN); |
||
679 | VAR |
||
680 | b: BYTE; |
||
681 | |||
682 | BEGIN |
||
683 | IF size = 16 THEN |
||
684 | OutByte(66H) |
||
685 | END; |
||
686 | IF (reg1 >= 8) OR (reg2 >= 8) OR (size = 64) THEN |
||
687 | OutByte(40H + reg2 DIV 8 + 4 * (reg1 DIV 8) + 8 * ORD(size = 64)) |
||
688 | END; |
||
689 | OutByte(8BH - 2 * ORD(mr) - ORD(size = 8)); |
||
690 | IF (offs = 0) & (reg2 # ebp) THEN |
||
691 | b := 0 |
||
692 | ELSE |
||
693 | b := 40H + long(offs) |
||
694 | END; |
||
695 | OutByte(b + (reg1 MOD 8) * 8 + reg2 MOD 8); |
||
696 | IF reg2 = esp THEN |
||
697 | OutByte(24H) |
||
698 | END; |
||
699 | IF b # 0 THEN |
||
700 | OutIntByte(offs) |
||
701 | END |
||
702 | END _movrm; |
||
703 | |||
704 | |||
9847 | akron1 | 705 | PROCEDURE movmr (reg1, offs, reg2: INTEGER); (* mov dword[reg1+offs], reg2 *) |
7983 | leency | 706 | BEGIN |
707 | _movrm(reg2, reg1, offs, 32, TRUE) |
||
708 | END movmr; |
||
709 | |||
710 | |||
711 | PROCEDURE movrm (reg1, reg2, offs: INTEGER); (* mov reg1, dword[reg2 + offs] *) |
||
712 | BEGIN |
||
713 | _movrm(reg1, reg2, offs, 32, FALSE) |
||
714 | END movrm; |
||
715 | |||
716 | |||
717 | PROCEDURE movmr8* (reg1, offs, reg2: INTEGER); (* mov byte[reg1+offs], reg2_8 *) |
||
718 | BEGIN |
||
719 | _movrm(reg2, reg1, offs, 8, TRUE) |
||
720 | END movmr8; |
||
721 | |||
722 | |||
723 | PROCEDURE movrm8* (reg1, reg2, offs: INTEGER); (* mov reg1_8, byte[reg2+offs] *) |
||
724 | BEGIN |
||
725 | _movrm(reg1, reg2, offs, 8, FALSE) |
||
726 | END movrm8; |
||
727 | |||
728 | |||
729 | PROCEDURE movmr16* (reg1, offs, reg2: INTEGER); (* mov word[reg1+offs], reg2_16 *) |
||
730 | BEGIN |
||
731 | _movrm(reg2, reg1, offs, 16, TRUE) |
||
732 | END movmr16; |
||
733 | |||
734 | |||
735 | PROCEDURE movrm16* (reg1, reg2, offs: INTEGER); (* mov reg1_16, word[reg2+offs] *) |
||
736 | BEGIN |
||
737 | _movrm(reg1, reg2, offs, 16, FALSE) |
||
738 | END movrm16; |
||
739 | |||
740 | |||
741 | PROCEDURE pushm* (reg, offs: INTEGER); (* push qword[reg+offs] *) |
||
742 | VAR |
||
743 | b: BYTE; |
||
744 | |||
745 | BEGIN |
||
746 | IF reg >= 8 THEN |
||
747 | OutByte(41H) |
||
748 | END; |
||
749 | OutByte(0FFH); |
||
750 | IF (offs = 0) & (reg # ebp) THEN |
||
751 | b := 30H |
||
752 | ELSE |
||
753 | b := 70H + long(offs) |
||
754 | END; |
||
755 | OutByte(b + reg MOD 8); |
||
756 | IF reg = esp THEN |
||
757 | OutByte(24H) |
||
758 | END; |
||
759 | IF b # 30H THEN |
||
760 | OutIntByte(offs) |
||
761 | END |
||
762 | END pushm; |
||
763 | |||
764 | |||
9873 | akron1 | 765 | PROCEDURE LoadFltConst (value: REAL); |
766 | BEGIN |
||
767 | PushFlt(FltConstLabel, value); |
||
768 | INC(LocVarSize, 8); |
||
769 | IF FltConstLabel = mainFltConstLabel THEN |
||
770 | mainLocVarSize := LocVarSize |
||
771 | END; |
||
772 | OutByte2(0DDH, 045H + long(-LocVarSize)); (* fld qword[ebp - LocVarSize] *) |
||
773 | OutIntByte(-LocVarSize) |
||
774 | END LoadFltConst; |
||
775 | |||
776 | |||
7696 | akron1 | 777 | PROCEDURE translate (pic: BOOLEAN; stroffs: INTEGER); |
7597 | akron1 | 778 | VAR |
7983 | leency | 779 | cmd, next: COMMAND; |
6613 | leency | 780 | |
9847 | akron1 | 781 | reg1, reg2, reg3, fr: INTEGER; |
6613 | leency | 782 | |
9873 | akron1 | 783 | n, a, label, cc: INTEGER; |
6613 | leency | 784 | |
7693 | akron1 | 785 | opcode, param1, param2: INTEGER; |
6613 | leency | 786 | |
7597 | akron1 | 787 | float: REAL; |
6613 | leency | 788 | |
789 | BEGIN |
||
7696 | akron1 | 790 | cmd := IL.codes.commands.first(COMMAND); |
6613 | leency | 791 | |
8097 | maxcodehac | 792 | fr := -1; |
793 | |||
7597 | akron1 | 794 | WHILE cmd # NIL DO |
6613 | leency | 795 | |
7597 | akron1 | 796 | param1 := cmd.param1; |
797 | param2 := cmd.param2; |
||
6613 | leency | 798 | |
7693 | akron1 | 799 | opcode := cmd.opcode; |
6613 | leency | 800 | |
7693 | akron1 | 801 | CASE opcode OF |
802 | |||
803 | |IL.opJMP: |
||
7597 | akron1 | 804 | jmp(param1) |
6613 | leency | 805 | |
7693 | akron1 | 806 | |IL.opCALL: |
7597 | akron1 | 807 | call(param1) |
6613 | leency | 808 | |
7693 | akron1 | 809 | |IL.opCALLI: |
7597 | akron1 | 810 | IF pic THEN |
7693 | akron1 | 811 | reg1 := GetAnyReg(); |
7597 | akron1 | 812 | Pic(reg1, BIN.PICIMP, param1); |
7983 | leency | 813 | OutByte2(0FFH, 010H + reg1); (* call dword[reg1] *) |
7597 | akron1 | 814 | drop |
815 | ELSE |
||
7983 | leency | 816 | OutByte2(0FFH, 015H); (* call dword[L] *) |
7597 | akron1 | 817 | Reloc(BIN.RIMP, param1) |
818 | END |
||
6613 | leency | 819 | |
7693 | akron1 | 820 | |IL.opCALLP: |
7597 | akron1 | 821 | UnOp(reg1); |
7983 | leency | 822 | OutByte2(0FFH, 0D0H + reg1); (* call reg1 *) |
7597 | akron1 | 823 | drop; |
824 | ASSERT(R.top = -1) |
||
6613 | leency | 825 | |
9847 | akron1 | 826 | |IL.opFASTCALL: |
827 | IF param2 = 1 THEN |
||
828 | pop(ecx) |
||
829 | ELSIF param2 = 2 THEN |
||
830 | pop(ecx); |
||
831 | pop(edx) |
||
832 | END |
||
833 | |||
7693 | akron1 | 834 | |IL.opPRECALL: |
8097 | maxcodehac | 835 | PushAll(0); |
836 | IF (param2 # 0) & (fr >= 0) THEN |
||
7597 | akron1 | 837 | subrc(esp, 8) |
838 | END; |
||
8097 | maxcodehac | 839 | INC(FR[0]); |
840 | FR[FR[0]] := fr + 1; |
||
841 | WHILE fr >= 0 DO |
||
7597 | akron1 | 842 | subrc(esp, 8); |
7983 | leency | 843 | OutByte3(0DDH, 01CH, 024H); (* fstp qword[esp] *) |
8097 | maxcodehac | 844 | DEC(fr) |
7597 | akron1 | 845 | END; |
8097 | maxcodehac | 846 | ASSERT(fr = -1) |
6613 | leency | 847 | |
7693 | akron1 | 848 | |IL.opALIGN16: |
7597 | akron1 | 849 | ASSERT(eax IN R.regs); |
850 | mov(eax, esp); |
||
851 | andrc(esp, -16); |
||
852 | n := (3 - param2 MOD 4) * 4; |
||
853 | IF n > 0 THEN |
||
854 | subrc(esp, n) |
||
855 | END; |
||
856 | push(eax) |
||
857 | |||
8097 | maxcodehac | 858 | |IL.opRESF, IL.opRES: |
7597 | akron1 | 859 | ASSERT(R.top = -1); |
8097 | maxcodehac | 860 | ASSERT(fr = -1); |
861 | n := FR[FR[0]]; DEC(FR[0]); |
||
7597 | akron1 | 862 | |
8097 | maxcodehac | 863 | IF opcode = IL.opRESF THEN |
864 | INC(fr); |
||
865 | IF n > 0 THEN |
||
866 | OutByte3(0DDH, 5CH + long(n * 8), 24H); |
||
867 | OutIntByte(n * 8); (* fstp qword[esp + n*8] *) |
||
868 | DEC(fr); |
||
869 | INC(n) |
||
870 | END; |
||
871 | |||
872 | IF fr + n > MAX_FR THEN |
||
873 | ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
||
874 | END |
||
875 | ELSE |
||
876 | GetRegA |
||
7597 | akron1 | 877 | END; |
878 | |||
879 | WHILE n > 0 DO |
||
7983 | leency | 880 | OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *) |
7597 | akron1 | 881 | addrc(esp, 8); |
8097 | maxcodehac | 882 | INC(fr); |
7597 | akron1 | 883 | DEC(n) |
884 | END |
||
885 | |||
7693 | akron1 | 886 | |IL.opENTER: |
7597 | akron1 | 887 | ASSERT(R.top = -1); |
888 | |||
889 | SetLabel(param1); |
||
890 | |||
9847 | akron1 | 891 | IF cmd.param3 > 0 THEN |
892 | pop(eax); |
||
893 | IF cmd.param3 >= 2 THEN |
||
894 | push(edx) |
||
895 | END; |
||
896 | push(ecx); |
||
897 | push(eax) |
||
898 | END; |
||
899 | |||
7597 | akron1 | 900 | push(ebp); |
901 | mov(ebp, esp); |
||
902 | |||
903 | n := param2; |
||
904 | IF n > 4 THEN |
||
905 | movrc(ecx, n); |
||
7983 | leency | 906 | pushc(0); (* L: push 0 *) |
907 | OutByte2(0E2H, 0FCH) (* loop L *) |
||
7597 | akron1 | 908 | ELSE |
909 | WHILE n > 0 DO |
||
910 | pushc(0); |
||
911 | DEC(n) |
||
912 | END |
||
9873 | akron1 | 913 | END; |
914 | SetLabel(NewLabel()); |
||
915 | FltConstLabel := CodeList.last(LABEL); |
||
916 | LocVarSize := param2 * 4 |
||
7597 | akron1 | 917 | |
7693 | akron1 | 918 | |IL.opLEAVE, IL.opLEAVER, IL.opLEAVEF: |
919 | IF opcode = IL.opLEAVER THEN |
||
7597 | akron1 | 920 | UnOp(reg1); |
921 | IF reg1 # eax THEN |
||
8859 | leency | 922 | mov(eax, reg1) |
7597 | akron1 | 923 | END; |
924 | drop |
||
925 | END; |
||
926 | |||
927 | ASSERT(R.top = -1); |
||
928 | |||
8097 | maxcodehac | 929 | IF opcode = IL.opLEAVEF THEN |
930 | DEC(fr) |
||
931 | END; |
||
932 | |||
933 | ASSERT(fr = -1); |
||
934 | |||
9873 | akron1 | 935 | IF LocVarSize > 0 THEN |
7693 | akron1 | 936 | mov(esp, ebp) |
937 | END; |
||
938 | |||
7597 | akron1 | 939 | pop(ebp); |
940 | |||
8859 | leency | 941 | IF param2 > 0 THEN |
942 | OutByte(0C2H); OutWord(param2 * 4 MOD 65536) (* ret param2*4 *) |
||
7597 | akron1 | 943 | ELSE |
7983 | leency | 944 | ret |
9873 | akron1 | 945 | END; |
946 | FltConstLabel := mainFltConstLabel; |
||
947 | LocVarSize := mainLocVarSize |
||
7597 | akron1 | 948 | |
7693 | akron1 | 949 | |IL.opPUSHC: |
7597 | akron1 | 950 | pushc(param2) |
951 | |||
7983 | leency | 952 | |IL.opONERR: |
953 | pushc(param2); |
||
954 | jmp(param1) |
||
955 | |||
7693 | akron1 | 956 | |IL.opPARAM: |
7597 | akron1 | 957 | n := param2; |
958 | IF n = 1 THEN |
||
959 | UnOp(reg1); |
||
960 | push(reg1); |
||
961 | drop |
||
962 | ELSE |
||
963 | ASSERT(R.top + 1 <= n); |
||
964 | PushAll(n) |
||
965 | END |
||
966 | |||
7693 | akron1 | 967 | |IL.opCLEANUP: |
8097 | maxcodehac | 968 | IF param2 # 0 THEN |
969 | addrc(esp, param2 * 4) |
||
7597 | akron1 | 970 | END |
971 | |||
7693 | akron1 | 972 | |IL.opPOPSP: |
7597 | akron1 | 973 | pop(esp) |
974 | |||
7693 | akron1 | 975 | |IL.opCONST: |
976 | movrc(GetAnyReg(), param2) |
||
7597 | akron1 | 977 | |
7693 | akron1 | 978 | |IL.opLABEL: |
7983 | leency | 979 | SetLabel(param1) (* L: *) |
7597 | akron1 | 980 | |
8097 | maxcodehac | 981 | |IL.opNOP, IL.opAND, IL.opOR: |
7597 | akron1 | 982 | |
7693 | akron1 | 983 | |IL.opGADR: |
8097 | maxcodehac | 984 | next := cmd.next(COMMAND); |
985 | IF next.opcode = IL.opADDC THEN |
||
986 | INC(param2, next.param2); |
||
987 | cmd := next |
||
988 | END; |
||
7693 | akron1 | 989 | reg1 := GetAnyReg(); |
7597 | akron1 | 990 | IF pic THEN |
991 | Pic(reg1, BIN.PICBSS, param2) |
||
992 | ELSE |
||
7983 | leency | 993 | OutByte(0B8H + reg1); (* mov reg1, _bss + param2 *) |
7597 | akron1 | 994 | Reloc(BIN.RBSS, param2) |
995 | END |
||
996 | |||
7693 | akron1 | 997 | |IL.opLADR: |
8097 | maxcodehac | 998 | next := cmd.next(COMMAND); |
7597 | akron1 | 999 | n := param2 * 4; |
8097 | maxcodehac | 1000 | IF next.opcode = IL.opADDC THEN |
1001 | INC(n, next.param2); |
||
1002 | cmd := next |
||
1003 | END; |
||
7983 | leency | 1004 | OutByte2(8DH, 45H + GetAnyReg() * 8 + long(n)); (* lea reg1, dword[ebp + n] *) |
7597 | akron1 | 1005 | OutIntByte(n) |
1006 | |||
7983 | leency | 1007 | |IL.opVADR, IL.opLLOAD32: |
1008 | movrm(GetAnyReg(), ebp, param2 * 4) |
||
7597 | akron1 | 1009 | |
7693 | akron1 | 1010 | |IL.opSADR: |
1011 | reg1 := GetAnyReg(); |
||
7597 | akron1 | 1012 | IF pic THEN |
1013 | Pic(reg1, BIN.PICDATA, stroffs + param2); |
||
1014 | ELSE |
||
7983 | leency | 1015 | OutByte(0B8H + reg1); (* mov reg1, _data + stroffs + param2 *) |
7597 | akron1 | 1016 | Reloc(BIN.RDATA, stroffs + param2) |
1017 | END |
||
1018 | |||
7693 | akron1 | 1019 | |IL.opSAVEC: |
7597 | akron1 | 1020 | UnOp(reg1); |
7983 | leency | 1021 | OutByte2(0C7H, reg1); OutInt(param2); (* mov dword[reg1], param2 *) |
7597 | akron1 | 1022 | drop |
1023 | |||
7693 | akron1 | 1024 | |IL.opSAVE8C: |
7597 | akron1 | 1025 | UnOp(reg1); |
7983 | leency | 1026 | OutByte3(0C6H, reg1, param2 MOD 256); (* mov byte[reg1], param2 *) |
7597 | akron1 | 1027 | drop |
1028 | |||
7693 | akron1 | 1029 | |IL.opSAVE16C: |
7597 | akron1 | 1030 | UnOp(reg1); |
7983 | leency | 1031 | OutByte3(66H, 0C7H, reg1); OutWord(param2 MOD 65536); (* mov word[reg1], param2 *) |
7597 | akron1 | 1032 | drop |
1033 | |||
7693 | akron1 | 1034 | |IL.opVLOAD32: |
1035 | reg1 := GetAnyReg(); |
||
7983 | leency | 1036 | movrm(reg1, ebp, param2 * 4); |
1037 | movrm(reg1, reg1, 0) |
||
7597 | akron1 | 1038 | |
7693 | akron1 | 1039 | |IL.opGLOAD32: |
1040 | reg1 := GetAnyReg(); |
||
7597 | akron1 | 1041 | IF pic THEN |
1042 | Pic(reg1, BIN.PICBSS, param2); |
||
7983 | leency | 1043 | movrm(reg1, reg1, 0) |
7597 | akron1 | 1044 | ELSE |
7983 | leency | 1045 | OutByte2(08BH, 05H + reg1 * 8); (* mov reg1, dword[_bss + param2] *) |
7597 | akron1 | 1046 | Reloc(BIN.RBSS, param2) |
1047 | END |
||
1048 | |||
7693 | akron1 | 1049 | |IL.opLOAD32: |
7597 | akron1 | 1050 | UnOp(reg1); |
7983 | leency | 1051 | movrm(reg1, reg1, 0) |
7597 | akron1 | 1052 | |
7693 | akron1 | 1053 | |IL.opVLOAD8: |
1054 | reg1 := GetAnyReg(); |
||
7983 | leency | 1055 | movrm(reg1, ebp, param2 * 4); |
1056 | movzx(reg1, reg1, 0, FALSE) |
||
7597 | akron1 | 1057 | |
7693 | akron1 | 1058 | |IL.opGLOAD8: |
1059 | reg1 := GetAnyReg(); |
||
7597 | akron1 | 1060 | IF pic THEN |
1061 | Pic(reg1, BIN.PICBSS, param2); |
||
7983 | leency | 1062 | movzx(reg1, reg1, 0, FALSE) |
7597 | akron1 | 1063 | ELSE |
7983 | leency | 1064 | OutByte3(00FH, 0B6H, 05H + reg1 * 8); (* movzx reg1, byte[_bss + param2] *) |
7597 | akron1 | 1065 | Reloc(BIN.RBSS, param2) |
1066 | END |
||
1067 | |||
7693 | akron1 | 1068 | |IL.opLLOAD8: |
7983 | leency | 1069 | movzx(GetAnyReg(), ebp, param2 * 4, FALSE) |
7597 | akron1 | 1070 | |
7693 | akron1 | 1071 | |IL.opLOAD8: |
7597 | akron1 | 1072 | UnOp(reg1); |
7983 | leency | 1073 | movzx(reg1, reg1, 0, FALSE) |
7597 | akron1 | 1074 | |
7693 | akron1 | 1075 | |IL.opVLOAD16: |
1076 | reg1 := GetAnyReg(); |
||
7983 | leency | 1077 | movrm(reg1, ebp, param2 * 4); |
1078 | movzx(reg1, reg1, 0, TRUE) |
||
7597 | akron1 | 1079 | |
7693 | akron1 | 1080 | |IL.opGLOAD16: |
1081 | reg1 := GetAnyReg(); |
||
7597 | akron1 | 1082 | IF pic THEN |
1083 | Pic(reg1, BIN.PICBSS, param2); |
||
7983 | leency | 1084 | movzx(reg1, reg1, 0, TRUE) |
7597 | akron1 | 1085 | ELSE |
7983 | leency | 1086 | OutByte3(00FH, 0B7H, 05H + reg1 * 8); (* movzx reg1, word[_bss + param2] *) |
7597 | akron1 | 1087 | Reloc(BIN.RBSS, param2) |
1088 | END |
||
1089 | |||
7693 | akron1 | 1090 | |IL.opLLOAD16: |
7983 | leency | 1091 | movzx(GetAnyReg(), ebp, param2 * 4, TRUE) |
7597 | akron1 | 1092 | |
7693 | akron1 | 1093 | |IL.opLOAD16: |
7597 | akron1 | 1094 | UnOp(reg1); |
7983 | leency | 1095 | movzx(reg1, reg1, 0, TRUE) |
7597 | akron1 | 1096 | |
7693 | akron1 | 1097 | |IL.opUMINUS: |
7597 | akron1 | 1098 | UnOp(reg1); |
1099 | neg(reg1) |
||
1100 | |||
7693 | akron1 | 1101 | |IL.opADD: |
7597 | akron1 | 1102 | BinOp(reg1, reg2); |
1103 | add(reg1, reg2); |
||
1104 | drop |
||
1105 | |||
8097 | maxcodehac | 1106 | |IL.opADDC: |
7597 | akron1 | 1107 | IF param2 # 0 THEN |
1108 | UnOp(reg1); |
||
7983 | leency | 1109 | next := cmd.next(COMMAND); |
1110 | CASE next.opcode OF |
||
1111 | |IL.opLOAD32: |
||
1112 | movrm(reg1, reg1, param2); |
||
1113 | cmd := next |
||
1114 | |IL.opLOAD16: |
||
1115 | movzx(reg1, reg1, param2, TRUE); |
||
1116 | cmd := next |
||
1117 | |IL.opLOAD8: |
||
1118 | movzx(reg1, reg1, param2, FALSE); |
||
1119 | cmd := next |
||
1120 | |IL.opLOAD32_PARAM: |
||
1121 | pushm(reg1, param2); |
||
1122 | drop; |
||
1123 | cmd := next |
||
7597 | akron1 | 1124 | ELSE |
7983 | leency | 1125 | IF param2 = 1 THEN |
1126 | OutByte(40H + reg1) (* inc reg1 *) |
||
1127 | ELSIF param2 = -1 THEN |
||
1128 | OutByte(48H + reg1) (* dec reg1 *) |
||
1129 | ELSE |
||
1130 | addrc(reg1, param2) |
||
1131 | END |
||
7597 | akron1 | 1132 | END |
1133 | END |
||
1134 | |||
7693 | akron1 | 1135 | |IL.opSUB: |
7597 | akron1 | 1136 | BinOp(reg1, reg2); |
8097 | maxcodehac | 1137 | oprr(29H, reg1, reg2); (* sub reg1, reg2 *) |
7597 | akron1 | 1138 | drop |
1139 | |||
7693 | akron1 | 1140 | |IL.opSUBR, IL.opSUBL: |
7597 | akron1 | 1141 | UnOp(reg1); |
8097 | maxcodehac | 1142 | IF param2 = 1 THEN |
7983 | leency | 1143 | OutByte(48H + reg1) (* dec reg1 *) |
8097 | maxcodehac | 1144 | ELSIF param2 = -1 THEN |
7983 | leency | 1145 | OutByte(40H + reg1) (* inc reg1 *) |
8097 | maxcodehac | 1146 | ELSIF param2 # 0 THEN |
1147 | subrc(reg1, param2) |
||
7597 | akron1 | 1148 | END; |
7693 | akron1 | 1149 | IF opcode = IL.opSUBL THEN |
7597 | akron1 | 1150 | neg(reg1) |
1151 | END |
||
1152 | |||
7693 | akron1 | 1153 | |IL.opMULC: |
7983 | leency | 1154 | IF (cmd.next(COMMAND).opcode = IL.opADD) & ((param2 = 2) OR (param2 = 4) OR (param2 = 8)) THEN |
1155 | BinOp(reg1, reg2); |
||
1156 | OutByte3(8DH, 04H + reg1 * 8, reg1 + reg2 * 8 + 40H * UTILS.Log2(param2)); (* lea reg1, [reg1 + reg2 * param2] *) |
||
1157 | drop; |
||
1158 | cmd := cmd.next(COMMAND) |
||
7597 | akron1 | 1159 | ELSE |
7983 | leency | 1160 | UnOp(reg1); |
7597 | akron1 | 1161 | |
7983 | leency | 1162 | a := param2; |
1163 | IF a > 1 THEN |
||
1164 | n := UTILS.Log2(a) |
||
1165 | ELSIF a < -1 THEN |
||
1166 | n := UTILS.Log2(-a) |
||
1167 | ELSE |
||
1168 | n := -1 |
||
1169 | END; |
||
7597 | akron1 | 1170 | |
7983 | leency | 1171 | IF a = 1 THEN |
7597 | akron1 | 1172 | |
7983 | leency | 1173 | ELSIF a = -1 THEN |
1174 | neg(reg1) |
||
1175 | ELSIF a = 0 THEN |
||
1176 | xor(reg1, reg1) |
||
1177 | ELSE |
||
1178 | IF n > 0 THEN |
||
1179 | IF a < 0 THEN |
||
1180 | neg(reg1) |
||
1181 | END; |
||
1182 | |||
1183 | IF n # 1 THEN |
||
1184 | OutByte3(0C1H, 0E0H + reg1, n) (* shl reg1, n *) |
||
1185 | ELSE |
||
1186 | OutByte2(0D1H, 0E0H + reg1) (* shl reg1, 1 *) |
||
1187 | END |
||
7597 | akron1 | 1188 | ELSE |
7983 | leency | 1189 | OutByte2(69H + short(a), 0C0H + reg1 * 9); (* imul reg1, a *) |
1190 | OutIntByte(a) |
||
7597 | akron1 | 1191 | END |
1192 | END |
||
1193 | END |
||
1194 | |||
7693 | akron1 | 1195 | |IL.opMUL: |
7597 | akron1 | 1196 | BinOp(reg1, reg2); |
7983 | leency | 1197 | OutByte3(0FH, 0AFH, 0C0H + reg1 * 8 + reg2); (* imul reg1, reg2 *) |
7597 | akron1 | 1198 | drop |
1199 | |||
7693 | akron1 | 1200 | |IL.opSAVE, IL.opSAVE32: |
7597 | akron1 | 1201 | BinOp(reg2, reg1); |
7983 | leency | 1202 | movmr(reg1, 0, reg2); |
7597 | akron1 | 1203 | drop; |
1204 | drop |
||
1205 | |||
7693 | akron1 | 1206 | |IL.opSAVE8: |
7597 | akron1 | 1207 | BinOp(reg2, reg1); |
7983 | leency | 1208 | movmr8(reg1, 0, reg2); |
7597 | akron1 | 1209 | drop; |
1210 | drop |
||
1211 | |||
7693 | akron1 | 1212 | |IL.opSAVE16: |
7597 | akron1 | 1213 | BinOp(reg2, reg1); |
7983 | leency | 1214 | movmr16(reg1, 0, reg2); |
7597 | akron1 | 1215 | drop; |
1216 | drop |
||
1217 | |||
7693 | akron1 | 1218 | |IL.opSAVEP: |
7597 | akron1 | 1219 | UnOp(reg1); |
1220 | IF pic THEN |
||
7693 | akron1 | 1221 | reg2 := GetAnyReg(); |
7597 | akron1 | 1222 | Pic(reg2, BIN.PICCODE, param2); |
7983 | leency | 1223 | movmr(reg1, 0, reg2); |
7597 | akron1 | 1224 | drop |
1225 | ELSE |
||
7983 | leency | 1226 | OutByte2(0C7H, reg1); (* mov dword[reg1], L *) |
7597 | akron1 | 1227 | Reloc(BIN.RCODE, param2) |
1228 | END; |
||
1229 | drop |
||
1230 | |||
7693 | akron1 | 1231 | |IL.opSAVEIP: |
7597 | akron1 | 1232 | UnOp(reg1); |
1233 | IF pic THEN |
||
7693 | akron1 | 1234 | reg2 := GetAnyReg(); |
7597 | akron1 | 1235 | Pic(reg2, BIN.PICIMP, param2); |
7983 | leency | 1236 | pushm(reg2, 0); |
8097 | maxcodehac | 1237 | OutByte2(08FH, reg1); (* pop dword[reg1] *) |
7597 | akron1 | 1238 | drop |
1239 | ELSE |
||
7983 | leency | 1240 | OutByte2(0FFH, 035H); (* push dword[L] *) |
7597 | akron1 | 1241 | Reloc(BIN.RIMP, param2); |
7983 | leency | 1242 | OutByte2(08FH, reg1) (* pop dword[reg1] *) |
7597 | akron1 | 1243 | END; |
1244 | drop |
||
1245 | |||
7693 | akron1 | 1246 | |IL.opPUSHP: |
1247 | reg1 := GetAnyReg(); |
||
7597 | akron1 | 1248 | IF pic THEN |
1249 | Pic(reg1, BIN.PICCODE, param2) |
||
1250 | ELSE |
||
7983 | leency | 1251 | OutByte(0B8H + reg1); (* mov reg1, L *) |
7597 | akron1 | 1252 | Reloc(BIN.RCODE, param2) |
1253 | END |
||
1254 | |||
7693 | akron1 | 1255 | |IL.opPUSHIP: |
1256 | reg1 := GetAnyReg(); |
||
7597 | akron1 | 1257 | IF pic THEN |
1258 | Pic(reg1, BIN.PICIMP, param2); |
||
7983 | leency | 1259 | movrm(reg1, reg1, 0) |
7597 | akron1 | 1260 | ELSE |
7983 | leency | 1261 | OutByte2(08BH, 05H + reg1 * 8); (* mov reg1, dword[L] *) |
7597 | akron1 | 1262 | Reloc(BIN.RIMP, param2) |
1263 | END |
||
1264 | |||
7693 | akron1 | 1265 | |IL.opNOT: |
7597 | akron1 | 1266 | UnOp(reg1); |
1267 | test(reg1); |
||
1268 | setcc(sete, reg1); |
||
1269 | andrc(reg1, 1) |
||
1270 | |||
7693 | akron1 | 1271 | |IL.opORD: |
7597 | akron1 | 1272 | UnOp(reg1); |
1273 | test(reg1); |
||
1274 | setcc(setne, reg1); |
||
1275 | andrc(reg1, 1) |
||
1276 | |||
7693 | akron1 | 1277 | |IL.opSBOOL: |
7597 | akron1 | 1278 | BinOp(reg2, reg1); |
1279 | test(reg2); |
||
7983 | leency | 1280 | OutByte3(0FH, 95H, reg1); (* setne byte[reg1] *) |
7597 | akron1 | 1281 | drop; |
1282 | drop |
||
1283 | |||
7693 | akron1 | 1284 | |IL.opSBOOLC: |
7597 | akron1 | 1285 | UnOp(reg1); |
7983 | leency | 1286 | OutByte3(0C6H, reg1, ORD(param2 # 0)); (* mov byte[reg1], 0/1 *) |
7597 | akron1 | 1287 | drop |
1288 | |||
7693 | akron1 | 1289 | |IL.opEQ..IL.opGE, |
1290 | IL.opEQC..IL.opGEC: |
||
1291 | |||
1292 | IF (IL.opEQ <= opcode) & (opcode <= IL.opGE) THEN |
||
1293 | BinOp(reg1, reg2); |
||
1294 | cmprr(reg1, reg2); |
||
1295 | drop |
||
7597 | akron1 | 1296 | ELSE |
7693 | akron1 | 1297 | UnOp(reg1); |
7983 | leency | 1298 | cmprc(reg1, param2) |
7597 | akron1 | 1299 | END; |
1300 | |||
1301 | drop; |
||
7693 | akron1 | 1302 | cc := cond(opcode); |
7983 | leency | 1303 | next := cmd.next(COMMAND); |
7597 | akron1 | 1304 | |
8097 | maxcodehac | 1305 | IF next.opcode = IL.opJNZ THEN |
7983 | leency | 1306 | jcc(cc, next.param1); |
1307 | cmd := next |
||
8097 | maxcodehac | 1308 | ELSIF next.opcode = IL.opJZ THEN |
7983 | leency | 1309 | jcc(inv0(cc), next.param1); |
1310 | cmd := next |
||
7597 | akron1 | 1311 | ELSE |
7693 | akron1 | 1312 | reg1 := GetAnyReg(); |
7597 | akron1 | 1313 | setcc(cc + 16, reg1); |
1314 | andrc(reg1, 1) |
||
1315 | END |
||
1316 | |||
7693 | akron1 | 1317 | |IL.opEQB, IL.opNEB: |
7597 | akron1 | 1318 | BinOp(reg1, reg2); |
1319 | drop; |
||
1320 | |||
1321 | test(reg1); |
||
7983 | leency | 1322 | OutByte2(74H, 5); (* je @f *) |
1323 | movrc(reg1, 1); (* mov reg1, 1 |
||
1324 | @@: *) |
||
7597 | akron1 | 1325 | test(reg2); |
7983 | leency | 1326 | OutByte2(74H, 5); (* je @f *) |
1327 | movrc(reg2, 1); (* mov reg2, 1 |
||
1328 | @@: *) |
||
7597 | akron1 | 1329 | |
1330 | cmprr(reg1, reg2); |
||
7693 | akron1 | 1331 | IF opcode = IL.opEQB THEN |
7597 | akron1 | 1332 | setcc(sete, reg1) |
1333 | ELSE |
||
1334 | setcc(setne, reg1) |
||
1335 | END; |
||
1336 | andrc(reg1, 1) |
||
7693 | akron1 | 1337 | |
1338 | |IL.opDROP: |
||
7597 | akron1 | 1339 | UnOp(reg1); |
1340 | drop |
||
1341 | |||
8097 | maxcodehac | 1342 | |IL.opJNZ1: |
7597 | akron1 | 1343 | UnOp(reg1); |
1344 | test(reg1); |
||
1345 | jcc(jne, param1) |
||
1346 | |||
7983 | leency | 1347 | |IL.opJG: |
1348 | UnOp(reg1); |
||
1349 | test(reg1); |
||
1350 | jcc(jg, param1) |
||
1351 | |||
8097 | maxcodehac | 1352 | |IL.opJNZ: |
7597 | akron1 | 1353 | UnOp(reg1); |
1354 | test(reg1); |
||
1355 | jcc(jne, param1); |
||
7693 | akron1 | 1356 | drop |
7597 | akron1 | 1357 | |
8097 | maxcodehac | 1358 | |IL.opJZ: |
7597 | akron1 | 1359 | UnOp(reg1); |
1360 | test(reg1); |
||
1361 | jcc(je, param1); |
||
7693 | akron1 | 1362 | drop |
7597 | akron1 | 1363 | |
7693 | akron1 | 1364 | |IL.opSWITCH: |
7597 | akron1 | 1365 | UnOp(reg1); |
1366 | IF param2 = 0 THEN |
||
1367 | reg2 := eax |
||
1368 | ELSE |
||
1369 | reg2 := ecx |
||
1370 | END; |
||
1371 | IF reg1 # reg2 THEN |
||
1372 | ASSERT(REG.GetReg(R, reg2)); |
||
1373 | ASSERT(REG.Exchange(R, reg1, reg2)); |
||
1374 | drop |
||
1375 | END; |
||
1376 | drop |
||
1377 | |||
7693 | akron1 | 1378 | |IL.opENDSW: |
7597 | akron1 | 1379 | |
7693 | akron1 | 1380 | |IL.opCASEL: |
7597 | akron1 | 1381 | cmprc(eax, param1); |
1382 | jcc(jl, param2) |
||
1383 | |||
7693 | akron1 | 1384 | |IL.opCASER: |
7597 | akron1 | 1385 | cmprc(eax, param1); |
1386 | jcc(jg, param2) |
||
1387 | |||
7693 | akron1 | 1388 | |IL.opCASELR: |
7597 | akron1 | 1389 | cmprc(eax, param1); |
8859 | leency | 1390 | IF param2 = cmd.param3 THEN |
1391 | jcc(jne, param2) |
||
1392 | ELSE |
||
1393 | jcc(jl, param2); |
||
1394 | jcc(jg, cmd.param3) |
||
1395 | END |
||
7597 | akron1 | 1396 | |
7693 | akron1 | 1397 | |IL.opCODE: |
7597 | akron1 | 1398 | OutByte(param2) |
1399 | |||
7693 | akron1 | 1400 | |IL.opGET, IL.opGETC: |
1401 | IF opcode = IL.opGET THEN |
||
1402 | BinOp(reg1, reg2) |
||
1403 | ELSIF opcode = IL.opGETC THEN |
||
1404 | UnOp(reg2); |
||
1405 | reg1 := GetAnyReg(); |
||
1406 | movrc(reg1, param1) |
||
1407 | END; |
||
7597 | akron1 | 1408 | drop; |
1409 | drop; |
||
1410 | |||
7983 | leency | 1411 | IF param2 # 8 THEN |
1412 | _movrm(reg1, reg1, 0, param2 * 8, FALSE); |
||
1413 | _movrm(reg1, reg2, 0, param2 * 8, TRUE) |
||
1414 | ELSE |
||
7597 | akron1 | 1415 | PushAll(0); |
7696 | akron1 | 1416 | push(reg1); |
7597 | akron1 | 1417 | push(reg2); |
1418 | pushc(8); |
||
7693 | akron1 | 1419 | CallRTL(pic, IL._move) |
7597 | akron1 | 1420 | END |
1421 | |||
7693 | akron1 | 1422 | |IL.opSAVES: |
7696 | akron1 | 1423 | UnOp(reg2); |
1424 | REG.PushAll_1(R); |
||
7597 | akron1 | 1425 | |
1426 | IF pic THEN |
||
7696 | akron1 | 1427 | reg1 := GetAnyReg(); |
7597 | akron1 | 1428 | Pic(reg1, BIN.PICDATA, stroffs + param2); |
7696 | akron1 | 1429 | push(reg1); |
1430 | drop |
||
7597 | akron1 | 1431 | ELSE |
7983 | leency | 1432 | OutByte(068H); (* push _data + stroffs + param2 *) |
7597 | akron1 | 1433 | Reloc(BIN.RDATA, stroffs + param2); |
1434 | END; |
||
1435 | |||
7696 | akron1 | 1436 | push(reg2); |
1437 | drop; |
||
7597 | akron1 | 1438 | pushc(param1); |
7693 | akron1 | 1439 | CallRTL(pic, IL._move) |
7597 | akron1 | 1440 | |
7693 | akron1 | 1441 | |IL.opCHKBYTE: |
7597 | akron1 | 1442 | BinOp(reg1, reg2); |
1443 | cmprc(reg1, 256); |
||
1444 | jcc(jb, param1) |
||
1445 | |||
7693 | akron1 | 1446 | |IL.opCHKIDX: |
7597 | akron1 | 1447 | UnOp(reg1); |
1448 | cmprc(reg1, param2); |
||
1449 | jcc(jb, param1) |
||
1450 | |||
7693 | akron1 | 1451 | |IL.opCHKIDX2: |
7597 | akron1 | 1452 | BinOp(reg1, reg2); |
1453 | IF param2 # -1 THEN |
||
1454 | cmprr(reg2, reg1); |
||
1455 | jcc(jb, param1) |
||
7983 | leency | 1456 | END; |
1457 | INCL(R.regs, reg1); |
||
1458 | DEC(R.top); |
||
1459 | R.stk[R.top] := reg2 |
||
7597 | akron1 | 1460 | |
7693 | akron1 | 1461 | |IL.opLEN: |
7597 | akron1 | 1462 | n := param2; |
1463 | UnOp(reg1); |
||
1464 | drop; |
||
1465 | EXCL(R.regs, reg1); |
||
1466 | |||
1467 | WHILE n > 0 DO |
||
1468 | UnOp(reg2); |
||
1469 | drop; |
||
1470 | DEC(n) |
||
1471 | END; |
||
1472 | |||
1473 | INCL(R.regs, reg1); |
||
1474 | ASSERT(REG.GetReg(R, reg1)) |
||
1475 | |||
7693 | akron1 | 1476 | |IL.opINCC: |
7597 | akron1 | 1477 | UnOp(reg1); |
7983 | leency | 1478 | IF param2 = 1 THEN |
1479 | OutByte2(0FFH, reg1) (* inc dword[reg1] *) |
||
1480 | ELSIF param2 = -1 THEN |
||
1481 | OutByte2(0FFH, reg1 + 8) (* dec dword[reg1] *) |
||
1482 | ELSE |
||
1483 | OutByte2(81H + short(param2), reg1); OutIntByte(param2) (* add dword[reg1], param2 *) |
||
1484 | END; |
||
7597 | akron1 | 1485 | drop |
1486 | |||
7693 | akron1 | 1487 | |IL.opINC, IL.opDEC: |
7597 | akron1 | 1488 | BinOp(reg1, reg2); |
7983 | leency | 1489 | OutByte2(01H + 28H * ORD(opcode = IL.opDEC), reg1 * 8 + reg2); (* add/sub dword[reg2], reg1 *) |
7597 | akron1 | 1490 | drop; |
1491 | drop |
||
1492 | |||
7693 | akron1 | 1493 | |IL.opINCCB, IL.opDECCB: |
7597 | akron1 | 1494 | UnOp(reg1); |
7983 | leency | 1495 | OutByte3(80H, 28H * ORD(opcode = IL.opDECCB) + reg1, param2 MOD 256); (* add/sub byte[reg1], n *) |
7597 | akron1 | 1496 | drop |
1497 | |||
7693 | akron1 | 1498 | |IL.opINCB, IL.opDECB: |
7597 | akron1 | 1499 | BinOp(reg1, reg2); |
7983 | leency | 1500 | OutByte2(28H * ORD(opcode = IL.opDECB), reg1 * 8 + reg2); (* add/sub byte[reg2], reg1 *) |
7597 | akron1 | 1501 | drop; |
1502 | drop |
||
1503 | |||
7693 | akron1 | 1504 | |IL.opMULS: |
7597 | akron1 | 1505 | BinOp(reg1, reg2); |
8097 | maxcodehac | 1506 | oprr(21H, reg1, reg2); (* and reg1, reg2 *) |
7597 | akron1 | 1507 | drop |
1508 | |||
7693 | akron1 | 1509 | |IL.opMULSC: |
7597 | akron1 | 1510 | UnOp(reg1); |
1511 | andrc(reg1, param2) |
||
1512 | |||
7693 | akron1 | 1513 | |IL.opDIVS: |
7597 | akron1 | 1514 | BinOp(reg1, reg2); |
7667 | akron1 | 1515 | xor(reg1, reg2); |
7597 | akron1 | 1516 | drop |
1517 | |||
7693 | akron1 | 1518 | |IL.opDIVSC: |
7597 | akron1 | 1519 | UnOp(reg1); |
8097 | maxcodehac | 1520 | xorrc(reg1, param2) |
7597 | akron1 | 1521 | |
7693 | akron1 | 1522 | |IL.opADDS: |
7597 | akron1 | 1523 | BinOp(reg1, reg2); |
8097 | maxcodehac | 1524 | oprr(9H, reg1, reg2); (* or reg1, reg2 *) |
7597 | akron1 | 1525 | drop |
1526 | |||
7693 | akron1 | 1527 | |IL.opSUBS: |
7597 | akron1 | 1528 | BinOp(reg1, reg2); |
1529 | not(reg2); |
||
8097 | maxcodehac | 1530 | oprr(21H, reg1, reg2); (* and reg1, reg2 *) |
7597 | akron1 | 1531 | drop |
1532 | |||
8097 | maxcodehac | 1533 | |IL.opADDSC: |
7597 | akron1 | 1534 | UnOp(reg1); |
1535 | orrc(reg1, param2) |
||
1536 | |||
7693 | akron1 | 1537 | |IL.opSUBSL: |
7597 | akron1 | 1538 | UnOp(reg1); |
1539 | not(reg1); |
||
1540 | andrc(reg1, param2) |
||
1541 | |||
7693 | akron1 | 1542 | |IL.opSUBSR: |
7597 | akron1 | 1543 | UnOp(reg1); |
7693 | akron1 | 1544 | andrc(reg1, ORD(-BITS(param2))) |
7597 | akron1 | 1545 | |
7693 | akron1 | 1546 | |IL.opUMINS: |
7597 | akron1 | 1547 | UnOp(reg1); |
1548 | not(reg1) |
||
1549 | |||
7693 | akron1 | 1550 | |IL.opLENGTH: |
7597 | akron1 | 1551 | PushAll(2); |
7693 | akron1 | 1552 | CallRTL(pic, IL._length); |
7597 | akron1 | 1553 | GetRegA |
1554 | |||
7693 | akron1 | 1555 | |IL.opLENGTHW: |
7597 | akron1 | 1556 | PushAll(2); |
7693 | akron1 | 1557 | CallRTL(pic, IL._lengthw); |
7597 | akron1 | 1558 | GetRegA |
1559 | |||
7693 | akron1 | 1560 | |IL.opCHR: |
7597 | akron1 | 1561 | UnOp(reg1); |
1562 | andrc(reg1, 255) |
||
1563 | |||
7693 | akron1 | 1564 | |IL.opWCHR: |
7597 | akron1 | 1565 | UnOp(reg1); |
1566 | andrc(reg1, 65535) |
||
1567 | |||
7693 | akron1 | 1568 | |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR: |
7597 | akron1 | 1569 | UnOp(reg1); |
1570 | IF reg1 # ecx THEN |
||
1571 | ASSERT(REG.GetReg(R, ecx)); |
||
1572 | ASSERT(REG.Exchange(R, reg1, ecx)); |
||
1573 | drop |
||
1574 | END; |
||
1575 | |||
1576 | BinOp(reg1, reg2); |
||
1577 | ASSERT(reg2 = ecx); |
||
1578 | OutByte(0D3H); |
||
7983 | leency | 1579 | shift(opcode, reg1); (* shift reg1, cl *) |
7597 | akron1 | 1580 | drop |
1581 | |||
7693 | akron1 | 1582 | |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1: |
7597 | akron1 | 1583 | UnOp(reg1); |
1584 | IF reg1 # ecx THEN |
||
1585 | ASSERT(REG.GetReg(R, ecx)); |
||
1586 | ASSERT(REG.Exchange(R, reg1, ecx)); |
||
1587 | drop |
||
1588 | END; |
||
1589 | |||
7693 | akron1 | 1590 | reg1 := GetAnyReg(); |
7597 | akron1 | 1591 | movrc(reg1, param2); |
1592 | BinOp(reg1, reg2); |
||
1593 | ASSERT(reg1 = ecx); |
||
1594 | OutByte(0D3H); |
||
7983 | leency | 1595 | shift(opcode, reg2); (* shift reg2, cl *) |
7597 | akron1 | 1596 | drop; |
1597 | drop; |
||
1598 | ASSERT(REG.GetReg(R, reg2)) |
||
1599 | |||
7693 | akron1 | 1600 | |IL.opASR2, IL.opROR2, IL.opLSL2, IL.opLSR2: |
7597 | akron1 | 1601 | UnOp(reg1); |
7693 | akron1 | 1602 | n := param2 MOD 32; |
7597 | akron1 | 1603 | IF n # 1 THEN |
1604 | OutByte(0C1H) |
||
1605 | ELSE |
||
1606 | OutByte(0D1H) |
||
1607 | END; |
||
7983 | leency | 1608 | shift(opcode, reg1); (* shift reg1, n *) |
7597 | akron1 | 1609 | IF n # 1 THEN |
1610 | OutByte(n) |
||
1611 | END |
||
1612 | |||
7983 | leency | 1613 | |IL.opMAX, IL.opMIN: |
7597 | akron1 | 1614 | BinOp(reg1, reg2); |
1615 | cmprr(reg1, reg2); |
||
7983 | leency | 1616 | OutByte2(07DH + ORD(opcode = IL.opMIN), 2); (* jge/jle L *) |
1617 | mov(reg1, reg2); |
||
1618 | (* L: *) |
||
7597 | akron1 | 1619 | drop |
1620 | |||
7983 | leency | 1621 | |IL.opMAXC, IL.opMINC: |
7597 | akron1 | 1622 | UnOp(reg1); |
1623 | cmprc(reg1, param2); |
||
8097 | maxcodehac | 1624 | label := NewLabel(); |
1625 | IF opcode = IL.opMINC THEN |
||
1626 | cc := jle |
||
1627 | ELSE |
||
1628 | cc := jge |
||
1629 | END; |
||
1630 | jcc(cc, label); |
||
1631 | movrc(reg1, param2); |
||
1632 | SetLabel(label) |
||
7597 | akron1 | 1633 | |
7983 | leency | 1634 | |IL.opIN, IL.opINR: |
1635 | IF opcode = IL.opINR THEN |
||
1636 | reg2 := GetAnyReg(); |
||
1637 | movrc(reg2, param2) |
||
1638 | END; |
||
7597 | akron1 | 1639 | label := NewLabel(); |
1640 | BinOp(reg1, reg2); |
||
1641 | cmprc(reg1, 32); |
||
7983 | leency | 1642 | OutByte2(72H, 4); (* jb L *) |
7667 | akron1 | 1643 | xor(reg1, reg1); |
7597 | akron1 | 1644 | jmp(label); |
7983 | leency | 1645 | (* L: *) |
1646 | OutByte3(0FH, 0A3H, 0C0H + reg2 + 8 * reg1); (* bt reg2, reg1 *) |
||
7597 | akron1 | 1647 | setcc(setc, reg1); |
1648 | andrc(reg1, 1); |
||
1649 | SetLabel(label); |
||
1650 | drop |
||
1651 | |||
7693 | akron1 | 1652 | |IL.opINL: |
7597 | akron1 | 1653 | UnOp(reg1); |
7983 | leency | 1654 | OutByte3(0FH, 0BAH, 0E0H + reg1); OutByte(param2); (* bt reg1, param2 *) |
7597 | akron1 | 1655 | setcc(setc, reg1); |
1656 | andrc(reg1, 1) |
||
1657 | |||
7693 | akron1 | 1658 | |IL.opRSET: |
7597 | akron1 | 1659 | PushAll(2); |
7693 | akron1 | 1660 | CallRTL(pic, IL._set); |
7597 | akron1 | 1661 | GetRegA |
1662 | |||
7693 | akron1 | 1663 | |IL.opRSETR: |
7597 | akron1 | 1664 | PushAll(1); |
1665 | pushc(param2); |
||
7693 | akron1 | 1666 | CallRTL(pic, IL._set); |
7597 | akron1 | 1667 | GetRegA |
1668 | |||
7693 | akron1 | 1669 | |IL.opRSETL: |
7696 | akron1 | 1670 | UnOp(reg1); |
1671 | REG.PushAll_1(R); |
||
7597 | akron1 | 1672 | pushc(param2); |
7696 | akron1 | 1673 | push(reg1); |
1674 | drop; |
||
1675 | CallRTL(pic, IL._set); |
||
7597 | akron1 | 1676 | GetRegA |
1677 | |||
7693 | akron1 | 1678 | |IL.opRSET1: |
7597 | akron1 | 1679 | PushAll(1); |
7696 | akron1 | 1680 | CallRTL(pic, IL._set1); |
7597 | akron1 | 1681 | GetRegA |
1682 | |||
7693 | akron1 | 1683 | |IL.opINCL, IL.opEXCL: |
7597 | akron1 | 1684 | BinOp(reg1, reg2); |
1685 | cmprc(reg1, 32); |
||
7983 | leency | 1686 | OutByte2(73H, 03H); (* jnb L *) |
7597 | akron1 | 1687 | OutByte(0FH); |
7693 | akron1 | 1688 | IF opcode = IL.opINCL THEN |
7983 | leency | 1689 | OutByte(0ABH) (* bts dword[reg2], reg1 *) |
7597 | akron1 | 1690 | ELSE |
7983 | leency | 1691 | OutByte(0B3H) (* btr dword[reg2], reg1 *) |
7597 | akron1 | 1692 | END; |
1693 | OutByte(reg2 + 8 * reg1); |
||
7983 | leency | 1694 | (* L: *) |
7597 | akron1 | 1695 | drop; |
1696 | drop |
||
1697 | |||
7693 | akron1 | 1698 | |IL.opINCLC: |
7597 | akron1 | 1699 | UnOp(reg1); |
7983 | leency | 1700 | OutByte3(0FH, 0BAH, 28H + reg1); OutByte(param2); (* bts dword[reg1], param2 *) |
7597 | akron1 | 1701 | drop |
1702 | |||
7693 | akron1 | 1703 | |IL.opEXCLC: |
7597 | akron1 | 1704 | UnOp(reg1); |
7983 | leency | 1705 | OutByte3(0FH, 0BAH, 30H + reg1); OutByte(param2); (* btr dword[reg1], param2 *) |
7597 | akron1 | 1706 | drop |
1707 | |||
7693 | akron1 | 1708 | |IL.opDIV: |
7597 | akron1 | 1709 | PushAll(2); |
7696 | akron1 | 1710 | CallRTL(pic, IL._divmod); |
7597 | akron1 | 1711 | GetRegA |
1712 | |||
7693 | akron1 | 1713 | |IL.opDIVR: |
7983 | leency | 1714 | n := UTILS.Log2(param2); |
1715 | IF n > 0 THEN |
||
7597 | akron1 | 1716 | UnOp(reg1); |
7983 | leency | 1717 | IF n # 1 THEN |
1718 | OutByte3(0C1H, 0F8H + reg1, n) (* sar reg1, n *) |
||
7597 | akron1 | 1719 | ELSE |
7983 | leency | 1720 | OutByte2(0D1H, 0F8H + reg1) (* sar reg1, 1 *) |
7597 | akron1 | 1721 | END |
7983 | leency | 1722 | ELSIF n < 0 THEN |
1723 | PushAll(1); |
||
1724 | pushc(param2); |
||
1725 | CallRTL(pic, IL._divmod); |
||
1726 | GetRegA |
||
7597 | akron1 | 1727 | END |
1728 | |||
7693 | akron1 | 1729 | |IL.opDIVL: |
7696 | akron1 | 1730 | UnOp(reg1); |
1731 | REG.PushAll_1(R); |
||
7597 | akron1 | 1732 | pushc(param2); |
7696 | akron1 | 1733 | push(reg1); |
1734 | drop; |
||
1735 | CallRTL(pic, IL._divmod); |
||
7597 | akron1 | 1736 | GetRegA |
1737 | |||
7693 | akron1 | 1738 | |IL.opMOD: |
7597 | akron1 | 1739 | PushAll(2); |
7696 | akron1 | 1740 | CallRTL(pic, IL._divmod); |
1741 | mov(eax, edx); |
||
7597 | akron1 | 1742 | GetRegA |
1743 | |||
7693 | akron1 | 1744 | |IL.opMODR: |
7983 | leency | 1745 | n := UTILS.Log2(param2); |
1746 | IF n > 0 THEN |
||
1747 | UnOp(reg1); |
||
1748 | andrc(reg1, param2 - 1); |
||
1749 | ELSIF n < 0 THEN |
||
1750 | PushAll(1); |
||
1751 | pushc(param2); |
||
1752 | CallRTL(pic, IL._divmod); |
||
1753 | mov(eax, edx); |
||
1754 | GetRegA |
||
7597 | akron1 | 1755 | ELSE |
1756 | UnOp(reg1); |
||
7667 | akron1 | 1757 | xor(reg1, reg1) |
7597 | akron1 | 1758 | END |
1759 | |||
7693 | akron1 | 1760 | |IL.opMODL: |
7696 | akron1 | 1761 | UnOp(reg1); |
1762 | REG.PushAll_1(R); |
||
7597 | akron1 | 1763 | pushc(param2); |
7696 | akron1 | 1764 | push(reg1); |
1765 | drop; |
||
1766 | CallRTL(pic, IL._divmod); |
||
1767 | mov(eax, edx); |
||
7597 | akron1 | 1768 | GetRegA |
1769 | |||
7693 | akron1 | 1770 | |IL.opERR: |
1771 | CallRTL(pic, IL._error) |
||
7597 | akron1 | 1772 | |
7693 | akron1 | 1773 | |IL.opABS: |
7597 | akron1 | 1774 | UnOp(reg1); |
1775 | test(reg1); |
||
7983 | leency | 1776 | OutByte2(07DH, 002H); (* jge L *) |
1777 | neg(reg1) (* neg reg1 |
||
1778 | L: *) |
||
7597 | akron1 | 1779 | |
7693 | akron1 | 1780 | |IL.opCOPY: |
9847 | akron1 | 1781 | IF (0 < param2) & (param2 <= 64) THEN |
1782 | BinOp(reg1, reg2); |
||
1783 | reg3 := GetAnyReg(); |
||
1784 | FOR n := 0 TO param2 - param2 MOD 4 - 1 BY 4 DO |
||
1785 | movrm(reg3, reg1, n); |
||
1786 | movmr(reg2, n, reg3) |
||
1787 | END; |
||
1788 | n := param2 - param2 MOD 4; |
||
1789 | IF param2 MOD 4 >= 2 THEN |
||
1790 | movrm16(reg3, reg1, n); |
||
1791 | movmr16(reg2, n, reg3); |
||
1792 | INC(n, 2); |
||
1793 | DEC(param2, 2) |
||
1794 | END; |
||
1795 | IF param2 MOD 4 = 1 THEN |
||
1796 | movrm8(reg3, reg1, n); |
||
1797 | movmr8(reg2, n, reg3); |
||
1798 | END; |
||
1799 | drop; |
||
1800 | drop; |
||
1801 | drop |
||
1802 | ELSE |
||
1803 | PushAll(2); |
||
1804 | pushc(param2); |
||
1805 | CallRTL(pic, IL._move) |
||
1806 | END |
||
7597 | akron1 | 1807 | |
7693 | akron1 | 1808 | |IL.opMOVE: |
7597 | akron1 | 1809 | PushAll(3); |
7696 | akron1 | 1810 | CallRTL(pic, IL._move) |
7597 | akron1 | 1811 | |
7693 | akron1 | 1812 | |IL.opCOPYA: |
7597 | akron1 | 1813 | PushAll(4); |
1814 | pushc(param2); |
||
7693 | akron1 | 1815 | CallRTL(pic, IL._arrcpy); |
7597 | akron1 | 1816 | GetRegA |
1817 | |||
7693 | akron1 | 1818 | |IL.opCOPYS: |
7597 | akron1 | 1819 | PushAll(4); |
1820 | pushc(param2); |
||
7693 | akron1 | 1821 | CallRTL(pic, IL._strcpy) |
7597 | akron1 | 1822 | |
7693 | akron1 | 1823 | |IL.opROT: |
7597 | akron1 | 1824 | PushAll(0); |
1825 | push(esp); |
||
1826 | pushc(param2); |
||
7693 | akron1 | 1827 | CallRTL(pic, IL._rot) |
7597 | akron1 | 1828 | |
7693 | akron1 | 1829 | |IL.opNEW: |
7597 | akron1 | 1830 | PushAll(1); |
1831 | n := param2 + 8; |
||
7693 | akron1 | 1832 | ASSERT(UTILS.Align(n, 32)); |
7597 | akron1 | 1833 | pushc(n); |
1834 | pushc(param1); |
||
7693 | akron1 | 1835 | CallRTL(pic, IL._new) |
7597 | akron1 | 1836 | |
7693 | akron1 | 1837 | |IL.opDISP: |
7597 | akron1 | 1838 | PushAll(1); |
7693 | akron1 | 1839 | CallRTL(pic, IL._dispose) |
7597 | akron1 | 1840 | |
7693 | akron1 | 1841 | |IL.opEQS .. IL.opGES: |
7597 | akron1 | 1842 | PushAll(4); |
7693 | akron1 | 1843 | pushc(opcode - IL.opEQS); |
1844 | CallRTL(pic, IL._strcmp); |
||
7597 | akron1 | 1845 | GetRegA |
1846 | |||
7693 | akron1 | 1847 | |IL.opEQSW .. IL.opGESW: |
7597 | akron1 | 1848 | PushAll(4); |
7693 | akron1 | 1849 | pushc(opcode - IL.opEQSW); |
1850 | CallRTL(pic, IL._strcmpw); |
||
7597 | akron1 | 1851 | GetRegA |
1852 | |||
7693 | akron1 | 1853 | |IL.opEQP, IL.opNEP, IL.opEQIP, IL.opNEIP: |
7597 | akron1 | 1854 | UnOp(reg1); |
7693 | akron1 | 1855 | CASE opcode OF |
1856 | |IL.opEQP, IL.opNEP: |
||
7597 | akron1 | 1857 | IF pic THEN |
7693 | akron1 | 1858 | reg2 := GetAnyReg(); |
7597 | akron1 | 1859 | Pic(reg2, BIN.PICCODE, param1); |
1860 | cmprr(reg1, reg2); |
||
1861 | drop |
||
1862 | ELSE |
||
7983 | leency | 1863 | OutByte2(081H, 0F8H + reg1); (* cmp reg1, L *) |
7597 | akron1 | 1864 | Reloc(BIN.RCODE, param1) |
1865 | END |
||
1866 | |||
7693 | akron1 | 1867 | |IL.opEQIP, IL.opNEIP: |
7597 | akron1 | 1868 | IF pic THEN |
7693 | akron1 | 1869 | reg2 := GetAnyReg(); |
7597 | akron1 | 1870 | Pic(reg2, BIN.PICIMP, param1); |
7983 | leency | 1871 | OutByte2(03BH, reg1 * 8 + reg2); (* cmp reg1, dword [reg2] *) |
7597 | akron1 | 1872 | drop |
1873 | ELSE |
||
7983 | leency | 1874 | OutByte2(3BH, 05H + reg1 * 8); (* cmp reg1, dword[L] *) |
7597 | akron1 | 1875 | Reloc(BIN.RIMP, param1) |
1876 | END |
||
1877 | |||
1878 | END; |
||
1879 | drop; |
||
7693 | akron1 | 1880 | reg1 := GetAnyReg(); |
7597 | akron1 | 1881 | |
7693 | akron1 | 1882 | CASE opcode OF |
1883 | |IL.opEQP, IL.opEQIP: setcc(sete, reg1) |
||
1884 | |IL.opNEP, IL.opNEIP: setcc(setne, reg1) |
||
7597 | akron1 | 1885 | END; |
1886 | |||
1887 | andrc(reg1, 1) |
||
1888 | |||
7693 | akron1 | 1889 | |IL.opPUSHT: |
7597 | akron1 | 1890 | UnOp(reg1); |
7983 | leency | 1891 | movrm(GetAnyReg(), reg1, -4) |
7597 | akron1 | 1892 | |
7693 | akron1 | 1893 | |IL.opISREC: |
7597 | akron1 | 1894 | PushAll(2); |
7693 | akron1 | 1895 | pushc(param2 * tcount); |
1896 | CallRTL(pic, IL._isrec); |
||
7597 | akron1 | 1897 | GetRegA |
1898 | |||
7693 | akron1 | 1899 | |IL.opIS: |
7597 | akron1 | 1900 | PushAll(1); |
7693 | akron1 | 1901 | pushc(param2 * tcount); |
1902 | CallRTL(pic, IL._is); |
||
7597 | akron1 | 1903 | GetRegA |
1904 | |||
7693 | akron1 | 1905 | |IL.opTYPEGR: |
7597 | akron1 | 1906 | PushAll(1); |
7693 | akron1 | 1907 | pushc(param2 * tcount); |
1908 | CallRTL(pic, IL._guardrec); |
||
7597 | akron1 | 1909 | GetRegA |
1910 | |||
7693 | akron1 | 1911 | |IL.opTYPEGP: |
7597 | akron1 | 1912 | UnOp(reg1); |
1913 | PushAll(0); |
||
1914 | push(reg1); |
||
7693 | akron1 | 1915 | pushc(param2 * tcount); |
1916 | CallRTL(pic, IL._guard); |
||
7597 | akron1 | 1917 | GetRegA |
1918 | |||
7693 | akron1 | 1919 | |IL.opTYPEGD: |
7597 | akron1 | 1920 | UnOp(reg1); |
1921 | PushAll(0); |
||
7983 | leency | 1922 | pushm(reg1, -4); |
7693 | akron1 | 1923 | pushc(param2 * tcount); |
1924 | CallRTL(pic, IL._guardrec); |
||
7597 | akron1 | 1925 | GetRegA |
1926 | |||
7693 | akron1 | 1927 | |IL.opCASET: |
7597 | akron1 | 1928 | push(ecx); |
1929 | push(ecx); |
||
7693 | akron1 | 1930 | pushc(param2 * tcount); |
1931 | CallRTL(pic, IL._guardrec); |
||
7597 | akron1 | 1932 | pop(ecx); |
1933 | test(eax); |
||
1934 | jcc(jne, param1) |
||
1935 | |||
7693 | akron1 | 1936 | |IL.opPACK: |
7597 | akron1 | 1937 | BinOp(reg1, reg2); |
1938 | push(reg2); |
||
7983 | leency | 1939 | OutByte3(0DBH, 004H, 024H); (* fild dword[esp] *) |
1940 | OutByte2(0DDH, reg1); (* fld qword[reg1] *) |
||
1941 | OutByte2(0D9H, 0FDH); (* fscale *) |
||
1942 | OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *) |
||
1943 | OutByte3(0DBH, 01CH, 024H); (* fistp dword[esp] *) |
||
7597 | akron1 | 1944 | pop(reg2); |
1945 | drop; |
||
1946 | drop |
||
1947 | |||
7693 | akron1 | 1948 | |IL.opPACKC: |
7597 | akron1 | 1949 | UnOp(reg1); |
1950 | pushc(param2); |
||
7983 | leency | 1951 | OutByte3(0DBH, 004H, 024H); (* fild dword[esp] *) |
1952 | OutByte2(0DDH, reg1); (* fld qword[reg1] *) |
||
1953 | OutByte2(0D9H, 0FDH); (* fscale *) |
||
1954 | OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *) |
||
1955 | OutByte3(0DBH, 01CH, 024H); (* fistp dword[esp] *) |
||
7597 | akron1 | 1956 | pop(reg1); |
1957 | drop |
||
1958 | |||
7693 | akron1 | 1959 | |IL.opUNPK: |
7597 | akron1 | 1960 | BinOp(reg1, reg2); |
7983 | leency | 1961 | OutByte2(0DDH, reg1); (* fld qword[reg1] *) |
1962 | OutByte2(0D9H, 0F4H); (* fxtract *) |
||
1963 | OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *) |
||
1964 | OutByte2(0DBH, 018H + reg2); (* fistp dword[reg2] *) |
||
7597 | akron1 | 1965 | drop; |
1966 | drop |
||
1967 | |||
7693 | akron1 | 1968 | |IL.opPUSHF: |
8097 | maxcodehac | 1969 | ASSERT(fr >= 0); |
1970 | DEC(fr); |
||
7597 | akron1 | 1971 | subrc(esp, 8); |
7983 | leency | 1972 | OutByte3(0DDH, 01CH, 024H) (* fstp qword[esp] *) |
7597 | akron1 | 1973 | |
7693 | akron1 | 1974 | |IL.opLOADF: |
8097 | maxcodehac | 1975 | INC(fr); |
1976 | IF fr > MAX_FR THEN |
||
1977 | ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
||
1978 | END; |
||
7597 | akron1 | 1979 | UnOp(reg1); |
7983 | leency | 1980 | OutByte2(0DDH, reg1); (* fld qword[reg1] *) |
7597 | akron1 | 1981 | drop |
1982 | |||
7693 | akron1 | 1983 | |IL.opCONSTF: |
8097 | maxcodehac | 1984 | INC(fr); |
1985 | IF fr > MAX_FR THEN |
||
1986 | ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
||
1987 | END; |
||
7597 | akron1 | 1988 | float := cmd.float; |
1989 | IF float = 0.0 THEN |
||
7983 | leency | 1990 | OutByte2(0D9H, 0EEH) (* fldz *) |
7597 | akron1 | 1991 | ELSIF float = 1.0 THEN |
7983 | leency | 1992 | OutByte2(0D9H, 0E8H) (* fld1 *) |
7597 | akron1 | 1993 | ELSIF float = -1.0 THEN |
7983 | leency | 1994 | OutByte2(0D9H, 0E8H); (* fld1 *) |
1995 | OutByte2(0D9H, 0E0H) (* fchs *) |
||
7597 | akron1 | 1996 | ELSE |
9873 | akron1 | 1997 | LoadFltConst(float) |
7597 | akron1 | 1998 | END |
1999 | |||
7983 | leency | 2000 | |IL.opSAVEF, IL.opSAVEFI: |
8097 | maxcodehac | 2001 | ASSERT(fr >= 0); |
2002 | DEC(fr); |
||
7597 | akron1 | 2003 | UnOp(reg1); |
7983 | leency | 2004 | OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *) |
7597 | akron1 | 2005 | drop |
2006 | |||
8097 | maxcodehac | 2007 | |IL.opADDF: |
2008 | ASSERT(fr >= 1); |
||
2009 | DEC(fr); |
||
7983 | leency | 2010 | OutByte2(0DEH, 0C1H) (* faddp st1, st *) |
7597 | akron1 | 2011 | |
7693 | akron1 | 2012 | |IL.opSUBF: |
8097 | maxcodehac | 2013 | ASSERT(fr >= 1); |
2014 | DEC(fr); |
||
7983 | leency | 2015 | OutByte2(0DEH, 0E9H) (* fsubp st1, st *) |
7597 | akron1 | 2016 | |
7693 | akron1 | 2017 | |IL.opSUBFI: |
8097 | maxcodehac | 2018 | ASSERT(fr >= 1); |
2019 | DEC(fr); |
||
7983 | leency | 2020 | OutByte2(0DEH, 0E1H) (* fsubrp st1, st *) |
7597 | akron1 | 2021 | |
7693 | akron1 | 2022 | |IL.opMULF: |
8097 | maxcodehac | 2023 | ASSERT(fr >= 1); |
2024 | DEC(fr); |
||
7983 | leency | 2025 | OutByte2(0DEH, 0C9H) (* fmulp st1, st *) |
7597 | akron1 | 2026 | |
7693 | akron1 | 2027 | |IL.opDIVF: |
8097 | maxcodehac | 2028 | ASSERT(fr >= 1); |
2029 | DEC(fr); |
||
7983 | leency | 2030 | OutByte2(0DEH, 0F9H) (* fdivp st1, st *) |
7597 | akron1 | 2031 | |
7693 | akron1 | 2032 | |IL.opDIVFI: |
8097 | maxcodehac | 2033 | ASSERT(fr >= 1); |
2034 | DEC(fr); |
||
7983 | leency | 2035 | OutByte2(0DEH, 0F1H) (* fdivrp st1, st *) |
7597 | akron1 | 2036 | |
7693 | akron1 | 2037 | |IL.opUMINF: |
8097 | maxcodehac | 2038 | ASSERT(fr >= 0); |
7983 | leency | 2039 | OutByte2(0D9H, 0E0H) (* fchs *) |
7597 | akron1 | 2040 | |
7693 | akron1 | 2041 | |IL.opFABS: |
8097 | maxcodehac | 2042 | ASSERT(fr >= 0); |
7983 | leency | 2043 | OutByte2(0D9H, 0E1H) (* fabs *) |
7597 | akron1 | 2044 | |
7693 | akron1 | 2045 | |IL.opFLT: |
8097 | maxcodehac | 2046 | INC(fr); |
2047 | IF fr > MAX_FR THEN |
||
2048 | ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
||
2049 | END; |
||
7597 | akron1 | 2050 | UnOp(reg1); |
2051 | push(reg1); |
||
7983 | leency | 2052 | OutByte3(0DBH, 004H, 024H); (* fild dword[esp] *) |
7597 | akron1 | 2053 | pop(reg1); |
2054 | drop |
||
2055 | |||
7693 | akron1 | 2056 | |IL.opFLOOR: |
8097 | maxcodehac | 2057 | ASSERT(fr >= 0); |
2058 | DEC(fr); |
||
7597 | akron1 | 2059 | subrc(esp, 8); |
7983 | leency | 2060 | OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 004H); (* fstcw word[esp+4] *) |
2061 | OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 006H); (* fstcw word[esp+6] *) |
||
2062 | OutByte2(066H, 081H); OutByte3(064H, 024H, 004H); OutWord(0F3FFH); (* and word[esp+4], 1111001111111111b *) |
||
2063 | OutByte2(066H, 081H); OutByte3(04CH, 024H, 004H); OutWord(00400H); (* or word[esp+4], 0000010000000000b *) |
||
2064 | OutByte2(0D9H, 06CH); OutByte2(024H, 004H); (* fldcw word[esp+4] *) |
||
2065 | OutByte2(0D9H, 0FCH); (* frndint *) |
||
2066 | OutByte3(0DBH, 01CH, 024H); (* fistp dword[esp] *) |
||
7693 | akron1 | 2067 | pop(GetAnyReg()); |
7983 | leency | 2068 | OutByte2(0D9H, 06CH); OutByte2(024H, 002H); (* fldcw word[esp+2] *) |
7597 | akron1 | 2069 | addrc(esp, 4) |
2070 | |||
7693 | akron1 | 2071 | |IL.opEQF: |
8097 | maxcodehac | 2072 | ASSERT(fr >= 1); |
2073 | DEC(fr, 2); |
||
7983 | leency | 2074 | fcmp; |
2075 | OutByte2(07AH, 003H); (* jp L *) |
||
7597 | akron1 | 2076 | setcc(sete, al) |
7983 | leency | 2077 | (* L: *) |
7597 | akron1 | 2078 | |
7693 | akron1 | 2079 | |IL.opNEF: |
8097 | maxcodehac | 2080 | ASSERT(fr >= 1); |
2081 | DEC(fr, 2); |
||
7983 | leency | 2082 | fcmp; |
2083 | OutByte2(07AH, 003H); (* jp L *) |
||
7597 | akron1 | 2084 | setcc(setne, al) |
7983 | leency | 2085 | (* L: *) |
7597 | akron1 | 2086 | |
7693 | akron1 | 2087 | |IL.opLTF: |
8097 | maxcodehac | 2088 | ASSERT(fr >= 1); |
2089 | DEC(fr, 2); |
||
7983 | leency | 2090 | fcmp; |
2091 | OutByte2(07AH, 00EH); (* jp L *) |
||
7597 | akron1 | 2092 | setcc(setc, al); |
2093 | setcc(sete, ah); |
||
2094 | test(eax); |
||
2095 | setcc(sete, al); |
||
2096 | andrc(eax, 1) |
||
7983 | leency | 2097 | (* L: *) |
7597 | akron1 | 2098 | |
7693 | akron1 | 2099 | |IL.opGTF: |
8097 | maxcodehac | 2100 | ASSERT(fr >= 1); |
2101 | DEC(fr, 2); |
||
7983 | leency | 2102 | fcmp; |
2103 | OutByte2(07AH, 00FH); (* jp L *) |
||
7597 | akron1 | 2104 | setcc(setc, al); |
2105 | setcc(sete, ah); |
||
2106 | cmprc(eax, 1); |
||
2107 | setcc(sete, al); |
||
2108 | andrc(eax, 1) |
||
7983 | leency | 2109 | (* L: *) |
7597 | akron1 | 2110 | |
7693 | akron1 | 2111 | |IL.opLEF: |
8097 | maxcodehac | 2112 | ASSERT(fr >= 1); |
2113 | DEC(fr, 2); |
||
7983 | leency | 2114 | fcmp; |
2115 | OutByte2(07AH, 003H); (* jp L *) |
||
7597 | akron1 | 2116 | setcc(setnc, al) |
7983 | leency | 2117 | (* L: *) |
7597 | akron1 | 2118 | |
7693 | akron1 | 2119 | |IL.opGEF: |
8097 | maxcodehac | 2120 | ASSERT(fr >= 1); |
2121 | DEC(fr, 2); |
||
7983 | leency | 2122 | fcmp; |
2123 | OutByte2(07AH, 010H); (* jp L *) |
||
7597 | akron1 | 2124 | setcc(setc, al); |
2125 | setcc(sete, ah); |
||
7983 | leency | 2126 | OutByte2(000H, 0E0H); (* add al, ah *) |
2127 | OutByte2(03CH, 001H); (* cmp al, 1 *) |
||
7597 | akron1 | 2128 | setcc(sete, al); |
2129 | andrc(eax, 1) |
||
7983 | leency | 2130 | (* L: *) |
7597 | akron1 | 2131 | |
7693 | akron1 | 2132 | |IL.opINF: |
8097 | maxcodehac | 2133 | INC(fr); |
2134 | IF fr > MAX_FR THEN |
||
2135 | ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
||
2136 | END; |
||
9873 | akron1 | 2137 | LoadFltConst(UTILS.inf) |
7597 | akron1 | 2138 | |
9873 | akron1 | 2139 | |
7693 | akron1 | 2140 | |IL.opLADR_UNPK: |
7597 | akron1 | 2141 | n := param2 * 4; |
7693 | akron1 | 2142 | reg1 := GetAnyReg(); |
7983 | leency | 2143 | OutByte2(8DH, 45H + reg1 * 8 + long(n)); (* lea reg1, dword[ebp + n] *) |
7597 | akron1 | 2144 | OutIntByte(n); |
2145 | BinOp(reg1, reg2); |
||
7983 | leency | 2146 | OutByte2(0DDH, reg1); (* fld qword[reg1] *) |
2147 | OutByte2(0D9H, 0F4H); (* fxtract *) |
||
2148 | OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *) |
||
2149 | OutByte2(0DBH, 018H + reg2); (* fistp dword[reg2] *) |
||
7597 | akron1 | 2150 | drop; |
2151 | drop |
||
2152 | |||
7693 | akron1 | 2153 | |IL.opSADR_PARAM: |
7597 | akron1 | 2154 | IF pic THEN |
7693 | akron1 | 2155 | reg1 := GetAnyReg(); |
7597 | akron1 | 2156 | Pic(reg1, BIN.PICDATA, stroffs + param2); |
2157 | push(reg1); |
||
2158 | drop |
||
2159 | ELSE |
||
7983 | leency | 2160 | OutByte(068H); (* push _data + stroffs + param2 *) |
7597 | akron1 | 2161 | Reloc(BIN.RDATA, stroffs + param2) |
2162 | END |
||
2163 | |||
7983 | leency | 2164 | |IL.opVADR_PARAM, IL.opLLOAD32_PARAM: |
2165 | pushm(ebp, param2 * 4) |
||
7597 | akron1 | 2166 | |
7693 | akron1 | 2167 | |IL.opCONST_PARAM: |
7597 | akron1 | 2168 | pushc(param2) |
2169 | |||
7693 | akron1 | 2170 | |IL.opGLOAD32_PARAM: |
7597 | akron1 | 2171 | IF pic THEN |
7693 | akron1 | 2172 | reg1 := GetAnyReg(); |
7597 | akron1 | 2173 | Pic(reg1, BIN.PICBSS, param2); |
7983 | leency | 2174 | pushm(reg1, 0); |
7597 | akron1 | 2175 | drop |
2176 | ELSE |
||
7983 | leency | 2177 | OutByte2(0FFH, 035H); (* push dword[_bss + param2] *) |
7597 | akron1 | 2178 | Reloc(BIN.RBSS, param2) |
2179 | END |
||
2180 | |||
7693 | akron1 | 2181 | |IL.opLOAD32_PARAM: |
7597 | akron1 | 2182 | UnOp(reg1); |
7983 | leency | 2183 | pushm(reg1, 0); |
7597 | akron1 | 2184 | drop |
2185 | |||
7693 | akron1 | 2186 | |IL.opGADR_SAVEC: |
7597 | akron1 | 2187 | IF pic THEN |
7693 | akron1 | 2188 | reg1 := GetAnyReg(); |
7597 | akron1 | 2189 | Pic(reg1, BIN.PICBSS, param1); |
7983 | leency | 2190 | OutByte2(0C7H, reg1); (* mov dword[reg1], param2 *) |
7597 | akron1 | 2191 | OutInt(param2); |
2192 | drop |
||
2193 | ELSE |
||
7983 | leency | 2194 | OutByte2(0C7H, 05H); (* mov dword[_bss + param1], param2 *) |
7597 | akron1 | 2195 | Reloc(BIN.RBSS, param1); |
2196 | OutInt(param2) |
||
2197 | END |
||
2198 | |||
7693 | akron1 | 2199 | |IL.opLADR_SAVEC: |
7597 | akron1 | 2200 | n := param1 * 4; |
7983 | leency | 2201 | OutByte2(0C7H, 45H + long(n)); (* mov dword[ebp + n], param2 *) |
7597 | akron1 | 2202 | OutIntByte(n); |
2203 | OutInt(param2) |
||
2204 | |||
7693 | akron1 | 2205 | |IL.opLADR_SAVE: |
7597 | akron1 | 2206 | UnOp(reg1); |
7983 | leency | 2207 | movmr(ebp, param2 * 4, reg1); |
7597 | akron1 | 2208 | drop |
2209 | |||
7693 | akron1 | 2210 | |IL.opLADR_INCC: |
7597 | akron1 | 2211 | n := param1 * 4; |
7693 | akron1 | 2212 | IF ABS(param2) = 1 THEN |
7983 | leency | 2213 | OutByte2(0FFH, 45H + 8 * ORD(param2 = -1) + long(n)); (* inc/dec dword[ebp + n] *) |
7693 | akron1 | 2214 | OutIntByte(n) |
2215 | ELSE |
||
7983 | leency | 2216 | OutByte2(81H + short(param2), 45H + long(n)); (* add dword[ebp + n], param2 *) |
7693 | akron1 | 2217 | OutIntByte(n); |
2218 | OutIntByte(param2) |
||
2219 | END |
||
7597 | akron1 | 2220 | |
7693 | akron1 | 2221 | |IL.opLADR_INCCB, IL.opLADR_DECCB: |
7597 | akron1 | 2222 | n := param1 * 4; |
7693 | akron1 | 2223 | IF param2 = 1 THEN |
7983 | leency | 2224 | OutByte2(0FEH, 45H + 8 * ORD(opcode = IL.opLADR_DECCB) + long(n)); (* inc/dec byte[ebp + n] *) |
7693 | akron1 | 2225 | OutIntByte(n) |
2226 | ELSE |
||
7983 | leency | 2227 | OutByte2(80H, 45H + 28H * ORD(opcode = IL.opLADR_DECCB) + long(n)); (* add/sub byte[ebp + n], param2 *) |
7693 | akron1 | 2228 | OutIntByte(n); |
2229 | OutByte(param2 MOD 256) |
||
2230 | END |
||
7597 | akron1 | 2231 | |
7693 | akron1 | 2232 | |IL.opLADR_INC, IL.opLADR_DEC: |
7597 | akron1 | 2233 | n := param2 * 4; |
2234 | UnOp(reg1); |
||
7983 | leency | 2235 | OutByte2(01H + 28H * ORD(opcode = IL.opLADR_DEC), 45H + long(n) + reg1 * 8); (* add/sub dword[ebp + n], reg1 *) |
7597 | akron1 | 2236 | OutIntByte(n); |
2237 | drop |
||
2238 | |||
7693 | akron1 | 2239 | |IL.opLADR_INCB, IL.opLADR_DECB: |
7597 | akron1 | 2240 | n := param2 * 4; |
2241 | UnOp(reg1); |
||
7983 | leency | 2242 | OutByte2(28H * ORD(opcode = IL.opLADR_DECB), 45H + long(n) + reg1 * 8); (* add/sub byte[ebp + n], reg1 *) |
7597 | akron1 | 2243 | OutIntByte(n); |
2244 | drop |
||
2245 | |||
7693 | akron1 | 2246 | |IL.opLADR_INCL, IL.opLADR_EXCL: |
7597 | akron1 | 2247 | n := param2 * 4; |
2248 | UnOp(reg1); |
||
2249 | cmprc(reg1, 32); |
||
2250 | label := NewLabel(); |
||
2251 | jcc(jnb, label); |
||
7983 | leency | 2252 | OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), 45H + long(n) + reg1 * 8); (* bts(r) dword[ebp + n], reg1 *) |
7597 | akron1 | 2253 | OutIntByte(n); |
2254 | SetLabel(label); |
||
2255 | drop |
||
2256 | |||
7693 | akron1 | 2257 | |IL.opLADR_INCLC, IL.opLADR_EXCLC: |
7597 | akron1 | 2258 | n := param1 * 4; |
7983 | leency | 2259 | OutByte3(0FH, 0BAH, 6DH + long(n) + 8 * ORD(opcode = IL.opLADR_EXCLC)); (* bts(r) dword[ebp + n], param2 *) |
7597 | akron1 | 2260 | OutIntByte(n); |
2261 | OutByte(param2) |
||
2262 | |||
8097 | maxcodehac | 2263 | |IL.opFNAME: |
2264 | fname := cmd(IL.FNAMECMD).fname |
||
2265 | |||
6613 | leency | 2266 | END; |
7597 | akron1 | 2267 | |
2268 | cmd := cmd.next(COMMAND) |
||
6613 | leency | 2269 | END; |
2270 | |||
7597 | akron1 | 2271 | ASSERT(R.pushed = 0); |
8097 | maxcodehac | 2272 | ASSERT(R.top = -1); |
2273 | ASSERT(fr = -1) |
||
7597 | akron1 | 2274 | END translate; |
6613 | leency | 2275 | |
2276 | |||
9873 | akron1 | 2277 | PROCEDURE prolog (pic: BOOLEAN; target, stack, dllret: INTEGER): INTEGER; |
7597 | akron1 | 2278 | VAR |
7696 | akron1 | 2279 | reg1, entry, L, dcount: INTEGER; |
6613 | leency | 2280 | |
7597 | akron1 | 2281 | BEGIN |
2282 | entry := NewLabel(); |
||
2283 | SetLabel(entry); |
||
8097 | maxcodehac | 2284 | dcount := CHL.Length(IL.codes.data); |
6613 | leency | 2285 | |
9873 | akron1 | 2286 | push(ebp); |
2287 | mov(ebp, esp); |
||
2288 | SetLabel(NewLabel()); |
||
2289 | mainFltConstLabel := CodeList.last(LABEL); |
||
2290 | FltConstLabel := mainFltConstLabel; |
||
2291 | mainLocVarSize := 0; |
||
2292 | LocVarSize := 0; |
||
2293 | |||
7983 | leency | 2294 | IF target = TARGETS.Win32DLL THEN |
2295 | pushm(ebp, 16); |
||
2296 | pushm(ebp, 12); |
||
2297 | pushm(ebp, 8); |
||
7693 | akron1 | 2298 | CallRTL(pic, IL._dllentry); |
7597 | akron1 | 2299 | test(eax); |
8097 | maxcodehac | 2300 | jcc(je, dllret); |
2301 | pushc(0) |
||
7983 | leency | 2302 | ELSIF target = TARGETS.KolibriOSDLL THEN |
8097 | maxcodehac | 2303 | OutByte(68H); (* push IMPORT *) |
2304 | Reloc(BIN.IMPTAB, 0) |
||
2305 | ELSIF target = TARGETS.KolibriOS THEN |
||
7693 | akron1 | 2306 | reg1 := GetAnyReg(); |
7597 | akron1 | 2307 | Pic(reg1, BIN.IMPTAB, 0); |
7983 | leency | 2308 | push(reg1); (* push IMPORT *) |
7597 | akron1 | 2309 | drop |
7983 | leency | 2310 | ELSIF target = TARGETS.Linux32 THEN |
9873 | akron1 | 2311 | mov(eax, ebp); |
2312 | addrc(eax, 4); |
||
2313 | push(eax) |
||
7597 | akron1 | 2314 | ELSE |
2315 | pushc(0) |
||
7667 | akron1 | 2316 | END; |
2317 | |||
7597 | akron1 | 2318 | IF pic THEN |
7693 | akron1 | 2319 | reg1 := GetAnyReg(); |
7597 | akron1 | 2320 | Pic(reg1, BIN.PICCODE, entry); |
8097 | maxcodehac | 2321 | push(reg1); (* push CODE *) |
7597 | akron1 | 2322 | Pic(reg1, BIN.PICDATA, 0); |
7983 | leency | 2323 | push(reg1); (* push _data *) |
8097 | maxcodehac | 2324 | pushc(tcount); |
7597 | akron1 | 2325 | Pic(reg1, BIN.PICDATA, tcount * 4 + dcount); |
7983 | leency | 2326 | push(reg1); (* push _data + tcount * 4 + dcount *) |
7597 | akron1 | 2327 | drop |
2328 | ELSE |
||
8097 | maxcodehac | 2329 | OutByte(68H); (* push CODE *) |
2330 | Reloc(BIN.RCODE, entry); |
||
7983 | leency | 2331 | OutByte(68H); (* push _data *) |
8097 | maxcodehac | 2332 | Reloc(BIN.RDATA, 0); |
2333 | pushc(tcount); |
||
2334 | OutByte(68H); (* push _data + tcount * 4 + dcount *) |
||
7597 | akron1 | 2335 | Reloc(BIN.RDATA, tcount * 4 + dcount) |
2336 | END; |
||
6613 | leency | 2337 | |
7696 | akron1 | 2338 | CallRTL(pic, IL._init); |
2339 | |||
8097 | maxcodehac | 2340 | IF target IN {TARGETS.Win32C, TARGETS.Win32GUI, TARGETS.Linux32} THEN |
7696 | akron1 | 2341 | L := NewLabel(); |
2342 | pushc(0); |
||
2343 | push(esp); |
||
2344 | pushc(1024 * 1024 * stack); |
||
2345 | pushc(0); |
||
2346 | CallRTL(pic, IL._new); |
||
2347 | pop(eax); |
||
2348 | test(eax); |
||
2349 | jcc(je, L); |
||
2350 | addrc(eax, 1024 * 1024 * stack - 4); |
||
2351 | mov(esp, eax); |
||
2352 | SetLabel(L) |
||
2353 | END |
||
9873 | akron1 | 2354 | |
2355 | RETURN entry |
||
7597 | akron1 | 2356 | END prolog; |
6613 | leency | 2357 | |
2358 | |||
7696 | akron1 | 2359 | PROCEDURE epilog (pic: BOOLEAN; modname: ARRAY OF CHAR; target, stack, ver, dllinit, dllret, sofinit: INTEGER); |
7597 | akron1 | 2360 | VAR |
7693 | akron1 | 2361 | exp: IL.EXPORT_PROC; |
7597 | akron1 | 2362 | path, name, ext: PATHS.PATH; |
6613 | leency | 2363 | |
7693 | akron1 | 2364 | dcount, i: INTEGER; |
6613 | leency | 2365 | |
7597 | akron1 | 2366 | |
8097 | maxcodehac | 2367 | PROCEDURE _import (imp: LISTS.LIST); |
7597 | akron1 | 2368 | VAR |
7693 | akron1 | 2369 | lib: IL.IMPORT_LIB; |
2370 | proc: IL.IMPORT_PROC; |
||
7597 | akron1 | 2371 | |
2372 | BEGIN |
||
2373 | |||
7693 | akron1 | 2374 | lib := imp.first(IL.IMPORT_LIB); |
7597 | akron1 | 2375 | WHILE lib # NIL DO |
2376 | BIN.Import(program, lib.name, 0); |
||
7693 | akron1 | 2377 | proc := lib.procs.first(IL.IMPORT_PROC); |
7597 | akron1 | 2378 | WHILE proc # NIL DO |
2379 | BIN.Import(program, proc.name, proc.label); |
||
7693 | akron1 | 2380 | proc := proc.next(IL.IMPORT_PROC) |
7597 | akron1 | 2381 | END; |
7693 | akron1 | 2382 | lib := lib.next(IL.IMPORT_LIB) |
7597 | akron1 | 2383 | END |
2384 | |||
8097 | maxcodehac | 2385 | END _import; |
7597 | akron1 | 2386 | |
2387 | |||
6613 | leency | 2388 | BEGIN |
2389 | |||
7983 | leency | 2390 | IF target IN {TARGETS.Win32C, TARGETS.Win32GUI, TARGETS.KolibriOS, TARGETS.Linux32} THEN |
7597 | akron1 | 2391 | pushc(0); |
7693 | akron1 | 2392 | CallRTL(pic, IL._exit); |
7983 | leency | 2393 | ELSIF target = TARGETS.Win32DLL THEN |
7597 | akron1 | 2394 | SetLabel(dllret); |
2395 | movrc(eax, 1); |
||
7983 | leency | 2396 | OutByte(0C9H); (* leave *) |
2397 | OutByte3(0C2H, 0CH, 0) (* ret 12 *) |
||
2398 | ELSIF target = TARGETS.KolibriOSDLL THEN |
||
7597 | akron1 | 2399 | movrc(eax, 1); |
9873 | akron1 | 2400 | OutByte(0C9H); (* leave *) |
7983 | leency | 2401 | ret |
2402 | ELSIF target = TARGETS.Linux32SO THEN |
||
9873 | akron1 | 2403 | OutByte(0C9H); (* leave *) |
7983 | leency | 2404 | ret; |
7693 | akron1 | 2405 | SetLabel(sofinit); |
2406 | CallRTL(pic, IL._sofinit); |
||
7983 | leency | 2407 | ret |
7597 | akron1 | 2408 | END; |
6613 | leency | 2409 | |
7597 | akron1 | 2410 | fixup; |
2411 | |||
7696 | akron1 | 2412 | dcount := CHL.Length(IL.codes.data); |
7597 | akron1 | 2413 | |
2414 | FOR i := 0 TO tcount - 1 DO |
||
7696 | akron1 | 2415 | BIN.PutData32LE(program, CHL.GetInt(IL.codes.types, i)) |
6613 | leency | 2416 | END; |
2417 | |||
7597 | akron1 | 2418 | FOR i := 0 TO dcount - 1 DO |
7696 | akron1 | 2419 | BIN.PutData(program, CHL.GetByte(IL.codes.data, i)) |
6613 | leency | 2420 | END; |
2421 | |||
7597 | akron1 | 2422 | program.modname := CHL.Length(program.data); |
6613 | leency | 2423 | |
7597 | akron1 | 2424 | PATHS.split(modname, path, name, ext); |
2425 | BIN.PutDataStr(program, name); |
||
2426 | BIN.PutDataStr(program, ext); |
||
2427 | BIN.PutData(program, 0); |
||
6613 | leency | 2428 | |
7983 | leency | 2429 | IF target = TARGETS.KolibriOSDLL THEN |
7597 | akron1 | 2430 | BIN.Export(program, "lib_init", dllinit); |
2431 | END; |
||
6613 | leency | 2432 | |
7696 | akron1 | 2433 | exp := IL.codes.export.first(IL.EXPORT_PROC); |
7597 | akron1 | 2434 | WHILE exp # NIL DO |
2435 | BIN.Export(program, exp.name, exp.label); |
||
7693 | akron1 | 2436 | exp := exp.next(IL.EXPORT_PROC) |
6613 | leency | 2437 | END; |
2438 | |||
8097 | maxcodehac | 2439 | _import(IL.codes._import); |
6613 | leency | 2440 | |
7696 | akron1 | 2441 | IL.set_bss(MAX(IL.codes.bss, MAX(IL.codes.dmin - CHL.Length(IL.codes.data), 4))); |
6613 | leency | 2442 | |
8097 | maxcodehac | 2443 | BIN.SetParams(program, IL.codes.bss, stack * (1024 * 1024), WCHR(ver DIV 65536), WCHR(ver MOD 65536)) |
7597 | akron1 | 2444 | END epilog; |
2445 | |||
2446 | |||
7696 | akron1 | 2447 | PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS); |
7597 | akron1 | 2448 | VAR |
7693 | akron1 | 2449 | dllret, dllinit, sofinit: INTEGER; |
2450 | opt: PROG.OPTIONS; |
||
7597 | akron1 | 2451 | |
6613 | leency | 2452 | BEGIN |
8097 | maxcodehac | 2453 | FR[0] := 0; |
7696 | akron1 | 2454 | tcount := CHL.Length(IL.codes.types); |
6613 | leency | 2455 | |
7693 | akron1 | 2456 | opt := options; |
7597 | akron1 | 2457 | CodeList := LISTS.create(NIL); |
2458 | |||
7696 | akron1 | 2459 | program := BIN.create(IL.codes.lcount); |
7597 | akron1 | 2460 | |
2461 | dllret := NewLabel(); |
||
7693 | akron1 | 2462 | sofinit := NewLabel(); |
7597 | akron1 | 2463 | |
7983 | leency | 2464 | IF target = TARGETS.KolibriOSDLL THEN |
7693 | akron1 | 2465 | opt.pic := FALSE |
6613 | leency | 2466 | END; |
7597 | akron1 | 2467 | |
7983 | leency | 2468 | IF TARGETS.OS IN {TARGETS.osWIN32, TARGETS.osLINUX32} THEN |
7693 | akron1 | 2469 | opt.pic := TRUE |
7597 | akron1 | 2470 | END; |
2471 | |||
8859 | leency | 2472 | REG.Init(R, push, pop, mov, xchg, {eax, ecx, edx}); |
7597 | akron1 | 2473 | |
9873 | akron1 | 2474 | dllinit := prolog(opt.pic, target, opt.stack, dllret); |
7696 | akron1 | 2475 | translate(opt.pic, tcount * 4); |
2476 | epilog(opt.pic, outname, target, opt.stack, opt.version, dllinit, dllret, sofinit); |
||
7597 | akron1 | 2477 | |
2478 | BIN.fixup(program); |
||
2479 | |||
7983 | leency | 2480 | IF TARGETS.OS = TARGETS.osWIN32 THEN |
2481 | PE32.write(program, outname, target = TARGETS.Win32C, target = TARGETS.Win32DLL, FALSE) |
||
2482 | ELSIF target = TARGETS.KolibriOS THEN |
||
7597 | akron1 | 2483 | KOS.write(program, outname) |
7983 | leency | 2484 | ELSIF target = TARGETS.KolibriOSDLL THEN |
7693 | akron1 | 2485 | MSCOFF.write(program, outname, opt.version) |
7983 | leency | 2486 | ELSIF TARGETS.OS = TARGETS.osLINUX32 THEN |
2487 | ELF.write(program, outname, sofinit, target = TARGETS.Linux32SO, FALSE) |
||
6613 | leency | 2488 | END |
2489 | |||
7597 | akron1 | 2490 | END CodeGen; |
7209 | akron1 | 2491 | |
7597 | akron1 | 2492 | |
2493 | PROCEDURE SetProgram* (prog: BIN.PROGRAM); |
||
7209 | akron1 | 2494 | BEGIN |
7597 | akron1 | 2495 | program := prog; |
2496 | CodeList := LISTS.create(NIL) |
||
2497 | END SetProgram; |
||
2498 | |||
2499 | |||
7983 | leency | 2500 | END X86.=>>>>=>=>>>=>>=>=>=>=>> |