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