|
|
@@ -1,11 +1,4 @@
|
|
|
-(*
|
|
|
- BSD 2-Clause License
|
|
|
-
|
|
|
- Copyright (c) 2018-2023, Anton Krotov
|
|
|
- All rights reserved.
|
|
|
-*)
|
|
|
-
|
|
|
-MODULE X86;
|
|
|
+MODULE X86;
|
|
|
|
|
|
IMPORT IL, REG, UTILS, LISTS, BIN, PE32, KOS, MSCOFF, ELF, PROG,
|
|
|
CHL := CHUNKLISTS, PATHS, TARGETS, ERRORS;
|
|
|
@@ -104,2442 +97,2442 @@ VAR
|
|
|
|
|
|
|
|
|
PROCEDURE OutByte* (n: BYTE);
|
|
|
-VAR
|
|
|
- c: CODE;
|
|
|
- last: ANYCODE;
|
|
|
+ VAR
|
|
|
+ c: CODE;
|
|
|
+ last: ANYCODE;
|
|
|
|
|
|
-BEGIN
|
|
|
- last := CodeList.last(ANYCODE);
|
|
|
+ BEGIN
|
|
|
+ last := CodeList.last(ANYCODE);
|
|
|
|
|
|
- IF (last IS CODE) & (last(CODE).length < CODECHUNK) THEN
|
|
|
- c := last(CODE);
|
|
|
- c.code[c.length] := n;
|
|
|
- INC(c.length)
|
|
|
- ELSE
|
|
|
- NEW(c);
|
|
|
- c.code[0] := n;
|
|
|
- c.length := 1;
|
|
|
- LISTS.push(CodeList, c)
|
|
|
- END
|
|
|
+ IF (last IS CODE) & (last(CODE).length < CODECHUNK) THEN
|
|
|
+ c := last(CODE);
|
|
|
+ c.code[c.length] := n;
|
|
|
+ INC(c.length)
|
|
|
+ ELSE
|
|
|
+ NEW(c);
|
|
|
+ c.code[0] := n;
|
|
|
+ c.length := 1;
|
|
|
+ LISTS.push(CodeList, c)
|
|
|
+ END
|
|
|
|
|
|
-END OutByte;
|
|
|
+ END OutByte;
|
|
|
|
|
|
|
|
|
PROCEDURE OutInt (n: INTEGER);
|
|
|
-BEGIN
|
|
|
- OutByte(n MOD 256);
|
|
|
- OutByte(UTILS.Byte(n, 1));
|
|
|
- OutByte(UTILS.Byte(n, 2));
|
|
|
- OutByte(UTILS.Byte(n, 3))
|
|
|
-END OutInt;
|
|
|
+ BEGIN
|
|
|
+ OutByte(n MOD 256);
|
|
|
+ OutByte(UTILS.Byte(n, 1));
|
|
|
+ OutByte(UTILS.Byte(n, 2));
|
|
|
+ OutByte(UTILS.Byte(n, 3))
|
|
|
+ END OutInt;
|
|
|
|
|
|
|
|
|
PROCEDURE OutByte2 (a, b: BYTE);
|
|
|
-BEGIN
|
|
|
- OutByte(a);
|
|
|
- OutByte(b)
|
|
|
-END OutByte2;
|
|
|
+ BEGIN
|
|
|
+ OutByte(a);
|
|
|
+ OutByte(b)
|
|
|
+ END OutByte2;
|
|
|
|
|
|
|
|
|
PROCEDURE OutByte3 (a, b, c: BYTE);
|
|
|
-BEGIN
|
|
|
- OutByte(a);
|
|
|
- OutByte(b);
|
|
|
- OutByte(c)
|
|
|
-END OutByte3;
|
|
|
+ BEGIN
|
|
|
+ OutByte(a);
|
|
|
+ OutByte(b);
|
|
|
+ OutByte(c)
|
|
|
+ END OutByte3;
|
|
|
|
|
|
|
|
|
PROCEDURE OutWord (n: INTEGER);
|
|
|
-BEGIN
|
|
|
- ASSERT((0 <= n) & (n <= 65535));
|
|
|
- OutByte2(n MOD 256, n DIV 256)
|
|
|
-END OutWord;
|
|
|
+ BEGIN
|
|
|
+ ASSERT((0 <= n) & (n <= 65535));
|
|
|
+ OutByte2(n MOD 256, n DIV 256)
|
|
|
+ END OutWord;
|
|
|
|
|
|
|
|
|
PROCEDURE isByte* (n: INTEGER): BOOLEAN;
|
|
|
- RETURN (-128 <= n) & (n <= 127)
|
|
|
-END isByte;
|
|
|
+ RETURN (-128 <= n) & (n <= 127)
|
|
|
+ END isByte;
|
|
|
|
|
|
|
|
|
PROCEDURE short (n: INTEGER): INTEGER;
|
|
|
- RETURN 2 * ORD(isByte(n))
|
|
|
-END short;
|
|
|
+ RETURN 2 * ORD(isByte(n))
|
|
|
+ END short;
|
|
|
|
|
|
|
|
|
PROCEDURE long (n: INTEGER): INTEGER;
|
|
|
- RETURN 40H * ORD(~isByte(n))
|
|
|
-END long;
|
|
|
+ RETURN 40H * ORD(~isByte(n))
|
|
|
+ END long;
|
|
|
|
|
|
|
|
|
PROCEDURE OutIntByte (n: INTEGER);
|
|
|
-BEGIN
|
|
|
- IF isByte(n) THEN
|
|
|
- OutByte(n MOD 256)
|
|
|
- ELSE
|
|
|
- OutInt(n)
|
|
|
- END
|
|
|
-END OutIntByte;
|
|
|
+ BEGIN
|
|
|
+ IF isByte(n) THEN
|
|
|
+ OutByte(n MOD 256)
|
|
|
+ ELSE
|
|
|
+ OutInt(n)
|
|
|
+ END
|
|
|
+ END OutIntByte;
|
|
|
|
|
|
|
|
|
PROCEDURE shift* (op, reg: INTEGER);
|
|
|
-BEGIN
|
|
|
- CASE op OF
|
|
|
- |IL.opASR, IL.opASR1, IL.opASR2: OutByte(0F8H + reg)
|
|
|
- |IL.opROR, IL.opROR1, IL.opROR2: OutByte(0C8H + reg)
|
|
|
- |IL.opLSL, IL.opLSL1, IL.opLSL2: OutByte(0E0H + reg)
|
|
|
- |IL.opLSR, IL.opLSR1, IL.opLSR2: OutByte(0E8H + reg)
|
|
|
- END
|
|
|
-END shift;
|
|
|
+ BEGIN
|
|
|
+ CASE op OF
|
|
|
+ |IL.opASR, IL.opASR1, IL.opASR2: OutByte(0F8H + reg)
|
|
|
+ |IL.opROR, IL.opROR1, IL.opROR2: OutByte(0C8H + reg)
|
|
|
+ |IL.opLSL, IL.opLSL1, IL.opLSL2: OutByte(0E0H + reg)
|
|
|
+ |IL.opLSR, IL.opLSR1, IL.opLSR2: OutByte(0E8H + reg)
|
|
|
+ END
|
|
|
+ END shift;
|
|
|
|
|
|
|
|
|
PROCEDURE oprr (op: BYTE; reg1, reg2: INTEGER); (* op reg1, reg2 *)
|
|
|
-BEGIN
|
|
|
- OutByte2(op, 0C0H + 8 * reg2 + reg1)
|
|
|
-END oprr;
|
|
|
+ BEGIN
|
|
|
+ OutByte2(op, 0C0H + 8 * reg2 + reg1)
|
|
|
+ END oprr;
|
|
|
|
|
|
|
|
|
PROCEDURE mov (reg1, reg2: INTEGER); (* mov reg1, reg2 *)
|
|
|
-BEGIN
|
|
|
- oprr(89H, reg1, reg2)
|
|
|
-END mov;
|
|
|
+ BEGIN
|
|
|
+ oprr(89H, reg1, reg2)
|
|
|
+ END mov;
|
|
|
|
|
|
|
|
|
PROCEDURE xchg (reg1, reg2: INTEGER); (* xchg reg1, reg2 *)
|
|
|
-BEGIN
|
|
|
- IF eax IN {reg1, reg2} THEN
|
|
|
- OutByte(90H + reg1 + reg2)
|
|
|
- ELSE
|
|
|
- oprr(87H, reg1, reg2)
|
|
|
- END
|
|
|
-END xchg;
|
|
|
+ BEGIN
|
|
|
+ IF eax IN {reg1, reg2} THEN
|
|
|
+ OutByte(90H + reg1 + reg2)
|
|
|
+ ELSE
|
|
|
+ oprr(87H, reg1, reg2)
|
|
|
+ END
|
|
|
+ END xchg;
|
|
|
|
|
|
|
|
|
PROCEDURE pop (reg: INTEGER);
|
|
|
-BEGIN
|
|
|
- OutByte(58H + reg) (* pop reg *)
|
|
|
-END pop;
|
|
|
+ BEGIN
|
|
|
+ OutByte(58H + reg) (* pop reg *)
|
|
|
+ END pop;
|
|
|
|
|
|
|
|
|
PROCEDURE push (reg: INTEGER);
|
|
|
-BEGIN
|
|
|
- OutByte(50H + reg) (* push reg *)
|
|
|
-END push;
|
|
|
+ BEGIN
|
|
|
+ OutByte(50H + reg) (* push reg *)
|
|
|
+ END push;
|
|
|
|
|
|
|
|
|
PROCEDURE xor (reg1, reg2: INTEGER); (* xor reg1, reg2 *)
|
|
|
-BEGIN
|
|
|
- oprr(31H, reg1, reg2)
|
|
|
-END xor;
|
|
|
+ BEGIN
|
|
|
+ oprr(31H, reg1, reg2)
|
|
|
+ END xor;
|
|
|
|
|
|
|
|
|
PROCEDURE movrc (reg, n: INTEGER);
|
|
|
-BEGIN
|
|
|
- IF n = 0 THEN
|
|
|
- xor(reg, reg)
|
|
|
- ELSE
|
|
|
- OutByte(0B8H + reg); (* mov reg, n *)
|
|
|
- OutInt(n)
|
|
|
- END
|
|
|
-END movrc;
|
|
|
+ BEGIN
|
|
|
+ IF n = 0 THEN
|
|
|
+ xor(reg, reg)
|
|
|
+ ELSE
|
|
|
+ OutByte(0B8H + reg); (* mov reg, n *)
|
|
|
+ OutInt(n)
|
|
|
+ END
|
|
|
+ END movrc;
|
|
|
|
|
|
|
|
|
PROCEDURE pushc* (n: INTEGER);
|
|
|
-BEGIN
|
|
|
- OutByte(68H + short(n)); (* push n *)
|
|
|
- OutIntByte(n)
|
|
|
-END pushc;
|
|
|
+ BEGIN
|
|
|
+ OutByte(68H + short(n)); (* push n *)
|
|
|
+ OutIntByte(n)
|
|
|
+ END pushc;
|
|
|
|
|
|
|
|
|
PROCEDURE test (reg: INTEGER);
|
|
|
-BEGIN
|
|
|
- OutByte2(85H, 0C0H + reg * 9) (* test reg, reg *)
|
|
|
-END test;
|
|
|
+ BEGIN
|
|
|
+ OutByte2(85H, 0C0H + reg * 9) (* test reg, reg *)
|
|
|
+ END test;
|
|
|
|
|
|
|
|
|
PROCEDURE neg (reg: INTEGER);
|
|
|
-BEGIN
|
|
|
- OutByte2(0F7H, 0D8H + reg) (* neg reg *)
|
|
|
-END neg;
|
|
|
+ BEGIN
|
|
|
+ OutByte2(0F7H, 0D8H + reg) (* neg reg *)
|
|
|
+ END neg;
|
|
|
|
|
|
|
|
|
PROCEDURE not (reg: INTEGER);
|
|
|
-BEGIN
|
|
|
- OutByte2(0F7H, 0D0H + reg) (* not reg *)
|
|
|
-END not;
|
|
|
+ BEGIN
|
|
|
+ OutByte2(0F7H, 0D0H + reg) (* not reg *)
|
|
|
+ END not;
|
|
|
|
|
|
|
|
|
PROCEDURE add (reg1, reg2: INTEGER); (* add reg1, reg2 *)
|
|
|
-BEGIN
|
|
|
- oprr(01H, reg1, reg2)
|
|
|
-END add;
|
|
|
+ BEGIN
|
|
|
+ oprr(01H, reg1, reg2)
|
|
|
+ END add;
|
|
|
|
|
|
|
|
|
PROCEDURE oprc* (op, reg, n: INTEGER);
|
|
|
-BEGIN
|
|
|
- IF (reg = eax) & ~isByte(n) THEN
|
|
|
- CASE op OF
|
|
|
- |0C0H: op := 05H (* add *)
|
|
|
- |0E8H: op := 2DH (* sub *)
|
|
|
- |0F8H: op := 3DH (* cmp *)
|
|
|
- |0E0H: op := 25H (* and *)
|
|
|
- |0C8H: op := 0DH (* or *)
|
|
|
- |0F0H: op := 35H (* xor *)
|
|
|
- END;
|
|
|
- OutByte(op);
|
|
|
- OutInt(n)
|
|
|
- ELSE
|
|
|
- OutByte2(81H + short(n), op + reg MOD 8);
|
|
|
- OutIntByte(n)
|
|
|
- END
|
|
|
-END oprc;
|
|
|
+ BEGIN
|
|
|
+ IF (reg = eax) & ~isByte(n) THEN
|
|
|
+ CASE op OF
|
|
|
+ |0C0H: op := 05H (* add *)
|
|
|
+ |0E8H: op := 2DH (* sub *)
|
|
|
+ |0F8H: op := 3DH (* cmp *)
|
|
|
+ |0E0H: op := 25H (* and *)
|
|
|
+ |0C8H: op := 0DH (* or *)
|
|
|
+ |0F0H: op := 35H (* xor *)
|
|
|
+ END;
|
|
|
+ OutByte(op);
|
|
|
+ OutInt(n)
|
|
|
+ ELSE
|
|
|
+ OutByte2(81H + short(n), op + reg MOD 8);
|
|
|
+ OutIntByte(n)
|
|
|
+ END
|
|
|
+ END oprc;
|
|
|
|
|
|
|
|
|
PROCEDURE andrc (reg, n: INTEGER); (* and reg, n *)
|
|
|
-BEGIN
|
|
|
- oprc(0E0H, reg, n)
|
|
|
-END andrc;
|
|
|
+ BEGIN
|
|
|
+ oprc(0E0H, reg, n)
|
|
|
+ END andrc;
|
|
|
|
|
|
|
|
|
PROCEDURE orrc (reg, n: INTEGER); (* or reg, n *)
|
|
|
-BEGIN
|
|
|
- oprc(0C8H, reg, n)
|
|
|
-END orrc;
|
|
|
+ BEGIN
|
|
|
+ oprc(0C8H, reg, n)
|
|
|
+ END orrc;
|
|
|
|
|
|
|
|
|
PROCEDURE xorrc (reg, n: INTEGER); (* xor reg, n *)
|
|
|
-BEGIN
|
|
|
- oprc(0F0H, reg, n)
|
|
|
-END xorrc;
|
|
|
+ BEGIN
|
|
|
+ oprc(0F0H, reg, n)
|
|
|
+ END xorrc;
|
|
|
|
|
|
|
|
|
PROCEDURE addrc (reg, n: INTEGER); (* add reg, n *)
|
|
|
-BEGIN
|
|
|
- oprc(0C0H, reg, n)
|
|
|
-END addrc;
|
|
|
+ BEGIN
|
|
|
+ oprc(0C0H, reg, n)
|
|
|
+ END addrc;
|
|
|
|
|
|
|
|
|
PROCEDURE subrc (reg, n: INTEGER); (* sub reg, n *)
|
|
|
-BEGIN
|
|
|
- oprc(0E8H, reg, n)
|
|
|
-END subrc;
|
|
|
+ BEGIN
|
|
|
+ oprc(0E8H, reg, n)
|
|
|
+ END subrc;
|
|
|
|
|
|
|
|
|
PROCEDURE cmprc (reg, n: INTEGER); (* cmp reg, n *)
|
|
|
-BEGIN
|
|
|
- IF n = 0 THEN
|
|
|
- test(reg)
|
|
|
- ELSE
|
|
|
- oprc(0F8H, reg, n)
|
|
|
- END
|
|
|
-END cmprc;
|
|
|
+ BEGIN
|
|
|
+ IF n = 0 THEN
|
|
|
+ test(reg)
|
|
|
+ ELSE
|
|
|
+ oprc(0F8H, reg, n)
|
|
|
+ END
|
|
|
+ END cmprc;
|
|
|
|
|
|
|
|
|
PROCEDURE cmprr (reg1, reg2: INTEGER); (* cmp reg1, reg2 *)
|
|
|
-BEGIN
|
|
|
- oprr(39H, reg1, reg2)
|
|
|
-END cmprr;
|
|
|
+ BEGIN
|
|
|
+ oprr(39H, reg1, reg2)
|
|
|
+ END cmprr;
|
|
|
|
|
|
|
|
|
PROCEDURE setcc* (cc, reg: INTEGER); (* setcc reg *)
|
|
|
-BEGIN
|
|
|
- IF reg >= 8 THEN
|
|
|
- OutByte(41H)
|
|
|
- END;
|
|
|
- OutByte3(0FH, cc, 0C0H + reg MOD 8)
|
|
|
-END setcc;
|
|
|
+ BEGIN
|
|
|
+ IF reg >= 8 THEN
|
|
|
+ OutByte(41H)
|
|
|
+ END;
|
|
|
+ OutByte3(0FH, cc, 0C0H + reg MOD 8)
|
|
|
+ END setcc;
|
|
|
|
|
|
|
|
|
PROCEDURE ret*;
|
|
|
-BEGIN
|
|
|
- OutByte(0C3H)
|
|
|
-END ret;
|
|
|
+ BEGIN
|
|
|
+ OutByte(0C3H)
|
|
|
+ END ret;
|
|
|
|
|
|
|
|
|
PROCEDURE drop;
|
|
|
-BEGIN
|
|
|
- REG.Drop(R)
|
|
|
-END drop;
|
|
|
+ BEGIN
|
|
|
+ REG.Drop(R)
|
|
|
+ END drop;
|
|
|
|
|
|
|
|
|
PROCEDURE GetAnyReg (): INTEGER;
|
|
|
- RETURN REG.GetAnyReg(R)
|
|
|
-END GetAnyReg;
|
|
|
+ RETURN REG.GetAnyReg(R)
|
|
|
+ END GetAnyReg;
|
|
|
|
|
|
|
|
|
PROCEDURE cond* (op: INTEGER): INTEGER;
|
|
|
-VAR
|
|
|
- res: INTEGER;
|
|
|
+ VAR
|
|
|
+ res: INTEGER;
|
|
|
|
|
|
-BEGIN
|
|
|
- CASE op OF
|
|
|
- |IL.opGT, IL.opGTC: res := jg
|
|
|
- |IL.opGE, IL.opGEC: res := jge
|
|
|
- |IL.opLT, IL.opLTC: res := jl
|
|
|
- |IL.opLE, IL.opLEC: res := jle
|
|
|
- |IL.opEQ, IL.opEQC: res := je
|
|
|
- |IL.opNE, IL.opNEC: res := jne
|
|
|
- END
|
|
|
+ BEGIN
|
|
|
+ CASE op OF
|
|
|
+ |IL.opGT, IL.opGTC: res := jg
|
|
|
+ |IL.opGE, IL.opGEC: res := jge
|
|
|
+ |IL.opLT, IL.opLTC: res := jl
|
|
|
+ |IL.opLE, IL.opLEC: res := jle
|
|
|
+ |IL.opEQ, IL.opEQC: res := je
|
|
|
+ |IL.opNE, IL.opNEC: res := jne
|
|
|
+ END
|
|
|
|
|
|
- RETURN res
|
|
|
-END cond;
|
|
|
+ RETURN res
|
|
|
+ END cond;
|
|
|
|
|
|
|
|
|
PROCEDURE inv0* (op: INTEGER): INTEGER;
|
|
|
- RETURN ORD(BITS(op) / {0})
|
|
|
-END inv0;
|
|
|
+ RETURN ORD(BITS(op) / {0})
|
|
|
+ END inv0;
|
|
|
|
|
|
|
|
|
PROCEDURE Reloc* (op, value: INTEGER);
|
|
|
-VAR
|
|
|
- reloc: RELOC;
|
|
|
+ VAR
|
|
|
+ reloc: RELOC;
|
|
|
|
|
|
-BEGIN
|
|
|
- NEW(reloc);
|
|
|
- reloc.op := op;
|
|
|
- reloc.value := value;
|
|
|
- LISTS.push(CodeList, reloc)
|
|
|
-END Reloc;
|
|
|
+ BEGIN
|
|
|
+ NEW(reloc);
|
|
|
+ reloc.op := op;
|
|
|
+ reloc.value := value;
|
|
|
+ LISTS.push(CodeList, reloc)
|
|
|
+ END Reloc;
|
|
|
|
|
|
|
|
|
PROCEDURE PushFlt (label: LABEL; value: REAL);
|
|
|
-VAR
|
|
|
- a, b, n: INTEGER;
|
|
|
+ VAR
|
|
|
+ a, b, n: INTEGER;
|
|
|
|
|
|
|
|
|
- PROCEDURE pushImm (label: LABEL; value: INTEGER);
|
|
|
- VAR
|
|
|
- c: CODE;
|
|
|
- i: INTEGER;
|
|
|
+ PROCEDURE pushImm (label: LABEL; value: INTEGER);
|
|
|
+ VAR
|
|
|
+ c: CODE;
|
|
|
+ i: INTEGER;
|
|
|
|
|
|
- BEGIN
|
|
|
- NEW(c);
|
|
|
- IF isByte(value) THEN
|
|
|
- c.code[0] := 6AH;
|
|
|
- c.code[1] := value MOD 256;
|
|
|
- c.length := 2
|
|
|
- ELSE
|
|
|
- c.code[0] := 68H;
|
|
|
- FOR i := 1 TO 4 DO
|
|
|
- c.code[i] := UTILS.Byte(value, i - 1)
|
|
|
+ BEGIN
|
|
|
+ NEW(c);
|
|
|
+ IF isByte(value) THEN
|
|
|
+ c.code[0] := 6AH;
|
|
|
+ c.code[1] := value MOD 256;
|
|
|
+ c.length := 2
|
|
|
+ ELSE
|
|
|
+ c.code[0] := 68H;
|
|
|
+ FOR i := 1 TO 4 DO
|
|
|
+ c.code[i] := UTILS.Byte(value, i - 1)
|
|
|
+ END;
|
|
|
+ c.length := 5
|
|
|
END;
|
|
|
- c.length := 5
|
|
|
- END;
|
|
|
- LISTS.insertL(CodeList, label, c)
|
|
|
- END pushImm;
|
|
|
+ LISTS.insertL(CodeList, label, c)
|
|
|
+ END pushImm;
|
|
|
|
|
|
|
|
|
-BEGIN
|
|
|
- n := UTILS.splitf(value, a, b);
|
|
|
- pushImm(label, b);
|
|
|
- pushImm(label, a)
|
|
|
-END PushFlt;
|
|
|
+ BEGIN
|
|
|
+ n := UTILS.splitf(value, a, b);
|
|
|
+ pushImm(label, b);
|
|
|
+ pushImm(label, a)
|
|
|
+ END PushFlt;
|
|
|
|
|
|
|
|
|
PROCEDURE jcc* (cc, label: INTEGER);
|
|
|
-VAR
|
|
|
- j: JCC;
|
|
|
+ VAR
|
|
|
+ j: JCC;
|
|
|
|
|
|
-BEGIN
|
|
|
- NEW(j);
|
|
|
- j.label := label;
|
|
|
- j.jmp := cc;
|
|
|
- j.short := FALSE;
|
|
|
- LISTS.push(CodeList, j)
|
|
|
-END jcc;
|
|
|
+ BEGIN
|
|
|
+ NEW(j);
|
|
|
+ j.label := label;
|
|
|
+ j.jmp := cc;
|
|
|
+ j.short := FALSE;
|
|
|
+ LISTS.push(CodeList, j)
|
|
|
+ END jcc;
|
|
|
|
|
|
|
|
|
PROCEDURE jmp* (label: INTEGER);
|
|
|
-VAR
|
|
|
- j: JMP;
|
|
|
+ VAR
|
|
|
+ j: JMP;
|
|
|
|
|
|
-BEGIN
|
|
|
- NEW(j);
|
|
|
- j.label := label;
|
|
|
- j.short := FALSE;
|
|
|
- LISTS.push(CodeList, j)
|
|
|
-END jmp;
|
|
|
+ BEGIN
|
|
|
+ NEW(j);
|
|
|
+ j.label := label;
|
|
|
+ j.short := FALSE;
|
|
|
+ LISTS.push(CodeList, j)
|
|
|
+ END jmp;
|
|
|
|
|
|
|
|
|
PROCEDURE call* (label: INTEGER);
|
|
|
-VAR
|
|
|
- c: CALL;
|
|
|
+ VAR
|
|
|
+ c: CALL;
|
|
|
|
|
|
-BEGIN
|
|
|
- NEW(c);
|
|
|
- c.label := label;
|
|
|
- c.short := TRUE;
|
|
|
- LISTS.push(CodeList, c)
|
|
|
-END call;
|
|
|
+ BEGIN
|
|
|
+ NEW(c);
|
|
|
+ c.label := label;
|
|
|
+ c.short := TRUE;
|
|
|
+ LISTS.push(CodeList, c)
|
|
|
+ END call;
|
|
|
|
|
|
|
|
|
PROCEDURE Pic (reg, opcode, value: INTEGER);
|
|
|
-BEGIN
|
|
|
- OutByte(0E8H); OutInt(0); (* call L
|
|
|
- L: *)
|
|
|
- pop(reg);
|
|
|
- OutByte2(081H, 0C0H + reg); (* add reg, ... *)
|
|
|
- Reloc(opcode, value)
|
|
|
-END Pic;
|
|
|
+ BEGIN
|
|
|
+ OutByte(0E8H); OutInt(0); (* call L
|
|
|
+ L: *)
|
|
|
+ pop(reg);
|
|
|
+ OutByte2(081H, 0C0H + reg); (* add reg, ... *)
|
|
|
+ Reloc(opcode, value)
|
|
|
+ END Pic;
|
|
|
|
|
|
|
|
|
PROCEDURE CallRTL (pic: BOOLEAN; proc: INTEGER);
|
|
|
-VAR
|
|
|
- label: INTEGER;
|
|
|
- reg1: INTEGER;
|
|
|
+ VAR
|
|
|
+ label: INTEGER;
|
|
|
+ reg1: INTEGER;
|
|
|
|
|
|
-BEGIN
|
|
|
- label := IL.codes.rtl[proc];
|
|
|
+ BEGIN
|
|
|
+ label := IL.codes.rtl[proc];
|
|
|
|
|
|
- IF label < 0 THEN
|
|
|
- label := -label;
|
|
|
- IF pic THEN
|
|
|
- reg1 := GetAnyReg();
|
|
|
- Pic(reg1, BIN.PICIMP, label);
|
|
|
- OutByte2(0FFH, 010H + reg1); (* call dword[reg1] *)
|
|
|
- drop
|
|
|
+ IF label < 0 THEN
|
|
|
+ label := -label;
|
|
|
+ IF pic THEN
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ Pic(reg1, BIN.PICIMP, label);
|
|
|
+ OutByte2(0FFH, 010H + reg1); (* call dword[reg1] *)
|
|
|
+ drop
|
|
|
+ ELSE
|
|
|
+ OutByte2(0FFH, 015H); (* call dword[label] *)
|
|
|
+ Reloc(BIN.RIMP, label)
|
|
|
+ END
|
|
|
ELSE
|
|
|
- OutByte2(0FFH, 015H); (* call dword[label] *)
|
|
|
- Reloc(BIN.RIMP, label)
|
|
|
+ call(label)
|
|
|
END
|
|
|
- ELSE
|
|
|
- call(label)
|
|
|
- END
|
|
|
-END CallRTL;
|
|
|
+ END CallRTL;
|
|
|
|
|
|
|
|
|
PROCEDURE SetLabel* (label: INTEGER);
|
|
|
-VAR
|
|
|
- L: LABEL;
|
|
|
+ VAR
|
|
|
+ L: LABEL;
|
|
|
|
|
|
-BEGIN
|
|
|
- NEW(L);
|
|
|
- L.label := label;
|
|
|
- LISTS.push(CodeList, L)
|
|
|
-END SetLabel;
|
|
|
+ BEGIN
|
|
|
+ NEW(L);
|
|
|
+ L.label := label;
|
|
|
+ LISTS.push(CodeList, L)
|
|
|
+ END SetLabel;
|
|
|
|
|
|
|
|
|
PROCEDURE fixup*;
|
|
|
-VAR
|
|
|
- code: ANYCODE;
|
|
|
- count, i: INTEGER;
|
|
|
- shorted: BOOLEAN;
|
|
|
- jump: JUMP;
|
|
|
+ VAR
|
|
|
+ code: ANYCODE;
|
|
|
+ count, i: INTEGER;
|
|
|
+ shorted: BOOLEAN;
|
|
|
+ jump: JUMP;
|
|
|
|
|
|
-BEGIN
|
|
|
+ BEGIN
|
|
|
|
|
|
- REPEAT
|
|
|
+ REPEAT
|
|
|
|
|
|
- shorted := FALSE;
|
|
|
- count := 0;
|
|
|
+ shorted := FALSE;
|
|
|
+ count := 0;
|
|
|
|
|
|
- code := CodeList.first(ANYCODE);
|
|
|
- WHILE code # NIL DO
|
|
|
- code.offset := count;
|
|
|
+ code := CodeList.first(ANYCODE);
|
|
|
+ WHILE code # NIL DO
|
|
|
+ code.offset := count;
|
|
|
|
|
|
- CASE code OF
|
|
|
- |CODE: INC(count, code.length)
|
|
|
- |LABEL: BIN.SetLabel(program, code.label, count)
|
|
|
- |JMP: IF code.short THEN INC(count, 2) ELSE INC(count, 5) END; code.offset := count
|
|
|
- |JCC: IF code.short THEN INC(count, 2) ELSE INC(count, 6) END; code.offset := count
|
|
|
- |CALL: INC(count, 5); code.offset := count
|
|
|
- |RELOC: INC(count, 4)
|
|
|
+ CASE code OF
|
|
|
+ |CODE: INC(count, code.length)
|
|
|
+ |LABEL: BIN.SetLabel(program, code.label, count)
|
|
|
+ |JMP: IF code.short THEN INC(count, 2) ELSE INC(count, 5) END; code.offset := count
|
|
|
+ |JCC: IF code.short THEN INC(count, 2) ELSE INC(count, 6) END; code.offset := count
|
|
|
+ |CALL: INC(count, 5); code.offset := count
|
|
|
+ |RELOC: INC(count, 4)
|
|
|
+ END;
|
|
|
+
|
|
|
+ code := code.next(ANYCODE)
|
|
|
END;
|
|
|
|
|
|
- code := code.next(ANYCODE)
|
|
|
- END;
|
|
|
+ code := CodeList.first(ANYCODE);
|
|
|
+ WHILE code # NIL DO
|
|
|
|
|
|
- code := CodeList.first(ANYCODE);
|
|
|
- WHILE code # NIL DO
|
|
|
+ IF code IS JUMP THEN
|
|
|
+ jump := code(JUMP);
|
|
|
+ jump.diff := BIN.GetLabel(program, jump.label) - code.offset;
|
|
|
+ IF ~jump.short & isByte(jump.diff) THEN
|
|
|
+ jump.short := TRUE;
|
|
|
+ shorted := TRUE
|
|
|
+ END
|
|
|
+ END;
|
|
|
|
|
|
- IF code IS JUMP THEN
|
|
|
- jump := code(JUMP);
|
|
|
- jump.diff := BIN.GetLabel(program, jump.label) - code.offset;
|
|
|
- IF ~jump.short & isByte(jump.diff) THEN
|
|
|
- jump.short := TRUE;
|
|
|
- shorted := TRUE
|
|
|
- END
|
|
|
- END;
|
|
|
+ code := code.next(ANYCODE)
|
|
|
+ END
|
|
|
|
|
|
- code := code.next(ANYCODE)
|
|
|
- END
|
|
|
+ UNTIL ~shorted;
|
|
|
|
|
|
- UNTIL ~shorted;
|
|
|
+ code := CodeList.first(ANYCODE);
|
|
|
+ WHILE code # NIL DO
|
|
|
|
|
|
- code := CodeList.first(ANYCODE);
|
|
|
- WHILE code # NIL DO
|
|
|
+ CASE code OF
|
|
|
|
|
|
- CASE code OF
|
|
|
+ |CODE:
|
|
|
+ FOR i := 0 TO code.length - 1 DO
|
|
|
+ BIN.PutCode(program, code.code[i])
|
|
|
+ END
|
|
|
|
|
|
- |CODE:
|
|
|
- FOR i := 0 TO code.length - 1 DO
|
|
|
- BIN.PutCode(program, code.code[i])
|
|
|
- END
|
|
|
+ |LABEL:
|
|
|
|
|
|
- |LABEL:
|
|
|
+ |JMP:
|
|
|
+ IF code.short THEN
|
|
|
+ BIN.PutCode(program, 0EBH);
|
|
|
+ BIN.PutCode(program, code.diff MOD 256)
|
|
|
+ ELSE
|
|
|
+ BIN.PutCode(program, 0E9H);
|
|
|
+ BIN.PutCode32LE(program, code.diff)
|
|
|
+ END
|
|
|
|
|
|
- |JMP:
|
|
|
- IF code.short THEN
|
|
|
- BIN.PutCode(program, 0EBH);
|
|
|
- BIN.PutCode(program, code.diff MOD 256)
|
|
|
- ELSE
|
|
|
- BIN.PutCode(program, 0E9H);
|
|
|
- BIN.PutCode32LE(program, code.diff)
|
|
|
- END
|
|
|
+ |JCC:
|
|
|
+ IF code.short THEN
|
|
|
+ BIN.PutCode(program, code.jmp - 16);
|
|
|
+ BIN.PutCode(program, code.diff MOD 256)
|
|
|
+ ELSE
|
|
|
+ BIN.PutCode(program, 0FH);
|
|
|
+ BIN.PutCode(program, code.jmp);
|
|
|
+ BIN.PutCode32LE(program, code.diff)
|
|
|
+ END
|
|
|
|
|
|
- |JCC:
|
|
|
- IF code.short THEN
|
|
|
- BIN.PutCode(program, code.jmp - 16);
|
|
|
- BIN.PutCode(program, code.diff MOD 256)
|
|
|
- ELSE
|
|
|
- BIN.PutCode(program, 0FH);
|
|
|
- BIN.PutCode(program, code.jmp);
|
|
|
+ |CALL:
|
|
|
+ BIN.PutCode(program, 0E8H);
|
|
|
BIN.PutCode32LE(program, code.diff)
|
|
|
- END
|
|
|
|
|
|
- |CALL:
|
|
|
- BIN.PutCode(program, 0E8H);
|
|
|
- BIN.PutCode32LE(program, code.diff)
|
|
|
+ |RELOC:
|
|
|
+ BIN.PutReloc(program, code.op);
|
|
|
+ BIN.PutCode32LE(program, code.value)
|
|
|
|
|
|
- |RELOC:
|
|
|
- BIN.PutReloc(program, code.op);
|
|
|
- BIN.PutCode32LE(program, code.value)
|
|
|
-
|
|
|
- END;
|
|
|
+ END;
|
|
|
|
|
|
- code := code.next(ANYCODE)
|
|
|
- END
|
|
|
+ code := code.next(ANYCODE)
|
|
|
+ END
|
|
|
|
|
|
-END fixup;
|
|
|
+ END fixup;
|
|
|
|
|
|
|
|
|
PROCEDURE UnOp (VAR reg: INTEGER);
|
|
|
-BEGIN
|
|
|
- REG.UnOp(R, reg)
|
|
|
-END UnOp;
|
|
|
+ BEGIN
|
|
|
+ REG.UnOp(R, reg)
|
|
|
+ END UnOp;
|
|
|
|
|
|
|
|
|
PROCEDURE BinOp (VAR reg1, reg2: INTEGER);
|
|
|
-BEGIN
|
|
|
- REG.BinOp(R, reg1, reg2)
|
|
|
-END BinOp;
|
|
|
+ BEGIN
|
|
|
+ REG.BinOp(R, reg1, reg2)
|
|
|
+ END BinOp;
|
|
|
|
|
|
|
|
|
PROCEDURE PushAll (NumberOfParameters: INTEGER);
|
|
|
-BEGIN
|
|
|
- REG.PushAll(R);
|
|
|
- DEC(R.pushed, NumberOfParameters)
|
|
|
-END PushAll;
|
|
|
+ BEGIN
|
|
|
+ REG.PushAll(R);
|
|
|
+ DEC(R.pushed, NumberOfParameters)
|
|
|
+ END PushAll;
|
|
|
|
|
|
|
|
|
PROCEDURE NewLabel (): INTEGER;
|
|
|
-BEGIN
|
|
|
- BIN.NewLabel(program)
|
|
|
- RETURN IL.NewLabel()
|
|
|
-END NewLabel;
|
|
|
+ BEGIN
|
|
|
+ BIN.NewLabel(program)
|
|
|
+ RETURN IL.NewLabel()
|
|
|
+ END NewLabel;
|
|
|
|
|
|
|
|
|
PROCEDURE GetRegA;
|
|
|
-BEGIN
|
|
|
- ASSERT(REG.GetReg(R, eax))
|
|
|
-END GetRegA;
|
|
|
+ BEGIN
|
|
|
+ ASSERT(REG.GetReg(R, eax))
|
|
|
+ END GetRegA;
|
|
|
|
|
|
|
|
|
PROCEDURE fcmp;
|
|
|
-BEGIN
|
|
|
- GetRegA;
|
|
|
- OutByte2(0DAH, 0E9H); (* fucompp *)
|
|
|
- OutByte3(09BH, 0DFH, 0E0H); (* fstsw ax *)
|
|
|
- OutByte(09EH); (* sahf *)
|
|
|
- OutByte(0B8H); OutInt(0) (* mov eax, 0 *)
|
|
|
-END fcmp;
|
|
|
+ BEGIN
|
|
|
+ GetRegA;
|
|
|
+ OutByte2(0DAH, 0E9H); (* fucompp *)
|
|
|
+ OutByte3(09BH, 0DFH, 0E0H); (* fstsw ax *)
|
|
|
+ OutByte(09EH); (* sahf *)
|
|
|
+ OutByte(0B8H); OutInt(0) (* mov eax, 0 *)
|
|
|
+ END fcmp;
|
|
|
|
|
|
|
|
|
PROCEDURE movzx* (reg1, reg2, offs: INTEGER; word: BOOLEAN); (* movzx reg1, byte/word[reg2 + offs] *)
|
|
|
-VAR
|
|
|
- b: BYTE;
|
|
|
-
|
|
|
-BEGIN
|
|
|
- OutByte2(0FH, 0B6H + ORD(word));
|
|
|
- IF (offs = 0) & (reg2 # ebp) THEN
|
|
|
- b := 0
|
|
|
- ELSE
|
|
|
- b := 40H + long(offs)
|
|
|
- END;
|
|
|
- OutByte(b + (reg1 MOD 8) * 8 + reg2 MOD 8);
|
|
|
- IF reg2 = esp THEN
|
|
|
- OutByte(24H)
|
|
|
- END;
|
|
|
- IF b # 0 THEN
|
|
|
- OutIntByte(offs)
|
|
|
- END
|
|
|
-END movzx;
|
|
|
+ VAR
|
|
|
+ b: BYTE;
|
|
|
+
|
|
|
+ BEGIN
|
|
|
+ OutByte2(0FH, 0B6H + ORD(word));
|
|
|
+ IF (offs = 0) & (reg2 # ebp) THEN
|
|
|
+ b := 0
|
|
|
+ ELSE
|
|
|
+ b := 40H + long(offs)
|
|
|
+ END;
|
|
|
+ OutByte(b + (reg1 MOD 8) * 8 + reg2 MOD 8);
|
|
|
+ IF reg2 = esp THEN
|
|
|
+ OutByte(24H)
|
|
|
+ END;
|
|
|
+ IF b # 0 THEN
|
|
|
+ OutIntByte(offs)
|
|
|
+ END
|
|
|
+ END movzx;
|
|
|
|
|
|
|
|
|
PROCEDURE _movrm* (reg1, reg2, offs, size: INTEGER; mr: BOOLEAN);
|
|
|
-VAR
|
|
|
- b: BYTE;
|
|
|
+ VAR
|
|
|
+ b: BYTE;
|
|
|
|
|
|
-BEGIN
|
|
|
- IF size = 16 THEN
|
|
|
- OutByte(66H)
|
|
|
- END;
|
|
|
- IF (reg1 >= 8) OR (reg2 >= 8) OR (size = 64) THEN
|
|
|
- OutByte(40H + reg2 DIV 8 + 4 * (reg1 DIV 8) + 8 * ORD(size = 64))
|
|
|
- END;
|
|
|
- OutByte(8BH - 2 * ORD(mr) - ORD(size = 8));
|
|
|
- IF (offs = 0) & (reg2 # ebp) THEN
|
|
|
- b := 0
|
|
|
- ELSE
|
|
|
- b := 40H + long(offs)
|
|
|
- END;
|
|
|
- OutByte(b + (reg1 MOD 8) * 8 + reg2 MOD 8);
|
|
|
- IF reg2 = esp THEN
|
|
|
- OutByte(24H)
|
|
|
- END;
|
|
|
- IF b # 0 THEN
|
|
|
- OutIntByte(offs)
|
|
|
- END
|
|
|
-END _movrm;
|
|
|
+ BEGIN
|
|
|
+ IF size = 16 THEN
|
|
|
+ OutByte(66H)
|
|
|
+ END;
|
|
|
+ IF (reg1 >= 8) OR (reg2 >= 8) OR (size = 64) THEN
|
|
|
+ OutByte(40H + reg2 DIV 8 + 4 * (reg1 DIV 8) + 8 * ORD(size = 64))
|
|
|
+ END;
|
|
|
+ OutByte(8BH - 2 * ORD(mr) - ORD(size = 8));
|
|
|
+ IF (offs = 0) & (reg2 # ebp) THEN
|
|
|
+ b := 0
|
|
|
+ ELSE
|
|
|
+ b := 40H + long(offs)
|
|
|
+ END;
|
|
|
+ OutByte(b + (reg1 MOD 8) * 8 + reg2 MOD 8);
|
|
|
+ IF reg2 = esp THEN
|
|
|
+ OutByte(24H)
|
|
|
+ END;
|
|
|
+ IF b # 0 THEN
|
|
|
+ OutIntByte(offs)
|
|
|
+ END
|
|
|
+ END _movrm;
|
|
|
|
|
|
|
|
|
PROCEDURE movmr (reg1, offs, reg2: INTEGER); (* mov dword[reg1+offs], reg2 *)
|
|
|
-BEGIN
|
|
|
- _movrm(reg2, reg1, offs, 32, TRUE)
|
|
|
-END movmr;
|
|
|
+ BEGIN
|
|
|
+ _movrm(reg2, reg1, offs, 32, TRUE)
|
|
|
+ END movmr;
|
|
|
|
|
|
|
|
|
PROCEDURE movrm (reg1, reg2, offs: INTEGER); (* mov reg1, dword[reg2 + offs] *)
|
|
|
-BEGIN
|
|
|
- _movrm(reg1, reg2, offs, 32, FALSE)
|
|
|
-END movrm;
|
|
|
+ BEGIN
|
|
|
+ _movrm(reg1, reg2, offs, 32, FALSE)
|
|
|
+ END movrm;
|
|
|
|
|
|
|
|
|
PROCEDURE movmr8* (reg1, offs, reg2: INTEGER); (* mov byte[reg1+offs], reg2_8 *)
|
|
|
-BEGIN
|
|
|
- _movrm(reg2, reg1, offs, 8, TRUE)
|
|
|
-END movmr8;
|
|
|
+ BEGIN
|
|
|
+ _movrm(reg2, reg1, offs, 8, TRUE)
|
|
|
+ END movmr8;
|
|
|
|
|
|
|
|
|
PROCEDURE movrm8* (reg1, reg2, offs: INTEGER); (* mov reg1_8, byte[reg2+offs] *)
|
|
|
-BEGIN
|
|
|
- _movrm(reg1, reg2, offs, 8, FALSE)
|
|
|
-END movrm8;
|
|
|
+ BEGIN
|
|
|
+ _movrm(reg1, reg2, offs, 8, FALSE)
|
|
|
+ END movrm8;
|
|
|
|
|
|
|
|
|
PROCEDURE movmr16* (reg1, offs, reg2: INTEGER); (* mov word[reg1+offs], reg2_16 *)
|
|
|
-BEGIN
|
|
|
- _movrm(reg2, reg1, offs, 16, TRUE)
|
|
|
-END movmr16;
|
|
|
+ BEGIN
|
|
|
+ _movrm(reg2, reg1, offs, 16, TRUE)
|
|
|
+ END movmr16;
|
|
|
|
|
|
|
|
|
PROCEDURE movrm16* (reg1, reg2, offs: INTEGER); (* mov reg1_16, word[reg2+offs] *)
|
|
|
-BEGIN
|
|
|
- _movrm(reg1, reg2, offs, 16, FALSE)
|
|
|
-END movrm16;
|
|
|
+ BEGIN
|
|
|
+ _movrm(reg1, reg2, offs, 16, FALSE)
|
|
|
+ END movrm16;
|
|
|
|
|
|
|
|
|
PROCEDURE pushm* (reg, offs: INTEGER); (* push qword[reg+offs] *)
|
|
|
-VAR
|
|
|
- b: BYTE;
|
|
|
+ VAR
|
|
|
+ b: BYTE;
|
|
|
|
|
|
-BEGIN
|
|
|
- IF reg >= 8 THEN
|
|
|
- OutByte(41H)
|
|
|
- END;
|
|
|
- OutByte(0FFH);
|
|
|
- IF (offs = 0) & (reg # ebp) THEN
|
|
|
- b := 30H
|
|
|
- ELSE
|
|
|
- b := 70H + long(offs)
|
|
|
- END;
|
|
|
- OutByte(b + reg MOD 8);
|
|
|
- IF reg = esp THEN
|
|
|
- OutByte(24H)
|
|
|
- END;
|
|
|
- IF b # 30H THEN
|
|
|
- OutIntByte(offs)
|
|
|
- END
|
|
|
-END pushm;
|
|
|
+ BEGIN
|
|
|
+ IF reg >= 8 THEN
|
|
|
+ OutByte(41H)
|
|
|
+ END;
|
|
|
+ OutByte(0FFH);
|
|
|
+ IF (offs = 0) & (reg # ebp) THEN
|
|
|
+ b := 30H
|
|
|
+ ELSE
|
|
|
+ b := 70H + long(offs)
|
|
|
+ END;
|
|
|
+ OutByte(b + reg MOD 8);
|
|
|
+ IF reg = esp THEN
|
|
|
+ OutByte(24H)
|
|
|
+ END;
|
|
|
+ IF b # 30H THEN
|
|
|
+ OutIntByte(offs)
|
|
|
+ END
|
|
|
+ END pushm;
|
|
|
|
|
|
|
|
|
PROCEDURE LoadFltConst (value: REAL);
|
|
|
-BEGIN
|
|
|
- PushFlt(FltConstLabel, value);
|
|
|
- INC(LocVarSize, 8);
|
|
|
- IF FltConstLabel = mainFltConstLabel THEN
|
|
|
- mainLocVarSize := LocVarSize
|
|
|
- END;
|
|
|
- OutByte2(0DDH, 045H + long(-LocVarSize)); (* fld qword[ebp - LocVarSize] *)
|
|
|
- OutIntByte(-LocVarSize)
|
|
|
-END LoadFltConst;
|
|
|
+ BEGIN
|
|
|
+ PushFlt(FltConstLabel, value);
|
|
|
+ INC(LocVarSize, 8);
|
|
|
+ IF FltConstLabel = mainFltConstLabel THEN
|
|
|
+ mainLocVarSize := LocVarSize
|
|
|
+ END;
|
|
|
+ OutByte2(0DDH, 045H + long(-LocVarSize)); (* fld qword[ebp - LocVarSize] *)
|
|
|
+ OutIntByte(-LocVarSize)
|
|
|
+ END LoadFltConst;
|
|
|
|
|
|
|
|
|
PROCEDURE translate (pic: BOOLEAN; stroffs, target: INTEGER);
|
|
|
-VAR
|
|
|
- cmd, next: COMMAND;
|
|
|
-
|
|
|
- reg1, reg2, reg3, fr: INTEGER;
|
|
|
-
|
|
|
- n, a, label, cc: INTEGER;
|
|
|
+ VAR
|
|
|
+ cmd, next: COMMAND;
|
|
|
|
|
|
- opcode, param1, param2: INTEGER;
|
|
|
+ reg1, reg2, reg3, fr: INTEGER;
|
|
|
|
|
|
- float: REAL;
|
|
|
+ n, a, label, cc: INTEGER;
|
|
|
|
|
|
-BEGIN
|
|
|
- cmd := IL.codes.commands.first(COMMAND);
|
|
|
+ opcode, param1, param2: INTEGER;
|
|
|
|
|
|
- fr := -1;
|
|
|
+ float: REAL;
|
|
|
|
|
|
- WHILE cmd # NIL DO
|
|
|
+ BEGIN
|
|
|
+ cmd := IL.codes.commands.first(COMMAND);
|
|
|
|
|
|
- param1 := cmd.param1;
|
|
|
- param2 := cmd.param2;
|
|
|
+ fr := -1;
|
|
|
|
|
|
- opcode := cmd.opcode;
|
|
|
+ WHILE cmd # NIL DO
|
|
|
|
|
|
- CASE opcode OF
|
|
|
+ param1 := cmd.param1;
|
|
|
+ param2 := cmd.param2;
|
|
|
|
|
|
- |IL.opJMP:
|
|
|
- jmp(param1)
|
|
|
+ opcode := cmd.opcode;
|
|
|
|
|
|
- |IL.opCALL:
|
|
|
- call(param1)
|
|
|
+ CASE opcode OF
|
|
|
|
|
|
- |IL.opCALLI:
|
|
|
- IF pic THEN
|
|
|
- reg1 := GetAnyReg();
|
|
|
- Pic(reg1, BIN.PICIMP, param1);
|
|
|
- OutByte2(0FFH, 010H + reg1); (* call dword[reg1] *)
|
|
|
- drop
|
|
|
- ELSE
|
|
|
- OutByte2(0FFH, 015H); (* call dword[L] *)
|
|
|
- Reloc(BIN.RIMP, param1)
|
|
|
- END
|
|
|
+ |IL.opJMP:
|
|
|
+ jmp(param1)
|
|
|
|
|
|
- |IL.opCALLP:
|
|
|
- UnOp(reg1);
|
|
|
- OutByte2(0FFH, 0D0H + reg1); (* call reg1 *)
|
|
|
- drop;
|
|
|
- ASSERT(R.top = -1)
|
|
|
+ |IL.opCALL:
|
|
|
+ call(param1)
|
|
|
|
|
|
- |IL.opFASTCALL:
|
|
|
- IF param2 = 1 THEN
|
|
|
- pop(ecx)
|
|
|
- ELSIF param2 = 2 THEN
|
|
|
- pop(ecx);
|
|
|
- pop(edx)
|
|
|
- END
|
|
|
+ |IL.opCALLI:
|
|
|
+ IF pic THEN
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ Pic(reg1, BIN.PICIMP, param1);
|
|
|
+ OutByte2(0FFH, 010H + reg1); (* call dword[reg1] *)
|
|
|
+ drop
|
|
|
+ ELSE
|
|
|
+ OutByte2(0FFH, 015H); (* call dword[L] *)
|
|
|
+ Reloc(BIN.RIMP, param1)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opPRECALL:
|
|
|
- PushAll(0);
|
|
|
- IF (param2 # 0) & (fr >= 0) THEN
|
|
|
- subrc(esp, 8)
|
|
|
- END;
|
|
|
- INC(FR[0]);
|
|
|
- FR[FR[0]] := fr + 1;
|
|
|
- WHILE fr >= 0 DO
|
|
|
- subrc(esp, 8);
|
|
|
- OutByte3(0DDH, 01CH, 024H); (* fstp qword[esp] *)
|
|
|
- DEC(fr)
|
|
|
- END;
|
|
|
- ASSERT(fr = -1)
|
|
|
-
|
|
|
- |IL.opALIGN16:
|
|
|
- ASSERT(eax IN R.regs);
|
|
|
- mov(eax, esp);
|
|
|
- andrc(esp, -16);
|
|
|
- n := (3 - param2 MOD 4) * 4;
|
|
|
- IF n > 0 THEN
|
|
|
- subrc(esp, n)
|
|
|
- END;
|
|
|
- push(eax)
|
|
|
+ |IL.opCALLP:
|
|
|
+ UnOp(reg1);
|
|
|
+ OutByte2(0FFH, 0D0H + reg1); (* call reg1 *)
|
|
|
+ drop;
|
|
|
+ ASSERT(R.top = -1)
|
|
|
+
|
|
|
+ |IL.opFASTCALL:
|
|
|
+ IF param2 = 1 THEN
|
|
|
+ pop(ecx)
|
|
|
+ ELSIF param2 = 2 THEN
|
|
|
+ pop(ecx);
|
|
|
+ pop(edx)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opRESF, IL.opRES:
|
|
|
- ASSERT(R.top = -1);
|
|
|
- ASSERT(fr = -1);
|
|
|
- n := FR[FR[0]]; DEC(FR[0]);
|
|
|
+ |IL.opPRECALL:
|
|
|
+ PushAll(0);
|
|
|
+ IF (param2 # 0) & (fr >= 0) THEN
|
|
|
+ subrc(esp, 8)
|
|
|
+ END;
|
|
|
+ INC(FR[0]);
|
|
|
+ FR[FR[0]] := fr + 1;
|
|
|
+ WHILE fr >= 0 DO
|
|
|
+ subrc(esp, 8);
|
|
|
+ OutByte3(0DDH, 01CH, 024H); (* fstp qword[esp] *)
|
|
|
+ DEC(fr)
|
|
|
+ END;
|
|
|
+ ASSERT(fr = -1)
|
|
|
|
|
|
- IF opcode = IL.opRESF THEN
|
|
|
- INC(fr);
|
|
|
+ |IL.opALIGN16:
|
|
|
+ ASSERT(eax IN R.regs);
|
|
|
+ mov(eax, esp);
|
|
|
+ andrc(esp, -16);
|
|
|
+ n := (3 - param2 MOD 4) * 4;
|
|
|
IF n > 0 THEN
|
|
|
- OutByte3(0DDH, 5CH + long(n * 8), 24H);
|
|
|
- OutIntByte(n * 8); (* fstp qword[esp + n*8] *)
|
|
|
- DEC(fr);
|
|
|
- INC(n)
|
|
|
+ subrc(esp, n)
|
|
|
END;
|
|
|
+ push(eax)
|
|
|
|
|
|
- IF fr + n > MAX_FR THEN
|
|
|
- ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
|
|
- END
|
|
|
- ELSE
|
|
|
- GetRegA
|
|
|
- END;
|
|
|
-
|
|
|
- WHILE n > 0 DO
|
|
|
- OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *)
|
|
|
- addrc(esp, 8);
|
|
|
- INC(fr);
|
|
|
- DEC(n)
|
|
|
- END
|
|
|
-
|
|
|
- |IL.opENTER:
|
|
|
- ASSERT(R.top = -1);
|
|
|
-
|
|
|
- SetLabel(param1);
|
|
|
+ |IL.opRESF, IL.opRES:
|
|
|
+ ASSERT(R.top = -1);
|
|
|
+ ASSERT(fr = -1);
|
|
|
+ n := FR[FR[0]]; DEC(FR[0]);
|
|
|
|
|
|
- IF cmd.param3 > 0 THEN
|
|
|
- pop(eax);
|
|
|
- IF cmd.param3 >= 2 THEN
|
|
|
- push(edx)
|
|
|
+ IF opcode = IL.opRESF THEN
|
|
|
+ INC(fr);
|
|
|
+ IF n > 0 THEN
|
|
|
+ OutByte3(0DDH, 5CH + long(n * 8), 24H);
|
|
|
+ OutIntByte(n * 8); (* fstp qword[esp + n*8] *)
|
|
|
+ DEC(fr);
|
|
|
+ INC(n)
|
|
|
+ END;
|
|
|
+
|
|
|
+ IF fr + n > MAX_FR THEN
|
|
|
+ ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
|
|
+ END
|
|
|
+ ELSE
|
|
|
+ GetRegA
|
|
|
END;
|
|
|
- push(ecx);
|
|
|
- push(eax)
|
|
|
- END;
|
|
|
|
|
|
- push(ebp);
|
|
|
- mov(ebp, esp);
|
|
|
-
|
|
|
- n := param2;
|
|
|
- IF n > 4 THEN
|
|
|
- movrc(ecx, n);
|
|
|
- pushc(0); (* L: push 0 *)
|
|
|
- OutByte2(0E2H, 0FCH) (* loop L *)
|
|
|
- ELSE
|
|
|
WHILE n > 0 DO
|
|
|
- pushc(0);
|
|
|
+ OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *)
|
|
|
+ addrc(esp, 8);
|
|
|
+ INC(fr);
|
|
|
DEC(n)
|
|
|
END
|
|
|
- END;
|
|
|
- SetLabel(NewLabel());
|
|
|
- FltConstLabel := CodeList.last(LABEL);
|
|
|
- LocVarSize := param2 * 4
|
|
|
|
|
|
- |IL.opLEAVE, IL.opLEAVER, IL.opLEAVEF:
|
|
|
- IF opcode = IL.opLEAVER THEN
|
|
|
- UnOp(reg1);
|
|
|
- IF reg1 # eax THEN
|
|
|
- mov(eax, reg1)
|
|
|
+ |IL.opENTER:
|
|
|
+ ASSERT(R.top = -1);
|
|
|
+
|
|
|
+ SetLabel(param1);
|
|
|
+
|
|
|
+ IF cmd.param3 > 0 THEN
|
|
|
+ pop(eax);
|
|
|
+ IF cmd.param3 >= 2 THEN
|
|
|
+ push(edx)
|
|
|
+ END;
|
|
|
+ push(ecx);
|
|
|
+ push(eax)
|
|
|
END;
|
|
|
- drop
|
|
|
- END;
|
|
|
|
|
|
- ASSERT(R.top = -1);
|
|
|
+ push(ebp);
|
|
|
+ mov(ebp, esp);
|
|
|
|
|
|
- IF opcode = IL.opLEAVEF THEN
|
|
|
- DEC(fr)
|
|
|
- END;
|
|
|
+ n := param2;
|
|
|
+ IF n > 4 THEN
|
|
|
+ movrc(ecx, n);
|
|
|
+ pushc(0); (* L: push 0 *)
|
|
|
+ OutByte2(0E2H, 0FCH) (* loop L *)
|
|
|
+ ELSE
|
|
|
+ WHILE n > 0 DO
|
|
|
+ pushc(0);
|
|
|
+ DEC(n)
|
|
|
+ END
|
|
|
+ END;
|
|
|
+ SetLabel(NewLabel());
|
|
|
+ FltConstLabel := CodeList.last(LABEL);
|
|
|
+ LocVarSize := param2 * 4
|
|
|
+
|
|
|
+ |IL.opLEAVE, IL.opLEAVER, IL.opLEAVEF:
|
|
|
+ IF opcode = IL.opLEAVER THEN
|
|
|
+ UnOp(reg1);
|
|
|
+ IF reg1 # eax THEN
|
|
|
+ mov(eax, reg1)
|
|
|
+ END;
|
|
|
+ drop
|
|
|
+ END;
|
|
|
|
|
|
- ASSERT(fr = -1);
|
|
|
+ ASSERT(R.top = -1);
|
|
|
|
|
|
- IF LocVarSize > 0 THEN
|
|
|
- mov(esp, ebp)
|
|
|
- END;
|
|
|
+ IF opcode = IL.opLEAVEF THEN
|
|
|
+ DEC(fr)
|
|
|
+ END;
|
|
|
|
|
|
- pop(ebp);
|
|
|
+ ASSERT(fr = -1);
|
|
|
|
|
|
- IF param2 > 0 THEN
|
|
|
- OutByte(0C2H); OutWord(param2 * 4 MOD 65536) (* ret param2*4 *)
|
|
|
- ELSE
|
|
|
- ret
|
|
|
- END;
|
|
|
- FltConstLabel := mainFltConstLabel;
|
|
|
- LocVarSize := mainLocVarSize
|
|
|
+ IF LocVarSize > 0 THEN
|
|
|
+ mov(esp, ebp)
|
|
|
+ END;
|
|
|
|
|
|
- |IL.opPUSHC:
|
|
|
- pushc(param2)
|
|
|
+ pop(ebp);
|
|
|
|
|
|
- |IL.opONERR:
|
|
|
- pushc(param2);
|
|
|
- jmp(param1)
|
|
|
+ IF param2 > 0 THEN
|
|
|
+ OutByte(0C2H); OutWord(param2 * 4 MOD 65536) (* ret param2*4 *)
|
|
|
+ ELSE
|
|
|
+ ret
|
|
|
+ END;
|
|
|
+ FltConstLabel := mainFltConstLabel;
|
|
|
+ LocVarSize := mainLocVarSize
|
|
|
|
|
|
- |IL.opPARAM:
|
|
|
- IF param2 = 1 THEN
|
|
|
- UnOp(reg1);
|
|
|
- push(reg1);
|
|
|
- drop
|
|
|
- ELSE
|
|
|
- ASSERT(R.top + 1 <= param2);
|
|
|
- PushAll(param2)
|
|
|
- END
|
|
|
+ |IL.opPUSHC:
|
|
|
+ pushc(param2)
|
|
|
|
|
|
- |IL.opCLEANUP:
|
|
|
- IF param2 # 0 THEN
|
|
|
- addrc(esp, param2 * 4)
|
|
|
- END
|
|
|
+ |IL.opONERR:
|
|
|
+ pushc(param2);
|
|
|
+ jmp(param1)
|
|
|
|
|
|
- |IL.opPOPSP:
|
|
|
- pop(esp)
|
|
|
+ |IL.opPARAM:
|
|
|
+ IF param2 = 1 THEN
|
|
|
+ UnOp(reg1);
|
|
|
+ push(reg1);
|
|
|
+ drop
|
|
|
+ ELSE
|
|
|
+ ASSERT(R.top + 1 <= param2);
|
|
|
+ PushAll(param2)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opCONST:
|
|
|
- movrc(GetAnyReg(), param2)
|
|
|
+ |IL.opCLEANUP:
|
|
|
+ IF param2 # 0 THEN
|
|
|
+ addrc(esp, param2 * 4)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opLABEL:
|
|
|
- SetLabel(param1) (* L: *)
|
|
|
+ |IL.opPOPSP:
|
|
|
+ pop(esp)
|
|
|
|
|
|
- |IL.opNOP, IL.opAND, IL.opOR:
|
|
|
+ |IL.opCONST:
|
|
|
+ movrc(GetAnyReg(), param2)
|
|
|
|
|
|
- |IL.opGADR:
|
|
|
- next := cmd.next(COMMAND);
|
|
|
- IF next.opcode = IL.opADDC THEN
|
|
|
- INC(param2, next.param2);
|
|
|
- cmd := next
|
|
|
- END;
|
|
|
- reg1 := GetAnyReg();
|
|
|
- IF pic THEN
|
|
|
- Pic(reg1, BIN.PICBSS, param2)
|
|
|
- ELSE
|
|
|
- OutByte(0B8H + reg1); (* mov reg1, _bss + param2 *)
|
|
|
- Reloc(BIN.RBSS, param2)
|
|
|
- END
|
|
|
+ |IL.opLABEL:
|
|
|
+ SetLabel(param1) (* L: *)
|
|
|
|
|
|
- |IL.opLADR:
|
|
|
- next := cmd.next(COMMAND);
|
|
|
- n := param2 * 4;
|
|
|
- IF next.opcode = IL.opADDC THEN
|
|
|
- INC(n, next.param2);
|
|
|
- cmd := next
|
|
|
- END;
|
|
|
- OutByte2(8DH, 45H + GetAnyReg() * 8 + long(n)); (* lea reg1, dword[ebp + n] *)
|
|
|
- OutIntByte(n)
|
|
|
+ |IL.opNOP, IL.opAND, IL.opOR:
|
|
|
|
|
|
- |IL.opVADR, IL.opLLOAD32:
|
|
|
- movrm(GetAnyReg(), ebp, param2 * 4)
|
|
|
+ |IL.opGADR:
|
|
|
+ next := cmd.next(COMMAND);
|
|
|
+ IF next.opcode = IL.opADDC THEN
|
|
|
+ INC(param2, next.param2);
|
|
|
+ cmd := next
|
|
|
+ END;
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ IF pic THEN
|
|
|
+ Pic(reg1, BIN.PICBSS, param2)
|
|
|
+ ELSE
|
|
|
+ OutByte(0B8H + reg1); (* mov reg1, _bss + param2 *)
|
|
|
+ Reloc(BIN.RBSS, param2)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opSADR:
|
|
|
- reg1 := GetAnyReg();
|
|
|
- IF pic THEN
|
|
|
- Pic(reg1, BIN.PICDATA, stroffs + param2);
|
|
|
- ELSE
|
|
|
- OutByte(0B8H + reg1); (* mov reg1, _data + stroffs + param2 *)
|
|
|
- Reloc(BIN.RDATA, stroffs + param2)
|
|
|
- END
|
|
|
+ |IL.opLADR:
|
|
|
+ next := cmd.next(COMMAND);
|
|
|
+ n := param2 * 4;
|
|
|
+ IF next.opcode = IL.opADDC THEN
|
|
|
+ INC(n, next.param2);
|
|
|
+ cmd := next
|
|
|
+ END;
|
|
|
+ OutByte2(8DH, 45H + GetAnyReg() * 8 + long(n)); (* lea reg1, dword[ebp + n] *)
|
|
|
+ OutIntByte(n)
|
|
|
|
|
|
- |IL.opSAVEC:
|
|
|
- UnOp(reg1);
|
|
|
- OutByte2(0C7H, reg1); OutInt(param2); (* mov dword[reg1], param2 *)
|
|
|
- drop
|
|
|
+ |IL.opVADR, IL.opLLOAD32:
|
|
|
+ movrm(GetAnyReg(), ebp, param2 * 4)
|
|
|
|
|
|
- |IL.opSAVE8C:
|
|
|
- UnOp(reg1);
|
|
|
- OutByte3(0C6H, reg1, param2 MOD 256); (* mov byte[reg1], param2 *)
|
|
|
- drop
|
|
|
+ |IL.opSADR:
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ IF pic THEN
|
|
|
+ Pic(reg1, BIN.PICDATA, stroffs + param2);
|
|
|
+ ELSE
|
|
|
+ OutByte(0B8H + reg1); (* mov reg1, _data + stroffs + param2 *)
|
|
|
+ Reloc(BIN.RDATA, stroffs + param2)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opSAVE16C:
|
|
|
- UnOp(reg1);
|
|
|
- OutByte3(66H, 0C7H, reg1); OutWord(param2 MOD 65536); (* mov word[reg1], param2 *)
|
|
|
- drop
|
|
|
+ |IL.opSAVEC:
|
|
|
+ UnOp(reg1);
|
|
|
+ OutByte2(0C7H, reg1); OutInt(param2); (* mov dword[reg1], param2 *)
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opVLOAD32:
|
|
|
- reg1 := GetAnyReg();
|
|
|
- movrm(reg1, ebp, param2 * 4);
|
|
|
- movrm(reg1, reg1, 0)
|
|
|
+ |IL.opSAVE8C:
|
|
|
+ UnOp(reg1);
|
|
|
+ OutByte3(0C6H, reg1, param2 MOD 256); (* mov byte[reg1], param2 *)
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opGLOAD32:
|
|
|
- reg1 := GetAnyReg();
|
|
|
- IF pic THEN
|
|
|
- Pic(reg1, BIN.PICBSS, param2);
|
|
|
+ |IL.opSAVE16C:
|
|
|
+ UnOp(reg1);
|
|
|
+ OutByte3(66H, 0C7H, reg1); OutWord(param2 MOD 65536); (* mov word[reg1], param2 *)
|
|
|
+ drop
|
|
|
+
|
|
|
+ |IL.opVLOAD32:
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ movrm(reg1, ebp, param2 * 4);
|
|
|
movrm(reg1, reg1, 0)
|
|
|
- ELSE
|
|
|
- OutByte2(08BH, 05H + reg1 * 8); (* mov reg1, dword[_bss + param2] *)
|
|
|
- Reloc(BIN.RBSS, param2)
|
|
|
- END
|
|
|
|
|
|
- |IL.opLOAD32:
|
|
|
- UnOp(reg1);
|
|
|
- movrm(reg1, reg1, 0)
|
|
|
+ |IL.opGLOAD32:
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ IF pic THEN
|
|
|
+ Pic(reg1, BIN.PICBSS, param2);
|
|
|
+ movrm(reg1, reg1, 0)
|
|
|
+ ELSE
|
|
|
+ OutByte2(08BH, 05H + reg1 * 8); (* mov reg1, dword[_bss + param2] *)
|
|
|
+ Reloc(BIN.RBSS, param2)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opVLOAD8:
|
|
|
- reg1 := GetAnyReg();
|
|
|
- movrm(reg1, ebp, param2 * 4);
|
|
|
- movzx(reg1, reg1, 0, FALSE)
|
|
|
+ |IL.opLOAD32:
|
|
|
+ UnOp(reg1);
|
|
|
+ movrm(reg1, reg1, 0)
|
|
|
|
|
|
- |IL.opGLOAD8:
|
|
|
- reg1 := GetAnyReg();
|
|
|
- IF pic THEN
|
|
|
- Pic(reg1, BIN.PICBSS, param2);
|
|
|
+ |IL.opVLOAD8:
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ movrm(reg1, ebp, param2 * 4);
|
|
|
movzx(reg1, reg1, 0, FALSE)
|
|
|
- ELSE
|
|
|
- OutByte3(00FH, 0B6H, 05H + reg1 * 8); (* movzx reg1, byte[_bss + param2] *)
|
|
|
- Reloc(BIN.RBSS, param2)
|
|
|
- END
|
|
|
|
|
|
- |IL.opLLOAD8:
|
|
|
- movzx(GetAnyReg(), ebp, param2 * 4, FALSE)
|
|
|
+ |IL.opGLOAD8:
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ IF pic THEN
|
|
|
+ Pic(reg1, BIN.PICBSS, param2);
|
|
|
+ movzx(reg1, reg1, 0, FALSE)
|
|
|
+ ELSE
|
|
|
+ OutByte3(00FH, 0B6H, 05H + reg1 * 8); (* movzx reg1, byte[_bss + param2] *)
|
|
|
+ Reloc(BIN.RBSS, param2)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opLOAD8:
|
|
|
- UnOp(reg1);
|
|
|
- movzx(reg1, reg1, 0, FALSE)
|
|
|
+ |IL.opLLOAD8:
|
|
|
+ movzx(GetAnyReg(), ebp, param2 * 4, FALSE)
|
|
|
|
|
|
- |IL.opVLOAD16:
|
|
|
- reg1 := GetAnyReg();
|
|
|
- movrm(reg1, ebp, param2 * 4);
|
|
|
- movzx(reg1, reg1, 0, TRUE)
|
|
|
+ |IL.opLOAD8:
|
|
|
+ UnOp(reg1);
|
|
|
+ movzx(reg1, reg1, 0, FALSE)
|
|
|
|
|
|
- |IL.opGLOAD16:
|
|
|
- reg1 := GetAnyReg();
|
|
|
- IF pic THEN
|
|
|
- Pic(reg1, BIN.PICBSS, param2);
|
|
|
+ |IL.opVLOAD16:
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ movrm(reg1, ebp, param2 * 4);
|
|
|
movzx(reg1, reg1, 0, TRUE)
|
|
|
- ELSE
|
|
|
- OutByte3(00FH, 0B7H, 05H + reg1 * 8); (* movzx reg1, word[_bss + param2] *)
|
|
|
- Reloc(BIN.RBSS, param2)
|
|
|
- END
|
|
|
|
|
|
- |IL.opLLOAD16:
|
|
|
- movzx(GetAnyReg(), ebp, param2 * 4, TRUE)
|
|
|
+ |IL.opGLOAD16:
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ IF pic THEN
|
|
|
+ Pic(reg1, BIN.PICBSS, param2);
|
|
|
+ movzx(reg1, reg1, 0, TRUE)
|
|
|
+ ELSE
|
|
|
+ OutByte3(00FH, 0B7H, 05H + reg1 * 8); (* movzx reg1, word[_bss + param2] *)
|
|
|
+ Reloc(BIN.RBSS, param2)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opLOAD16:
|
|
|
- UnOp(reg1);
|
|
|
- movzx(reg1, reg1, 0, TRUE)
|
|
|
+ |IL.opLLOAD16:
|
|
|
+ movzx(GetAnyReg(), ebp, param2 * 4, TRUE)
|
|
|
|
|
|
- |IL.opUMINUS:
|
|
|
- UnOp(reg1);
|
|
|
- neg(reg1)
|
|
|
+ |IL.opLOAD16:
|
|
|
+ UnOp(reg1);
|
|
|
+ movzx(reg1, reg1, 0, TRUE)
|
|
|
|
|
|
- |IL.opADD:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- add(reg1, reg2);
|
|
|
- drop
|
|
|
+ |IL.opUMINUS:
|
|
|
+ UnOp(reg1);
|
|
|
+ neg(reg1)
|
|
|
+
|
|
|
+ |IL.opADD:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ add(reg1, reg2);
|
|
|
+ drop
|
|
|
+
|
|
|
+ |IL.opADDC:
|
|
|
+ IF param2 # 0 THEN
|
|
|
+ UnOp(reg1);
|
|
|
+ next := cmd.next(COMMAND);
|
|
|
+ CASE next.opcode OF
|
|
|
+ |IL.opLOAD32:
|
|
|
+ movrm(reg1, reg1, param2);
|
|
|
+ cmd := next
|
|
|
+ |IL.opLOAD16:
|
|
|
+ movzx(reg1, reg1, param2, TRUE);
|
|
|
+ cmd := next
|
|
|
+ |IL.opLOAD8:
|
|
|
+ movzx(reg1, reg1, param2, FALSE);
|
|
|
+ cmd := next
|
|
|
+ |IL.opLOAD32_PARAM:
|
|
|
+ pushm(reg1, param2);
|
|
|
+ drop;
|
|
|
+ cmd := next
|
|
|
+ ELSE
|
|
|
+ IF param2 = 1 THEN
|
|
|
+ OutByte(40H + reg1) (* inc reg1 *)
|
|
|
+ ELSIF param2 = -1 THEN
|
|
|
+ OutByte(48H + reg1) (* dec reg1 *)
|
|
|
+ ELSE
|
|
|
+ addrc(reg1, param2)
|
|
|
+ END
|
|
|
+ END
|
|
|
+ END
|
|
|
|
|
|
- |IL.opADDC:
|
|
|
- IF param2 # 0 THEN
|
|
|
+ |IL.opSUB:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ oprr(29H, reg1, reg2); (* sub reg1, reg2 *)
|
|
|
+ drop
|
|
|
+
|
|
|
+ |IL.opSUBR, IL.opSUBL:
|
|
|
UnOp(reg1);
|
|
|
- next := cmd.next(COMMAND);
|
|
|
- CASE next.opcode OF
|
|
|
- |IL.opLOAD32:
|
|
|
- movrm(reg1, reg1, param2);
|
|
|
- cmd := next
|
|
|
- |IL.opLOAD16:
|
|
|
- movzx(reg1, reg1, param2, TRUE);
|
|
|
- cmd := next
|
|
|
- |IL.opLOAD8:
|
|
|
- movzx(reg1, reg1, param2, FALSE);
|
|
|
- cmd := next
|
|
|
- |IL.opLOAD32_PARAM:
|
|
|
- pushm(reg1, param2);
|
|
|
+ IF param2 = 1 THEN
|
|
|
+ OutByte(48H + reg1) (* dec reg1 *)
|
|
|
+ ELSIF param2 = -1 THEN
|
|
|
+ OutByte(40H + reg1) (* inc reg1 *)
|
|
|
+ ELSIF param2 # 0 THEN
|
|
|
+ subrc(reg1, param2)
|
|
|
+ END;
|
|
|
+ IF opcode = IL.opSUBL THEN
|
|
|
+ neg(reg1)
|
|
|
+ END
|
|
|
+
|
|
|
+ |IL.opMULC:
|
|
|
+ IF (cmd.next(COMMAND).opcode = IL.opADD) & ((param2 = 2) OR (param2 = 4) OR (param2 = 8)) THEN
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ OutByte3(8DH, 04H + reg1 * 8, reg1 + reg2 * 8 + 40H * UTILS.Log2(param2)); (* lea reg1, [reg1 + reg2 * param2] *)
|
|
|
drop;
|
|
|
- cmd := next
|
|
|
+ cmd := cmd.next(COMMAND)
|
|
|
ELSE
|
|
|
- IF param2 = 1 THEN
|
|
|
- OutByte(40H + reg1) (* inc reg1 *)
|
|
|
- ELSIF param2 = -1 THEN
|
|
|
- OutByte(48H + reg1) (* dec reg1 *)
|
|
|
+ UnOp(reg1);
|
|
|
+
|
|
|
+ a := param2;
|
|
|
+ IF a > 1 THEN
|
|
|
+ n := UTILS.Log2(a)
|
|
|
+ ELSIF a < -1 THEN
|
|
|
+ n := UTILS.Log2(-a)
|
|
|
ELSE
|
|
|
- addrc(reg1, param2)
|
|
|
+ n := -1
|
|
|
+ END;
|
|
|
+
|
|
|
+ IF a = 1 THEN
|
|
|
+
|
|
|
+ ELSIF a = -1 THEN
|
|
|
+ neg(reg1)
|
|
|
+ ELSIF a = 0 THEN
|
|
|
+ xor(reg1, reg1)
|
|
|
+ ELSE
|
|
|
+ IF n > 0 THEN
|
|
|
+ IF a < 0 THEN
|
|
|
+ neg(reg1)
|
|
|
+ END;
|
|
|
+
|
|
|
+ IF n # 1 THEN
|
|
|
+ OutByte3(0C1H, 0E0H + reg1, n) (* shl reg1, n *)
|
|
|
+ ELSE
|
|
|
+ OutByte2(0D1H, 0E0H + reg1) (* shl reg1, 1 *)
|
|
|
+ END
|
|
|
+ ELSE
|
|
|
+ OutByte2(69H + short(a), 0C0H + reg1 * 9); (* imul reg1, a *)
|
|
|
+ OutIntByte(a)
|
|
|
+ END
|
|
|
END
|
|
|
END
|
|
|
- END
|
|
|
|
|
|
- |IL.opSUB:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- oprr(29H, reg1, reg2); (* sub reg1, reg2 *)
|
|
|
- drop
|
|
|
+ |IL.opMUL:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ OutByte3(0FH, 0AFH, 0C0H + reg1 * 8 + reg2); (* imul reg1, reg2 *)
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opSUBR, IL.opSUBL:
|
|
|
- UnOp(reg1);
|
|
|
- IF param2 = 1 THEN
|
|
|
- OutByte(48H + reg1) (* dec reg1 *)
|
|
|
- ELSIF param2 = -1 THEN
|
|
|
- OutByte(40H + reg1) (* inc reg1 *)
|
|
|
- ELSIF param2 # 0 THEN
|
|
|
- subrc(reg1, param2)
|
|
|
- END;
|
|
|
- IF opcode = IL.opSUBL THEN
|
|
|
- neg(reg1)
|
|
|
- END
|
|
|
+ |IL.opSAVE, IL.opSAVE32:
|
|
|
+ BinOp(reg2, reg1);
|
|
|
+ movmr(reg1, 0, reg2);
|
|
|
+ drop;
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opMULC:
|
|
|
- IF (cmd.next(COMMAND).opcode = IL.opADD) & ((param2 = 2) OR (param2 = 4) OR (param2 = 8)) THEN
|
|
|
- BinOp(reg1, reg2);
|
|
|
- OutByte3(8DH, 04H + reg1 * 8, reg1 + reg2 * 8 + 40H * UTILS.Log2(param2)); (* lea reg1, [reg1 + reg2 * param2] *)
|
|
|
+ |IL.opSAVE8:
|
|
|
+ BinOp(reg2, reg1);
|
|
|
+ movmr8(reg1, 0, reg2);
|
|
|
drop;
|
|
|
- cmd := cmd.next(COMMAND)
|
|
|
- ELSE
|
|
|
+ drop
|
|
|
+
|
|
|
+ |IL.opSAVE16:
|
|
|
+ BinOp(reg2, reg1);
|
|
|
+ movmr16(reg1, 0, reg2);
|
|
|
+ drop;
|
|
|
+ drop
|
|
|
+
|
|
|
+ |IL.opSAVEP:
|
|
|
UnOp(reg1);
|
|
|
+ IF pic THEN
|
|
|
+ reg2 := GetAnyReg();
|
|
|
+ Pic(reg2, BIN.PICCODE, param2);
|
|
|
+ movmr(reg1, 0, reg2);
|
|
|
+ drop
|
|
|
+ ELSE
|
|
|
+ OutByte2(0C7H, reg1); (* mov dword[reg1], L *)
|
|
|
+ Reloc(BIN.RCODE, param2)
|
|
|
+ END;
|
|
|
+ drop
|
|
|
|
|
|
- a := param2;
|
|
|
- IF a > 1 THEN
|
|
|
- n := UTILS.Log2(a)
|
|
|
- ELSIF a < -1 THEN
|
|
|
- n := UTILS.Log2(-a)
|
|
|
+ |IL.opSAVEIP:
|
|
|
+ UnOp(reg1);
|
|
|
+ IF pic THEN
|
|
|
+ reg2 := GetAnyReg();
|
|
|
+ Pic(reg2, BIN.PICIMP, param2);
|
|
|
+ pushm(reg2, 0);
|
|
|
+ OutByte2(08FH, reg1); (* pop dword[reg1] *)
|
|
|
+ drop
|
|
|
ELSE
|
|
|
- n := -1
|
|
|
+ OutByte2(0FFH, 035H); (* push dword[L] *)
|
|
|
+ Reloc(BIN.RIMP, param2);
|
|
|
+ OutByte2(08FH, reg1) (* pop dword[reg1] *)
|
|
|
END;
|
|
|
+ drop
|
|
|
|
|
|
- IF a = 1 THEN
|
|
|
+ |IL.opPUSHP:
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ IF pic THEN
|
|
|
+ Pic(reg1, BIN.PICCODE, param2)
|
|
|
+ ELSE
|
|
|
+ OutByte(0B8H + reg1); (* mov reg1, L *)
|
|
|
+ Reloc(BIN.RCODE, param2)
|
|
|
+ END
|
|
|
|
|
|
- ELSIF a = -1 THEN
|
|
|
- neg(reg1)
|
|
|
- ELSIF a = 0 THEN
|
|
|
- xor(reg1, reg1)
|
|
|
+ |IL.opPUSHIP:
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ IF pic THEN
|
|
|
+ Pic(reg1, BIN.PICIMP, param2);
|
|
|
+ movrm(reg1, reg1, 0)
|
|
|
ELSE
|
|
|
- IF n > 0 THEN
|
|
|
- IF a < 0 THEN
|
|
|
- neg(reg1)
|
|
|
- END;
|
|
|
+ OutByte2(08BH, 05H + reg1 * 8); (* mov reg1, dword[L] *)
|
|
|
+ Reloc(BIN.RIMP, param2)
|
|
|
+ END
|
|
|
|
|
|
- IF n # 1 THEN
|
|
|
- OutByte3(0C1H, 0E0H + reg1, n) (* shl reg1, n *)
|
|
|
- ELSE
|
|
|
- OutByte2(0D1H, 0E0H + reg1) (* shl reg1, 1 *)
|
|
|
- END
|
|
|
- ELSE
|
|
|
- OutByte2(69H + short(a), 0C0H + reg1 * 9); (* imul reg1, a *)
|
|
|
- OutIntByte(a)
|
|
|
- END
|
|
|
+ |IL.opNOT:
|
|
|
+ UnOp(reg1);
|
|
|
+ test(reg1);
|
|
|
+ setcc(sete, reg1);
|
|
|
+ andrc(reg1, 1)
|
|
|
+
|
|
|
+ |IL.opORD:
|
|
|
+ UnOp(reg1);
|
|
|
+ test(reg1);
|
|
|
+ setcc(setne, reg1);
|
|
|
+ andrc(reg1, 1)
|
|
|
+
|
|
|
+ |IL.opSBOOL:
|
|
|
+ BinOp(reg2, reg1);
|
|
|
+ test(reg2);
|
|
|
+ OutByte3(0FH, 95H, reg1); (* setne byte[reg1] *)
|
|
|
+ drop;
|
|
|
+ drop
|
|
|
+
|
|
|
+ |IL.opSBOOLC:
|
|
|
+ UnOp(reg1);
|
|
|
+ OutByte3(0C6H, reg1, ORD(param2 # 0)); (* mov byte[reg1], 0/1 *)
|
|
|
+ drop
|
|
|
+
|
|
|
+ |IL.opEQ..IL.opGE,
|
|
|
+ IL.opEQC..IL.opGEC:
|
|
|
+
|
|
|
+ IF (IL.opEQ <= opcode) & (opcode <= IL.opGE) THEN
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ cmprr(reg1, reg2);
|
|
|
+ drop
|
|
|
+ ELSE
|
|
|
+ UnOp(reg1);
|
|
|
+ cmprc(reg1, param2)
|
|
|
+ END;
|
|
|
+
|
|
|
+ drop;
|
|
|
+ cc := cond(opcode);
|
|
|
+ next := cmd.next(COMMAND);
|
|
|
+
|
|
|
+ IF next.opcode = IL.opJNZ THEN
|
|
|
+ jcc(cc, next.param1);
|
|
|
+ cmd := next
|
|
|
+ ELSIF next.opcode = IL.opJZ THEN
|
|
|
+ jcc(inv0(cc), next.param1);
|
|
|
+ cmd := next
|
|
|
+ ELSE
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ setcc(cc + 16, reg1);
|
|
|
+ andrc(reg1, 1)
|
|
|
END
|
|
|
- END
|
|
|
|
|
|
- |IL.opMUL:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- OutByte3(0FH, 0AFH, 0C0H + reg1 * 8 + reg2); (* imul reg1, reg2 *)
|
|
|
- drop
|
|
|
+ |IL.opEQB, IL.opNEB:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ drop;
|
|
|
|
|
|
- |IL.opSAVE, IL.opSAVE32:
|
|
|
- BinOp(reg2, reg1);
|
|
|
- movmr(reg1, 0, reg2);
|
|
|
- drop;
|
|
|
- drop
|
|
|
+ test(reg1);
|
|
|
+ OutByte2(74H, 5); (* je @f *)
|
|
|
+ movrc(reg1, 1); (* mov reg1, 1
|
|
|
+ @@: *)
|
|
|
+ test(reg2);
|
|
|
+ OutByte2(74H, 5); (* je @f *)
|
|
|
+ movrc(reg2, 1); (* mov reg2, 1
|
|
|
+ @@: *)
|
|
|
|
|
|
- |IL.opSAVE8:
|
|
|
- BinOp(reg2, reg1);
|
|
|
- movmr8(reg1, 0, reg2);
|
|
|
- drop;
|
|
|
- drop
|
|
|
+ cmprr(reg1, reg2);
|
|
|
+ IF opcode = IL.opEQB THEN
|
|
|
+ setcc(sete, reg1)
|
|
|
+ ELSE
|
|
|
+ setcc(setne, reg1)
|
|
|
+ END;
|
|
|
+ andrc(reg1, 1)
|
|
|
|
|
|
- |IL.opSAVE16:
|
|
|
- BinOp(reg2, reg1);
|
|
|
- movmr16(reg1, 0, reg2);
|
|
|
- drop;
|
|
|
- drop
|
|
|
+ |IL.opDROP:
|
|
|
+ UnOp(reg1);
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opSAVEP:
|
|
|
- UnOp(reg1);
|
|
|
- IF pic THEN
|
|
|
- reg2 := GetAnyReg();
|
|
|
- Pic(reg2, BIN.PICCODE, param2);
|
|
|
- movmr(reg1, 0, reg2);
|
|
|
+ |IL.opJNZ1:
|
|
|
+ UnOp(reg1);
|
|
|
+ test(reg1);
|
|
|
+ jcc(jne, param1)
|
|
|
+
|
|
|
+ |IL.opJG:
|
|
|
+ UnOp(reg1);
|
|
|
+ test(reg1);
|
|
|
+ jcc(jg, param1)
|
|
|
+
|
|
|
+ |IL.opJNZ:
|
|
|
+ UnOp(reg1);
|
|
|
+ test(reg1);
|
|
|
+ jcc(jne, param1);
|
|
|
drop
|
|
|
- ELSE
|
|
|
- OutByte2(0C7H, reg1); (* mov dword[reg1], L *)
|
|
|
- Reloc(BIN.RCODE, param2)
|
|
|
- END;
|
|
|
- drop
|
|
|
|
|
|
- |IL.opSAVEIP:
|
|
|
- UnOp(reg1);
|
|
|
- IF pic THEN
|
|
|
- reg2 := GetAnyReg();
|
|
|
- Pic(reg2, BIN.PICIMP, param2);
|
|
|
- pushm(reg2, 0);
|
|
|
- OutByte2(08FH, reg1); (* pop dword[reg1] *)
|
|
|
+ |IL.opJZ:
|
|
|
+ UnOp(reg1);
|
|
|
+ test(reg1);
|
|
|
+ jcc(je, param1);
|
|
|
drop
|
|
|
- ELSE
|
|
|
- OutByte2(0FFH, 035H); (* push dword[L] *)
|
|
|
- Reloc(BIN.RIMP, param2);
|
|
|
- OutByte2(08FH, reg1) (* pop dword[reg1] *)
|
|
|
- END;
|
|
|
- drop
|
|
|
|
|
|
- |IL.opPUSHP:
|
|
|
- reg1 := GetAnyReg();
|
|
|
- IF pic THEN
|
|
|
- Pic(reg1, BIN.PICCODE, param2)
|
|
|
- ELSE
|
|
|
- OutByte(0B8H + reg1); (* mov reg1, L *)
|
|
|
- Reloc(BIN.RCODE, param2)
|
|
|
- END
|
|
|
+ |IL.opSWITCH:
|
|
|
+ UnOp(reg1);
|
|
|
+ IF param2 = 0 THEN
|
|
|
+ reg2 := eax
|
|
|
+ ELSE
|
|
|
+ reg2 := ecx
|
|
|
+ END;
|
|
|
+ IF reg1 # reg2 THEN
|
|
|
+ ASSERT(REG.GetReg(R, reg2));
|
|
|
+ ASSERT(REG.Exchange(R, reg1, reg2));
|
|
|
+ drop
|
|
|
+ END;
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opPUSHIP:
|
|
|
- reg1 := GetAnyReg();
|
|
|
- IF pic THEN
|
|
|
- Pic(reg1, BIN.PICIMP, param2);
|
|
|
- movrm(reg1, reg1, 0)
|
|
|
- ELSE
|
|
|
- OutByte2(08BH, 05H + reg1 * 8); (* mov reg1, dword[L] *)
|
|
|
- Reloc(BIN.RIMP, param2)
|
|
|
- END
|
|
|
+ |IL.opENDSW:
|
|
|
|
|
|
- |IL.opNOT:
|
|
|
- UnOp(reg1);
|
|
|
- test(reg1);
|
|
|
- setcc(sete, reg1);
|
|
|
- andrc(reg1, 1)
|
|
|
-
|
|
|
- |IL.opORD:
|
|
|
- UnOp(reg1);
|
|
|
- test(reg1);
|
|
|
- setcc(setne, reg1);
|
|
|
- andrc(reg1, 1)
|
|
|
-
|
|
|
- |IL.opSBOOL:
|
|
|
- BinOp(reg2, reg1);
|
|
|
- test(reg2);
|
|
|
- OutByte3(0FH, 95H, reg1); (* setne byte[reg1] *)
|
|
|
- drop;
|
|
|
- drop
|
|
|
+ |IL.opCASEL:
|
|
|
+ cmprc(eax, param1);
|
|
|
+ jcc(jl, param2)
|
|
|
|
|
|
- |IL.opSBOOLC:
|
|
|
- UnOp(reg1);
|
|
|
- OutByte3(0C6H, reg1, ORD(param2 # 0)); (* mov byte[reg1], 0/1 *)
|
|
|
- drop
|
|
|
+ |IL.opCASER:
|
|
|
+ cmprc(eax, param1);
|
|
|
+ jcc(jg, param2)
|
|
|
+
|
|
|
+ |IL.opCASELR:
|
|
|
+ cmprc(eax, param1);
|
|
|
+ IF param2 = cmd.param3 THEN
|
|
|
+ jcc(jne, param2)
|
|
|
+ ELSE
|
|
|
+ jcc(jl, param2);
|
|
|
+ jcc(jg, cmd.param3)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opEQ..IL.opGE,
|
|
|
- IL.opEQC..IL.opGEC:
|
|
|
+ |IL.opCODE:
|
|
|
+ OutByte(param2)
|
|
|
|
|
|
- IF (IL.opEQ <= opcode) & (opcode <= IL.opGE) THEN
|
|
|
+ |IL.opGET, IL.opGETC:
|
|
|
+ IF opcode = IL.opGET THEN
|
|
|
+ BinOp(reg1, reg2)
|
|
|
+ ELSIF opcode = IL.opGETC THEN
|
|
|
+ UnOp(reg2);
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ movrc(reg1, param1)
|
|
|
+ END;
|
|
|
+ drop;
|
|
|
+ drop;
|
|
|
+
|
|
|
+ IF param2 # 8 THEN
|
|
|
+ _movrm(reg1, reg1, 0, param2 * 8, FALSE);
|
|
|
+ _movrm(reg1, reg2, 0, param2 * 8, TRUE)
|
|
|
+ ELSE
|
|
|
+ PushAll(0);
|
|
|
+ push(reg1);
|
|
|
+ push(reg2);
|
|
|
+ pushc(8);
|
|
|
+ CallRTL(pic, IL._move)
|
|
|
+ END
|
|
|
+
|
|
|
+ |IL.opSAVES:
|
|
|
+ UnOp(reg2);
|
|
|
+ REG.PushAll_1(R);
|
|
|
+
|
|
|
+ IF pic THEN
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ Pic(reg1, BIN.PICDATA, stroffs + param2);
|
|
|
+ push(reg1);
|
|
|
+ drop
|
|
|
+ ELSE
|
|
|
+ OutByte(068H); (* push _data + stroffs + param2 *)
|
|
|
+ Reloc(BIN.RDATA, stroffs + param2);
|
|
|
+ END;
|
|
|
+
|
|
|
+ push(reg2);
|
|
|
+ drop;
|
|
|
+ pushc(param1);
|
|
|
+ CallRTL(pic, IL._move)
|
|
|
+
|
|
|
+ |IL.opCHKIDX:
|
|
|
+ UnOp(reg1);
|
|
|
+ cmprc(reg1, param2);
|
|
|
+ jcc(jb, param1)
|
|
|
+
|
|
|
+ |IL.opCHKIDX2:
|
|
|
BinOp(reg1, reg2);
|
|
|
- cmprr(reg1, reg2);
|
|
|
- drop
|
|
|
- ELSE
|
|
|
+ IF param2 # -1 THEN
|
|
|
+ cmprr(reg2, reg1);
|
|
|
+ jcc(jb, param1)
|
|
|
+ END;
|
|
|
+ INCL(R.regs, reg1);
|
|
|
+ DEC(R.top);
|
|
|
+ R.stk[R.top] := reg2
|
|
|
+
|
|
|
+ |IL.opLEN:
|
|
|
+ n := param2;
|
|
|
UnOp(reg1);
|
|
|
- cmprc(reg1, param2)
|
|
|
- END;
|
|
|
+ drop;
|
|
|
+ EXCL(R.regs, reg1);
|
|
|
|
|
|
- drop;
|
|
|
- cc := cond(opcode);
|
|
|
- next := cmd.next(COMMAND);
|
|
|
+ WHILE n > 0 DO
|
|
|
+ UnOp(reg2);
|
|
|
+ drop;
|
|
|
+ DEC(n)
|
|
|
+ END;
|
|
|
|
|
|
- IF next.opcode = IL.opJNZ THEN
|
|
|
- jcc(cc, next.param1);
|
|
|
- cmd := next
|
|
|
- ELSIF next.opcode = IL.opJZ THEN
|
|
|
- jcc(inv0(cc), next.param1);
|
|
|
- cmd := next
|
|
|
- ELSE
|
|
|
- reg1 := GetAnyReg();
|
|
|
- setcc(cc + 16, reg1);
|
|
|
- andrc(reg1, 1)
|
|
|
- END
|
|
|
+ INCL(R.regs, reg1);
|
|
|
+ ASSERT(REG.GetReg(R, reg1))
|
|
|
|
|
|
- |IL.opEQB, IL.opNEB:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- drop;
|
|
|
-
|
|
|
- test(reg1);
|
|
|
- OutByte2(74H, 5); (* je @f *)
|
|
|
- movrc(reg1, 1); (* mov reg1, 1
|
|
|
- @@: *)
|
|
|
- test(reg2);
|
|
|
- OutByte2(74H, 5); (* je @f *)
|
|
|
- movrc(reg2, 1); (* mov reg2, 1
|
|
|
- @@: *)
|
|
|
-
|
|
|
- cmprr(reg1, reg2);
|
|
|
- IF opcode = IL.opEQB THEN
|
|
|
- setcc(sete, reg1)
|
|
|
- ELSE
|
|
|
- setcc(setne, reg1)
|
|
|
- END;
|
|
|
- andrc(reg1, 1)
|
|
|
+ |IL.opINCC:
|
|
|
+ UnOp(reg1);
|
|
|
+ IF param2 = 1 THEN
|
|
|
+ OutByte2(0FFH, reg1) (* inc dword[reg1] *)
|
|
|
+ ELSIF param2 = -1 THEN
|
|
|
+ OutByte2(0FFH, reg1 + 8) (* dec dword[reg1] *)
|
|
|
+ ELSE
|
|
|
+ OutByte2(81H + short(param2), reg1); OutIntByte(param2) (* add dword[reg1], param2 *)
|
|
|
+ END;
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opDROP:
|
|
|
- UnOp(reg1);
|
|
|
- drop
|
|
|
+ |IL.opINC, IL.opDEC:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ OutByte2(01H + 28H * ORD(opcode = IL.opDEC), reg1 * 8 + reg2); (* add/sub dword[reg2], reg1 *)
|
|
|
+ drop;
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opJNZ1:
|
|
|
- UnOp(reg1);
|
|
|
- test(reg1);
|
|
|
- jcc(jne, param1)
|
|
|
+ |IL.opINCCB, IL.opDECCB:
|
|
|
+ UnOp(reg1);
|
|
|
+ OutByte3(80H, 28H * ORD(opcode = IL.opDECCB) + reg1, param2 MOD 256); (* add/sub byte[reg1], n *)
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opJG:
|
|
|
- UnOp(reg1);
|
|
|
- test(reg1);
|
|
|
- jcc(jg, param1)
|
|
|
+ |IL.opINCB, IL.opDECB:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ OutByte2(28H * ORD(opcode = IL.opDECB), reg1 * 8 + reg2); (* add/sub byte[reg2], reg1 *)
|
|
|
+ drop;
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opJNZ:
|
|
|
- UnOp(reg1);
|
|
|
- test(reg1);
|
|
|
- jcc(jne, param1);
|
|
|
- drop
|
|
|
+ |IL.opMULS:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ oprr(21H, reg1, reg2); (* and reg1, reg2 *)
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opJZ:
|
|
|
- UnOp(reg1);
|
|
|
- test(reg1);
|
|
|
- jcc(je, param1);
|
|
|
- drop
|
|
|
+ |IL.opMULSC:
|
|
|
+ UnOp(reg1);
|
|
|
+ andrc(reg1, param2)
|
|
|
|
|
|
- |IL.opSWITCH:
|
|
|
- UnOp(reg1);
|
|
|
- IF param2 = 0 THEN
|
|
|
- reg2 := eax
|
|
|
- ELSE
|
|
|
- reg2 := ecx
|
|
|
- END;
|
|
|
- IF reg1 # reg2 THEN
|
|
|
- ASSERT(REG.GetReg(R, reg2));
|
|
|
- ASSERT(REG.Exchange(R, reg1, reg2));
|
|
|
+ |IL.opDIVS:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ xor(reg1, reg2);
|
|
|
drop
|
|
|
- END;
|
|
|
- drop
|
|
|
|
|
|
- |IL.opENDSW:
|
|
|
+ |IL.opDIVSC:
|
|
|
+ UnOp(reg1);
|
|
|
+ xorrc(reg1, param2)
|
|
|
|
|
|
- |IL.opCASEL:
|
|
|
- cmprc(eax, param1);
|
|
|
- jcc(jl, param2)
|
|
|
+ |IL.opADDS:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ oprr(9H, reg1, reg2); (* or reg1, reg2 *)
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opCASER:
|
|
|
- cmprc(eax, param1);
|
|
|
- jcc(jg, param2)
|
|
|
+ |IL.opSUBS:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ not(reg2);
|
|
|
+ oprr(21H, reg1, reg2); (* and reg1, reg2 *)
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opCASELR:
|
|
|
- cmprc(eax, param1);
|
|
|
- IF param2 = cmd.param3 THEN
|
|
|
- jcc(jne, param2)
|
|
|
- ELSE
|
|
|
- jcc(jl, param2);
|
|
|
- jcc(jg, cmd.param3)
|
|
|
- END
|
|
|
+ |IL.opADDSC:
|
|
|
+ UnOp(reg1);
|
|
|
+ orrc(reg1, param2)
|
|
|
|
|
|
- |IL.opCODE:
|
|
|
- OutByte(param2)
|
|
|
+ |IL.opSUBSL:
|
|
|
+ UnOp(reg1);
|
|
|
+ not(reg1);
|
|
|
+ andrc(reg1, param2)
|
|
|
|
|
|
- |IL.opGET, IL.opGETC:
|
|
|
- IF opcode = IL.opGET THEN
|
|
|
- BinOp(reg1, reg2)
|
|
|
- ELSIF opcode = IL.opGETC THEN
|
|
|
- UnOp(reg2);
|
|
|
- reg1 := GetAnyReg();
|
|
|
- movrc(reg1, param1)
|
|
|
- END;
|
|
|
- drop;
|
|
|
- drop;
|
|
|
+ |IL.opSUBSR:
|
|
|
+ UnOp(reg1);
|
|
|
+ andrc(reg1, ORD(-BITS(param2)))
|
|
|
|
|
|
- IF param2 # 8 THEN
|
|
|
- _movrm(reg1, reg1, 0, param2 * 8, FALSE);
|
|
|
- _movrm(reg1, reg2, 0, param2 * 8, TRUE)
|
|
|
- ELSE
|
|
|
- PushAll(0);
|
|
|
- push(reg1);
|
|
|
- push(reg2);
|
|
|
- pushc(8);
|
|
|
- CallRTL(pic, IL._move)
|
|
|
- END
|
|
|
+ |IL.opUMINS:
|
|
|
+ UnOp(reg1);
|
|
|
+ not(reg1)
|
|
|
|
|
|
- |IL.opSAVES:
|
|
|
- UnOp(reg2);
|
|
|
- REG.PushAll_1(R);
|
|
|
+ |IL.opLENGTH:
|
|
|
+ PushAll(2);
|
|
|
+ CallRTL(pic, IL._length);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opLENGTHW:
|
|
|
+ PushAll(2);
|
|
|
+ CallRTL(pic, IL._lengthw);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR:
|
|
|
+ UnOp(reg1);
|
|
|
+ IF reg1 # ecx THEN
|
|
|
+ ASSERT(REG.GetReg(R, ecx));
|
|
|
+ ASSERT(REG.Exchange(R, reg1, ecx));
|
|
|
+ drop
|
|
|
+ END;
|
|
|
+
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ ASSERT(reg2 = ecx);
|
|
|
+ OutByte(0D3H);
|
|
|
+ shift(opcode, reg1); (* shift reg1, cl *)
|
|
|
+ drop
|
|
|
+
|
|
|
+ |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1:
|
|
|
+ UnOp(reg1);
|
|
|
+ IF reg1 # ecx THEN
|
|
|
+ ASSERT(REG.GetReg(R, ecx));
|
|
|
+ ASSERT(REG.Exchange(R, reg1, ecx));
|
|
|
+ drop
|
|
|
+ END;
|
|
|
|
|
|
- IF pic THEN
|
|
|
reg1 := GetAnyReg();
|
|
|
- Pic(reg1, BIN.PICDATA, stroffs + param2);
|
|
|
- push(reg1);
|
|
|
+ movrc(reg1, param2);
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ ASSERT(reg1 = ecx);
|
|
|
+ OutByte(0D3H);
|
|
|
+ shift(opcode, reg2); (* shift reg2, cl *)
|
|
|
+ drop;
|
|
|
+ drop;
|
|
|
+ ASSERT(REG.GetReg(R, reg2))
|
|
|
+
|
|
|
+ |IL.opASR2, IL.opROR2, IL.opLSL2, IL.opLSR2:
|
|
|
+ UnOp(reg1);
|
|
|
+ n := param2 MOD 32;
|
|
|
+ IF n # 1 THEN
|
|
|
+ OutByte(0C1H)
|
|
|
+ ELSE
|
|
|
+ OutByte(0D1H)
|
|
|
+ END;
|
|
|
+ shift(opcode, reg1); (* shift reg1, n *)
|
|
|
+ IF n # 1 THEN
|
|
|
+ OutByte(n)
|
|
|
+ END
|
|
|
+
|
|
|
+ |IL.opMAX, IL.opMIN:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ cmprr(reg1, reg2);
|
|
|
+ OutByte2(07DH + ORD(opcode = IL.opMIN), 2); (* jge/jle L *)
|
|
|
+ mov(reg1, reg2);
|
|
|
+ (* L: *)
|
|
|
drop
|
|
|
- ELSE
|
|
|
- OutByte(068H); (* push _data + stroffs + param2 *)
|
|
|
- Reloc(BIN.RDATA, stroffs + param2);
|
|
|
- END;
|
|
|
|
|
|
- push(reg2);
|
|
|
- drop;
|
|
|
- pushc(param1);
|
|
|
- CallRTL(pic, IL._move)
|
|
|
+ |IL.opMAXC, IL.opMINC:
|
|
|
+ UnOp(reg1);
|
|
|
+ cmprc(reg1, param2);
|
|
|
+ label := NewLabel();
|
|
|
+ IF opcode = IL.opMINC THEN
|
|
|
+ cc := jle
|
|
|
+ ELSE
|
|
|
+ cc := jge
|
|
|
+ END;
|
|
|
+ jcc(cc, label);
|
|
|
+ movrc(reg1, param2);
|
|
|
+ SetLabel(label)
|
|
|
|
|
|
- |IL.opCHKIDX:
|
|
|
- UnOp(reg1);
|
|
|
- cmprc(reg1, param2);
|
|
|
- jcc(jb, param1)
|
|
|
+ |IL.opIN, IL.opINR:
|
|
|
+ IF opcode = IL.opINR THEN
|
|
|
+ reg2 := GetAnyReg();
|
|
|
+ movrc(reg2, param2)
|
|
|
+ END;
|
|
|
+ label := NewLabel();
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ cmprc(reg1, 32);
|
|
|
+ OutByte2(72H, 4); (* jb L *)
|
|
|
+ xor(reg1, reg1);
|
|
|
+ jmp(label);
|
|
|
+ (* L: *)
|
|
|
+ OutByte3(0FH, 0A3H, 0C0H + reg2 + 8 * reg1); (* bt reg2, reg1 *)
|
|
|
+ setcc(setc, reg1);
|
|
|
+ andrc(reg1, 1);
|
|
|
+ SetLabel(label);
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opCHKIDX2:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- IF param2 # -1 THEN
|
|
|
- cmprr(reg2, reg1);
|
|
|
- jcc(jb, param1)
|
|
|
- END;
|
|
|
- INCL(R.regs, reg1);
|
|
|
- DEC(R.top);
|
|
|
- R.stk[R.top] := reg2
|
|
|
+ |IL.opINL:
|
|
|
+ UnOp(reg1);
|
|
|
+ OutByte3(0FH, 0BAH, 0E0H + reg1); OutByte(param2); (* bt reg1, param2 *)
|
|
|
+ setcc(setc, reg1);
|
|
|
+ andrc(reg1, 1)
|
|
|
|
|
|
- |IL.opLEN:
|
|
|
- n := param2;
|
|
|
- UnOp(reg1);
|
|
|
- drop;
|
|
|
- EXCL(R.regs, reg1);
|
|
|
+ |IL.opRSET:
|
|
|
+ PushAll(2);
|
|
|
+ CallRTL(pic, IL._set);
|
|
|
+ GetRegA
|
|
|
|
|
|
- WHILE n > 0 DO
|
|
|
- UnOp(reg2);
|
|
|
+ |IL.opRSETR:
|
|
|
+ PushAll(1);
|
|
|
+ pushc(param2);
|
|
|
+ CallRTL(pic, IL._set);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opRSETL:
|
|
|
+ UnOp(reg1);
|
|
|
+ REG.PushAll_1(R);
|
|
|
+ pushc(param2);
|
|
|
+ push(reg1);
|
|
|
drop;
|
|
|
- DEC(n)
|
|
|
- END;
|
|
|
+ CallRTL(pic, IL._set);
|
|
|
+ GetRegA
|
|
|
|
|
|
- INCL(R.regs, reg1);
|
|
|
- ASSERT(REG.GetReg(R, reg1))
|
|
|
+ |IL.opRSET1:
|
|
|
+ PushAll(1);
|
|
|
+ CallRTL(pic, IL._set1);
|
|
|
+ GetRegA
|
|
|
|
|
|
- |IL.opINCC:
|
|
|
- UnOp(reg1);
|
|
|
- IF param2 = 1 THEN
|
|
|
- OutByte2(0FFH, reg1) (* inc dword[reg1] *)
|
|
|
- ELSIF param2 = -1 THEN
|
|
|
- OutByte2(0FFH, reg1 + 8) (* dec dword[reg1] *)
|
|
|
- ELSE
|
|
|
- OutByte2(81H + short(param2), reg1); OutIntByte(param2) (* add dword[reg1], param2 *)
|
|
|
- END;
|
|
|
- drop
|
|
|
+ |IL.opINCL, IL.opEXCL:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ cmprc(reg1, 32);
|
|
|
+ OutByte2(73H, 03H); (* jnb L *)
|
|
|
+ OutByte(0FH);
|
|
|
+ IF opcode = IL.opINCL THEN
|
|
|
+ OutByte(0ABH) (* bts dword[reg2], reg1 *)
|
|
|
+ ELSE
|
|
|
+ OutByte(0B3H) (* btr dword[reg2], reg1 *)
|
|
|
+ END;
|
|
|
+ OutByte(reg2 + 8 * reg1);
|
|
|
+ (* L: *)
|
|
|
+ drop;
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opINC, IL.opDEC:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- OutByte2(01H + 28H * ORD(opcode = IL.opDEC), reg1 * 8 + reg2); (* add/sub dword[reg2], reg1 *)
|
|
|
- drop;
|
|
|
- drop
|
|
|
+ |IL.opINCLC:
|
|
|
+ UnOp(reg1);
|
|
|
+ OutByte3(0FH, 0BAH, 28H + reg1); OutByte(param2); (* bts dword[reg1], param2 *)
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opINCCB, IL.opDECCB:
|
|
|
- UnOp(reg1);
|
|
|
- OutByte3(80H, 28H * ORD(opcode = IL.opDECCB) + reg1, param2 MOD 256); (* add/sub byte[reg1], n *)
|
|
|
- drop
|
|
|
+ |IL.opEXCLC:
|
|
|
+ UnOp(reg1);
|
|
|
+ OutByte3(0FH, 0BAH, 30H + reg1); OutByte(param2); (* btr dword[reg1], param2 *)
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opINCB, IL.opDECB:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- OutByte2(28H * ORD(opcode = IL.opDECB), reg1 * 8 + reg2); (* add/sub byte[reg2], reg1 *)
|
|
|
- drop;
|
|
|
- drop
|
|
|
+ |IL.opDIV:
|
|
|
+ PushAll(2);
|
|
|
+ CallRTL(pic, IL._divmod);
|
|
|
+ GetRegA
|
|
|
|
|
|
- |IL.opMULS:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- oprr(21H, reg1, reg2); (* and reg1, reg2 *)
|
|
|
- drop
|
|
|
+ |IL.opDIVR:
|
|
|
+ n := UTILS.Log2(param2);
|
|
|
+ IF n > 0 THEN
|
|
|
+ UnOp(reg1);
|
|
|
+ IF n # 1 THEN
|
|
|
+ OutByte3(0C1H, 0F8H + reg1, n) (* sar reg1, n *)
|
|
|
+ ELSE
|
|
|
+ OutByte2(0D1H, 0F8H + reg1) (* sar reg1, 1 *)
|
|
|
+ END
|
|
|
+ ELSIF n < 0 THEN
|
|
|
+ PushAll(1);
|
|
|
+ pushc(param2);
|
|
|
+ CallRTL(pic, IL._divmod);
|
|
|
+ GetRegA
|
|
|
+ END
|
|
|
|
|
|
- |IL.opMULSC:
|
|
|
- UnOp(reg1);
|
|
|
- andrc(reg1, param2)
|
|
|
+ |IL.opDIVL:
|
|
|
+ UnOp(reg1);
|
|
|
+ REG.PushAll_1(R);
|
|
|
+ pushc(param2);
|
|
|
+ push(reg1);
|
|
|
+ drop;
|
|
|
+ CallRTL(pic, IL._divmod);
|
|
|
+ GetRegA
|
|
|
|
|
|
- |IL.opDIVS:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- xor(reg1, reg2);
|
|
|
- drop
|
|
|
+ |IL.opMOD:
|
|
|
+ PushAll(2);
|
|
|
+ CallRTL(pic, IL._divmod);
|
|
|
+ mov(eax, edx);
|
|
|
+ GetRegA
|
|
|
|
|
|
- |IL.opDIVSC:
|
|
|
- UnOp(reg1);
|
|
|
- xorrc(reg1, param2)
|
|
|
+ |IL.opMODR:
|
|
|
+ n := UTILS.Log2(param2);
|
|
|
+ IF n > 0 THEN
|
|
|
+ UnOp(reg1);
|
|
|
+ andrc(reg1, param2 - 1);
|
|
|
+ ELSIF n < 0 THEN
|
|
|
+ PushAll(1);
|
|
|
+ pushc(param2);
|
|
|
+ CallRTL(pic, IL._divmod);
|
|
|
+ mov(eax, edx);
|
|
|
+ GetRegA
|
|
|
+ ELSE
|
|
|
+ UnOp(reg1);
|
|
|
+ xor(reg1, reg1)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opADDS:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- oprr(9H, reg1, reg2); (* or reg1, reg2 *)
|
|
|
- drop
|
|
|
+ |IL.opMODL:
|
|
|
+ UnOp(reg1);
|
|
|
+ REG.PushAll_1(R);
|
|
|
+ pushc(param2);
|
|
|
+ push(reg1);
|
|
|
+ drop;
|
|
|
+ CallRTL(pic, IL._divmod);
|
|
|
+ mov(eax, edx);
|
|
|
+ GetRegA
|
|
|
|
|
|
- |IL.opSUBS:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- not(reg2);
|
|
|
- oprr(21H, reg1, reg2); (* and reg1, reg2 *)
|
|
|
- drop
|
|
|
+ |IL.opERR:
|
|
|
+ CallRTL(pic, IL._error)
|
|
|
|
|
|
- |IL.opADDSC:
|
|
|
- UnOp(reg1);
|
|
|
- orrc(reg1, param2)
|
|
|
-
|
|
|
- |IL.opSUBSL:
|
|
|
- UnOp(reg1);
|
|
|
- not(reg1);
|
|
|
- andrc(reg1, param2)
|
|
|
-
|
|
|
- |IL.opSUBSR:
|
|
|
- UnOp(reg1);
|
|
|
- andrc(reg1, ORD(-BITS(param2)))
|
|
|
-
|
|
|
- |IL.opUMINS:
|
|
|
- UnOp(reg1);
|
|
|
- not(reg1)
|
|
|
-
|
|
|
- |IL.opLENGTH:
|
|
|
- PushAll(2);
|
|
|
- CallRTL(pic, IL._length);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opLENGTHW:
|
|
|
- PushAll(2);
|
|
|
- CallRTL(pic, IL._lengthw);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR:
|
|
|
- UnOp(reg1);
|
|
|
- IF reg1 # ecx THEN
|
|
|
- ASSERT(REG.GetReg(R, ecx));
|
|
|
- ASSERT(REG.Exchange(R, reg1, ecx));
|
|
|
- drop
|
|
|
- END;
|
|
|
+ |IL.opABS:
|
|
|
+ UnOp(reg1);
|
|
|
+ test(reg1);
|
|
|
+ OutByte2(07DH, 002H); (* jge L *)
|
|
|
+ neg(reg1) (* neg reg1
|
|
|
+ L: *)
|
|
|
+
|
|
|
+ |IL.opCOPY:
|
|
|
+ IF (0 < param2) & (param2 <= 64) THEN
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ reg3 := GetAnyReg();
|
|
|
+ FOR n := 0 TO param2 - param2 MOD 4 - 1 BY 4 DO
|
|
|
+ movrm(reg3, reg1, n);
|
|
|
+ movmr(reg2, n, reg3)
|
|
|
+ END;
|
|
|
+ n := param2 - param2 MOD 4;
|
|
|
+ IF param2 MOD 4 >= 2 THEN
|
|
|
+ movrm16(reg3, reg1, n);
|
|
|
+ movmr16(reg2, n, reg3);
|
|
|
+ INC(n, 2);
|
|
|
+ DEC(param2, 2)
|
|
|
+ END;
|
|
|
+ IF param2 MOD 4 = 1 THEN
|
|
|
+ movrm8(reg3, reg1, n);
|
|
|
+ movmr8(reg2, n, reg3);
|
|
|
+ END;
|
|
|
+ drop;
|
|
|
+ drop;
|
|
|
+ drop
|
|
|
+ ELSE
|
|
|
+ PushAll(2);
|
|
|
+ pushc(param2);
|
|
|
+ CallRTL(pic, IL._move)
|
|
|
+ END
|
|
|
|
|
|
- BinOp(reg1, reg2);
|
|
|
- ASSERT(reg2 = ecx);
|
|
|
- OutByte(0D3H);
|
|
|
- shift(opcode, reg1); (* shift reg1, cl *)
|
|
|
- drop
|
|
|
+ |IL.opMOVE:
|
|
|
+ PushAll(3);
|
|
|
+ CallRTL(pic, IL._move)
|
|
|
|
|
|
- |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1:
|
|
|
- UnOp(reg1);
|
|
|
- IF reg1 # ecx THEN
|
|
|
- ASSERT(REG.GetReg(R, ecx));
|
|
|
- ASSERT(REG.Exchange(R, reg1, ecx));
|
|
|
- drop
|
|
|
- END;
|
|
|
+ |IL.opCOPYA:
|
|
|
+ PushAll(4);
|
|
|
+ pushc(param2);
|
|
|
+ CallRTL(pic, IL._arrcpy);
|
|
|
+ GetRegA
|
|
|
|
|
|
- reg1 := GetAnyReg();
|
|
|
- movrc(reg1, param2);
|
|
|
- BinOp(reg1, reg2);
|
|
|
- ASSERT(reg1 = ecx);
|
|
|
- OutByte(0D3H);
|
|
|
- shift(opcode, reg2); (* shift reg2, cl *)
|
|
|
- drop;
|
|
|
- drop;
|
|
|
- ASSERT(REG.GetReg(R, reg2))
|
|
|
-
|
|
|
- |IL.opASR2, IL.opROR2, IL.opLSL2, IL.opLSR2:
|
|
|
- UnOp(reg1);
|
|
|
- n := param2 MOD 32;
|
|
|
- IF n # 1 THEN
|
|
|
- OutByte(0C1H)
|
|
|
- ELSE
|
|
|
- OutByte(0D1H)
|
|
|
- END;
|
|
|
- shift(opcode, reg1); (* shift reg1, n *)
|
|
|
- IF n # 1 THEN
|
|
|
- OutByte(n)
|
|
|
- END
|
|
|
+ |IL.opCOPYS:
|
|
|
+ PushAll(4);
|
|
|
+ pushc(param2);
|
|
|
+ CallRTL(pic, IL._strcpy)
|
|
|
|
|
|
- |IL.opMAX, IL.opMIN:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- cmprr(reg1, reg2);
|
|
|
- OutByte2(07DH + ORD(opcode = IL.opMIN), 2); (* jge/jle L *)
|
|
|
- mov(reg1, reg2);
|
|
|
- (* L: *)
|
|
|
- drop
|
|
|
+ |IL.opROT:
|
|
|
+ PushAll(0);
|
|
|
+ push(esp);
|
|
|
+ pushc(param2);
|
|
|
+ CallRTL(pic, IL._rot)
|
|
|
|
|
|
- |IL.opMAXC, IL.opMINC:
|
|
|
- UnOp(reg1);
|
|
|
- cmprc(reg1, param2);
|
|
|
- label := NewLabel();
|
|
|
- IF opcode = IL.opMINC THEN
|
|
|
- cc := jle
|
|
|
- ELSE
|
|
|
- cc := jge
|
|
|
- END;
|
|
|
- jcc(cc, label);
|
|
|
- movrc(reg1, param2);
|
|
|
- SetLabel(label)
|
|
|
-
|
|
|
- |IL.opIN, IL.opINR:
|
|
|
- IF opcode = IL.opINR THEN
|
|
|
- reg2 := GetAnyReg();
|
|
|
- movrc(reg2, param2)
|
|
|
- END;
|
|
|
- label := NewLabel();
|
|
|
- BinOp(reg1, reg2);
|
|
|
- cmprc(reg1, 32);
|
|
|
- OutByte2(72H, 4); (* jb L *)
|
|
|
- xor(reg1, reg1);
|
|
|
- jmp(label);
|
|
|
- (* L: *)
|
|
|
- OutByte3(0FH, 0A3H, 0C0H + reg2 + 8 * reg1); (* bt reg2, reg1 *)
|
|
|
- setcc(setc, reg1);
|
|
|
- andrc(reg1, 1);
|
|
|
- SetLabel(label);
|
|
|
- drop
|
|
|
+ |IL.opNEW:
|
|
|
+ PushAll(1);
|
|
|
+ CASE TARGETS.OS OF
|
|
|
+ |TARGETS.osWIN32:
|
|
|
+ n := param2 + 4;
|
|
|
+ ASSERT(UTILS.Align(n, 4))
|
|
|
+ |TARGETS.osLINUX32:
|
|
|
+ n := param2 + 16;
|
|
|
+ ASSERT(UTILS.Align(n, 16))
|
|
|
+ |TARGETS.osKOS:
|
|
|
+ n := param2 + 8;
|
|
|
+ ASSERT(UTILS.Align(n, 32))
|
|
|
+ END;
|
|
|
+ pushc(n);
|
|
|
+ pushc(param1);
|
|
|
+ CallRTL(pic, IL._new)
|
|
|
+
|
|
|
+ |IL.opDISP:
|
|
|
+ PushAll(1);
|
|
|
+ CallRTL(pic, IL._dispose)
|
|
|
+
|
|
|
+ |IL.opEQS .. IL.opGES:
|
|
|
+ PushAll(4);
|
|
|
+ pushc(opcode - IL.opEQS);
|
|
|
+ CallRTL(pic, IL._strcmp);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opEQSW .. IL.opGESW:
|
|
|
+ PushAll(4);
|
|
|
+ pushc(opcode - IL.opEQSW);
|
|
|
+ CallRTL(pic, IL._strcmpw);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opEQP, IL.opNEP, IL.opEQIP, IL.opNEIP:
|
|
|
+ UnOp(reg1);
|
|
|
+ CASE opcode OF
|
|
|
+ |IL.opEQP, IL.opNEP:
|
|
|
+ IF pic THEN
|
|
|
+ reg2 := GetAnyReg();
|
|
|
+ Pic(reg2, BIN.PICCODE, param1);
|
|
|
+ cmprr(reg1, reg2);
|
|
|
+ drop
|
|
|
+ ELSE
|
|
|
+ OutByte2(081H, 0F8H + reg1); (* cmp reg1, L *)
|
|
|
+ Reloc(BIN.RCODE, param1)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opINL:
|
|
|
- UnOp(reg1);
|
|
|
- OutByte3(0FH, 0BAH, 0E0H + reg1); OutByte(param2); (* bt reg1, param2 *)
|
|
|
- setcc(setc, reg1);
|
|
|
- andrc(reg1, 1)
|
|
|
-
|
|
|
- |IL.opRSET:
|
|
|
- PushAll(2);
|
|
|
- CallRTL(pic, IL._set);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opRSETR:
|
|
|
- PushAll(1);
|
|
|
- pushc(param2);
|
|
|
- CallRTL(pic, IL._set);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opRSETL:
|
|
|
- UnOp(reg1);
|
|
|
- REG.PushAll_1(R);
|
|
|
- pushc(param2);
|
|
|
- push(reg1);
|
|
|
- drop;
|
|
|
- CallRTL(pic, IL._set);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opRSET1:
|
|
|
- PushAll(1);
|
|
|
- CallRTL(pic, IL._set1);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opINCL, IL.opEXCL:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- cmprc(reg1, 32);
|
|
|
- OutByte2(73H, 03H); (* jnb L *)
|
|
|
- OutByte(0FH);
|
|
|
- IF opcode = IL.opINCL THEN
|
|
|
- OutByte(0ABH) (* bts dword[reg2], reg1 *)
|
|
|
- ELSE
|
|
|
- OutByte(0B3H) (* btr dword[reg2], reg1 *)
|
|
|
- END;
|
|
|
- OutByte(reg2 + 8 * reg1);
|
|
|
- (* L: *)
|
|
|
- drop;
|
|
|
- drop
|
|
|
+ |IL.opEQIP, IL.opNEIP:
|
|
|
+ IF pic THEN
|
|
|
+ reg2 := GetAnyReg();
|
|
|
+ Pic(reg2, BIN.PICIMP, param1);
|
|
|
+ OutByte2(03BH, reg1 * 8 + reg2); (* cmp reg1, dword [reg2] *)
|
|
|
+ drop
|
|
|
+ ELSE
|
|
|
+ OutByte2(3BH, 05H + reg1 * 8); (* cmp reg1, dword[L] *)
|
|
|
+ Reloc(BIN.RIMP, param1)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opINCLC:
|
|
|
- UnOp(reg1);
|
|
|
- OutByte3(0FH, 0BAH, 28H + reg1); OutByte(param2); (* bts dword[reg1], param2 *)
|
|
|
- drop
|
|
|
+ END;
|
|
|
+ drop;
|
|
|
+ reg1 := GetAnyReg();
|
|
|
|
|
|
- |IL.opEXCLC:
|
|
|
- UnOp(reg1);
|
|
|
- OutByte3(0FH, 0BAH, 30H + reg1); OutByte(param2); (* btr dword[reg1], param2 *)
|
|
|
- drop
|
|
|
+ CASE opcode OF
|
|
|
+ |IL.opEQP, IL.opEQIP: setcc(sete, reg1)
|
|
|
+ |IL.opNEP, IL.opNEIP: setcc(setne, reg1)
|
|
|
+ END;
|
|
|
|
|
|
- |IL.opDIV:
|
|
|
- PushAll(2);
|
|
|
- CallRTL(pic, IL._divmod);
|
|
|
- GetRegA
|
|
|
+ andrc(reg1, 1)
|
|
|
|
|
|
- |IL.opDIVR:
|
|
|
- n := UTILS.Log2(param2);
|
|
|
- IF n > 0 THEN
|
|
|
+ |IL.opPUSHT:
|
|
|
UnOp(reg1);
|
|
|
- IF n # 1 THEN
|
|
|
- OutByte3(0C1H, 0F8H + reg1, n) (* sar reg1, n *)
|
|
|
- ELSE
|
|
|
- OutByte2(0D1H, 0F8H + reg1) (* sar reg1, 1 *)
|
|
|
- END
|
|
|
- ELSIF n < 0 THEN
|
|
|
+ movrm(GetAnyReg(), reg1, -4)
|
|
|
+
|
|
|
+ |IL.opISREC:
|
|
|
+ PushAll(2);
|
|
|
+ IF ~(target IN {TARGETS.KolibriOSDrv, TARGETS.KolibriOSKer}) THEN
|
|
|
+ param2 := param2*tcount
|
|
|
+ END;
|
|
|
+ pushc(param2);
|
|
|
+ CallRTL(pic, IL._isrec);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opIS:
|
|
|
PushAll(1);
|
|
|
+ IF ~(target IN {TARGETS.KolibriOSDrv, TARGETS.KolibriOSKer}) THEN
|
|
|
+ param2 := param2*tcount
|
|
|
+ END;
|
|
|
pushc(param2);
|
|
|
- CallRTL(pic, IL._divmod);
|
|
|
+ CallRTL(pic, IL._is);
|
|
|
GetRegA
|
|
|
- END
|
|
|
|
|
|
- |IL.opDIVL:
|
|
|
- UnOp(reg1);
|
|
|
- REG.PushAll_1(R);
|
|
|
- pushc(param2);
|
|
|
- push(reg1);
|
|
|
- drop;
|
|
|
- CallRTL(pic, IL._divmod);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opMOD:
|
|
|
- PushAll(2);
|
|
|
- CallRTL(pic, IL._divmod);
|
|
|
- mov(eax, edx);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opMODR:
|
|
|
- n := UTILS.Log2(param2);
|
|
|
- IF n > 0 THEN
|
|
|
- UnOp(reg1);
|
|
|
- andrc(reg1, param2 - 1);
|
|
|
- ELSIF n < 0 THEN
|
|
|
+ |IL.opTYPEGR:
|
|
|
PushAll(1);
|
|
|
+ IF ~(target IN {TARGETS.KolibriOSDrv, TARGETS.KolibriOSKer}) THEN
|
|
|
+ param2 := param2*tcount
|
|
|
+ END;
|
|
|
pushc(param2);
|
|
|
- CallRTL(pic, IL._divmod);
|
|
|
- mov(eax, edx);
|
|
|
+ CallRTL(pic, IL._guardrec);
|
|
|
GetRegA
|
|
|
- ELSE
|
|
|
- UnOp(reg1);
|
|
|
- xor(reg1, reg1)
|
|
|
- END
|
|
|
|
|
|
- |IL.opMODL:
|
|
|
- UnOp(reg1);
|
|
|
- REG.PushAll_1(R);
|
|
|
- pushc(param2);
|
|
|
- push(reg1);
|
|
|
- drop;
|
|
|
- CallRTL(pic, IL._divmod);
|
|
|
- mov(eax, edx);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opERR:
|
|
|
- CallRTL(pic, IL._error)
|
|
|
-
|
|
|
- |IL.opABS:
|
|
|
- UnOp(reg1);
|
|
|
- test(reg1);
|
|
|
- OutByte2(07DH, 002H); (* jge L *)
|
|
|
- neg(reg1) (* neg reg1
|
|
|
- L: *)
|
|
|
-
|
|
|
- |IL.opCOPY:
|
|
|
- IF (0 < param2) & (param2 <= 64) THEN
|
|
|
- BinOp(reg1, reg2);
|
|
|
- reg3 := GetAnyReg();
|
|
|
- FOR n := 0 TO param2 - param2 MOD 4 - 1 BY 4 DO
|
|
|
- movrm(reg3, reg1, n);
|
|
|
- movmr(reg2, n, reg3)
|
|
|
+ |IL.opTYPEGP:
|
|
|
+ UnOp(reg1);
|
|
|
+ PushAll(0);
|
|
|
+ push(reg1);
|
|
|
+ IF ~(target IN {TARGETS.KolibriOSDrv, TARGETS.KolibriOSKer}) THEN
|
|
|
+ param2 := param2*tcount
|
|
|
END;
|
|
|
- n := param2 - param2 MOD 4;
|
|
|
- IF param2 MOD 4 >= 2 THEN
|
|
|
- movrm16(reg3, reg1, n);
|
|
|
- movmr16(reg2, n, reg3);
|
|
|
- INC(n, 2);
|
|
|
- DEC(param2, 2)
|
|
|
+ pushc(param2);
|
|
|
+ CallRTL(pic, IL._guard);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opTYPEGD:
|
|
|
+ UnOp(reg1);
|
|
|
+ PushAll(0);
|
|
|
+ pushm(reg1, -4);
|
|
|
+ IF ~(target IN {TARGETS.KolibriOSDrv, TARGETS.KolibriOSKer}) THEN
|
|
|
+ param2 := param2*tcount
|
|
|
END;
|
|
|
- IF param2 MOD 4 = 1 THEN
|
|
|
- movrm8(reg3, reg1, n);
|
|
|
- movmr8(reg2, n, reg3);
|
|
|
+ pushc(param2);
|
|
|
+ CallRTL(pic, IL._guardrec);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opCASET:
|
|
|
+ push(ecx);
|
|
|
+ push(ecx);
|
|
|
+ IF ~(target IN {TARGETS.KolibriOSDrv, TARGETS.KolibriOSKer}) THEN
|
|
|
+ param2 := param2*tcount
|
|
|
END;
|
|
|
- drop;
|
|
|
+ pushc(param2);
|
|
|
+ CallRTL(pic, IL._guardrec);
|
|
|
+ pop(ecx);
|
|
|
+ test(eax);
|
|
|
+ jcc(jne, param1)
|
|
|
+
|
|
|
+ |IL.opPACK:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ push(reg2);
|
|
|
+ OutByte3(0DBH, 004H, 024H); (* fild dword[esp] *)
|
|
|
+ OutByte2(0DDH, reg1); (* fld qword[reg1] *)
|
|
|
+ OutByte2(0D9H, 0FDH); (* fscale *)
|
|
|
+ OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *)
|
|
|
+ OutByte3(0DBH, 01CH, 024H); (* fistp dword[esp] *)
|
|
|
+ pop(reg2);
|
|
|
drop;
|
|
|
drop
|
|
|
- ELSE
|
|
|
- PushAll(2);
|
|
|
- pushc(param2);
|
|
|
- CallRTL(pic, IL._move)
|
|
|
- END
|
|
|
|
|
|
- |IL.opMOVE:
|
|
|
- PushAll(3);
|
|
|
- CallRTL(pic, IL._move)
|
|
|
+ |IL.opPACKC:
|
|
|
+ UnOp(reg1);
|
|
|
+ pushc(param2);
|
|
|
+ OutByte3(0DBH, 004H, 024H); (* fild dword[esp] *)
|
|
|
+ OutByte2(0DDH, reg1); (* fld qword[reg1] *)
|
|
|
+ OutByte2(0D9H, 0FDH); (* fscale *)
|
|
|
+ OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *)
|
|
|
+ OutByte3(0DBH, 01CH, 024H); (* fistp dword[esp] *)
|
|
|
+ pop(reg1);
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opCOPYA:
|
|
|
- PushAll(4);
|
|
|
- pushc(param2);
|
|
|
- CallRTL(pic, IL._arrcpy);
|
|
|
- GetRegA
|
|
|
+ |IL.opUNPK:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ OutByte2(0DDH, reg1); (* fld qword[reg1] *)
|
|
|
+ OutByte2(0D9H, 0F4H); (* fxtract *)
|
|
|
+ OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *)
|
|
|
+ OutByte2(0DBH, 018H + reg2); (* fistp dword[reg2] *)
|
|
|
+ drop;
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opCOPYS:
|
|
|
- PushAll(4);
|
|
|
- pushc(param2);
|
|
|
- CallRTL(pic, IL._strcpy)
|
|
|
+ |IL.opPUSHF:
|
|
|
+ ASSERT(fr >= 0);
|
|
|
+ DEC(fr);
|
|
|
+ subrc(esp, 8);
|
|
|
+ OutByte3(0DDH, 01CH, 024H) (* fstp qword[esp] *)
|
|
|
|
|
|
- |IL.opROT:
|
|
|
- PushAll(0);
|
|
|
- push(esp);
|
|
|
- pushc(param2);
|
|
|
- CallRTL(pic, IL._rot)
|
|
|
-
|
|
|
- |IL.opNEW:
|
|
|
- PushAll(1);
|
|
|
- CASE TARGETS.OS OF
|
|
|
- |TARGETS.osWIN32:
|
|
|
- n := param2 + 4;
|
|
|
- ASSERT(UTILS.Align(n, 4))
|
|
|
- |TARGETS.osLINUX32:
|
|
|
- n := param2 + 16;
|
|
|
- ASSERT(UTILS.Align(n, 16))
|
|
|
- |TARGETS.osKOS:
|
|
|
- n := param2 + 8;
|
|
|
- ASSERT(UTILS.Align(n, 32))
|
|
|
- END;
|
|
|
- pushc(n);
|
|
|
- pushc(param1);
|
|
|
- CallRTL(pic, IL._new)
|
|
|
-
|
|
|
- |IL.opDISP:
|
|
|
- PushAll(1);
|
|
|
- CallRTL(pic, IL._dispose)
|
|
|
-
|
|
|
- |IL.opEQS .. IL.opGES:
|
|
|
- PushAll(4);
|
|
|
- pushc(opcode - IL.opEQS);
|
|
|
- CallRTL(pic, IL._strcmp);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opEQSW .. IL.opGESW:
|
|
|
- PushAll(4);
|
|
|
- pushc(opcode - IL.opEQSW);
|
|
|
- CallRTL(pic, IL._strcmpw);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opEQP, IL.opNEP, IL.opEQIP, IL.opNEIP:
|
|
|
- UnOp(reg1);
|
|
|
- CASE opcode OF
|
|
|
- |IL.opEQP, IL.opNEP:
|
|
|
- IF pic THEN
|
|
|
- reg2 := GetAnyReg();
|
|
|
- Pic(reg2, BIN.PICCODE, param1);
|
|
|
- cmprr(reg1, reg2);
|
|
|
- drop
|
|
|
- ELSE
|
|
|
- OutByte2(081H, 0F8H + reg1); (* cmp reg1, L *)
|
|
|
- Reloc(BIN.RCODE, param1)
|
|
|
- END
|
|
|
+ |IL.opLOADF:
|
|
|
+ INC(fr);
|
|
|
+ IF fr > MAX_FR THEN
|
|
|
+ ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
|
|
+ END;
|
|
|
+ UnOp(reg1);
|
|
|
+ OutByte2(0DDH, reg1); (* fld qword[reg1] *)
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opEQIP, IL.opNEIP:
|
|
|
- IF pic THEN
|
|
|
- reg2 := GetAnyReg();
|
|
|
- Pic(reg2, BIN.PICIMP, param1);
|
|
|
- OutByte2(03BH, reg1 * 8 + reg2); (* cmp reg1, dword [reg2] *)
|
|
|
- drop
|
|
|
+ |IL.opCONSTF:
|
|
|
+ INC(fr);
|
|
|
+ IF fr > MAX_FR THEN
|
|
|
+ ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
|
|
+ END;
|
|
|
+ float := cmd.float;
|
|
|
+ IF float = 0.0 THEN
|
|
|
+ OutByte2(0D9H, 0EEH) (* fldz *)
|
|
|
+ ELSIF float = 1.0 THEN
|
|
|
+ OutByte2(0D9H, 0E8H) (* fld1 *)
|
|
|
+ ELSIF float = -1.0 THEN
|
|
|
+ OutByte2(0D9H, 0E8H); (* fld1 *)
|
|
|
+ OutByte2(0D9H, 0E0H) (* fchs *)
|
|
|
ELSE
|
|
|
- OutByte2(3BH, 05H + reg1 * 8); (* cmp reg1, dword[L] *)
|
|
|
- Reloc(BIN.RIMP, param1)
|
|
|
+ LoadFltConst(float)
|
|
|
END
|
|
|
|
|
|
- END;
|
|
|
- drop;
|
|
|
- reg1 := GetAnyReg();
|
|
|
-
|
|
|
- CASE opcode OF
|
|
|
- |IL.opEQP, IL.opEQIP: setcc(sete, reg1)
|
|
|
- |IL.opNEP, IL.opNEIP: setcc(setne, reg1)
|
|
|
- END;
|
|
|
-
|
|
|
- andrc(reg1, 1)
|
|
|
-
|
|
|
- |IL.opPUSHT:
|
|
|
- UnOp(reg1);
|
|
|
- movrm(GetAnyReg(), reg1, -4)
|
|
|
+ |IL.opSAVEF, IL.opSAVEFI:
|
|
|
+ ASSERT(fr >= 0);
|
|
|
+ DEC(fr);
|
|
|
+ UnOp(reg1);
|
|
|
+ OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *)
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opISREC:
|
|
|
- PushAll(2);
|
|
|
- IF ~(target IN {TARGETS.KolibriOSDrv, TARGETS.KolibriOSKer}) THEN
|
|
|
- param2 := param2*tcount
|
|
|
- END;
|
|
|
- pushc(param2);
|
|
|
- CallRTL(pic, IL._isrec);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opIS:
|
|
|
- PushAll(1);
|
|
|
- IF ~(target IN {TARGETS.KolibriOSDrv, TARGETS.KolibriOSKer}) THEN
|
|
|
- param2 := param2*tcount
|
|
|
- END;
|
|
|
- pushc(param2);
|
|
|
- CallRTL(pic, IL._is);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opTYPEGR:
|
|
|
- PushAll(1);
|
|
|
- IF ~(target IN {TARGETS.KolibriOSDrv, TARGETS.KolibriOSKer}) THEN
|
|
|
- param2 := param2*tcount
|
|
|
- END;
|
|
|
- pushc(param2);
|
|
|
- CallRTL(pic, IL._guardrec);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opTYPEGP:
|
|
|
- UnOp(reg1);
|
|
|
- PushAll(0);
|
|
|
- push(reg1);
|
|
|
- IF ~(target IN {TARGETS.KolibriOSDrv, TARGETS.KolibriOSKer}) THEN
|
|
|
- param2 := param2*tcount
|
|
|
- END;
|
|
|
- pushc(param2);
|
|
|
- CallRTL(pic, IL._guard);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opTYPEGD:
|
|
|
- UnOp(reg1);
|
|
|
- PushAll(0);
|
|
|
- pushm(reg1, -4);
|
|
|
- IF ~(target IN {TARGETS.KolibriOSDrv, TARGETS.KolibriOSKer}) THEN
|
|
|
- param2 := param2*tcount
|
|
|
- END;
|
|
|
- pushc(param2);
|
|
|
- CallRTL(pic, IL._guardrec);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opCASET:
|
|
|
- push(ecx);
|
|
|
- push(ecx);
|
|
|
- IF ~(target IN {TARGETS.KolibriOSDrv, TARGETS.KolibriOSKer}) THEN
|
|
|
- param2 := param2*tcount
|
|
|
- END;
|
|
|
- pushc(param2);
|
|
|
- CallRTL(pic, IL._guardrec);
|
|
|
- pop(ecx);
|
|
|
- test(eax);
|
|
|
- jcc(jne, param1)
|
|
|
-
|
|
|
- |IL.opPACK:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- push(reg2);
|
|
|
- OutByte3(0DBH, 004H, 024H); (* fild dword[esp] *)
|
|
|
- OutByte2(0DDH, reg1); (* fld qword[reg1] *)
|
|
|
- OutByte2(0D9H, 0FDH); (* fscale *)
|
|
|
- OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *)
|
|
|
- OutByte3(0DBH, 01CH, 024H); (* fistp dword[esp] *)
|
|
|
- pop(reg2);
|
|
|
- drop;
|
|
|
- drop
|
|
|
+ |IL.opADDF:
|
|
|
+ ASSERT(fr >= 1);
|
|
|
+ DEC(fr);
|
|
|
+ OutByte2(0DEH, 0C1H) (* faddp st1, st *)
|
|
|
+
|
|
|
+ |IL.opSUBF:
|
|
|
+ ASSERT(fr >= 1);
|
|
|
+ DEC(fr);
|
|
|
+ OutByte2(0DEH, 0E9H) (* fsubp st1, st *)
|
|
|
+
|
|
|
+ |IL.opSUBFI:
|
|
|
+ ASSERT(fr >= 1);
|
|
|
+ DEC(fr);
|
|
|
+ OutByte2(0DEH, 0E1H) (* fsubrp st1, st *)
|
|
|
+
|
|
|
+ |IL.opMULF:
|
|
|
+ ASSERT(fr >= 1);
|
|
|
+ DEC(fr);
|
|
|
+ OutByte2(0DEH, 0C9H) (* fmulp st1, st *)
|
|
|
+
|
|
|
+ |IL.opDIVF:
|
|
|
+ ASSERT(fr >= 1);
|
|
|
+ DEC(fr);
|
|
|
+ OutByte2(0DEH, 0F9H) (* fdivp st1, st *)
|
|
|
+
|
|
|
+ |IL.opDIVFI:
|
|
|
+ ASSERT(fr >= 1);
|
|
|
+ DEC(fr);
|
|
|
+ OutByte2(0DEH, 0F1H) (* fdivrp st1, st *)
|
|
|
+
|
|
|
+ |IL.opUMINF:
|
|
|
+ ASSERT(fr >= 0);
|
|
|
+ OutByte2(0D9H, 0E0H) (* fchs *)
|
|
|
+
|
|
|
+ |IL.opFABS:
|
|
|
+ ASSERT(fr >= 0);
|
|
|
+ OutByte2(0D9H, 0E1H) (* fabs *)
|
|
|
+
|
|
|
+ |IL.opFLT:
|
|
|
+ INC(fr);
|
|
|
+ IF fr > MAX_FR THEN
|
|
|
+ ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
|
|
+ END;
|
|
|
+ UnOp(reg1);
|
|
|
+ push(reg1);
|
|
|
+ OutByte3(0DBH, 004H, 024H); (* fild dword[esp] *)
|
|
|
+ pop(reg1);
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opPACKC:
|
|
|
- UnOp(reg1);
|
|
|
- pushc(param2);
|
|
|
- OutByte3(0DBH, 004H, 024H); (* fild dword[esp] *)
|
|
|
- OutByte2(0DDH, reg1); (* fld qword[reg1] *)
|
|
|
- OutByte2(0D9H, 0FDH); (* fscale *)
|
|
|
- OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *)
|
|
|
- OutByte3(0DBH, 01CH, 024H); (* fistp dword[esp] *)
|
|
|
- pop(reg1);
|
|
|
- drop
|
|
|
+ |IL.opFLOOR:
|
|
|
+ ASSERT(fr >= 0);
|
|
|
+ DEC(fr);
|
|
|
+ subrc(esp, 8);
|
|
|
+ OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 004H); (* fstcw word[esp+4] *)
|
|
|
+ OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 006H); (* fstcw word[esp+6] *)
|
|
|
+ OutByte2(066H, 081H); OutByte3(064H, 024H, 004H); OutWord(0F3FFH); (* and word[esp+4], 1111001111111111b *)
|
|
|
+ OutByte2(066H, 081H); OutByte3(04CH, 024H, 004H); OutWord(00400H); (* or word[esp+4], 0000010000000000b *)
|
|
|
+ OutByte2(0D9H, 06CH); OutByte2(024H, 004H); (* fldcw word[esp+4] *)
|
|
|
+ OutByte2(0D9H, 0FCH); (* frndint *)
|
|
|
+ OutByte3(0DBH, 01CH, 024H); (* fistp dword[esp] *)
|
|
|
+ pop(GetAnyReg());
|
|
|
+ OutByte2(0D9H, 06CH); OutByte2(024H, 002H); (* fldcw word[esp+2] *)
|
|
|
+ addrc(esp, 4)
|
|
|
+
|
|
|
+ |IL.opEQF:
|
|
|
+ ASSERT(fr >= 1);
|
|
|
+ DEC(fr, 2);
|
|
|
+ fcmp;
|
|
|
+ OutByte2(07AH, 003H); (* jp L *)
|
|
|
+ setcc(sete, al)
|
|
|
+ (* L: *)
|
|
|
+
|
|
|
+ |IL.opNEF:
|
|
|
+ ASSERT(fr >= 1);
|
|
|
+ DEC(fr, 2);
|
|
|
+ fcmp;
|
|
|
+ OutByte2(07AH, 003H); (* jp L *)
|
|
|
+ setcc(setne, al)
|
|
|
+ (* L: *)
|
|
|
+
|
|
|
+ |IL.opLTF:
|
|
|
+ ASSERT(fr >= 1);
|
|
|
+ DEC(fr, 2);
|
|
|
+ fcmp;
|
|
|
+ OutByte2(07AH, 00EH); (* jp L *)
|
|
|
+ setcc(setc, al);
|
|
|
+ setcc(sete, ah);
|
|
|
+ test(eax);
|
|
|
+ setcc(sete, al);
|
|
|
+ andrc(eax, 1)
|
|
|
+ (* L: *)
|
|
|
+
|
|
|
+ |IL.opGTF:
|
|
|
+ ASSERT(fr >= 1);
|
|
|
+ DEC(fr, 2);
|
|
|
+ fcmp;
|
|
|
+ OutByte2(07AH, 00FH); (* jp L *)
|
|
|
+ setcc(setc, al);
|
|
|
+ setcc(sete, ah);
|
|
|
+ cmprc(eax, 1);
|
|
|
+ setcc(sete, al);
|
|
|
+ andrc(eax, 1)
|
|
|
+ (* L: *)
|
|
|
+
|
|
|
+ |IL.opLEF:
|
|
|
+ ASSERT(fr >= 1);
|
|
|
+ DEC(fr, 2);
|
|
|
+ fcmp;
|
|
|
+ OutByte2(07AH, 003H); (* jp L *)
|
|
|
+ setcc(setnc, al)
|
|
|
+ (* L: *)
|
|
|
+
|
|
|
+ |IL.opGEF:
|
|
|
+ ASSERT(fr >= 1);
|
|
|
+ DEC(fr, 2);
|
|
|
+ fcmp;
|
|
|
+ OutByte2(07AH, 010H); (* jp L *)
|
|
|
+ setcc(setc, al);
|
|
|
+ setcc(sete, ah);
|
|
|
+ OutByte2(000H, 0E0H); (* add al, ah *)
|
|
|
+ OutByte2(03CH, 001H); (* cmp al, 1 *)
|
|
|
+ setcc(sete, al);
|
|
|
+ andrc(eax, 1)
|
|
|
+ (* L: *)
|
|
|
+
|
|
|
+ |IL.opINF:
|
|
|
+ INC(fr);
|
|
|
+ IF fr > MAX_FR THEN
|
|
|
+ ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
|
|
+ END;
|
|
|
+ LoadFltConst(UTILS.inf)
|
|
|
|
|
|
- |IL.opUNPK:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- OutByte2(0DDH, reg1); (* fld qword[reg1] *)
|
|
|
- OutByte2(0D9H, 0F4H); (* fxtract *)
|
|
|
- OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *)
|
|
|
- OutByte2(0DBH, 018H + reg2); (* fistp dword[reg2] *)
|
|
|
- drop;
|
|
|
- drop
|
|
|
|
|
|
- |IL.opPUSHF:
|
|
|
- ASSERT(fr >= 0);
|
|
|
- DEC(fr);
|
|
|
- subrc(esp, 8);
|
|
|
- OutByte3(0DDH, 01CH, 024H) (* fstp qword[esp] *)
|
|
|
+ |IL.opLADR_UNPK:
|
|
|
+ n := param2 * 4;
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ OutByte2(8DH, 45H + reg1 * 8 + long(n)); (* lea reg1, dword[ebp + n] *)
|
|
|
+ OutIntByte(n);
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ OutByte2(0DDH, reg1); (* fld qword[reg1] *)
|
|
|
+ OutByte2(0D9H, 0F4H); (* fxtract *)
|
|
|
+ OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *)
|
|
|
+ OutByte2(0DBH, 018H + reg2); (* fistp dword[reg2] *)
|
|
|
+ drop;
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opLOADF:
|
|
|
- INC(fr);
|
|
|
- IF fr > MAX_FR THEN
|
|
|
- ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
|
|
- END;
|
|
|
- UnOp(reg1);
|
|
|
- OutByte2(0DDH, reg1); (* fld qword[reg1] *)
|
|
|
- drop
|
|
|
+ |IL.opSADR_PARAM:
|
|
|
+ IF pic THEN
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ Pic(reg1, BIN.PICDATA, stroffs + param2);
|
|
|
+ push(reg1);
|
|
|
+ drop
|
|
|
+ ELSE
|
|
|
+ OutByte(068H); (* push _data + stroffs + param2 *)
|
|
|
+ Reloc(BIN.RDATA, stroffs + param2)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opCONSTF:
|
|
|
- INC(fr);
|
|
|
- IF fr > MAX_FR THEN
|
|
|
- ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
|
|
- END;
|
|
|
- float := cmd.float;
|
|
|
- IF float = 0.0 THEN
|
|
|
- OutByte2(0D9H, 0EEH) (* fldz *)
|
|
|
- ELSIF float = 1.0 THEN
|
|
|
- OutByte2(0D9H, 0E8H) (* fld1 *)
|
|
|
- ELSIF float = -1.0 THEN
|
|
|
- OutByte2(0D9H, 0E8H); (* fld1 *)
|
|
|
- OutByte2(0D9H, 0E0H) (* fchs *)
|
|
|
- ELSE
|
|
|
- LoadFltConst(float)
|
|
|
- END
|
|
|
+ |IL.opVADR_PARAM, IL.opLLOAD32_PARAM:
|
|
|
+ pushm(ebp, param2 * 4)
|
|
|
|
|
|
- |IL.opSAVEF, IL.opSAVEFI:
|
|
|
- ASSERT(fr >= 0);
|
|
|
- DEC(fr);
|
|
|
- UnOp(reg1);
|
|
|
- OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *)
|
|
|
- drop
|
|
|
+ |IL.opCONST_PARAM:
|
|
|
+ pushc(param2)
|
|
|
|
|
|
- |IL.opADDF:
|
|
|
- ASSERT(fr >= 1);
|
|
|
- DEC(fr);
|
|
|
- OutByte2(0DEH, 0C1H) (* faddp st1, st *)
|
|
|
-
|
|
|
- |IL.opSUBF:
|
|
|
- ASSERT(fr >= 1);
|
|
|
- DEC(fr);
|
|
|
- OutByte2(0DEH, 0E9H) (* fsubp st1, st *)
|
|
|
-
|
|
|
- |IL.opSUBFI:
|
|
|
- ASSERT(fr >= 1);
|
|
|
- DEC(fr);
|
|
|
- OutByte2(0DEH, 0E1H) (* fsubrp st1, st *)
|
|
|
-
|
|
|
- |IL.opMULF:
|
|
|
- ASSERT(fr >= 1);
|
|
|
- DEC(fr);
|
|
|
- OutByte2(0DEH, 0C9H) (* fmulp st1, st *)
|
|
|
-
|
|
|
- |IL.opDIVF:
|
|
|
- ASSERT(fr >= 1);
|
|
|
- DEC(fr);
|
|
|
- OutByte2(0DEH, 0F9H) (* fdivp st1, st *)
|
|
|
-
|
|
|
- |IL.opDIVFI:
|
|
|
- ASSERT(fr >= 1);
|
|
|
- DEC(fr);
|
|
|
- OutByte2(0DEH, 0F1H) (* fdivrp st1, st *)
|
|
|
-
|
|
|
- |IL.opUMINF:
|
|
|
- ASSERT(fr >= 0);
|
|
|
- OutByte2(0D9H, 0E0H) (* fchs *)
|
|
|
-
|
|
|
- |IL.opFABS:
|
|
|
- ASSERT(fr >= 0);
|
|
|
- OutByte2(0D9H, 0E1H) (* fabs *)
|
|
|
-
|
|
|
- |IL.opFLT:
|
|
|
- INC(fr);
|
|
|
- IF fr > MAX_FR THEN
|
|
|
- ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
|
|
- END;
|
|
|
- UnOp(reg1);
|
|
|
- push(reg1);
|
|
|
- OutByte3(0DBH, 004H, 024H); (* fild dword[esp] *)
|
|
|
- pop(reg1);
|
|
|
- drop
|
|
|
+ |IL.opGLOAD32_PARAM:
|
|
|
+ IF pic THEN
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ Pic(reg1, BIN.PICBSS, param2);
|
|
|
+ pushm(reg1, 0);
|
|
|
+ drop
|
|
|
+ ELSE
|
|
|
+ OutByte2(0FFH, 035H); (* push dword[_bss + param2] *)
|
|
|
+ Reloc(BIN.RBSS, param2)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opFLOOR:
|
|
|
- ASSERT(fr >= 0);
|
|
|
- DEC(fr);
|
|
|
- subrc(esp, 8);
|
|
|
- OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 004H); (* fstcw word[esp+4] *)
|
|
|
- OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 006H); (* fstcw word[esp+6] *)
|
|
|
- OutByte2(066H, 081H); OutByte3(064H, 024H, 004H); OutWord(0F3FFH); (* and word[esp+4], 1111001111111111b *)
|
|
|
- OutByte2(066H, 081H); OutByte3(04CH, 024H, 004H); OutWord(00400H); (* or word[esp+4], 0000010000000000b *)
|
|
|
- OutByte2(0D9H, 06CH); OutByte2(024H, 004H); (* fldcw word[esp+4] *)
|
|
|
- OutByte2(0D9H, 0FCH); (* frndint *)
|
|
|
- OutByte3(0DBH, 01CH, 024H); (* fistp dword[esp] *)
|
|
|
- pop(GetAnyReg());
|
|
|
- OutByte2(0D9H, 06CH); OutByte2(024H, 002H); (* fldcw word[esp+2] *)
|
|
|
- addrc(esp, 4)
|
|
|
-
|
|
|
- |IL.opEQF:
|
|
|
- ASSERT(fr >= 1);
|
|
|
- DEC(fr, 2);
|
|
|
- fcmp;
|
|
|
- OutByte2(07AH, 003H); (* jp L *)
|
|
|
- setcc(sete, al)
|
|
|
- (* L: *)
|
|
|
-
|
|
|
- |IL.opNEF:
|
|
|
- ASSERT(fr >= 1);
|
|
|
- DEC(fr, 2);
|
|
|
- fcmp;
|
|
|
- OutByte2(07AH, 003H); (* jp L *)
|
|
|
- setcc(setne, al)
|
|
|
- (* L: *)
|
|
|
-
|
|
|
- |IL.opLTF:
|
|
|
- ASSERT(fr >= 1);
|
|
|
- DEC(fr, 2);
|
|
|
- fcmp;
|
|
|
- OutByte2(07AH, 00EH); (* jp L *)
|
|
|
- setcc(setc, al);
|
|
|
- setcc(sete, ah);
|
|
|
- test(eax);
|
|
|
- setcc(sete, al);
|
|
|
- andrc(eax, 1)
|
|
|
- (* L: *)
|
|
|
-
|
|
|
- |IL.opGTF:
|
|
|
- ASSERT(fr >= 1);
|
|
|
- DEC(fr, 2);
|
|
|
- fcmp;
|
|
|
- OutByte2(07AH, 00FH); (* jp L *)
|
|
|
- setcc(setc, al);
|
|
|
- setcc(sete, ah);
|
|
|
- cmprc(eax, 1);
|
|
|
- setcc(sete, al);
|
|
|
- andrc(eax, 1)
|
|
|
- (* L: *)
|
|
|
-
|
|
|
- |IL.opLEF:
|
|
|
- ASSERT(fr >= 1);
|
|
|
- DEC(fr, 2);
|
|
|
- fcmp;
|
|
|
- OutByte2(07AH, 003H); (* jp L *)
|
|
|
- setcc(setnc, al)
|
|
|
- (* L: *)
|
|
|
-
|
|
|
- |IL.opGEF:
|
|
|
- ASSERT(fr >= 1);
|
|
|
- DEC(fr, 2);
|
|
|
- fcmp;
|
|
|
- OutByte2(07AH, 010H); (* jp L *)
|
|
|
- setcc(setc, al);
|
|
|
- setcc(sete, ah);
|
|
|
- OutByte2(000H, 0E0H); (* add al, ah *)
|
|
|
- OutByte2(03CH, 001H); (* cmp al, 1 *)
|
|
|
- setcc(sete, al);
|
|
|
- andrc(eax, 1)
|
|
|
- (* L: *)
|
|
|
-
|
|
|
- |IL.opINF:
|
|
|
- INC(fr);
|
|
|
- IF fr > MAX_FR THEN
|
|
|
- ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
|
|
- END;
|
|
|
- LoadFltConst(UTILS.inf)
|
|
|
+ |IL.opLOAD32_PARAM:
|
|
|
+ UnOp(reg1);
|
|
|
+ pushm(reg1, 0);
|
|
|
+ drop
|
|
|
|
|
|
+ |IL.opGADR_SAVEC:
|
|
|
+ IF pic THEN
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ Pic(reg1, BIN.PICBSS, param1);
|
|
|
+ OutByte2(0C7H, reg1); (* mov dword[reg1], param2 *)
|
|
|
+ OutInt(param2);
|
|
|
+ drop
|
|
|
+ ELSE
|
|
|
+ OutByte2(0C7H, 05H); (* mov dword[_bss + param1], param2 *)
|
|
|
+ Reloc(BIN.RBSS, param1);
|
|
|
+ OutInt(param2)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opLADR_UNPK:
|
|
|
- n := param2 * 4;
|
|
|
- reg1 := GetAnyReg();
|
|
|
- OutByte2(8DH, 45H + reg1 * 8 + long(n)); (* lea reg1, dword[ebp + n] *)
|
|
|
- OutIntByte(n);
|
|
|
- BinOp(reg1, reg2);
|
|
|
- OutByte2(0DDH, reg1); (* fld qword[reg1] *)
|
|
|
- OutByte2(0D9H, 0F4H); (* fxtract *)
|
|
|
- OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *)
|
|
|
- OutByte2(0DBH, 018H + reg2); (* fistp dword[reg2] *)
|
|
|
- drop;
|
|
|
- drop
|
|
|
+ |IL.opLADR_SAVEC:
|
|
|
+ n := param1 * 4;
|
|
|
+ OutByte2(0C7H, 45H + long(n)); (* mov dword[ebp + n], param2 *)
|
|
|
+ OutIntByte(n);
|
|
|
+ OutInt(param2)
|
|
|
|
|
|
- |IL.opSADR_PARAM:
|
|
|
- IF pic THEN
|
|
|
- reg1 := GetAnyReg();
|
|
|
- Pic(reg1, BIN.PICDATA, stroffs + param2);
|
|
|
- push(reg1);
|
|
|
+ |IL.opLADR_SAVE:
|
|
|
+ UnOp(reg1);
|
|
|
+ movmr(ebp, param2 * 4, reg1);
|
|
|
drop
|
|
|
- ELSE
|
|
|
- OutByte(068H); (* push _data + stroffs + param2 *)
|
|
|
- Reloc(BIN.RDATA, stroffs + param2)
|
|
|
- END
|
|
|
|
|
|
- |IL.opVADR_PARAM, IL.opLLOAD32_PARAM:
|
|
|
- pushm(ebp, param2 * 4)
|
|
|
+ |IL.opLADR_INCC:
|
|
|
+ n := param1 * 4;
|
|
|
+ IF ABS(param2) = 1 THEN
|
|
|
+ OutByte2(0FFH, 45H + 8 * ORD(param2 = -1) + long(n)); (* inc/dec dword[ebp + n] *)
|
|
|
+ OutIntByte(n)
|
|
|
+ ELSE
|
|
|
+ OutByte2(81H + short(param2), 45H + long(n)); (* add dword[ebp + n], param2 *)
|
|
|
+ OutIntByte(n);
|
|
|
+ OutIntByte(param2)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opCONST_PARAM:
|
|
|
- pushc(param2)
|
|
|
+ |IL.opLADR_INCCB, IL.opLADR_DECCB:
|
|
|
+ n := param1 * 4;
|
|
|
+ IF param2 = 1 THEN
|
|
|
+ OutByte2(0FEH, 45H + 8 * ORD(opcode = IL.opLADR_DECCB) + long(n)); (* inc/dec byte[ebp + n] *)
|
|
|
+ OutIntByte(n)
|
|
|
+ ELSE
|
|
|
+ OutByte2(80H, 45H + 28H * ORD(opcode = IL.opLADR_DECCB) + long(n)); (* add/sub byte[ebp + n], param2 *)
|
|
|
+ OutIntByte(n);
|
|
|
+ OutByte(param2 MOD 256)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opGLOAD32_PARAM:
|
|
|
- IF pic THEN
|
|
|
- reg1 := GetAnyReg();
|
|
|
- Pic(reg1, BIN.PICBSS, param2);
|
|
|
- pushm(reg1, 0);
|
|
|
+ |IL.opLADR_INC, IL.opLADR_DEC:
|
|
|
+ n := param2 * 4;
|
|
|
+ UnOp(reg1);
|
|
|
+ OutByte2(01H + 28H * ORD(opcode = IL.opLADR_DEC), 45H + long(n) + reg1 * 8); (* add/sub dword[ebp + n], reg1 *)
|
|
|
+ OutIntByte(n);
|
|
|
drop
|
|
|
- ELSE
|
|
|
- OutByte2(0FFH, 035H); (* push dword[_bss + param2] *)
|
|
|
- Reloc(BIN.RBSS, param2)
|
|
|
- END
|
|
|
-
|
|
|
- |IL.opLOAD32_PARAM:
|
|
|
- UnOp(reg1);
|
|
|
- pushm(reg1, 0);
|
|
|
- drop
|
|
|
|
|
|
- |IL.opGADR_SAVEC:
|
|
|
- IF pic THEN
|
|
|
- reg1 := GetAnyReg();
|
|
|
- Pic(reg1, BIN.PICBSS, param1);
|
|
|
- OutByte2(0C7H, reg1); (* mov dword[reg1], param2 *)
|
|
|
- OutInt(param2);
|
|
|
+ |IL.opLADR_INCB, IL.opLADR_DECB:
|
|
|
+ n := param2 * 4;
|
|
|
+ UnOp(reg1);
|
|
|
+ OutByte2(28H * ORD(opcode = IL.opLADR_DECB), 45H + long(n) + reg1 * 8); (* add/sub byte[ebp + n], reg1 *)
|
|
|
+ OutIntByte(n);
|
|
|
drop
|
|
|
- ELSE
|
|
|
- OutByte2(0C7H, 05H); (* mov dword[_bss + param1], param2 *)
|
|
|
- Reloc(BIN.RBSS, param1);
|
|
|
- OutInt(param2)
|
|
|
- END
|
|
|
|
|
|
- |IL.opLADR_SAVEC:
|
|
|
- n := param1 * 4;
|
|
|
- OutByte2(0C7H, 45H + long(n)); (* mov dword[ebp + n], param2 *)
|
|
|
- OutIntByte(n);
|
|
|
- OutInt(param2)
|
|
|
-
|
|
|
- |IL.opLADR_SAVE:
|
|
|
- UnOp(reg1);
|
|
|
- movmr(ebp, param2 * 4, reg1);
|
|
|
- drop
|
|
|
-
|
|
|
- |IL.opLADR_INCC:
|
|
|
- n := param1 * 4;
|
|
|
- IF ABS(param2) = 1 THEN
|
|
|
- OutByte2(0FFH, 45H + 8 * ORD(param2 = -1) + long(n)); (* inc/dec dword[ebp + n] *)
|
|
|
- OutIntByte(n)
|
|
|
- ELSE
|
|
|
- OutByte2(81H + short(param2), 45H + long(n)); (* add dword[ebp + n], param2 *)
|
|
|
+ |IL.opLADR_INCL, IL.opLADR_EXCL:
|
|
|
+ n := param2 * 4;
|
|
|
+ UnOp(reg1);
|
|
|
+ cmprc(reg1, 32);
|
|
|
+ label := NewLabel();
|
|
|
+ jcc(jnb, label);
|
|
|
+ OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), 45H + long(n) + reg1 * 8); (* bts(r) dword[ebp + n], reg1 *)
|
|
|
OutIntByte(n);
|
|
|
- OutIntByte(param2)
|
|
|
- END
|
|
|
+ SetLabel(label);
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opLADR_INCCB, IL.opLADR_DECCB:
|
|
|
- n := param1 * 4;
|
|
|
- IF param2 = 1 THEN
|
|
|
- OutByte2(0FEH, 45H + 8 * ORD(opcode = IL.opLADR_DECCB) + long(n)); (* inc/dec byte[ebp + n] *)
|
|
|
- OutIntByte(n)
|
|
|
- ELSE
|
|
|
- OutByte2(80H, 45H + 28H * ORD(opcode = IL.opLADR_DECCB) + long(n)); (* add/sub byte[ebp + n], param2 *)
|
|
|
+ |IL.opLADR_INCLC, IL.opLADR_EXCLC:
|
|
|
+ n := param1 * 4;
|
|
|
+ OutByte3(0FH, 0BAH, 6DH + long(n) + 8 * ORD(opcode = IL.opLADR_EXCLC)); (* bts(r) dword[ebp + n], param2 *)
|
|
|
OutIntByte(n);
|
|
|
- OutByte(param2 MOD 256)
|
|
|
- END
|
|
|
-
|
|
|
- |IL.opLADR_INC, IL.opLADR_DEC:
|
|
|
- n := param2 * 4;
|
|
|
- UnOp(reg1);
|
|
|
- OutByte2(01H + 28H * ORD(opcode = IL.opLADR_DEC), 45H + long(n) + reg1 * 8); (* add/sub dword[ebp + n], reg1 *)
|
|
|
- OutIntByte(n);
|
|
|
- drop
|
|
|
-
|
|
|
- |IL.opLADR_INCB, IL.opLADR_DECB:
|
|
|
- n := param2 * 4;
|
|
|
- UnOp(reg1);
|
|
|
- OutByte2(28H * ORD(opcode = IL.opLADR_DECB), 45H + long(n) + reg1 * 8); (* add/sub byte[ebp + n], reg1 *)
|
|
|
- OutIntByte(n);
|
|
|
- drop
|
|
|
-
|
|
|
- |IL.opLADR_INCL, IL.opLADR_EXCL:
|
|
|
- n := param2 * 4;
|
|
|
- UnOp(reg1);
|
|
|
- cmprc(reg1, 32);
|
|
|
- label := NewLabel();
|
|
|
- jcc(jnb, label);
|
|
|
- OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), 45H + long(n) + reg1 * 8); (* bts(r) dword[ebp + n], reg1 *)
|
|
|
- OutIntByte(n);
|
|
|
- SetLabel(label);
|
|
|
- drop
|
|
|
+ OutByte(param2)
|
|
|
|
|
|
- |IL.opLADR_INCLC, IL.opLADR_EXCLC:
|
|
|
- n := param1 * 4;
|
|
|
- OutByte3(0FH, 0BAH, 6DH + long(n) + 8 * ORD(opcode = IL.opLADR_EXCLC)); (* bts(r) dword[ebp + n], param2 *)
|
|
|
- OutIntByte(n);
|
|
|
- OutByte(param2)
|
|
|
+ |IL.opFNAME:
|
|
|
+ fname := cmd(IL.FNAMECMD).fname
|
|
|
|
|
|
- |IL.opFNAME:
|
|
|
- fname := cmd(IL.FNAMECMD).fname
|
|
|
+ END;
|
|
|
|
|
|
+ cmd := cmd.next(COMMAND)
|
|
|
END;
|
|
|
|
|
|
- cmd := cmd.next(COMMAND)
|
|
|
- END;
|
|
|
-
|
|
|
- ASSERT(R.pushed = 0);
|
|
|
- ASSERT(R.top = -1);
|
|
|
- ASSERT(fr = -1)
|
|
|
-END translate;
|
|
|
+ ASSERT(R.pushed = 0);
|
|
|
+ ASSERT(R.top = -1);
|
|
|
+ ASSERT(fr = -1)
|
|
|
+ END translate;
|
|
|
|
|
|
|
|
|
PROCEDURE prolog (pic: BOOLEAN; target, stack, dllret: INTEGER): INTEGER;
|
|
|
-VAR
|
|
|
- reg1, entry, L, dcount: INTEGER;
|
|
|
-
|
|
|
-BEGIN
|
|
|
- entry := NewLabel();
|
|
|
- SetLabel(entry);
|
|
|
- dcount := CHL.Length(IL.codes.data);
|
|
|
-
|
|
|
- push(ebp);
|
|
|
- mov(ebp, esp);
|
|
|
- SetLabel(NewLabel());
|
|
|
- mainFltConstLabel := CodeList.last(LABEL);
|
|
|
- FltConstLabel := mainFltConstLabel;
|
|
|
- mainLocVarSize := 0;
|
|
|
- LocVarSize := 0;
|
|
|
-
|
|
|
- IF target IN {TARGETS.Win32DLL, TARGETS.KolibriOSDrv} THEN
|
|
|
- IF target = TARGETS.Win32DLL THEN
|
|
|
- pushm(ebp, 16)
|
|
|
+ VAR
|
|
|
+ reg1, entry, L, dcount: INTEGER;
|
|
|
+
|
|
|
+ BEGIN
|
|
|
+ entry := NewLabel();
|
|
|
+ SetLabel(entry);
|
|
|
+ dcount := CHL.Length(IL.codes.data);
|
|
|
+
|
|
|
+ push(ebp);
|
|
|
+ mov(ebp, esp);
|
|
|
+ SetLabel(NewLabel());
|
|
|
+ mainFltConstLabel := CodeList.last(LABEL);
|
|
|
+ FltConstLabel := mainFltConstLabel;
|
|
|
+ mainLocVarSize := 0;
|
|
|
+ LocVarSize := 0;
|
|
|
+
|
|
|
+ IF target IN {TARGETS.Win32DLL, TARGETS.KolibriOSDrv} THEN
|
|
|
+ IF target = TARGETS.Win32DLL THEN
|
|
|
+ pushm(ebp, 16)
|
|
|
+ ELSE
|
|
|
+ pushc(0)
|
|
|
+ END;
|
|
|
+ pushm(ebp, 12);
|
|
|
+ pushm(ebp, 8);
|
|
|
+ CallRTL(pic, IL._dllentry);
|
|
|
+ test(eax);
|
|
|
+ jcc(je, dllret);
|
|
|
+ pushc(0)
|
|
|
+ ELSIF target = TARGETS.KolibriOSDLL THEN
|
|
|
+ OutByte(68H); (* push IMPORT *)
|
|
|
+ Reloc(BIN.IMPTAB, 0)
|
|
|
+ ELSIF target = TARGETS.KolibriOS THEN
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ Pic(reg1, BIN.IMPTAB, 0);
|
|
|
+ push(reg1); (* push IMPORT *)
|
|
|
+ drop
|
|
|
+ ELSIF target = TARGETS.Linux32 THEN
|
|
|
+ mov(eax, ebp);
|
|
|
+ addrc(eax, 4);
|
|
|
+ push(eax)
|
|
|
ELSE
|
|
|
pushc(0)
|
|
|
END;
|
|
|
- pushm(ebp, 12);
|
|
|
- pushm(ebp, 8);
|
|
|
- CallRTL(pic, IL._dllentry);
|
|
|
- test(eax);
|
|
|
- jcc(je, dllret);
|
|
|
- pushc(0)
|
|
|
- ELSIF target = TARGETS.KolibriOSDLL THEN
|
|
|
- OutByte(68H); (* push IMPORT *)
|
|
|
- Reloc(BIN.IMPTAB, 0)
|
|
|
- ELSIF target = TARGETS.KolibriOS THEN
|
|
|
- reg1 := GetAnyReg();
|
|
|
- Pic(reg1, BIN.IMPTAB, 0);
|
|
|
- push(reg1); (* push IMPORT *)
|
|
|
- drop
|
|
|
- ELSIF target = TARGETS.Linux32 THEN
|
|
|
- mov(eax, ebp);
|
|
|
- addrc(eax, 4);
|
|
|
- push(eax)
|
|
|
- ELSE
|
|
|
- pushc(0)
|
|
|
- END;
|
|
|
|
|
|
- IF pic THEN
|
|
|
- reg1 := GetAnyReg();
|
|
|
- Pic(reg1, BIN.PICCODE, entry);
|
|
|
- push(reg1); (* push CODE *)
|
|
|
- Pic(reg1, BIN.PICDATA, 0);
|
|
|
- push(reg1); (* push _data *)
|
|
|
- pushc(tcount);
|
|
|
- Pic(reg1, BIN.PICDATA, tcount * 4 + dcount);
|
|
|
- push(reg1); (* push _data + tcount * 4 + dcount *)
|
|
|
- drop
|
|
|
- ELSE
|
|
|
- OutByte(68H); (* push CODE *)
|
|
|
- Reloc(BIN.RCODE, entry);
|
|
|
- OutByte(68H); (* push _data *)
|
|
|
- Reloc(BIN.RDATA, 0);
|
|
|
- pushc(tcount);
|
|
|
- OutByte(68H); (* push _data + tcount * 4 + dcount *)
|
|
|
- Reloc(BIN.RDATA, tcount * 4 + dcount)
|
|
|
- END;
|
|
|
+ IF pic THEN
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ Pic(reg1, BIN.PICCODE, entry);
|
|
|
+ push(reg1); (* push CODE *)
|
|
|
+ Pic(reg1, BIN.PICDATA, 0);
|
|
|
+ push(reg1); (* push _data *)
|
|
|
+ pushc(tcount);
|
|
|
+ Pic(reg1, BIN.PICDATA, tcount * 4 + dcount);
|
|
|
+ push(reg1); (* push _data + tcount * 4 + dcount *)
|
|
|
+ drop
|
|
|
+ ELSE
|
|
|
+ OutByte(68H); (* push CODE *)
|
|
|
+ Reloc(BIN.RCODE, entry);
|
|
|
+ OutByte(68H); (* push _data *)
|
|
|
+ Reloc(BIN.RDATA, 0);
|
|
|
+ pushc(tcount);
|
|
|
+ OutByte(68H); (* push _data + tcount * 4 + dcount *)
|
|
|
+ Reloc(BIN.RDATA, tcount * 4 + dcount)
|
|
|
+ END;
|
|
|
|
|
|
- CallRTL(pic, IL._init);
|
|
|
+ CallRTL(pic, IL._init);
|
|
|
|
|
|
- IF target IN {TARGETS.Win32C, TARGETS.Win32GUI, TARGETS.Linux32} THEN
|
|
|
- L := NewLabel();
|
|
|
- pushc(0);
|
|
|
- push(esp);
|
|
|
- pushc(1024 * 1024 * stack);
|
|
|
- pushc(0);
|
|
|
- CallRTL(pic, IL._new);
|
|
|
- pop(eax);
|
|
|
- test(eax);
|
|
|
- jcc(je, L);
|
|
|
- addrc(eax, 1024 * 1024 * stack - 4);
|
|
|
- mov(esp, eax);
|
|
|
- SetLabel(L)
|
|
|
- END
|
|
|
+ IF target IN {TARGETS.Win32C, TARGETS.Win32GUI, TARGETS.Linux32} THEN
|
|
|
+ L := NewLabel();
|
|
|
+ pushc(0);
|
|
|
+ push(esp);
|
|
|
+ pushc(1024 * 1024 * stack);
|
|
|
+ pushc(0);
|
|
|
+ CallRTL(pic, IL._new);
|
|
|
+ pop(eax);
|
|
|
+ test(eax);
|
|
|
+ jcc(je, L);
|
|
|
+ addrc(eax, 1024 * 1024 * stack - 4);
|
|
|
+ mov(esp, eax);
|
|
|
+ SetLabel(L)
|
|
|
+ END
|
|
|
|
|
|
- RETURN entry
|
|
|
-END prolog;
|
|
|
+ RETURN entry
|
|
|
+ END prolog;
|
|
|
|
|
|
|
|
|
PROCEDURE epilog (pic: BOOLEAN; modname: ARRAY OF CHAR; target, stack, ver, dllinit, dllret, sofinit: INTEGER);
|
|
|
-VAR
|
|
|
- exp: IL.EXPORT_PROC;
|
|
|
- path, name, ext: PATHS.PATH;
|
|
|
+ VAR
|
|
|
+ exp: IL.EXPORT_PROC;
|
|
|
+ path, name, ext: PATHS.PATH;
|
|
|
|
|
|
- dcount, i: INTEGER;
|
|
|
+ dcount, i: INTEGER;
|
|
|
|
|
|
|
|
|
- PROCEDURE _import (imp: LISTS.LIST);
|
|
|
- VAR
|
|
|
- lib: IL.IMPORT_LIB;
|
|
|
- proc: IL.IMPORT_PROC;
|
|
|
+ PROCEDURE _import (imp: LISTS.LIST);
|
|
|
+ VAR
|
|
|
+ lib: IL.IMPORT_LIB;
|
|
|
+ proc: IL.IMPORT_PROC;
|
|
|
|
|
|
- BEGIN
|
|
|
+ BEGIN
|
|
|
|
|
|
- lib := imp.first(IL.IMPORT_LIB);
|
|
|
- WHILE lib # NIL DO
|
|
|
- BIN.Import(program, lib.name, 0);
|
|
|
- proc := lib.procs.first(IL.IMPORT_PROC);
|
|
|
- WHILE proc # NIL DO
|
|
|
- BIN.Import(program, proc.name, proc.label);
|
|
|
- proc := proc.next(IL.IMPORT_PROC)
|
|
|
- END;
|
|
|
- lib := lib.next(IL.IMPORT_LIB)
|
|
|
- END
|
|
|
+ lib := imp.first(IL.IMPORT_LIB);
|
|
|
+ WHILE lib # NIL DO
|
|
|
+ BIN.Import(program, lib.name, 0);
|
|
|
+ proc := lib.procs.first(IL.IMPORT_PROC);
|
|
|
+ WHILE proc # NIL DO
|
|
|
+ BIN.Import(program, proc.name, proc.label);
|
|
|
+ proc := proc.next(IL.IMPORT_PROC)
|
|
|
+ END;
|
|
|
+ lib := lib.next(IL.IMPORT_LIB)
|
|
|
+ END
|
|
|
|
|
|
- END _import;
|
|
|
-
|
|
|
-
|
|
|
-BEGIN
|
|
|
-
|
|
|
- IF target IN {TARGETS.Win32C, TARGETS.Win32GUI, TARGETS.KolibriOS, TARGETS.Linux32} THEN
|
|
|
- pushc(0);
|
|
|
- CallRTL(pic, IL._exit);
|
|
|
- ELSIF target = TARGETS.Win32DLL THEN
|
|
|
- SetLabel(dllret);
|
|
|
- movrc(eax, 1);
|
|
|
- OutByte(0C9H); (* leave *)
|
|
|
- OutByte3(0C2H, 0CH, 0) (* ret 12 *)
|
|
|
- ELSIF target = TARGETS.KolibriOSDrv THEN
|
|
|
- OutByte(0C9H); (* leave *)
|
|
|
- ret;
|
|
|
- SetLabel(dllret);
|
|
|
- movrc(eax, 0);
|
|
|
- OutByte(0C9H); (* leave *)
|
|
|
- ret
|
|
|
- ELSIF target = TARGETS.KolibriOSDLL THEN
|
|
|
- movrc(eax, 1);
|
|
|
- OutByte(0C9H); (* leave *)
|
|
|
- ret
|
|
|
- ELSIF target = TARGETS.KolibriOSKer THEN
|
|
|
- OutByte(0C9H); (* leave *)
|
|
|
- ret;
|
|
|
- ELSIF target = TARGETS.Linux32SO THEN
|
|
|
- OutByte(0C9H); (* leave *)
|
|
|
- ret;
|
|
|
- SetLabel(sofinit);
|
|
|
- CallRTL(pic, IL._sofinit);
|
|
|
- ret
|
|
|
- END;
|
|
|
+ END _import;
|
|
|
|
|
|
- fixup;
|
|
|
|
|
|
- dcount := CHL.Length(IL.codes.data);
|
|
|
+ BEGIN
|
|
|
|
|
|
- FOR i := 0 TO tcount - 1 DO
|
|
|
- BIN.PutData32LE(program, CHL.GetInt(IL.codes.types, i))
|
|
|
- END;
|
|
|
+ IF target IN {TARGETS.Win32C, TARGETS.Win32GUI, TARGETS.KolibriOS, TARGETS.Linux32} THEN
|
|
|
+ pushc(0);
|
|
|
+ CallRTL(pic, IL._exit);
|
|
|
+ ELSIF target = TARGETS.Win32DLL THEN
|
|
|
+ SetLabel(dllret);
|
|
|
+ movrc(eax, 1);
|
|
|
+ OutByte(0C9H); (* leave *)
|
|
|
+ OutByte3(0C2H, 0CH, 0) (* ret 12 *)
|
|
|
+ ELSIF target = TARGETS.KolibriOSDrv THEN
|
|
|
+ OutByte(0C9H); (* leave *)
|
|
|
+ ret;
|
|
|
+ SetLabel(dllret);
|
|
|
+ movrc(eax, 0);
|
|
|
+ OutByte(0C9H); (* leave *)
|
|
|
+ ret
|
|
|
+ ELSIF target = TARGETS.KolibriOSDLL THEN
|
|
|
+ movrc(eax, 1);
|
|
|
+ OutByte(0C9H); (* leave *)
|
|
|
+ ret
|
|
|
+ ELSIF target = TARGETS.KolibriOSKer THEN
|
|
|
+ OutByte(0C9H); (* leave *)
|
|
|
+ ret;
|
|
|
+ ELSIF target = TARGETS.Linux32SO THEN
|
|
|
+ OutByte(0C9H); (* leave *)
|
|
|
+ ret;
|
|
|
+ SetLabel(sofinit);
|
|
|
+ CallRTL(pic, IL._sofinit);
|
|
|
+ ret
|
|
|
+ END;
|
|
|
|
|
|
- FOR i := 0 TO dcount - 1 DO
|
|
|
- BIN.PutData(program, CHL.GetByte(IL.codes.data, i))
|
|
|
- END;
|
|
|
+ fixup;
|
|
|
|
|
|
- program.modname := CHL.Length(program.data);
|
|
|
+ dcount := CHL.Length(IL.codes.data);
|
|
|
|
|
|
- PATHS.split(modname, path, name, ext);
|
|
|
- BIN.PutDataStr(program, name);
|
|
|
- BIN.PutDataStr(program, ext);
|
|
|
- BIN.PutData(program, 0);
|
|
|
+ FOR i := 0 TO tcount - 1 DO
|
|
|
+ BIN.PutData32LE(program, CHL.GetInt(IL.codes.types, i))
|
|
|
+ END;
|
|
|
|
|
|
- IF target = TARGETS.KolibriOSDLL THEN
|
|
|
- BIN.Export(program, "lib_init", dllinit);
|
|
|
- END;
|
|
|
+ FOR i := 0 TO dcount - 1 DO
|
|
|
+ BIN.PutData(program, CHL.GetByte(IL.codes.data, i))
|
|
|
+ END;
|
|
|
|
|
|
- exp := IL.codes.export.first(IL.EXPORT_PROC);
|
|
|
- WHILE exp # NIL DO
|
|
|
- BIN.Export(program, exp.name, exp.label);
|
|
|
- exp := exp.next(IL.EXPORT_PROC)
|
|
|
- END;
|
|
|
+ program.modname := CHL.Length(program.data);
|
|
|
+
|
|
|
+ PATHS.split(modname, path, name, ext);
|
|
|
+ BIN.PutDataStr(program, name);
|
|
|
+ BIN.PutDataStr(program, ext);
|
|
|
+ BIN.PutData(program, 0);
|
|
|
+
|
|
|
+ IF target = TARGETS.KolibriOSDLL THEN
|
|
|
+ BIN.Export(program, "lib_init", dllinit);
|
|
|
+ END;
|
|
|
+
|
|
|
+ exp := IL.codes.export.first(IL.EXPORT_PROC);
|
|
|
+ WHILE exp # NIL DO
|
|
|
+ BIN.Export(program, exp.name, exp.label);
|
|
|
+ exp := exp.next(IL.EXPORT_PROC)
|
|
|
+ END;
|
|
|
|
|
|
- _import(IL.codes._import);
|
|
|
+ _import(IL.codes._import);
|
|
|
|
|
|
- IL.set_bss(MAX(IL.codes.bss, MAX(IL.codes.dmin - CHL.Length(IL.codes.data), 4)));
|
|
|
+ IL.set_bss(MAX(IL.codes.bss, MAX(IL.codes.dmin - CHL.Length(IL.codes.data), 4)));
|
|
|
|
|
|
- BIN.SetParams(program, IL.codes.bss, stack * (1024 * 1024), WCHR(ver DIV 65536), WCHR(ver MOD 65536))
|
|
|
-END epilog;
|
|
|
+ BIN.SetParams(program, IL.codes.bss, stack * (1024 * 1024), WCHR(ver DIV 65536), WCHR(ver MOD 65536))
|
|
|
+ END epilog;
|
|
|
|
|
|
|
|
|
PROCEDURE align16* (bit64: BOOLEAN);
|
|
|
-BEGIN
|
|
|
- IF TARGETS.WinLin THEN
|
|
|
- WHILE CHL.Length(IL.codes.data) MOD 16 # 0 DO
|
|
|
- CHL.PushByte(IL.codes.data, 0)
|
|
|
- END;
|
|
|
- WHILE CHL.Length(IL.codes.types) MOD (4 - 2*ORD(bit64)) # 0 DO
|
|
|
- CHL.PushInt(IL.codes.types, 0)
|
|
|
+ BEGIN
|
|
|
+ IF TARGETS.WinLin THEN
|
|
|
+ WHILE CHL.Length(IL.codes.data) MOD 16 # 0 DO
|
|
|
+ CHL.PushByte(IL.codes.data, 0)
|
|
|
+ END;
|
|
|
+ WHILE CHL.Length(IL.codes.types) MOD (4 - 2*ORD(bit64)) # 0 DO
|
|
|
+ CHL.PushInt(IL.codes.types, 0)
|
|
|
+ END
|
|
|
END
|
|
|
- END
|
|
|
-END align16;
|
|
|
+ END align16;
|
|
|
|
|
|
|
|
|
PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
|
|
|
-VAR
|
|
|
- dllret, dllinit, sofinit: INTEGER;
|
|
|
- opt: PROG.OPTIONS;
|
|
|
-
|
|
|
-BEGIN
|
|
|
- FR[0] := 0;
|
|
|
- align16(FALSE);
|
|
|
- tcount := CHL.Length(IL.codes.types);
|
|
|
-
|
|
|
- opt := options;
|
|
|
- CodeList := LISTS.create(NIL);
|
|
|
+ VAR
|
|
|
+ dllret, dllinit, sofinit: INTEGER;
|
|
|
+ opt: PROG.OPTIONS;
|
|
|
|
|
|
- program := BIN.create(IL.codes.lcount);
|
|
|
+ BEGIN
|
|
|
+ FR[0] := 0;
|
|
|
+ align16(FALSE);
|
|
|
+ tcount := CHL.Length(IL.codes.types);
|
|
|
|
|
|
- dllret := NewLabel();
|
|
|
- sofinit := NewLabel();
|
|
|
+ opt := options;
|
|
|
+ CodeList := LISTS.create(NIL);
|
|
|
|
|
|
- IF target = TARGETS.KolibriOSDLL THEN
|
|
|
- opt.pic := FALSE
|
|
|
- END;
|
|
|
+ program := BIN.create(IL.codes.lcount);
|
|
|
|
|
|
- IF target IN {TARGETS.KolibriOSKer, TARGETS.KolibriOSDrv} THEN
|
|
|
- opt.pic := TRUE
|
|
|
- END;
|
|
|
+ dllret := NewLabel();
|
|
|
+ sofinit := NewLabel();
|
|
|
|
|
|
- IF TARGETS.OS IN {TARGETS.osWIN32, TARGETS.osLINUX32} THEN
|
|
|
- opt.pic := TRUE
|
|
|
- END;
|
|
|
+ IF target = TARGETS.KolibriOSDLL THEN
|
|
|
+ opt.pic := FALSE
|
|
|
+ END;
|
|
|
|
|
|
- REG.Init(R, push, pop, mov, xchg, {eax, ecx, edx});
|
|
|
+ IF target IN {TARGETS.KolibriOSKer, TARGETS.KolibriOSDrv} THEN
|
|
|
+ opt.pic := TRUE
|
|
|
+ END;
|
|
|
|
|
|
- dllinit := prolog(opt.pic, target, opt.stack, dllret);
|
|
|
- translate(opt.pic, tcount * 4, target);
|
|
|
- epilog(opt.pic, outname, target, opt.stack, opt.version, dllinit, dllret, sofinit);
|
|
|
+ IF TARGETS.OS IN {TARGETS.osWIN32, TARGETS.osLINUX32} THEN
|
|
|
+ opt.pic := TRUE
|
|
|
+ END;
|
|
|
|
|
|
- BIN.fixup(program);
|
|
|
- IF TARGETS.OS = TARGETS.osWIN32 THEN
|
|
|
- PE32.write(program, outname, target = TARGETS.Win32C, target = TARGETS.Win32DLL, FALSE, opt.PE32FileAlignment)
|
|
|
- ELSIF target = TARGETS.KolibriOSDrv THEN
|
|
|
- PE32.write(program, outname, FALSE, TRUE, FALSE, 512)
|
|
|
- ELSIF target IN {TARGETS.KolibriOS, TARGETS.KolibriOSKer} THEN
|
|
|
- KOS.write(program, outname, target = TARGETS.KolibriOSKer)
|
|
|
- ELSIF target = TARGETS.KolibriOSDLL THEN
|
|
|
- MSCOFF.write(program, outname, opt.version)
|
|
|
- ELSIF TARGETS.OS = TARGETS.osLINUX32 THEN
|
|
|
- ELF.write(program, outname, sofinit, target = TARGETS.Linux32SO, FALSE)
|
|
|
- END
|
|
|
-END CodeGen;
|
|
|
+ REG.Init(R, push, pop, mov, xchg, {eax, ecx, edx});
|
|
|
+
|
|
|
+ dllinit := prolog(opt.pic, target, opt.stack, dllret);
|
|
|
+ translate(opt.pic, tcount * 4, target);
|
|
|
+ epilog(opt.pic, outname, target, opt.stack, opt.version, dllinit, dllret, sofinit);
|
|
|
+
|
|
|
+ BIN.fixup(program);
|
|
|
+ IF TARGETS.OS = TARGETS.osWIN32 THEN
|
|
|
+ PE32.write(program, outname, target = TARGETS.Win32C, target = TARGETS.Win32DLL, FALSE, opt.PE32FileAlignment)
|
|
|
+ ELSIF target = TARGETS.KolibriOSDrv THEN
|
|
|
+ PE32.write(program, outname, FALSE, TRUE, FALSE, 512)
|
|
|
+ ELSIF target IN {TARGETS.KolibriOS, TARGETS.KolibriOSKer} THEN
|
|
|
+ KOS.write(program, outname, target = TARGETS.KolibriOSKer)
|
|
|
+ ELSIF target = TARGETS.KolibriOSDLL THEN
|
|
|
+ MSCOFF.write(program, outname, opt.version)
|
|
|
+ ELSIF TARGETS.OS = TARGETS.osLINUX32 THEN
|
|
|
+ ELF.write(program, outname, sofinit, target = TARGETS.Linux32SO, FALSE)
|
|
|
+ END
|
|
|
+ END CodeGen;
|
|
|
|
|
|
|
|
|
PROCEDURE SetProgram* (prog: BIN.PROGRAM);
|
|
|
-BEGIN
|
|
|
- program := prog;
|
|
|
- CodeList := LISTS.create(NIL)
|
|
|
-END SetProgram;
|
|
|
+ BEGIN
|
|
|
+ program := prog;
|
|
|
+ CodeList := LISTS.create(NIL)
|
|
|
+ END SetProgram;
|
|
|
|
|
|
|
|
|
END X86.
|