mirror of
https://github.com/AntKrotov/oberon-07-compiler.git
synced 2026-10-05 09:45:47 +00:00
упрощение кода
This commit is contained in:
1 parent
d886a25860
commit
c05d034ee0
4 files changed
+366
-501
No files matched your search
+170
-241
@@ -94,6 +94,16 @@ PROCEDURE isByte (n: INTEGER): BOOLEAN;
|
||||
END isByte;
|
||||
|
||||
|
||||
PROCEDURE short (n: INTEGER): INTEGER;
|
||||
RETURN 2 * ORD(isByte(n))
|
||||
END short;
|
||||
|
||||
|
||||
PROCEDURE long (n: INTEGER): INTEGER;
|
||||
RETURN 40H * ORD(~isByte(n))
|
||||
END long;
|
||||
|
||||
|
||||
PROCEDURE OutIntByte (n: INTEGER);
|
||||
BEGIN
|
||||
IF isByte(n) THEN
|
||||
@@ -128,23 +138,31 @@ BEGIN
|
||||
END NewLabel;
|
||||
|
||||
|
||||
PROCEDURE Rex (reg1, reg2: INTEGER);
|
||||
BEGIN
|
||||
OutByte(48H + reg1 DIV 8 + 4 * (reg2 DIV 8))
|
||||
END Rex;
|
||||
|
||||
|
||||
PROCEDURE lea (reg, offset, section: INTEGER);
|
||||
BEGIN
|
||||
OutByte3(48H + 4 * (reg DIV 8), 8DH, 05H + 8 * (reg MOD 8)); //lea reg, [rip + offset]
|
||||
Rex(0, reg);
|
||||
OutByte2(8DH, 05H + 8 * (reg MOD 8)); // lea reg, [rip + offset]
|
||||
X86.Reloc(section, offset)
|
||||
END lea;
|
||||
|
||||
|
||||
PROCEDURE oprr (op: BYTE; reg1, reg2: INTEGER); // op reg1, reg2
|
||||
BEGIN
|
||||
OutByte3(48H + ORD(reg1 >= 8) + 4 * ORD(reg2 >= 8), op, 0C0H + 8 * (reg2 MOD 8) + reg1 MOD 8)
|
||||
Rex(reg1, reg2);
|
||||
OutByte2(op, 0C0H + 8 * (reg2 MOD 8) + reg1 MOD 8)
|
||||
END oprr;
|
||||
|
||||
|
||||
PROCEDURE oprr2 (op1, op2: BYTE; reg1, reg2: INTEGER); // op reg1, reg2
|
||||
BEGIN
|
||||
OutByte2(48H + ORD(reg1 >= 8) + 4 * ORD(reg2 >= 8), op1);
|
||||
OutByte2(op2, 0C0H + 8 * (reg2 MOD 8) + reg1 MOD 8)
|
||||
Rex(reg1, reg2);
|
||||
OutByte3(op1, op2, 0C0H + 8 * (reg2 MOD 8) + reg1 MOD 8)
|
||||
END oprr2;
|
||||
|
||||
|
||||
@@ -216,13 +234,15 @@ END push;
|
||||
|
||||
PROCEDURE decr (reg: INTEGER);
|
||||
BEGIN
|
||||
OutByte3(48H + reg DIV 8, 0FFH, 0C8H + reg MOD 8) // dec reg1
|
||||
Rex(reg, 0);
|
||||
OutByte2(0FFH, 0C8H + reg MOD 8) // dec reg1
|
||||
END decr;
|
||||
|
||||
|
||||
PROCEDURE incr (reg: INTEGER);
|
||||
BEGIN
|
||||
OutByte3(48H + reg DIV 8, 0FFH, 0C0H + reg MOD 8) // inc reg1
|
||||
Rex(reg, 0);
|
||||
OutByte2(0FFH, 0C0H + reg MOD 8) // inc reg1
|
||||
END incr;
|
||||
|
||||
|
||||
@@ -267,8 +287,7 @@ BEGIN
|
||||
REG.Store(R);
|
||||
label := CODE.codes.rtl[proc];
|
||||
IF label < 0 THEN
|
||||
label := -label;
|
||||
callimp(label)
|
||||
callimp(-label)
|
||||
ELSE
|
||||
X86.call(label)
|
||||
END;
|
||||
@@ -300,7 +319,8 @@ VAR
|
||||
i: INTEGER;
|
||||
|
||||
BEGIN
|
||||
OutByte2(48H + reg DIV 8, 0B8H + reg MOD 8); // movabs reg, n
|
||||
Rex(reg, 0);
|
||||
OutByte(0B8H + reg MOD 8); // movabs reg, n
|
||||
FOR i := 0 TO 7 DO
|
||||
OutByte(MACHINE.Byte(n, i))
|
||||
END
|
||||
@@ -312,7 +332,8 @@ BEGIN
|
||||
IF isLong(n) THEN
|
||||
movabs(reg, n)
|
||||
ELSE
|
||||
OutByte3(48H + reg DIV 8, 0C7H, 0C0H + reg MOD 8);
|
||||
Rex(reg, 0);
|
||||
OutByte2(0C7H, 0C0H + reg MOD 8);
|
||||
OutInt(n)
|
||||
END
|
||||
END movrc;
|
||||
@@ -336,47 +357,39 @@ BEGIN
|
||||
END oprlongc;
|
||||
|
||||
|
||||
PROCEDURE cmprc (reg, n: INTEGER); // cmp reg, n
|
||||
PROCEDURE oprc (op, reg, n: INTEGER; oprr: OPRR);
|
||||
BEGIN
|
||||
IF isLong(n) THEN
|
||||
oprlongc(reg, n, cmprr)
|
||||
oprlongc(reg, n, oprr)
|
||||
ELSE
|
||||
OutByte3(48H + reg DIV 8, 81H + ORD(isByte(n)) * 2, 0F8H + reg MOD 8);
|
||||
Rex(reg, 0);
|
||||
OutByte2(81H + short(n), op + reg MOD 8);
|
||||
OutIntByte(n)
|
||||
END
|
||||
END oprc;
|
||||
|
||||
|
||||
PROCEDURE cmprc (reg, n: INTEGER); // cmp reg, n
|
||||
BEGIN
|
||||
oprc(0F8H, reg, n, cmprr)
|
||||
END cmprc;
|
||||
|
||||
|
||||
PROCEDURE addrc (reg, n: INTEGER); // add reg, n
|
||||
BEGIN
|
||||
IF isLong(n) THEN
|
||||
oprlongc(reg, n, add)
|
||||
ELSE
|
||||
OutByte3(48H + reg DIV 8, 81H + ORD(isByte(n)) * 2, 0C0H + reg MOD 8);
|
||||
OutIntByte(n)
|
||||
END
|
||||
oprc(0C0H, reg, n, add)
|
||||
END addrc;
|
||||
|
||||
|
||||
PROCEDURE subrc (reg, n: INTEGER); // sub reg, n
|
||||
BEGIN
|
||||
IF isLong(n) THEN
|
||||
oprlongc(reg, n, sub)
|
||||
ELSE
|
||||
OutByte3(48H + reg DIV 8, 81H + ORD(isByte(n)) * 2, 0E8H + reg MOD 8);
|
||||
OutIntByte(n)
|
||||
END
|
||||
oprc(0E8H, reg, n, sub)
|
||||
END subrc;
|
||||
|
||||
|
||||
PROCEDURE andrc (reg, n: INTEGER); // and reg, n
|
||||
BEGIN
|
||||
IF isLong(n) THEN
|
||||
oprlongc(reg, n, and)
|
||||
ELSE
|
||||
OutByte3(48H + reg DIV 8, 81H + ORD(isByte(n)) * 2, 0E0H + reg MOD 8);
|
||||
OutIntByte(n)
|
||||
END
|
||||
oprc(0E0H, reg, n, and)
|
||||
END andrc;
|
||||
|
||||
|
||||
@@ -391,20 +404,22 @@ BEGIN
|
||||
push(reg2);
|
||||
drop
|
||||
ELSE
|
||||
OutByte(68H + ORD(isByte(n)) * 2); OutIntByte(n) // push n
|
||||
OutByte(68H + short(n)); OutIntByte(n) // push n
|
||||
END
|
||||
END pushc;
|
||||
|
||||
|
||||
PROCEDURE not (reg: INTEGER); // not reg
|
||||
BEGIN
|
||||
OutByte3(48H + reg DIV 8, 0F7H, 0D0H + reg MOD 8)
|
||||
Rex(reg, 0);
|
||||
OutByte2(0F7H, 0D0H + reg MOD 8)
|
||||
END not;
|
||||
|
||||
|
||||
PROCEDURE neg (reg: INTEGER); // neg reg
|
||||
BEGIN
|
||||
OutByte3(48H + reg DIV 8, 0F7H, 0D8H + reg MOD 8)
|
||||
Rex(reg, 0);
|
||||
OutByte2(0F7H, 0D8H + reg MOD 8)
|
||||
END neg;
|
||||
|
||||
|
||||
@@ -413,11 +428,12 @@ VAR
|
||||
b: BYTE;
|
||||
|
||||
BEGIN
|
||||
OutByte3(48H + reg2 DIV 8 + (reg1 DIV 8) * 4, 0FH, 0B6H + ORD(word));
|
||||
Rex(reg2, reg1);
|
||||
OutByte2(0FH, 0B6H + ORD(word));
|
||||
IF (offs = 0) & (reg2 # rbp) THEN
|
||||
b := 0
|
||||
ELSE
|
||||
b := 40H + 40H * ORD(~isByte(offs))
|
||||
b := 40H + long(offs)
|
||||
END;
|
||||
OutByte(b + (reg1 MOD 8) * 8 + reg2 MOD 8);
|
||||
IF reg2 = rsp THEN
|
||||
@@ -444,7 +460,7 @@ BEGIN
|
||||
IF (offs = 0) & (reg2 # rbp) THEN
|
||||
b := 0
|
||||
ELSE
|
||||
b := 40H + 40H * ORD(~isByte(offs))
|
||||
b := 40H + long(offs)
|
||||
END;
|
||||
OutByte(b + (reg1 MOD 8) * 8 + reg2 MOD 8);
|
||||
IF reg2 = rsp THEN
|
||||
@@ -516,7 +532,7 @@ BEGIN
|
||||
IF (offs = 0) & (reg # rbp) THEN
|
||||
b := 30H
|
||||
ELSE
|
||||
b := 70H + ORD(~isByte(offs)) * 40H
|
||||
b := 70H + long(offs)
|
||||
END;
|
||||
OutByte(b + reg MOD 8);
|
||||
IF reg = rsp THEN
|
||||
@@ -551,7 +567,7 @@ BEGIN
|
||||
IF (offs = 0) & (reg # rbp) THEN
|
||||
b := 0
|
||||
ELSE
|
||||
b := 40H + 40H * ORD(~isByte(offs))
|
||||
b := 40H + long(offs)
|
||||
END;
|
||||
OutByte(b + (xmm MOD 8) * 8 + reg MOD 8);
|
||||
IF reg = rsp THEN
|
||||
@@ -608,18 +624,13 @@ END setcc;
|
||||
|
||||
PROCEDURE shiftrc (op, reg, n: INTEGER);
|
||||
BEGIN
|
||||
OutByte(48H + ORD(reg >= 8));
|
||||
Rex(reg, 0);
|
||||
IF n = 1 THEN
|
||||
OutByte(0D1H)
|
||||
ELSE
|
||||
OutByte(0C1H)
|
||||
END;
|
||||
CASE op OF
|
||||
|sar: OutByte(0F8H + reg MOD 8) // sar reg, n
|
||||
|ror: OutByte(0C8H + reg MOD 8) // ror reg, n
|
||||
|shl: OutByte(0E0H + reg MOD 8) // shl reg, n
|
||||
|shr: OutByte(0E8H + reg MOD 8) // shr reg, n
|
||||
END;
|
||||
X86.shift(op, reg MOD 8);
|
||||
IF n # 1 THEN
|
||||
OutByte(n)
|
||||
END
|
||||
@@ -821,11 +832,17 @@ BEGIN
|
||||
END allocReg;
|
||||
|
||||
|
||||
PROCEDURE GetRegA;
|
||||
BEGIN
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
END GetRegA;
|
||||
|
||||
|
||||
PROCEDURE translate (commands: LISTS.LIST; stroffs: INTEGER);
|
||||
VAR
|
||||
cmd, next: COMMAND;
|
||||
|
||||
param1, param2, param3, a, b, n, label, L, i: INTEGER;
|
||||
param1, param2, param3, a, b, n, label, L, i, cc: INTEGER;
|
||||
|
||||
reg1, reg2, xmm: INTEGER;
|
||||
|
||||
@@ -879,7 +896,7 @@ BEGIN
|
||||
|CODE.opCALLP64:
|
||||
UnOp(reg1);
|
||||
IF reg1 # rax THEN
|
||||
ASSERT(REG.GetReg(R, rax));
|
||||
GetRegA;
|
||||
ASSERT(REG.Exchange(R, reg1, rax));
|
||||
drop
|
||||
END;
|
||||
@@ -955,7 +972,7 @@ BEGIN
|
||||
|
||||
|CODE.opRES:
|
||||
ASSERT(R.top = -1);
|
||||
ASSERT(REG.GetReg(R, rax));
|
||||
GetRegA;
|
||||
n := param2;
|
||||
WHILE n > 0 DO
|
||||
INC(xmm);
|
||||
@@ -1002,7 +1019,7 @@ BEGIN
|
||||
IF cmd.opcode = CODE.opLEAVER THEN
|
||||
UnOp(reg1);
|
||||
IF reg1 # rax THEN
|
||||
ASSERT(REG.GetReg(R, rax));
|
||||
GetRegA;
|
||||
ASSERT(REG.Exchange(R, reg1, rax));
|
||||
drop
|
||||
END;
|
||||
@@ -1140,7 +1157,8 @@ BEGIN
|
||||
cmd := next
|
||||
ELSE
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
OutByte3(48H + 4 * ORD(reg1 >= 8), 8DH, 45H + 40H * ORD(~isByte(n)) + (reg1 MOD 8) * 8); // lea reg1, qword[rbp+n]
|
||||
Rex(0, reg1);
|
||||
OutByte2(8DH, 45H + long(n) + (reg1 MOD 8) * 8); // lea reg1, qword[rbp+n]
|
||||
OutIntByte(n)
|
||||
END
|
||||
|
||||
@@ -1178,7 +1196,8 @@ BEGIN
|
||||
movmr(reg1, 0, reg2);
|
||||
drop
|
||||
ELSE
|
||||
OutByte3(48H + reg1 DIV 8, 0C7H, reg1 MOD 8); // mov qword[reg1], param2
|
||||
Rex(reg1, 0);
|
||||
OutByte2(0C7H, reg1 MOD 8); // mov qword[reg1], param2
|
||||
OutInt(param2)
|
||||
END;
|
||||
drop
|
||||
@@ -1186,102 +1205,72 @@ BEGIN
|
||||
|CODE.opRSET:
|
||||
PushAll(2);
|
||||
CallRTL(CODE._set);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opRSETR:
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(CODE._set);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opRSETL:
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(CODE._set2);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opRSET1:
|
||||
UnOp(reg1);
|
||||
PushAll(1);
|
||||
push(reg1);
|
||||
CallRTL(CODE._set);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opINCL, CODE.opEXCL:
|
||||
BinOp(reg1, reg2);
|
||||
cmprc(reg1, 64);
|
||||
OutByte2(73H, 04H); // jnb L
|
||||
OutByte2(48H + reg2 DIV 8 + 4 * (reg1 DIV 8), 0FH); // bts/btr qword[reg2], reg1
|
||||
OutByte2(0ABH + 8 * ORD(cmd.opcode = CODE.opEXCL), 8 * (reg1 MOD 8) + reg2 MOD 8);
|
||||
Rex(reg2, reg1);
|
||||
OutByte3(0FH, 0ABH + 8 * ORD(cmd.opcode = CODE.opEXCL), 8 * (reg1 MOD 8) + reg2 MOD 8); // bts/btr qword[reg2], reg1
|
||||
// L:
|
||||
drop;
|
||||
drop
|
||||
|
||||
|CODE.opINCLC, CODE.opEXCLC:
|
||||
UnOp(reg1);
|
||||
OutByte3(48H + reg1 DIV 8, 0FH, 0BAH); // bts/btr qword[reg1], param2
|
||||
Rex(reg1, 0);
|
||||
OutByte2(0FH, 0BAH); // bts/btr qword[reg1], param2
|
||||
OutByte2(28H + 8 * ORD(cmd.opcode = CODE.opEXCLC) + reg1 MOD 8, param2);
|
||||
drop
|
||||
|
||||
|CODE.opEQS, CODE.opNES, CODE.opLTS,
|
||||
CODE.opLES, CODE.opGTS, CODE.opGES:
|
||||
|CODE.opEQS .. CODE.opGES:
|
||||
PushAll(4);
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opEQS: pushc(0)
|
||||
|CODE.opNES: pushc(1)
|
||||
|CODE.opLTS: pushc(2)
|
||||
|CODE.opLES: pushc(3)
|
||||
|CODE.opGTS: pushc(4)
|
||||
|CODE.opGES: pushc(5)
|
||||
END;
|
||||
pushc(cmd.opcode - CODE.opEQS);
|
||||
CallRTL(CODE._strcmp);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opEQS2, CODE.opNES2, CODE.opLTS2,
|
||||
CODE.opLES2, CODE.opGTS2, CODE.opGES2:
|
||||
|CODE.opEQS2 .. CODE.opGES2:
|
||||
PushAll(4);
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opEQS2: pushc(0)
|
||||
|CODE.opNES2: pushc(1)
|
||||
|CODE.opLTS2: pushc(2)
|
||||
|CODE.opLES2: pushc(3)
|
||||
|CODE.opGTS2: pushc(4)
|
||||
|CODE.opGES2: pushc(5)
|
||||
END;
|
||||
pushc(cmd.opcode - CODE.opEQS2);
|
||||
CallRTL(CODE._strcmp2);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opEQSW, CODE.opNESW, CODE.opLTSW,
|
||||
CODE.opLESW, CODE.opGTSW, CODE.opGESW:
|
||||
|CODE.opEQSW .. CODE.opGESW:
|
||||
PushAll(4);
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opEQSW: pushc(0)
|
||||
|CODE.opNESW: pushc(1)
|
||||
|CODE.opLTSW: pushc(2)
|
||||
|CODE.opLESW: pushc(3)
|
||||
|CODE.opGTSW: pushc(4)
|
||||
|CODE.opGESW: pushc(5)
|
||||
END;
|
||||
pushc(cmd.opcode - CODE.opEQSW);
|
||||
CallRTL(CODE._strcmpw);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opEQSW2, CODE.opNESW2, CODE.opLTSW2,
|
||||
CODE.opLESW2, CODE.opGTSW2, CODE.opGESW2:
|
||||
|CODE.opEQSW2 .. CODE.opGESW2:
|
||||
PushAll(4);
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opEQSW2: pushc(0)
|
||||
|CODE.opNESW2: pushc(1)
|
||||
|CODE.opLTSW2: pushc(2)
|
||||
|CODE.opLESW2: pushc(3)
|
||||
|CODE.opGTSW2: pushc(4)
|
||||
|CODE.opGESW2: pushc(5)
|
||||
END;
|
||||
pushc(cmd.opcode - CODE.opEQSW2);
|
||||
CallRTL(CODE._strcmpw2);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opINC1, CODE.opDEC1:
|
||||
UnOp(reg1);
|
||||
OutByte3(48H + reg1 DIV 8, 0FFH, reg1 MOD 8 + 8 * ORD(cmd.opcode = CODE.opDEC1));
|
||||
Rex(reg1, 0);
|
||||
OutByte2(0FFH, reg1 MOD 8 + 8 * ORD(cmd.opcode = CODE.opDEC1));
|
||||
drop
|
||||
|
||||
|CODE.opCONST:
|
||||
@@ -1294,43 +1283,21 @@ BEGIN
|
||||
cmprr(reg1, reg2);
|
||||
drop;
|
||||
drop;
|
||||
cc := X86.cond(cmd.opcode);
|
||||
|
||||
IF cmd.next(COMMAND).opcode = CODE.opJE THEN
|
||||
label := cmd.next(COMMAND).param1;
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opGT: jcc(jg, label)
|
||||
|CODE.opGE: jcc(jge, label)
|
||||
|CODE.opLE: jcc(jle, label)
|
||||
|CODE.opLT: jcc(jl, label)
|
||||
|CODE.opEQ: jcc(je, label)
|
||||
|CODE.opNE: jcc(jne, label)
|
||||
END;
|
||||
jcc(cc, label);
|
||||
cmd := cmd.next(COMMAND)
|
||||
|
||||
ELSIF cmd.next(COMMAND).opcode = CODE.opJNE THEN
|
||||
label := cmd.next(COMMAND).param1;
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opGT: jcc(jle, label)
|
||||
|CODE.opGE: jcc(jl, label)
|
||||
|CODE.opLE: jcc(jg, label)
|
||||
|CODE.opLT: jcc(jge, label)
|
||||
|CODE.opEQ: jcc(jne, label)
|
||||
|CODE.opNE: jcc(je, label)
|
||||
END;
|
||||
jcc(X86.inv1(cc), label);
|
||||
cmd := cmd.next(COMMAND)
|
||||
|
||||
ELSE
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opGT: setcc(setg, reg1)
|
||||
|CODE.opGE: setcc(setge, reg1)
|
||||
|CODE.opLE: setcc(setle, reg1)
|
||||
|CODE.opLT: setcc(setl, reg1)
|
||||
|CODE.opEQ: setcc(sete, reg1)
|
||||
|CODE.opNE: setcc(setne, reg1)
|
||||
END;
|
||||
|
||||
setcc(cc + 16, reg1);
|
||||
andrc(reg1, 1)
|
||||
END
|
||||
|
||||
@@ -1344,43 +1311,21 @@ BEGIN
|
||||
cmprc(reg1, param2)
|
||||
END;
|
||||
drop;
|
||||
cc := X86.cond(cmd.opcode);
|
||||
|
||||
IF cmd.next(COMMAND).opcode = CODE.opJE THEN
|
||||
label := cmd.next(COMMAND).param1;
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opGTR, CODE.opLTL: jcc(jg, label)
|
||||
|CODE.opGER, CODE.opLEL: jcc(jge, label)
|
||||
|CODE.opLER, CODE.opGEL: jcc(jle, label)
|
||||
|CODE.opLTR, CODE.opGTL: jcc(jl, label)
|
||||
|CODE.opEQR, CODE.opEQL: jcc(je, label)
|
||||
|CODE.opNER, CODE.opNEL: jcc(jne, label)
|
||||
END;
|
||||
jcc(cc, label);
|
||||
cmd := cmd.next(COMMAND)
|
||||
|
||||
ELSIF cmd.next(COMMAND).opcode = CODE.opJNE THEN
|
||||
label := cmd.next(COMMAND).param1;
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opGTR, CODE.opLTL: jcc(jle, label)
|
||||
|CODE.opGER, CODE.opLEL: jcc(jl, label)
|
||||
|CODE.opLER, CODE.opGEL: jcc(jg, label)
|
||||
|CODE.opLTR, CODE.opGTL: jcc(jge, label)
|
||||
|CODE.opEQR, CODE.opEQL: jcc(jne, label)
|
||||
|CODE.opNER, CODE.opNEL: jcc(je, label)
|
||||
END;
|
||||
jcc(X86.inv1(cc), label);
|
||||
cmd := cmd.next(COMMAND)
|
||||
|
||||
ELSE
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opGTR, CODE.opLTL: setcc(setg, reg1)
|
||||
|CODE.opGER, CODE.opLEL: setcc(setge, reg1)
|
||||
|CODE.opLER, CODE.opGEL: setcc(setle, reg1)
|
||||
|CODE.opLTR, CODE.opGTL: setcc(setl, reg1)
|
||||
|CODE.opEQR, CODE.opEQL: setcc(sete, reg1)
|
||||
|CODE.opNER, CODE.opNEL: setcc(setne, reg1)
|
||||
END;
|
||||
|
||||
setcc(cc + 16, reg1);
|
||||
andrc(reg1, 1)
|
||||
END
|
||||
|
||||
@@ -1434,8 +1379,8 @@ BEGIN
|
||||
xor(reg1, reg1);
|
||||
jmp(label);
|
||||
X86.SetLabel(L);
|
||||
OutByte3(48H + ORD(reg2 >= 8) + 4 * ORD(reg1 >= 8), 0FH, 0A3H);
|
||||
OutByte(0C0H + 8 * (reg1 MOD 8) + reg2 MOD 8); // bt reg2, reg1
|
||||
Rex(reg2, reg1);
|
||||
OutByte3(0FH, 0A3H, 0C0H + 8 * (reg1 MOD 8) + reg2 MOD 8); // bt reg2, reg1
|
||||
setcc(setc, reg1);
|
||||
andrc(reg1, 1);
|
||||
X86.SetLabel(label);
|
||||
@@ -1452,8 +1397,8 @@ BEGIN
|
||||
jmp(label);
|
||||
X86.SetLabel(L);
|
||||
movrc(reg2, param2);
|
||||
OutByte3(48H + ORD(reg2 >= 8) + 4 * ORD(reg1 >= 8), 0FH, 0A3H);
|
||||
OutByte(0C0H + 8 * (reg1 MOD 8) + reg2 MOD 8); // bt reg2, reg1
|
||||
Rex(reg2, reg1);
|
||||
OutByte3(0FH, 0A3H, 0C0H + 8 * (reg1 MOD 8) + reg2 MOD 8); // bt reg2, reg1
|
||||
setcc(setc, reg1);
|
||||
andrc(reg1, 1);
|
||||
X86.SetLabel(label);
|
||||
@@ -1461,7 +1406,8 @@ BEGIN
|
||||
|
||||
|CODE.opINL:
|
||||
UnOp(reg1);
|
||||
OutByte3(48H + reg1 DIV 8, 0FH, 0BAH); // bt reg1, param2
|
||||
Rex(reg1, 0);
|
||||
OutByte2(0FH, 0BAH); // bt reg1, param2
|
||||
OutByte2(0E0H + reg1 MOD 8, param2);
|
||||
setcc(setc, reg1);
|
||||
andrc(reg1, 1)
|
||||
@@ -1513,7 +1459,8 @@ BEGIN
|
||||
|
||||
|CODE.opDIVSC, CODE.opADDSL, CODE.opADDSR:
|
||||
UnOp(reg1);
|
||||
OutByte3(48H + reg1 DIV 8, 81H + 2 * ORD(isByte(param2)), 0C8H + 28H * ORD(cmd.opcode = CODE.opDIVSC) + reg1 MOD 8); // or/xor reg1, param2
|
||||
Rex(reg1, 0);
|
||||
OutByte2(81H + short(param2), 0C8H + 28H * ORD(cmd.opcode = CODE.opDIVSC) + reg1 MOD 8); // or/xor reg1, param2
|
||||
OutIntByte(param2)
|
||||
|
||||
|CODE.opSUBSL:
|
||||
@@ -1552,7 +1499,7 @@ BEGIN
|
||||
PushAll(4);
|
||||
pushc(param2);
|
||||
CallRTL(CODE._arrcpy);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opCOPYS:
|
||||
PushAll(4);
|
||||
@@ -1591,19 +1538,19 @@ BEGIN
|
||||
PushAll(2);
|
||||
pushc(param2);
|
||||
CallRTL(CODE._isrec);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opIS:
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(CODE._is);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opTYPEGR:
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(CODE._guardrec);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opTYPEGP:
|
||||
UnOp(reg1);
|
||||
@@ -1611,7 +1558,7 @@ BEGIN
|
||||
push(reg1);
|
||||
pushc(param2);
|
||||
CallRTL(CODE._guard);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opTYPEGD:
|
||||
UnOp(reg1);
|
||||
@@ -1619,7 +1566,7 @@ BEGIN
|
||||
pushm(reg1, -8);
|
||||
pushc(param2);
|
||||
CallRTL(CODE._guardrec);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opCASET:
|
||||
push(r10);
|
||||
@@ -1645,7 +1592,8 @@ BEGIN
|
||||
|CODE.opINC, CODE.opDEC:
|
||||
BinOp(reg1, reg2);
|
||||
// add/sub qword[reg2], reg1
|
||||
OutByte3(48H + reg2 DIV 8 + (reg1 DIV 8) * 4, 01H + 28H * ORD(cmd.opcode = CODE.opDEC), reg2 MOD 8 + (reg1 MOD 8) * 8);
|
||||
Rex(reg2, reg1);
|
||||
OutByte2(01H + 28H * ORD(cmd.opcode = CODE.opDEC), reg2 MOD 8 + (reg1 MOD 8) * 8);
|
||||
drop;
|
||||
drop
|
||||
|
||||
@@ -1655,11 +1603,13 @@ BEGIN
|
||||
reg2 := REG.GetAnyReg(R);
|
||||
movrc(reg2, param2);
|
||||
// add/sub qword[reg1], reg2
|
||||
OutByte3(48H + reg1 DIV 8 + (reg2 DIV 8) * 4, 01H + 28H * ORD(cmd.opcode = CODE.opDECC), reg1 MOD 8 + (reg2 MOD 8) * 8);
|
||||
Rex(reg1, reg2);
|
||||
OutByte2(01H + 28H * ORD(cmd.opcode = CODE.opDECC), reg1 MOD 8 + (reg2 MOD 8) * 8);
|
||||
drop
|
||||
ELSE
|
||||
// add/sub qword[reg1], param2
|
||||
OutByte3(48H + reg1 DIV 8, 81H + 2 * ORD(isByte(param2)), 28H * ORD(cmd.opcode = CODE.opDECC) + reg1 MOD 8);
|
||||
Rex(reg1, 0);
|
||||
OutByte2(81H + short(param2), 28H * ORD(cmd.opcode = CODE.opDECC) + reg1 MOD 8);
|
||||
OutIntByte(param2)
|
||||
END;
|
||||
drop
|
||||
@@ -1787,7 +1737,7 @@ BEGIN
|
||||
|CODE.opDIV:
|
||||
PushAll(2);
|
||||
CallRTL(CODE._div);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opDIVR:
|
||||
a := param2;
|
||||
@@ -1822,7 +1772,7 @@ BEGIN
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(CODE._div);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
END
|
||||
END
|
||||
|
||||
@@ -1830,12 +1780,12 @@ BEGIN
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(CODE._div2);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opMOD:
|
||||
PushAll(2);
|
||||
CallRTL(CODE._mod);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opMODR:
|
||||
a := param2;
|
||||
@@ -1867,7 +1817,7 @@ BEGIN
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(CODE._mod);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
END
|
||||
END
|
||||
|
||||
@@ -1875,7 +1825,7 @@ BEGIN
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(CODE._mod2);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opMUL:
|
||||
BinOp(reg1, reg2);
|
||||
@@ -1908,7 +1858,8 @@ BEGIN
|
||||
shiftrc(shl, reg1, n)
|
||||
ELSE
|
||||
// imul reg1, a
|
||||
OutByte3(48H + 5 * (reg1 DIV 8), 69H + 2 * ORD(isByte(a)), 0C0H + (reg1 MOD 8) * 9);
|
||||
Rex(reg1, reg1);
|
||||
OutByte2(69H + short(a), 0C0H + (reg1 MOD 8) * 9);
|
||||
OutIntByte(a)
|
||||
END
|
||||
END
|
||||
@@ -1958,13 +1909,9 @@ BEGIN
|
||||
|CODE.opASR, CODE.opROR, CODE.opLSL, CODE.opLSR:
|
||||
BinOp(reg1, reg2);
|
||||
xchg(reg2, rcx);
|
||||
OutByte2(48H + ORD(reg1 >= 8), 0D3H);
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opASR: OutByte(0F8H + reg1 MOD 8) // sar reg1, cl
|
||||
|CODE.opROR: OutByte(0C8H + reg1 MOD 8) // ror reg1, cl
|
||||
|CODE.opLSL: OutByte(0E0H + reg1 MOD 8) // shl reg1, cl
|
||||
|CODE.opLSR: OutByte(0E8H + reg1 MOD 8) // shr reg1, cl
|
||||
END;
|
||||
Rex(reg1, 0);
|
||||
OutByte(0D3H);
|
||||
X86.shift(cmd.opcode, reg1 MOD 8); // shift reg1, cl
|
||||
xchg(reg2, rcx);
|
||||
drop
|
||||
|
||||
@@ -1973,13 +1920,9 @@ BEGIN
|
||||
movrc(reg1, param2);
|
||||
BinOp(reg1, reg2);
|
||||
xchg(reg1, rcx);
|
||||
OutByte2(48H + ORD(reg2 >= 8), 0D3H);
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opASR1: OutByte(0F8H + reg2 MOD 8) // sar reg2, cl
|
||||
|CODE.opROR1: OutByte(0C8H + reg2 MOD 8) // ror reg2, cl
|
||||
|CODE.opLSL1: OutByte(0E0H + reg2 MOD 8) // shl reg2, cl
|
||||
|CODE.opLSR1: OutByte(0E8H + reg2 MOD 8) // shr reg2, cl
|
||||
END;
|
||||
Rex(reg2, 0);
|
||||
OutByte(0D3H);
|
||||
X86.shift(cmd.opcode, reg2 MOD 8); // shift reg2, cl
|
||||
xchg(reg1, rcx);
|
||||
drop;
|
||||
drop;
|
||||
@@ -1993,25 +1936,8 @@ BEGIN
|
||||
BinOp(reg1, reg2);
|
||||
drop;
|
||||
drop;
|
||||
|
||||
CASE param2 OF
|
||||
|1:
|
||||
movrm8(reg1, reg1, 0);
|
||||
movmr8(reg2, 0, reg1)
|
||||
|
||||
|2:
|
||||
movrm16(reg1, reg1, 0);
|
||||
movmr16(reg2, 0, reg1)
|
||||
|
||||
|4:
|
||||
movrm32(reg1, reg1, 0);
|
||||
movmr32(reg2, 0, reg1)
|
||||
|
||||
|8:
|
||||
movrm(reg1, reg1, 0);
|
||||
movmr(reg2, 0, reg1)
|
||||
|
||||
END
|
||||
_movrm(reg1, reg1, 0, param2 * 8, FALSE);
|
||||
_movrm(reg1, reg2, 0, param2 * 8, TRUE)
|
||||
|
||||
|CODE.opCHKBYTE:
|
||||
BinOp(reg1, reg2);
|
||||
@@ -2039,12 +1965,12 @@ BEGIN
|
||||
|CODE.opLENGTH:
|
||||
PushAll(2);
|
||||
CallRTL(CODE._length);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opLENGTHW:
|
||||
PushAll(2);
|
||||
CallRTL(CODE._lengthw);
|
||||
ASSERT(REG.GetReg(R, rax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opLEN:
|
||||
n := param2;
|
||||
@@ -2212,7 +2138,7 @@ BEGIN
|
||||
|CODE.opFLT:
|
||||
UnOp(reg1);
|
||||
INC(xmm);
|
||||
OutByte3(0F2H, 48H + (xmm DIV 8) * 4 + reg1 DIV 8, 0FH); // cvtsi2sd xmm, reg1
|
||||
OutByte(0F2H); Rex(reg1, xmm); OutByte(0FH); // cvtsi2sd xmm, reg1
|
||||
OutByte2(2AH, 0C0H + (xmm MOD 8) * 8 + reg1 MOD 8);
|
||||
drop
|
||||
|
||||
@@ -2224,7 +2150,7 @@ BEGIN
|
||||
OutByte3(081H, 024H, 024H); OutByte2(0FFH, 09FH); OutByte2(0FFH, 0FFH); // and dword[rsp],11111111111111111001111111111111b;
|
||||
OutByte3(081H, 00CH, 024H); OutByte2(000H, 020H); OutByte2(000H, 000H); // or dword[rsp],00000000000000000010000000000000b;
|
||||
OutByte2(00FH, 0AEH); OutByte2(014H, 024H); // ldmxcsr dword[rsp];
|
||||
OutByte3(0F2H, 48H + xmm DIV 8 + (reg1 DIV 8) * 4, 0FH); // cvtsd2si reg1, xmm
|
||||
OutByte(0F2H); Rex(xmm, reg1); OutByte(0FH); // cvtsd2si reg1, xmm
|
||||
OutByte2(2DH, 0C0H + xmm MOD 8 + (reg1 MOD 8) * 8);
|
||||
OutByte3(00FH, 0AEH, 054H); OutByte2(024H, 004H); // ldmxcsr dword[rsp+4];
|
||||
addrc(rsp, 8);
|
||||
@@ -2234,7 +2160,7 @@ BEGIN
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
xor(reg1, reg1);
|
||||
comisd(xmm - 1, xmm);
|
||||
OutByte2(7AH, 3 + ORD(reg1 >= 8)); // jp L
|
||||
OutByte2(7AH, 3 + reg1 DIV 8); // jp L
|
||||
setcc(sete, reg1);
|
||||
// L:
|
||||
DEC(xmm, 2)
|
||||
@@ -2243,7 +2169,7 @@ BEGIN
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
xor(reg1, reg1);
|
||||
comisd(xmm - 1, xmm);
|
||||
OutByte2(7AH, 3 + ORD(reg1 >= 8)); // jp L
|
||||
OutByte2(7AH, 3 + reg1 DIV 8); // jp L
|
||||
setcc(setne, reg1);
|
||||
// L:
|
||||
DEC(xmm, 2)
|
||||
@@ -2252,7 +2178,7 @@ BEGIN
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
xor(reg1, reg1);
|
||||
comisd(xmm - 1, xmm);
|
||||
OutByte2(7AH, 3 + ORD(reg1 >= 8)); // jp L
|
||||
OutByte2(7AH, 3 + reg1 DIV 8); // jp L
|
||||
setcc(setc, reg1);
|
||||
// L:
|
||||
DEC(xmm, 2)
|
||||
@@ -2261,7 +2187,7 @@ BEGIN
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
xor(reg1, reg1);
|
||||
comisd(xmm, xmm - 1);
|
||||
OutByte2(7AH, 3 + ORD(reg1 >= 8)); // jp L
|
||||
OutByte2(7AH, 3 + reg1 DIV 8); // jp L
|
||||
setcc(setc, reg1);
|
||||
// L:
|
||||
DEC(xmm, 2)
|
||||
@@ -2270,7 +2196,7 @@ BEGIN
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
xor(reg1, reg1);
|
||||
comisd(xmm, xmm - 1);
|
||||
OutByte2(7AH, 3 + ORD(reg1 >= 8)); // jp L
|
||||
OutByte2(7AH, 3 + reg1 DIV 8); // jp L
|
||||
setcc(setnc, reg1);
|
||||
// L:
|
||||
DEC(xmm, 2)
|
||||
@@ -2279,7 +2205,7 @@ BEGIN
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
xor(reg1, reg1);
|
||||
comisd(xmm - 1, xmm);
|
||||
OutByte2(7AH, 3 + ORD(reg1 >= 8)); // jp L
|
||||
OutByte2(7AH, 3 + reg1 DIV 8); // jp L
|
||||
setcc(setnc, reg1);
|
||||
// L:
|
||||
DEC(xmm, 2)
|
||||
@@ -2330,7 +2256,8 @@ BEGIN
|
||||
regVar := reg2 # -1;
|
||||
IF ~regVar THEN
|
||||
reg2 := REG.GetAnyReg(R);
|
||||
OutByte3(48H + 4 * ORD(reg2 >= 8), 8DH, 45H + 40H * ORD(~isByte(n)) + (reg2 MOD 8) * 8); // lea reg2, qword[rbp+n]
|
||||
Rex(0, reg2);
|
||||
OutByte2(8DH, 45H + long(n) + (reg2 MOD 8) * 8); // lea reg2, qword[rbp+n]
|
||||
OutIntByte(n)
|
||||
END
|
||||
ELSE
|
||||
@@ -2360,7 +2287,8 @@ BEGIN
|
||||
or(reg1, reg2);
|
||||
pop(reg2);
|
||||
|
||||
OutByte3(48H + reg1 DIV 8, 0FH, 0BAH);
|
||||
Rex(reg1, 0);
|
||||
OutByte2(0FH, 0BAH);
|
||||
OutByte2(0F0H + reg1 MOD 8, 3EH); // btr reg1, 62
|
||||
movmr(reg2, 0, reg1);
|
||||
drop;
|
||||
@@ -2435,7 +2363,7 @@ BEGIN
|
||||
movmr(rbp, n, reg2);
|
||||
drop
|
||||
ELSE
|
||||
OutByte3(48H, 0C7H, 45H + 40H * ORD(~isByte(n))); // mov qword[rbp+n],param2
|
||||
OutByte3(48H, 0C7H, 45H + long(n)); // mov qword[rbp+n],param2
|
||||
OutIntByte(n);
|
||||
OutInt(param2)
|
||||
END
|
||||
@@ -2453,7 +2381,8 @@ BEGIN
|
||||
ELSE
|
||||
reg2 := REG.GetAnyReg(R);
|
||||
lea(reg2, param1, sBSS);
|
||||
OutByte3(48H + reg2 DIV 8, 0C7H, reg2 MOD 8); // mov qword[reg2], param2
|
||||
Rex(reg2, 0);
|
||||
OutByte2(0C7H, reg2 MOD 8); // mov qword[reg2], param2
|
||||
OutInt(param2);
|
||||
drop
|
||||
END
|
||||
@@ -2474,7 +2403,7 @@ BEGIN
|
||||
incr(reg1)
|
||||
ELSE
|
||||
n := param2 * 8;
|
||||
OutByte3(48H, 0FFH, 45H + 40H * ORD(~isByte(n))); // inc qword[rbp+n]
|
||||
OutByte3(48H, 0FFH, 45H + long(n)); // inc qword[rbp+n]
|
||||
OutIntByte(n)
|
||||
END
|
||||
|
||||
@@ -2484,7 +2413,7 @@ BEGIN
|
||||
decr(reg1)
|
||||
ELSE
|
||||
n := param2 * 8;
|
||||
OutByte3(48H, 0FFH, 4DH + 40H * ORD(~isByte(n))); // dec qword[rbp+n]
|
||||
OutByte3(48H, 0FFH, 4DH + long(n)); // dec qword[rbp+n]
|
||||
OutIntByte(n)
|
||||
END
|
||||
|
||||
@@ -2501,8 +2430,8 @@ BEGIN
|
||||
END
|
||||
ELSE
|
||||
n := param1 * 8;
|
||||
OutByte3(48H + 4 * (reg2 DIV 8), 01H + 28H * ORD(cmd.opcode = CODE.opLADR_DECC),
|
||||
45H + 40H * ORD(~isByte(n)) + (reg2 MOD 8) * 8);
|
||||
Rex(0, reg2);
|
||||
OutByte2(01H + 28H * ORD(cmd.opcode = CODE.opLADR_DECC), 45H + long(n) + (reg2 MOD 8) * 8);
|
||||
OutIntByte(n) // add/sub qword[rbp+n],reg2
|
||||
END;
|
||||
drop
|
||||
@@ -2515,8 +2444,7 @@ BEGIN
|
||||
END
|
||||
ELSE
|
||||
n := param1 * 8;
|
||||
OutByte3(48H, 81H + 2 * ORD(isByte(param2)),
|
||||
45H + 40H * ORD(~isByte(n)) + 28H * ORD(cmd.opcode = CODE.opLADR_DECC));
|
||||
OutByte3(48H, 81H + short(param2), 45H + long(n) + 28H * ORD(cmd.opcode = CODE.opLADR_DECC));
|
||||
OutIntByte(n);
|
||||
OutIntByte(param2) // add/sub qword[rbp+n],param2
|
||||
END
|
||||
@@ -2533,7 +2461,7 @@ BEGIN
|
||||
andrc(reg1, 255)
|
||||
ELSE
|
||||
n := param2 * 8;
|
||||
OutByte2(0FEH, 45H + 40H * ORD(~isByte(n)) + 8 * ORD(cmd.opcode = CODE.opLADR_DEC1B));
|
||||
OutByte2(0FEH, 45H + long(n) + 8 * ORD(cmd.opcode = CODE.opLADR_DEC1B));
|
||||
OutIntByte(n) // inc/dec byte[rbp+n]
|
||||
END
|
||||
|
||||
@@ -2549,7 +2477,7 @@ BEGIN
|
||||
andrc(reg1, 255)
|
||||
ELSE
|
||||
n := param1 * 8;
|
||||
OutByte2(80H, 45H + 40H * ORD(~isByte(n)) + 28H * ORD(cmd.opcode = CODE.opLADR_DECCB));
|
||||
OutByte2(80H, 45H + long(n) + 28H * ORD(cmd.opcode = CODE.opLADR_DECCB));
|
||||
OutIntByte(n);
|
||||
OutByte(param2) // add/sub byte[rbp+n],param2
|
||||
END
|
||||
@@ -2565,8 +2493,8 @@ BEGIN
|
||||
END
|
||||
ELSE
|
||||
n := param2 * 8;
|
||||
OutByte3(48H + 4 * (reg1 DIV 8), 01H + 28H * ORD(cmd.opcode = CODE.opLADR_DEC),
|
||||
45H + 40H * ORD(~isByte(n)) + (reg1 MOD 8) * 8);
|
||||
Rex(0, reg1);
|
||||
OutByte2(01H + 28H * ORD(cmd.opcode = CODE.opLADR_DEC), 45H + long(n) + (reg1 MOD 8) * 8);
|
||||
OutIntByte(n) // add/sub qword[rbp+n],reg1
|
||||
END;
|
||||
drop
|
||||
@@ -2586,7 +2514,7 @@ BEGIN
|
||||
IF reg1 >= 8 THEN
|
||||
OutByte(44H)
|
||||
END;
|
||||
OutByte2(28H * ORD(cmd.opcode = CODE.opLADR_DECB), 45H + 40H * ORD(~isByte(n)) + 8 * (reg1 MOD 8));
|
||||
OutByte2(28H * ORD(cmd.opcode = CODE.opLADR_DECB), 45H + long(n) + 8 * (reg1 MOD 8));
|
||||
OutIntByte(n) // add/sub byte[rbp+n], reg1_8
|
||||
END;
|
||||
drop
|
||||
@@ -2601,8 +2529,8 @@ BEGIN
|
||||
ELSE
|
||||
n := param2 * 8;
|
||||
OutByte2(73H, 5 + 3 * ORD(~isByte(n))); // jnb L
|
||||
OutByte3(48H + 4 * (reg1 DIV 8), 0FH, 0ABH + 8 * ORD(cmd.opcode = CODE.opLADR_EXCL));
|
||||
OutByte(45H + 40H * ORD(~isByte(n)) + 8 * (reg1 MOD 8));
|
||||
Rex(0, reg1);
|
||||
OutByte3(0FH, 0ABH + 8 * ORD(cmd.opcode = CODE.opLADR_EXCL), 45H + long(n) + 8 * (reg1 MOD 8));
|
||||
OutIntByte(n) // bts/btr qword[rbp+n], reg1
|
||||
END;
|
||||
// L:
|
||||
@@ -2611,12 +2539,13 @@ BEGIN
|
||||
|CODE.opLADR_INCLC, CODE.opLADR_EXCLC:
|
||||
reg1 := REG.GetVarReg(R, param1);
|
||||
IF reg1 # -1 THEN
|
||||
OutByte3(48H + reg1 DIV 8, 0FH, 0BAH); // bts/btr reg1, param2
|
||||
OutByte2(0E8H + reg1 MOD 8 + 8 * ORD(cmd.opcode = CODE.opLADR_EXCLC), param2)
|
||||
Rex(reg1, 0);
|
||||
OutByte3(0FH, 0BAH, 0E8H); // bts/btr reg1, param2
|
||||
OutByte2(reg1 MOD 8 + 8 * ORD(cmd.opcode = CODE.opLADR_EXCLC), param2)
|
||||
ELSE
|
||||
n := param1 * 8;
|
||||
OutByte3(48H, 0FH, 0BAH); // bts/btr qword[rbp+n], param2
|
||||
OutByte(6DH + 40H * ORD(~isByte(n)) + 8 * ORD(cmd.opcode = CODE.opLADR_EXCLC));
|
||||
OutByte(6DH + long(n) + 8 * ORD(cmd.opcode = CODE.opLADR_EXCLC));
|
||||
OutIntByte(n);
|
||||
OutByte(param2)
|
||||
END
|
||||
|
||||
+6
-6
@@ -31,7 +31,7 @@ CONST
|
||||
|
||||
opJNE* = 50; opJE* = 51;
|
||||
|
||||
opEQS* = 52; opNES* = 53; opLTS* = 54; opLES* = 55; opGTS* = 56; opGES* = 57;
|
||||
opEQS* = 52; opNES* = opEQS + 1; opLTS* = opEQS + 2; opLES* = opEQS + 3; opGTS* = opEQS + 4; opGES* = opEQS + 5 (* 58 *);
|
||||
|
||||
opSAVE32* = 58; opLLOAD8* = 59;
|
||||
|
||||
@@ -76,9 +76,9 @@ CONST
|
||||
opTYPEGD* = 207; opCALLI* = 208; opPUSHIP* = 209; opSAVEIP* = 210; opEQIP* = 211; opNEIP* = 212;
|
||||
opSAVE16C* = 213; opWCHR* = 214; opCOPYS2* = 215; opLENGTHW* = 216;
|
||||
|
||||
opEQS2* = 217; opNES2* = 218; opLTS2* = 219; opLES2* = 220; opGTS2* = 221; opGES2* = 222;
|
||||
opEQSW* = 223; opNESW* = 224; opLTSW* = 225; opLESW* = 226; opGTSW* = 227; opGESW* = 228;
|
||||
opEQSW2* = 229; opNESW2* = 230; opLTSW2* = 231; opLESW2* = 232; opGTSW2* = 233; opGESW2* = 234;
|
||||
opEQS2* = 217; opNES2* = opEQS2 + 1; opLTS2* = opEQS2 + 2; opLES2* = opEQS2 + 3; opGTS2* = opEQS2 + 4; opGES2* = opEQS2 + 5 (* 222 *);
|
||||
opEQSW* = 223; opNESW* = opEQSW + 1; opLTSW* = opEQSW + 2; opLESW* = opEQSW + 3; opGTSW* = opEQSW + 4; opGESW* = opEQSW + 5 (* 228 *);
|
||||
opEQSW2* = 229; opNESW2* = opEQSW2 + 1; opLTSW2* = opEQSW2 + 2; opLESW2* = opEQSW2 + 3; opGTSW2* = opEQSW2 + 4; opGESW2* = opEQSW2 + 5 (* 234 *);
|
||||
|
||||
opCODE* = 235;
|
||||
|
||||
@@ -421,10 +421,10 @@ END AddRec;
|
||||
PROCEDURE insert (cur, nov: COMMAND);
|
||||
VAR
|
||||
old_opcode, param2: INTEGER;
|
||||
|
||||
|
||||
|
||||
PROCEDURE set (cur: COMMAND; opcode, param2: INTEGER);
|
||||
BEGIN
|
||||
BEGIN
|
||||
cur.opcode := opcode;
|
||||
cur.param1 := cur.param2;
|
||||
cur.param2 := param2
|
||||
|
||||
+34
-56
@@ -32,7 +32,6 @@ CONST
|
||||
SHC_bss = 0C00000C0H;
|
||||
SHC_reloc = 042000040H;
|
||||
|
||||
|
||||
SectionAlignment = 1000H;
|
||||
FileAlignment = 200H;
|
||||
|
||||
@@ -41,8 +40,6 @@ TYPE
|
||||
|
||||
WORD = WCHAR;
|
||||
DWORD = INTEGER;
|
||||
INT64 = INTEGER;
|
||||
|
||||
|
||||
NAME* = ARRAY IMAGE_SIZEOF_SHORT_NAME OF CHAR;
|
||||
|
||||
@@ -66,7 +63,7 @@ TYPE
|
||||
AddressOfEntryPoint: DWORD;
|
||||
BaseOfCode: DWORD;
|
||||
BaseOfData: DWORD;
|
||||
ImageBase: INT64;
|
||||
ImageBase: DWORD;
|
||||
SectionAlignment: DWORD;
|
||||
FileAlignment: DWORD;
|
||||
MajorOperatingSystemVersion: WORD;
|
||||
@@ -81,10 +78,10 @@ TYPE
|
||||
CheckSum: DWORD;
|
||||
Subsystem: WORD;
|
||||
DllCharacteristics: WORD;
|
||||
SizeOfStackReserve: INT64;
|
||||
SizeOfStackCommit: INT64;
|
||||
SizeOfHeapReserve: INT64;
|
||||
SizeOfHeapCommit: INT64;
|
||||
SizeOfStackReserve: DWORD;
|
||||
SizeOfStackCommit: DWORD;
|
||||
SizeOfHeapReserve: DWORD;
|
||||
SizeOfHeapCommit: DWORD;
|
||||
LoaderFlags: DWORD;
|
||||
NumberOfRvaAndSizes: DWORD;
|
||||
|
||||
@@ -179,6 +176,11 @@ VAR
|
||||
libcnt: INTEGER;
|
||||
|
||||
|
||||
PROCEDURE SIZE (): INTEGER;
|
||||
RETURN SIZE_OF_DWORD * (ORD(bit64) + 1)
|
||||
END SIZE;
|
||||
|
||||
|
||||
PROCEDURE Export (program: BIN.PROGRAM; DataRVA: INTEGER; VAR ExportDir: IMAGE_EXPORT_DIRECTORY): INTEGER;
|
||||
BEGIN
|
||||
|
||||
@@ -265,7 +267,7 @@ BEGIN
|
||||
import := import.next(BIN.IMPRT)
|
||||
END
|
||||
|
||||
RETURN ((libcnt + 1) * 5 + (proccnt + libcnt) * 2 * (ORD(bit64) + 1)) * SIZE_OF_DWORD
|
||||
RETURN (libcnt + 1) * 5 * SIZE_OF_DWORD + (proccnt + libcnt) * 2 * SIZE()
|
||||
END GetImportSize;
|
||||
|
||||
|
||||
@@ -323,7 +325,7 @@ BEGIN
|
||||
|
||||
|BIN.RIMP:
|
||||
iproc := BIN.GetIProc(program, L);
|
||||
BIN.put32le(program.code, reloc.offset, iproc.FirstThunk * SIZE_OF_DWORD * (ORD(bit64) + 1) + AdrImp)
|
||||
BIN.put32le(program.code, reloc.offset, iproc.FirstThunk * SIZE() + AdrImp)
|
||||
|
||||
|BIN.RBSS:
|
||||
BIN.put32le(program.code, reloc.offset, L + Address.Bss)
|
||||
@@ -345,7 +347,7 @@ BEGIN
|
||||
|
||||
|BIN.PICIMP:
|
||||
iproc := BIN.GetIProc(program, L);
|
||||
BIN.put32le(program.code, reloc.offset, iproc.FirstThunk * SIZE_OF_DWORD * (ORD(bit64) + 1) + AdrImp + delta)
|
||||
BIN.put32le(program.code, reloc.offset, iproc.FirstThunk * SIZE() + AdrImp + delta)
|
||||
|
||||
END;
|
||||
|
||||
@@ -573,6 +575,17 @@ VAR
|
||||
END WritePEHeader;
|
||||
|
||||
|
||||
PROCEDURE InitSection (VAR section: IMAGE_SECTION_HEADER; Name: NAME; Characteristics: DWORD);
|
||||
BEGIN
|
||||
section.Name := Name;
|
||||
section.PointerToRelocations := 0;
|
||||
section.PointerToLinenumbers := 0;
|
||||
section.NumberOfRelocations := 0X;
|
||||
section.NumberOfLinenumbers := 0X;
|
||||
section.Characteristics := Characteristics
|
||||
END InitSection;
|
||||
|
||||
|
||||
BEGIN
|
||||
bit64 := amd64;
|
||||
Relocations := LISTS.create(NIL);
|
||||
@@ -599,12 +612,7 @@ BEGIN
|
||||
PEHeader.FileHeader.PointerToSymbolTable := 0H;
|
||||
PEHeader.FileHeader.NumberOfSymbols := 0H;
|
||||
PEHeader.FileHeader.SizeOfOptionalHeader := WCHR(0E0H + 10H * ORD(amd64));
|
||||
|
||||
IF dll THEN
|
||||
PEHeader.FileHeader.Characteristics := WCHR(210EH + (20H - 100H) * ORD(amd64))
|
||||
ELSE
|
||||
PEHeader.FileHeader.Characteristics := WCHR(010EH + (20H - 100H) * ORD(amd64))
|
||||
END;
|
||||
PEHeader.FileHeader.Characteristics := WCHR(010EH + (20H - 100H) * ORD(amd64) + 2000H * ORD(dll));
|
||||
|
||||
IF ~reloc & ~pic THEN
|
||||
PEHeader.FileHeader.Characteristics := WCHR(ORD(PEHeader.FileHeader.Characteristics) + 1)
|
||||
@@ -641,51 +649,31 @@ BEGIN
|
||||
PEHeader.OptionalHeader.LoaderFlags := 0;
|
||||
PEHeader.OptionalHeader.NumberOfRvaAndSizes := IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
|
||||
|
||||
SectionHeaders[0].Name := ".text";
|
||||
InitSection(SectionHeaders[0], ".text", SHC_text);
|
||||
SectionHeaders[0].VirtualSize := Size.Code;
|
||||
SectionHeaders[0].VirtualAddress := 1000H;
|
||||
SectionHeaders[0].SizeOfRawData := align(Size.Code, FileAlignment);
|
||||
SectionHeaders[0].PointerToRawData := PEHeader.OptionalHeader.SizeOfHeaders;
|
||||
SectionHeaders[0].PointerToRelocations := 0;
|
||||
SectionHeaders[0].PointerToLinenumbers := 0;
|
||||
SectionHeaders[0].NumberOfRelocations := 0X;
|
||||
SectionHeaders[0].NumberOfLinenumbers := 0X;
|
||||
SectionHeaders[0].Characteristics := SHC_text;
|
||||
|
||||
SectionHeaders[1].Name := ".data";
|
||||
InitSection(SectionHeaders[1], ".data", SHC_data);
|
||||
SectionHeaders[1].VirtualSize := Size.Data;
|
||||
SectionHeaders[1].VirtualAddress := align(SectionHeaders[0].VirtualAddress + SectionHeaders[0].VirtualSize, SectionAlignment);
|
||||
SectionHeaders[1].SizeOfRawData := align(Size.Data, FileAlignment);
|
||||
SectionHeaders[1].PointerToRawData := SectionHeaders[0].PointerToRawData + SectionHeaders[0].SizeOfRawData;
|
||||
SectionHeaders[1].PointerToRelocations := 0;
|
||||
SectionHeaders[1].PointerToLinenumbers := 0;
|
||||
SectionHeaders[1].NumberOfRelocations := 0X;
|
||||
SectionHeaders[1].NumberOfLinenumbers := 0X;
|
||||
SectionHeaders[1].Characteristics := SHC_data;
|
||||
|
||||
SectionHeaders[2].Name := ".bss";
|
||||
InitSection(SectionHeaders[2], ".bss", SHC_bss);
|
||||
SectionHeaders[2].VirtualSize := Size.Bss;
|
||||
SectionHeaders[2].VirtualAddress := align(SectionHeaders[1].VirtualAddress + SectionHeaders[1].VirtualSize, SectionAlignment);
|
||||
SectionHeaders[2].SizeOfRawData := 0;
|
||||
SectionHeaders[2].PointerToRawData := SectionHeaders[1].PointerToRawData + SectionHeaders[1].SizeOfRawData;
|
||||
SectionHeaders[2].PointerToRelocations := 0;
|
||||
SectionHeaders[2].PointerToLinenumbers := 0;
|
||||
SectionHeaders[2].NumberOfRelocations := 0X;
|
||||
SectionHeaders[2].NumberOfLinenumbers := 0X;
|
||||
SectionHeaders[2].Characteristics := SHC_bss;
|
||||
|
||||
Size.Import := GetImportSize(program.imp_list);
|
||||
|
||||
SectionHeaders[3].Name := ".idata";
|
||||
InitSection(SectionHeaders[3], ".idata", SHC_data);
|
||||
SectionHeaders[3].VirtualSize := Size.Import + CHL.Length(program.import);
|
||||
SectionHeaders[3].VirtualAddress := align(SectionHeaders[2].VirtualAddress + SectionHeaders[2].VirtualSize, SectionAlignment);
|
||||
SectionHeaders[3].SizeOfRawData := align(SectionHeaders[3].VirtualSize, FileAlignment);
|
||||
SectionHeaders[3].PointerToRawData := SectionHeaders[2].PointerToRawData + SectionHeaders[2].SizeOfRawData;
|
||||
SectionHeaders[3].PointerToRelocations := 0;
|
||||
SectionHeaders[3].PointerToLinenumbers := 0;
|
||||
SectionHeaders[3].NumberOfRelocations := 0X;
|
||||
SectionHeaders[3].NumberOfLinenumbers := 0X;
|
||||
SectionHeaders[3].Characteristics := SHC_data;
|
||||
|
||||
Address.Code := SectionHeaders[0].VirtualAddress + PEHeader.OptionalHeader.ImageBase;
|
||||
Address.Data := SectionHeaders[1].VirtualAddress + PEHeader.OptionalHeader.ImageBase;
|
||||
@@ -698,16 +686,11 @@ BEGIN
|
||||
IF dll THEN
|
||||
Size.Export := Export(program, SectionHeaders[1].VirtualAddress, ExportDir);
|
||||
|
||||
SectionHeaders[4].Name := ".edata";
|
||||
InitSection(SectionHeaders[4], ".edata", SHC_data);
|
||||
SectionHeaders[4].VirtualSize := Size.Export + CHL.Length(program.export);
|
||||
SectionHeaders[4].VirtualAddress := align(SectionHeaders[3].VirtualAddress + SectionHeaders[3].VirtualSize, SectionAlignment);
|
||||
SectionHeaders[4].SizeOfRawData := align(SectionHeaders[4].VirtualSize, FileAlignment);
|
||||
SectionHeaders[4].PointerToRawData := SectionHeaders[3].PointerToRawData + SectionHeaders[3].SizeOfRawData;
|
||||
SectionHeaders[4].PointerToRelocations := 0;
|
||||
SectionHeaders[4].PointerToLinenumbers := 0;
|
||||
SectionHeaders[4].NumberOfRelocations := 0X;
|
||||
SectionHeaders[4].NumberOfLinenumbers := 0X;
|
||||
SectionHeaders[4].Characteristics := SHC_data;
|
||||
|
||||
relsec := 5
|
||||
END;
|
||||
@@ -724,17 +707,12 @@ BEGIN
|
||||
END;
|
||||
|
||||
IF reloc THEN
|
||||
SectionHeaders[relsec].Name := ".reloc";
|
||||
InitSection(SectionHeaders[relsec], ".reloc", SHC_reloc);
|
||||
SectionHeaders[relsec].VirtualSize := Size.Reloc;
|
||||
SectionHeaders[relsec].VirtualAddress := align(SectionHeaders[relsec - 1].VirtualAddress + SectionHeaders[relsec - 1].VirtualSize,
|
||||
SectionAlignment);
|
||||
SectionHeaders[relsec].SizeOfRawData := align(Size.Reloc, FileAlignment);
|
||||
SectionHeaders[relsec].PointerToRawData := SectionHeaders[relsec - 1].PointerToRawData + SectionHeaders[relsec - 1].SizeOfRawData;
|
||||
SectionHeaders[relsec].PointerToRelocations := 0;
|
||||
SectionHeaders[relsec].PointerToLinenumbers := 0;
|
||||
SectionHeaders[relsec].NumberOfRelocations := 0X;
|
||||
SectionHeaders[relsec].NumberOfLinenumbers := 0X;
|
||||
SectionHeaders[relsec].Characteristics := SHC_reloc
|
||||
END;
|
||||
|
||||
FOR i := 0 TO IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1 DO
|
||||
@@ -795,7 +773,7 @@ BEGIN
|
||||
n := (libcnt + 1) * 5;
|
||||
ImportTable := CHL.CreateIntList();
|
||||
|
||||
FOR i := 0 TO (Size.Import - n * SIZE_OF_DWORD) DIV (SIZE_OF_DWORD * (ORD(amd64) + 1)) + n - 1 DO
|
||||
FOR i := 0 TO (Size.Import - n * SIZE_OF_DWORD) DIV SIZE() + n - 1 DO
|
||||
CHL.PushInt(ImportTable, 0)
|
||||
END;
|
||||
|
||||
@@ -803,11 +781,11 @@ BEGIN
|
||||
import := program.imp_list.first(BIN.IMPRT);
|
||||
WHILE import # NIL DO
|
||||
IF import.label = 0 THEN
|
||||
CHL.SetInt(ImportTable, i + 0, import.OriginalFirstThunk * SIZE_OF_DWORD * (ORD(amd64) + 1) + SectionHeaders[3].VirtualAddress + n * SIZE_OF_DWORD);
|
||||
CHL.SetInt(ImportTable, i + 0, import.OriginalFirstThunk * SIZE() + SectionHeaders[3].VirtualAddress + n * SIZE_OF_DWORD);
|
||||
CHL.SetInt(ImportTable, i + 1, 0);
|
||||
CHL.SetInt(ImportTable, i + 2, 0);
|
||||
CHL.SetInt(ImportTable, i + 3, import.nameoffs + Size.Import + SectionHeaders[3].VirtualAddress);
|
||||
CHL.SetInt(ImportTable, i + 4, import.FirstThunk * SIZE_OF_DWORD * (ORD(amd64) + 1) + SectionHeaders[3].VirtualAddress + n * SIZE_OF_DWORD);
|
||||
CHL.SetInt(ImportTable, i + 4, import.FirstThunk * SIZE() + SectionHeaders[3].VirtualAddress + n * SIZE_OF_DWORD);
|
||||
i := i + 5
|
||||
END;
|
||||
import := import.next(BIN.IMPRT)
|
||||
|
||||
+156
-198
@@ -155,6 +155,16 @@ PROCEDURE isByte (n: INTEGER): BOOLEAN;
|
||||
END isByte;
|
||||
|
||||
|
||||
PROCEDURE short (n: INTEGER): INTEGER;
|
||||
RETURN 2 * ORD(isByte(n))
|
||||
END short;
|
||||
|
||||
|
||||
PROCEDURE long (n: INTEGER): INTEGER;
|
||||
RETURN 40H * ORD(~isByte(n))
|
||||
END long;
|
||||
|
||||
|
||||
PROCEDURE OutIntByte (n: INTEGER);
|
||||
BEGIN
|
||||
IF isByte(n) THEN
|
||||
@@ -165,6 +175,17 @@ BEGIN
|
||||
END OutIntByte;
|
||||
|
||||
|
||||
PROCEDURE shift* (op, reg: INTEGER);
|
||||
BEGIN
|
||||
CASE op OF
|
||||
|CODE.opASR, CODE.opASR1, CODE.opASR2: OutByte(0F8H + reg)
|
||||
|CODE.opROR, CODE.opROR1, CODE.opROR2: OutByte(0C8H + reg)
|
||||
|CODE.opLSL, CODE.opLSL1, CODE.opLSL2: OutByte(0E0H + reg)
|
||||
|CODE.opLSR, CODE.opLSR1, CODE.opLSR2: OutByte(0E8H + reg)
|
||||
END
|
||||
END shift;
|
||||
|
||||
|
||||
PROCEDURE mov (reg1, reg2: INTEGER);
|
||||
BEGIN
|
||||
OutByte2(89H, 0C0H + reg2 * 8 + reg1) // mov reg1, reg2
|
||||
@@ -208,7 +229,7 @@ END movrc;
|
||||
|
||||
PROCEDURE pushc (n: INTEGER);
|
||||
BEGIN
|
||||
OutByte(68H + 2 * ORD(isByte(n))); // push n
|
||||
OutByte(68H + short(n)); // push n
|
||||
OutIntByte(n)
|
||||
END pushc;
|
||||
|
||||
@@ -239,21 +260,21 @@ END add;
|
||||
|
||||
PROCEDURE andrc (reg, n: INTEGER);
|
||||
BEGIN
|
||||
OutByte2(81H + 2 * ORD(isByte(n)), 0E0H + reg); // and reg, n
|
||||
OutByte2(81H + short(n), 0E0H + reg); // and reg, n
|
||||
OutIntByte(n)
|
||||
END andrc;
|
||||
|
||||
|
||||
PROCEDURE orrc (reg, n: INTEGER);
|
||||
BEGIN
|
||||
OutByte2(81H + 2 * ORD(isByte(n)), 0C8H + reg); // or reg, n
|
||||
OutByte2(81H + short(n), 0C8H + reg); // or reg, n
|
||||
OutIntByte(n)
|
||||
END orrc;
|
||||
|
||||
|
||||
PROCEDURE addrc (reg, n: INTEGER);
|
||||
BEGIN
|
||||
OutByte2(81H + 2 * ORD(isByte(n)), 0C0H + reg); // add reg, n
|
||||
OutByte2(81H + short(n), 0C0H + reg); // add reg, n
|
||||
OutIntByte(n)
|
||||
END addrc;
|
||||
|
||||
@@ -266,7 +287,7 @@ END cmprr;
|
||||
|
||||
PROCEDURE cmprc (reg, n: INTEGER);
|
||||
BEGIN
|
||||
OutByte2(81H + 2 * ORD(isByte(n)), 0F8H + reg); // cmp reg, n
|
||||
OutByte2(81H + short(n), 0F8H + reg); // cmp reg, n
|
||||
OutIntByte(n)
|
||||
END cmprc;
|
||||
|
||||
@@ -304,6 +325,36 @@ BEGIN
|
||||
END log2;
|
||||
|
||||
|
||||
PROCEDURE cond* (op: INTEGER): INTEGER;
|
||||
VAR
|
||||
res: INTEGER;
|
||||
|
||||
BEGIN
|
||||
CASE op OF
|
||||
|CODE.opGT, CODE.opGTR, CODE.opLTL: res := jg
|
||||
|CODE.opGE, CODE.opGER, CODE.opLEL: res := jge
|
||||
|CODE.opLT, CODE.opLTR, CODE.opGTL: res := jl
|
||||
|CODE.opLE, CODE.opLER, CODE.opGEL: res := jle
|
||||
|CODE.opEQ, CODE.opEQR, CODE.opEQL: res := je
|
||||
|CODE.opNE, CODE.opNER, CODE.opNEL: res := jne
|
||||
END
|
||||
|
||||
RETURN res
|
||||
END cond;
|
||||
|
||||
|
||||
PROCEDURE inv1* (op: INTEGER): INTEGER;
|
||||
BEGIN
|
||||
IF ODD(op) THEN
|
||||
DEC(op)
|
||||
ELSE
|
||||
INC(op)
|
||||
END
|
||||
|
||||
RETURN op
|
||||
END inv1;
|
||||
|
||||
|
||||
PROCEDURE Reloc* (op, value: INTEGER);
|
||||
VAR
|
||||
reloc: RELOC;
|
||||
@@ -517,7 +568,13 @@ PROCEDURE NewLabel (): INTEGER;
|
||||
BEGIN
|
||||
BIN.NewLabel(program)
|
||||
RETURN CODE.NewLabel()
|
||||
END NewLabel;
|
||||
END NewLabel;
|
||||
|
||||
|
||||
PROCEDURE GetRegA;
|
||||
BEGIN
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
END GetRegA;
|
||||
|
||||
|
||||
PROCEDURE translate (code: CODE.CODES; pic: BOOLEAN; stroffs: INTEGER);
|
||||
@@ -526,7 +583,7 @@ VAR
|
||||
|
||||
reg1, reg2: INTEGER;
|
||||
|
||||
n, a, b, label: INTEGER;
|
||||
n, a, b, label, cc: INTEGER;
|
||||
|
||||
param1, param2: INTEGER;
|
||||
|
||||
@@ -579,7 +636,7 @@ BEGIN
|
||||
|
||||
|CODE.opRES:
|
||||
ASSERT(R.top = -1);
|
||||
ASSERT(REG.GetReg(R, eax));
|
||||
GetRegA;
|
||||
n := param2;
|
||||
WHILE n > 0 DO
|
||||
OutByte3(0DDH, 004H, 024H); // fld qword[esp]
|
||||
@@ -590,7 +647,7 @@ BEGIN
|
||||
|CODE.opRESF:
|
||||
n := param2;
|
||||
IF n > 0 THEN
|
||||
OutByte3(0DDH, 5CH + 40H * ORD(~isByte(n * 8)), 24H);
|
||||
OutByte3(0DDH, 5CH + long(n * 8), 24H);
|
||||
OutIntByte(n * 8); // fstp qword[esp + n*8]
|
||||
INC(n)
|
||||
END;
|
||||
@@ -625,7 +682,7 @@ BEGIN
|
||||
IF cmd.opcode = CODE.opLEAVER THEN
|
||||
UnOp(reg1);
|
||||
IF reg1 # eax THEN
|
||||
ASSERT(REG.GetReg(R, eax));
|
||||
GetRegA;
|
||||
ASSERT(REG.Exchange(R, reg1, eax));
|
||||
drop
|
||||
END;
|
||||
@@ -662,7 +719,7 @@ BEGIN
|
||||
|CODE.opCLEANUP:
|
||||
n := param2 * 4;
|
||||
IF n # 0 THEN
|
||||
OutByte2(81H + 2 * ORD(isByte(n)), 0C4H); // add esp, n
|
||||
OutByte2(81H + short(n), 0C4H); // add esp, n
|
||||
OutIntByte(n)
|
||||
END
|
||||
|
||||
@@ -676,11 +733,10 @@ BEGIN
|
||||
|CODE.opNOP:
|
||||
|
||||
|CODE.opGADR:
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
IF pic THEN
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
Pic(reg1, BIN.PICBSS, param2)
|
||||
ELSE
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
OutByte(0B8H + reg1); // mov reg1, _bss + param2
|
||||
Reloc(BIN.RBSS, param2)
|
||||
END
|
||||
@@ -688,21 +744,20 @@ BEGIN
|
||||
|CODE.opLADR:
|
||||
n := param2 * 4;
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
OutByte2(8DH, 45H + reg1 * 8 + 40H * ORD(~isByte(n))); // lea reg1, dword[ebp + n]
|
||||
OutByte2(8DH, 45H + reg1 * 8 + long(n)); // lea reg1, dword[ebp + n]
|
||||
OutIntByte(n)
|
||||
|
||||
|CODE.opVADR:
|
||||
n := param2 * 4;
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
OutByte2(8BH, 45H + reg1 * 8 + 40H * ORD(~isByte(n))); // mov reg1, dword[ebp + n]
|
||||
OutByte2(8BH, 45H + reg1 * 8 + long(n)); // mov reg1, dword[ebp + n]
|
||||
OutIntByte(n)
|
||||
|
||||
|CODE.opSADR:
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
IF pic THEN
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
Pic(reg1, BIN.PICDATA, stroffs + param2);
|
||||
ELSE
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
OutByte(0B8H + reg1); // mov reg1, _data + stroffs + param2
|
||||
Reloc(BIN.RDATA, stroffs + param2)
|
||||
END
|
||||
@@ -725,7 +780,7 @@ BEGIN
|
||||
|CODE.opVLOAD32:
|
||||
n := param2 * 4;
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
OutByte2(8BH, 45H + reg1 * 8 + 40H * ORD(~isByte(n))); // mov reg1, dword[ebp + n]
|
||||
OutByte2(8BH, 45H + reg1 * 8 + long(n)); // mov reg1, dword[ebp + n]
|
||||
OutIntByte(n);
|
||||
OutByte2(8BH, reg1 * 9) // mov reg1, dword[reg1]
|
||||
|
||||
@@ -742,7 +797,7 @@ BEGIN
|
||||
|CODE.opLLOAD32:
|
||||
n := param2 * 4;
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
OutByte2(8BH, 45H + reg1 * 8 + 40H * ORD(~isByte(n))); // mov reg1, dword[ebp + n]
|
||||
OutByte2(8BH, 45H + reg1 * 8 + long(n)); // mov reg1, dword[ebp + n]
|
||||
OutIntByte(n)
|
||||
|
||||
|CODE.opLOAD32:
|
||||
@@ -752,7 +807,7 @@ BEGIN
|
||||
|CODE.opVLOAD8:
|
||||
n := param2 * 4;
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
OutByte2(8BH, 45H + reg1 * 8 + 40H * ORD(~isByte(n))); // mov reg1, dword[ebp + n]
|
||||
OutByte2(8BH, 45H + reg1 * 8 + long(n)); // mov reg1, dword[ebp + n]
|
||||
OutIntByte(n);
|
||||
OutByte3(0FH, 0B6H, reg1 * 9) // movzx reg1, byte[reg1]
|
||||
|
||||
@@ -769,7 +824,7 @@ BEGIN
|
||||
|CODE.opLLOAD8:
|
||||
n := param2 * 4;
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
OutByte3(0FH, 0B6H, 45H + reg1 * 8 + 40H * ORD(~isByte(n))); // movzx reg1, byte[ebp + n]
|
||||
OutByte3(0FH, 0B6H, 45H + reg1 * 8 + long(n)); // movzx reg1, byte[ebp + n]
|
||||
OutIntByte(n)
|
||||
|
||||
|CODE.opLOAD8:
|
||||
@@ -779,7 +834,7 @@ BEGIN
|
||||
|CODE.opVLOAD16:
|
||||
n := param2 * 4;
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
OutByte2(8BH, 45H + reg1 * 8 + 40H * ORD(~isByte(n))); // mov reg1, dword[ebp + n]
|
||||
OutByte2(8BH, 45H + reg1 * 8 + long(n)); // mov reg1, dword[ebp + n]
|
||||
OutIntByte(n);
|
||||
OutByte3(0FH, 0B7H, reg1 * 9) // movzx reg1, word[reg1]
|
||||
|
||||
@@ -796,7 +851,7 @@ BEGIN
|
||||
|CODE.opLLOAD16:
|
||||
n := param2 * 4;
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
OutByte3(0FH, 0B7H, 45H + reg1 * 8 + 40H * ORD(~isByte(n))); // movzx reg1, word[ebp + n]
|
||||
OutByte3(0FH, 0B7H, 45H + reg1 * 8 + long(n)); // movzx reg1, word[ebp + n]
|
||||
OutIntByte(n)
|
||||
|
||||
|CODE.opLOAD16:
|
||||
@@ -837,7 +892,7 @@ BEGIN
|
||||
ELSIF n = -1 THEN
|
||||
OutByte(40H + reg1) // inc reg1
|
||||
ELSIF n # 0 THEN
|
||||
OutByte2(81H + 2 * ORD(isByte(n)), 0E8H + reg1); // sub reg, n
|
||||
OutByte2(81H + short(n), 0E8H + reg1); // sub reg, n
|
||||
OutIntByte(n)
|
||||
END;
|
||||
IF cmd.opcode = CODE.opSUBL THEN
|
||||
@@ -874,7 +929,7 @@ BEGIN
|
||||
OutByte2(0D1H, 0E0H + reg1) // shl reg1, 1
|
||||
END
|
||||
ELSE
|
||||
OutByte2(69H + 2 * ORD(isByte(a)), 0C0H + reg1 * 9); // imul reg1, a
|
||||
OutByte2(69H + short(a), 0C0H + reg1 * 9); // imul reg1, a
|
||||
OutIntByte(a)
|
||||
END
|
||||
END
|
||||
@@ -988,43 +1043,21 @@ BEGIN
|
||||
cmprc(reg1, param2)
|
||||
END;
|
||||
drop;
|
||||
cc := cond(cmd.opcode);
|
||||
|
||||
IF cmd.next(COMMAND).opcode = CODE.opJE THEN
|
||||
label := cmd.next(COMMAND).param1;
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opGTR, CODE.opLTL: jcc(jg, label)
|
||||
|CODE.opGER, CODE.opLEL: jcc(jge, label)
|
||||
|CODE.opLER, CODE.opGEL: jcc(jle, label)
|
||||
|CODE.opLTR, CODE.opGTL: jcc(jl, label)
|
||||
|CODE.opEQR, CODE.opEQL: jcc(je, label)
|
||||
|CODE.opNER, CODE.opNEL: jcc(jne, label)
|
||||
END;
|
||||
jcc(cc, label);
|
||||
cmd := cmd.next(COMMAND)
|
||||
|
||||
ELSIF cmd.next(COMMAND).opcode = CODE.opJNE THEN
|
||||
label := cmd.next(COMMAND).param1;
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opGTR, CODE.opLTL: jcc(jle, label)
|
||||
|CODE.opGER, CODE.opLEL: jcc(jl, label)
|
||||
|CODE.opLER, CODE.opGEL: jcc(jg, label)
|
||||
|CODE.opLTR, CODE.opGTL: jcc(jge, label)
|
||||
|CODE.opEQR, CODE.opEQL: jcc(jne, label)
|
||||
|CODE.opNER, CODE.opNEL: jcc(je, label)
|
||||
END;
|
||||
jcc(inv1(cc), label);
|
||||
cmd := cmd.next(COMMAND)
|
||||
|
||||
ELSE
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opGTR, CODE.opLTL: setcc(setg, reg1)
|
||||
|CODE.opGER, CODE.opLEL: setcc(setge, reg1)
|
||||
|CODE.opLER, CODE.opGEL: setcc(setle, reg1)
|
||||
|CODE.opLTR, CODE.opGTL: setcc(setl, reg1)
|
||||
|CODE.opEQR, CODE.opEQL: setcc(sete, reg1)
|
||||
|CODE.opNER, CODE.opNEL: setcc(setne, reg1)
|
||||
END;
|
||||
|
||||
setcc(cc + 16, reg1);
|
||||
andrc(reg1, 1)
|
||||
END;
|
||||
|
||||
@@ -1034,43 +1067,21 @@ BEGIN
|
||||
cmprr(reg1, reg2);
|
||||
drop;
|
||||
drop;
|
||||
cc := cond(cmd.opcode);
|
||||
|
||||
IF cmd.next(COMMAND).opcode = CODE.opJE THEN
|
||||
label := cmd.next(COMMAND).param1;
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opGT: jcc(jg, label)
|
||||
|CODE.opGE: jcc(jge, label)
|
||||
|CODE.opLE: jcc(jle, label)
|
||||
|CODE.opLT: jcc(jl, label)
|
||||
|CODE.opEQ: jcc(je, label)
|
||||
|CODE.opNE: jcc(jne, label)
|
||||
END;
|
||||
jcc(cc, label);
|
||||
cmd := cmd.next(COMMAND)
|
||||
|
||||
ELSIF cmd.next(COMMAND).opcode = CODE.opJNE THEN
|
||||
label := cmd.next(COMMAND).param1;
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opGT: jcc(jle, label)
|
||||
|CODE.opGE: jcc(jl, label)
|
||||
|CODE.opLE: jcc(jg, label)
|
||||
|CODE.opLT: jcc(jge, label)
|
||||
|CODE.opEQ: jcc(jne, label)
|
||||
|CODE.opNE: jcc(je, label)
|
||||
END;
|
||||
jcc(inv1(cc), label);
|
||||
cmd := cmd.next(COMMAND)
|
||||
|
||||
ELSE
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opGT: setcc(setg, reg1)
|
||||
|CODE.opGE: setcc(setge, reg1)
|
||||
|CODE.opLE: setcc(setle, reg1)
|
||||
|CODE.opLT: setcc(setl, reg1)
|
||||
|CODE.opEQ: setcc(sete, reg1)
|
||||
|CODE.opNE: setcc(setne, reg1)
|
||||
END;
|
||||
|
||||
setcc(cc + 16, reg1);
|
||||
andrc(reg1, 1)
|
||||
END
|
||||
|
||||
@@ -1153,7 +1164,7 @@ BEGIN
|
||||
jcc(jg, cmd.param3)
|
||||
|
||||
|CODE.opCODE:
|
||||
OutByte(Byte(param2))
|
||||
OutByte(param2)
|
||||
|
||||
|CODE.opGET:
|
||||
BinOp(reg1, reg2);
|
||||
@@ -1250,13 +1261,13 @@ BEGIN
|
||||
|CODE.opINCC:
|
||||
UnOp(reg1);
|
||||
n := param2;
|
||||
OutByte2(81H + 2 * ORD(isByte(n)), reg1); OutIntByte(n); // add dword[reg1], n
|
||||
OutByte2(81H + short(n), reg1); OutIntByte(n); // add dword[reg1], n
|
||||
drop
|
||||
|
||||
|CODE.opDECC:
|
||||
UnOp(reg1);
|
||||
n := param2;
|
||||
OutByte2(81H + 2 * ORD(isByte(n)), 28H + reg1); OutIntByte(n); // sub dword[reg1], n
|
||||
OutByte2(81H + short(n), 28H + reg1); OutIntByte(n); // sub dword[reg1], n
|
||||
drop
|
||||
|
||||
|CODE.opINC:
|
||||
@@ -1317,7 +1328,7 @@ BEGIN
|
||||
|
||||
|CODE.opDIVSC:
|
||||
UnOp(reg1);
|
||||
OutByte2(81H + 2 * ORD(isByte(param2)), 0F0H + reg1); // xor reg1, n
|
||||
OutByte2(81H + short(param2), 0F0H + reg1); // xor reg1, n
|
||||
OutIntByte(param2)
|
||||
|
||||
|CODE.opADDS:
|
||||
@@ -1351,12 +1362,12 @@ BEGIN
|
||||
|CODE.opLENGTH:
|
||||
PushAll(2);
|
||||
CallRTL(pic, CODE._length);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opLENGTHW:
|
||||
PushAll(2);
|
||||
CallRTL(pic, CODE._lengthw);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opCHR:
|
||||
UnOp(reg1);
|
||||
@@ -1377,12 +1388,7 @@ BEGIN
|
||||
BinOp(reg1, reg2);
|
||||
ASSERT(reg2 = ecx);
|
||||
OutByte(0D3H);
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opASR: OutByte(0F8H + reg1) // sar reg1, cl
|
||||
|CODE.opROR: OutByte(0C8H + reg1) // ror reg1, cl
|
||||
|CODE.opLSL: OutByte(0E0H + reg1) // shl reg1, cl
|
||||
|CODE.opLSR: OutByte(0E8H + reg1) // shr reg1, cl
|
||||
END;
|
||||
shift(cmd.opcode, reg1); // shift reg1, cl
|
||||
drop
|
||||
|
||||
|CODE.opASR1, CODE.opROR1, CODE.opLSL1, CODE.opLSR1:
|
||||
@@ -1394,18 +1400,11 @@ BEGIN
|
||||
END;
|
||||
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
|
||||
movrc(reg1, param2);
|
||||
|
||||
BinOp(reg1, reg2);
|
||||
ASSERT(reg1 = ecx);
|
||||
OutByte(0D3H);
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opASR1: OutByte(0F8H + reg2) // sar reg2, cl
|
||||
|CODE.opROR1: OutByte(0C8H + reg2) // ror reg2, cl
|
||||
|CODE.opLSL1: OutByte(0E0H + reg2) // shl reg2, cl
|
||||
|CODE.opLSR1: OutByte(0E8H + reg2) // shr reg2, cl
|
||||
END;
|
||||
shift(cmd.opcode, reg2); // shift reg2, cl
|
||||
drop;
|
||||
drop;
|
||||
ASSERT(REG.GetReg(R, reg2))
|
||||
@@ -1418,14 +1417,7 @@ BEGIN
|
||||
ELSE
|
||||
OutByte(0D1H)
|
||||
END;
|
||||
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opASR2: OutByte(0F8H + reg1) // sar reg1, n
|
||||
|CODE.opROR2: OutByte(0C8H + reg1) // ror reg1, n
|
||||
|CODE.opLSL2: OutByte(0E0H + reg1) // shl reg1, n
|
||||
|CODE.opLSR2: OutByte(0E8H + reg1) // shr reg1, n
|
||||
END;
|
||||
|
||||
shift(cmd.opcode, reg1); // shift reg1, n
|
||||
IF n # 1 THEN
|
||||
OutByte(n)
|
||||
END
|
||||
@@ -1499,26 +1491,26 @@ BEGIN
|
||||
|CODE.opRSET:
|
||||
PushAll(2);
|
||||
CallRTL(pic, CODE._set);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opRSETR:
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(pic, CODE._set);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opRSETL:
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(pic, CODE._set2);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opRSET1:
|
||||
UnOp(reg1);
|
||||
PushAll(1);
|
||||
push(reg1);
|
||||
CallRTL(pic, CODE._set);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opINCL, CODE.opEXCL:
|
||||
BinOp(reg1, reg2);
|
||||
@@ -1548,7 +1540,7 @@ BEGIN
|
||||
|CODE.opDIV:
|
||||
PushAll(2);
|
||||
CallRTL(pic, CODE._div);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opDIVR:
|
||||
a := param2;
|
||||
@@ -1591,7 +1583,7 @@ BEGIN
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(pic, CODE._div);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
END
|
||||
END
|
||||
|
||||
@@ -1599,12 +1591,12 @@ BEGIN
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(pic, CODE._div2);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opMOD:
|
||||
PushAll(2);
|
||||
CallRTL(pic, CODE._mod);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opMODR:
|
||||
a := param2;
|
||||
@@ -1640,7 +1632,7 @@ BEGIN
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(pic, CODE._mod);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
END
|
||||
END
|
||||
|
||||
@@ -1648,7 +1640,7 @@ BEGIN
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(pic, CODE._mod2);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opERR:
|
||||
CallRTL(pic, CODE._error)
|
||||
@@ -1673,7 +1665,7 @@ BEGIN
|
||||
PushAll(4);
|
||||
pushc(param2);
|
||||
CallRTL(pic, CODE._arrcpy);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opCOPYS:
|
||||
PushAll(4);
|
||||
@@ -1703,61 +1695,29 @@ BEGIN
|
||||
PushAll(1);
|
||||
CallRTL(pic, CODE._dispose)
|
||||
|
||||
|CODE.opEQS, CODE.opNES, CODE.opLTS,
|
||||
CODE.opLES, CODE.opGTS, CODE.opGES:
|
||||
|CODE.opEQS .. CODE.opGES:
|
||||
PushAll(4);
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opEQS: pushc(0)
|
||||
|CODE.opNES: pushc(1)
|
||||
|CODE.opLTS: pushc(2)
|
||||
|CODE.opLES: pushc(3)
|
||||
|CODE.opGTS: pushc(4)
|
||||
|CODE.opGES: pushc(5)
|
||||
END;
|
||||
pushc(cmd.opcode - CODE.opEQS);
|
||||
CallRTL(pic, CODE._strcmp);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opEQS2, CODE.opNES2, CODE.opLTS2,
|
||||
CODE.opLES2, CODE.opGTS2, CODE.opGES2:
|
||||
|CODE.opEQS2 .. CODE.opGES2:
|
||||
PushAll(4);
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opEQS2: pushc(0)
|
||||
|CODE.opNES2: pushc(1)
|
||||
|CODE.opLTS2: pushc(2)
|
||||
|CODE.opLES2: pushc(3)
|
||||
|CODE.opGTS2: pushc(4)
|
||||
|CODE.opGES2: pushc(5)
|
||||
END;
|
||||
pushc(cmd.opcode - CODE.opEQS2);
|
||||
CallRTL(pic, CODE._strcmp2);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opEQSW, CODE.opNESW, CODE.opLTSW,
|
||||
CODE.opLESW, CODE.opGTSW, CODE.opGESW:
|
||||
|CODE.opEQSW .. CODE.opGESW:
|
||||
PushAll(4);
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opEQSW: pushc(0)
|
||||
|CODE.opNESW: pushc(1)
|
||||
|CODE.opLTSW: pushc(2)
|
||||
|CODE.opLESW: pushc(3)
|
||||
|CODE.opGTSW: pushc(4)
|
||||
|CODE.opGESW: pushc(5)
|
||||
END;
|
||||
pushc(cmd.opcode - CODE.opEQSW);
|
||||
CallRTL(pic, CODE._strcmpw);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opEQSW2, CODE.opNESW2, CODE.opLTSW2,
|
||||
CODE.opLESW2, CODE.opGTSW2, CODE.opGESW2:
|
||||
|CODE.opEQSW2 .. CODE.opGESW2:
|
||||
PushAll(4);
|
||||
CASE cmd.opcode OF
|
||||
|CODE.opEQSW2: pushc(0)
|
||||
|CODE.opNESW2: pushc(1)
|
||||
|CODE.opLTSW2: pushc(2)
|
||||
|CODE.opLESW2: pushc(3)
|
||||
|CODE.opGTSW2: pushc(4)
|
||||
|CODE.opGESW2: pushc(5)
|
||||
END;
|
||||
pushc(cmd.opcode - CODE.opEQSW2);
|
||||
CallRTL(pic, CODE._strcmpw2);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opEQP, CODE.opNEP, CODE.opEQIP, CODE.opNEIP:
|
||||
UnOp(reg1);
|
||||
@@ -1804,19 +1764,19 @@ BEGIN
|
||||
PushAll(2);
|
||||
pushc(param2);
|
||||
CallRTL(pic, CODE._isrec);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opIS:
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(pic, CODE._is);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opTYPEGR:
|
||||
PushAll(1);
|
||||
pushc(param2);
|
||||
CallRTL(pic, CODE._guardrec);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opTYPEGP:
|
||||
UnOp(reg1);
|
||||
@@ -1824,7 +1784,7 @@ BEGIN
|
||||
push(reg1);
|
||||
pushc(param2);
|
||||
CallRTL(pic, CODE._guard);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opTYPEGD:
|
||||
UnOp(reg1);
|
||||
@@ -1832,7 +1792,7 @@ BEGIN
|
||||
OutByte3(0FFH, 070H + reg1, 0FCH); // push dword[reg1 - 4]
|
||||
pushc(param2);
|
||||
CallRTL(pic, CODE._guardrec);
|
||||
ASSERT(REG.GetReg(R, eax))
|
||||
GetRegA
|
||||
|
||||
|CODE.opCASET:
|
||||
push(ecx);
|
||||
@@ -1952,7 +1912,7 @@ BEGIN
|
||||
OutByte3(083H, 0C4H, 004H) // add esp,4
|
||||
|
||||
|CODE.opEQF, CODE.opEQFI:
|
||||
ASSERT(REG.GetReg(R, eax));
|
||||
GetRegA;
|
||||
OutByte2(0DAH, 0E9H); // fucompp
|
||||
OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
|
||||
OutByte(09EH); // sahf
|
||||
@@ -1962,7 +1922,7 @@ BEGIN
|
||||
// L:
|
||||
|
||||
|CODE.opNEF, CODE.opNEFI:
|
||||
ASSERT(REG.GetReg(R, eax));
|
||||
GetRegA;
|
||||
OutByte2(0DAH, 0E9H); // fucompp
|
||||
OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
|
||||
OutByte(09EH); // sahf
|
||||
@@ -1972,7 +1932,7 @@ BEGIN
|
||||
// L:
|
||||
|
||||
|CODE.opLTF, CODE.opGTFI:
|
||||
ASSERT(REG.GetReg(R, eax));
|
||||
GetRegA;
|
||||
OutByte2(0DAH, 0E9H); // fucompp
|
||||
OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
|
||||
OutByte(09EH); // sahf
|
||||
@@ -1986,7 +1946,7 @@ BEGIN
|
||||
// L:
|
||||
|
||||
|CODE.opGTF, CODE.opLTFI:
|
||||
ASSERT(REG.GetReg(R, eax));
|
||||
GetRegA;
|
||||
OutByte2(0DAH, 0E9H); // fucompp
|
||||
OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
|
||||
OutByte(09EH); // sahf
|
||||
@@ -2000,7 +1960,7 @@ BEGIN
|
||||
// L:
|
||||
|
||||
|CODE.opLEF, CODE.opGEFI:
|
||||
ASSERT(REG.GetReg(R, eax));
|
||||
GetRegA;
|
||||
OutByte2(0DAH, 0E9H); // fucompp
|
||||
OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
|
||||
OutByte(09EH); // sahf
|
||||
@@ -2010,7 +1970,7 @@ BEGIN
|
||||
// L:
|
||||
|
||||
|CODE.opGEF, CODE.opLEFI:
|
||||
ASSERT(REG.GetReg(R, eax));
|
||||
GetRegA;
|
||||
OutByte2(0DAH, 0E9H); // fucompp
|
||||
OutByte3(09BH, 0DFH, 0E0H); // fstsw ax
|
||||
OutByte(09EH); // sahf
|
||||
@@ -2033,7 +1993,7 @@ BEGIN
|
||||
|CODE.opLADR_UNPK:
|
||||
n := param2 * 4;
|
||||
reg1 := REG.GetAnyReg(R);
|
||||
OutByte2(8DH, 45H + reg1 * 8 + 40H * ORD(~isByte(n))); // lea reg1, dword[ebp + n]
|
||||
OutByte2(8DH, 45H + reg1 * 8 + long(n)); // lea reg1, dword[ebp + n]
|
||||
OutIntByte(n);
|
||||
BinOp(reg1, reg2);
|
||||
OutByte2(0DDH, reg1); // fld qword[reg1]
|
||||
@@ -2056,7 +2016,7 @@ BEGIN
|
||||
|
||||
|CODE.opVADR_PARAM:
|
||||
n := param2 * 4;
|
||||
OutByte2(0FFH, 75H + 40H * ORD(~isByte(n))); // push dword[ebp + n]
|
||||
OutByte2(0FFH, 75H + long(n)); // push dword[ebp + n]
|
||||
OutIntByte(n)
|
||||
|
||||
|CODE.opCONST_PARAM:
|
||||
@@ -2075,7 +2035,7 @@ BEGIN
|
||||
|
||||
|CODE.opLLOAD32_PARAM:
|
||||
n := param2 * 4;
|
||||
OutByte2(0FFH, 75H + 40H * ORD(~isByte(n))); // push dword[ebp + n]
|
||||
OutByte2(0FFH, 75H + long(n)); // push dword[ebp + n]
|
||||
OutIntByte(n)
|
||||
|
||||
|CODE.opLOAD32_PARAM:
|
||||
@@ -2098,86 +2058,86 @@ BEGIN
|
||||
|
||||
|CODE.opLADR_SAVEC:
|
||||
n := param1 * 4;
|
||||
OutByte2(0C7H, 45H + 40H * ORD(~isByte(n))); // mov dword[ebp + n], param2
|
||||
OutByte2(0C7H, 45H + long(n)); // mov dword[ebp + n], param2
|
||||
OutIntByte(n);
|
||||
OutInt(param2)
|
||||
|
||||
|CODE.opLADR_SAVE:
|
||||
n := param2 * 4;
|
||||
UnOp(reg1);
|
||||
OutByte2(89H, 45H + reg1 * 8 + 40H * ORD(~isByte(n))); // mov dword[ebp + n], reg1
|
||||
OutByte2(89H, 45H + reg1 * 8 + long(n)); // mov dword[ebp + n], reg1
|
||||
OutIntByte(n);
|
||||
drop
|
||||
|
||||
|CODE.opLADR_INC1:
|
||||
n := param2 * 4;
|
||||
OutByte2(0FFH, 45H + 40H * ORD(~isByte(n))); // inc dword[ebp + n]
|
||||
OutByte2(0FFH, 45H + long(n)); // inc dword[ebp + n]
|
||||
OutIntByte(n)
|
||||
|
||||
|CODE.opLADR_DEC1:
|
||||
n := param2 * 4;
|
||||
OutByte2(0FFH, 4DH + 40H * ORD(~isByte(n))); // dec dword[ebp + n]
|
||||
OutByte2(0FFH, 4DH + long(n)); // dec dword[ebp + n]
|
||||
OutIntByte(n)
|
||||
|
||||
|CODE.opLADR_INCC:
|
||||
n := param1 * 4;
|
||||
OutByte2(81H + 2 * ORD(isByte(param2)), 45H + 40H * ORD(~isByte(n))); // add dword[ebp + n], param2
|
||||
OutByte2(81H + short(param2), 45H + long(n)); // add dword[ebp + n], param2
|
||||
OutIntByte(n);
|
||||
OutIntByte(param2)
|
||||
|
||||
|CODE.opLADR_DECC:
|
||||
n := param1 * 4;
|
||||
OutByte2(81H + 2 * ORD(isByte(param2)), 6DH + 40H * ORD(~isByte(n))); // sub dword[ebp + n], param2
|
||||
OutByte2(81H + short(param2), 6DH + long(n)); // sub dword[ebp + n], param2
|
||||
OutIntByte(n);
|
||||
OutIntByte(param2)
|
||||
|
||||
|CODE.opLADR_INC1B:
|
||||
n := param2 * 4;
|
||||
OutByte2(0FEH, 45H + 40H * ORD(~isByte(n))); // inc byte[ebp + n]
|
||||
OutByte2(0FEH, 45H + long(n)); // inc byte[ebp + n]
|
||||
OutIntByte(n)
|
||||
|
||||
|CODE.opLADR_DEC1B:
|
||||
n := param2 * 4;
|
||||
OutByte2(0FEH, 4DH + 40H * ORD(~isByte(n))); // dec byte[ebp + n]
|
||||
OutByte2(0FEH, 4DH + long(n)); // dec byte[ebp + n]
|
||||
OutIntByte(n)
|
||||
|
||||
|CODE.opLADR_INCCB:
|
||||
n := param1 * 4;
|
||||
OutByte2(80H, 45H + 40H * ORD(~isByte(n))); // add byte[ebp + n], param2
|
||||
OutByte2(80H, 45H + long(n)); // add byte[ebp + n], param2
|
||||
OutIntByte(n);
|
||||
OutByte(param2 MOD 256)
|
||||
|
||||
|CODE.opLADR_DECCB:
|
||||
n := param1 * 4;
|
||||
OutByte2(80H, 6DH + 40H * ORD(~isByte(n))); // sub byte[ebp + n], param2
|
||||
OutByte2(80H, 6DH + long(n)); // sub byte[ebp + n], param2
|
||||
OutIntByte(n);
|
||||
OutByte(param2 MOD 256)
|
||||
|
||||
|CODE.opLADR_INC:
|
||||
n := param2 * 4;
|
||||
UnOp(reg1);
|
||||
OutByte2(01H, 45H + 40H * ORD(~isByte(n)) + reg1 * 8); // add dword[ebp + n], reg1
|
||||
OutByte2(01H, 45H + long(n) + reg1 * 8); // add dword[ebp + n], reg1
|
||||
OutIntByte(n);
|
||||
drop
|
||||
|
||||
|CODE.opLADR_DEC:
|
||||
n := param2 * 4;
|
||||
UnOp(reg1);
|
||||
OutByte2(29H, 45H + 40H * ORD(~isByte(n)) + reg1 * 8); // sub dword[ebp + n], reg1
|
||||
OutByte2(29H, 45H + long(n) + reg1 * 8); // sub dword[ebp + n], reg1
|
||||
OutIntByte(n);
|
||||
drop
|
||||
|
||||
|CODE.opLADR_INCB:
|
||||
n := param2 * 4;
|
||||
UnOp(reg1);
|
||||
OutByte2(00H, 45H + 40H * ORD(~isByte(n)) + reg1 * 8); // add byte[ebp + n], reg1
|
||||
OutByte2(00H, 45H + long(n) + reg1 * 8); // add byte[ebp + n], reg1
|
||||
OutIntByte(n);
|
||||
drop
|
||||
|
||||
|CODE.opLADR_DECB:
|
||||
n := param2 * 4;
|
||||
UnOp(reg1);
|
||||
OutByte2(28H, 45H + 40H * ORD(~isByte(n)) + reg1 * 8); // sub byte[ebp + n], reg1
|
||||
OutByte2(28H, 45H + long(n) + reg1 * 8); // sub byte[ebp + n], reg1
|
||||
OutIntByte(n);
|
||||
drop
|
||||
|
||||
@@ -2187,16 +2147,14 @@ BEGIN
|
||||
cmprc(reg1, 32);
|
||||
label := NewLabel();
|
||||
jcc(jnb, label);
|
||||
OutByte2(0FH, 0ABH + 8 * ORD(cmd.opcode = CODE.opLADR_EXCL));
|
||||
OutByte(45H + 40H * ORD(~isByte(n)) + reg1 * 8); // bts(r) dword[ebp + n], reg1
|
||||
OutByte3(0FH, 0ABH + 8 * ORD(cmd.opcode = CODE.opLADR_EXCL), 45H + long(n) + reg1 * 8); // bts(r) dword[ebp + n], reg1
|
||||
OutIntByte(n);
|
||||
SetLabel(label);
|
||||
drop
|
||||
|
||||
|CODE.opLADR_INCLC, CODE.opLADR_EXCLC:
|
||||
n := param1 * 4;
|
||||
OutByte2(0FH, 0BAH);
|
||||
OutByte(6DH + 40H * ORD(~isByte(n)) + 8 * ORD(cmd.opcode = CODE.opLADR_EXCLC)); // bts(r) dword[ebp + n], param2
|
||||
OutByte3(0FH, 0BAH, 6DH + long(n) + 8 * ORD(cmd.opcode = CODE.opLADR_EXCLC)); // bts(r) dword[ebp + n], param2
|
||||
OutIntByte(n);
|
||||
OutByte(param2)
|
||||
|
||||
@@ -2241,7 +2199,7 @@ BEGIN
|
||||
push(reg1); // push CODE
|
||||
drop
|
||||
ELSE
|
||||
OutByte(068H); // push CODE
|
||||
OutByte(68H); // push CODE
|
||||
Reloc(BIN.RCODE, entry)
|
||||
END;
|
||||
|
||||
@@ -2251,10 +2209,10 @@ BEGIN
|
||||
push(reg1); // push IMPORT
|
||||
drop
|
||||
ELSIF target = mConst.Target_iObject THEN
|
||||
OutByte(068H); // push IMPORT
|
||||
OutByte(68H); // push IMPORT
|
||||
Reloc(BIN.IMPTAB, 0)
|
||||
ELSE
|
||||
OutByte2(6AH, 00H) // push 0
|
||||
pushc(0)
|
||||
END;
|
||||
|
||||
IF pic THEN
|
||||
@@ -2263,7 +2221,7 @@ BEGIN
|
||||
push(reg1); // push _data
|
||||
drop
|
||||
ELSE
|
||||
OutByte(068H); // push _data
|
||||
OutByte(68H); // push _data
|
||||
Reloc(BIN.RDATA, 0)
|
||||
END;
|
||||
|
||||
@@ -2278,7 +2236,7 @@ BEGIN
|
||||
push(reg1); // push _data + tcount * 4 + dcount
|
||||
drop
|
||||
ELSE
|
||||
OutByte(068H); // push _data
|
||||
OutByte(68H); // push _data
|
||||
Reloc(BIN.RDATA, tcount * 4 + dcount)
|
||||
END;
|
||||
|
||||
@@ -2325,7 +2283,7 @@ BEGIN
|
||||
SetLabel(dllret);
|
||||
movrc(eax, 1);
|
||||
OutByte(0C9H); // leave
|
||||
OutByte3(0C2H, 00CH, 000H) // ret 12
|
||||
OutByte3(0C2H, 0CH, 0) // ret 12
|
||||
ELSIF target = mConst.Target_iObject THEN
|
||||
movrc(eax, 1);
|
||||
OutByte(0C3H) // ret
|
||||
|
||||
Reference in new issue
Block a user