упрощение кода

This commit is contained in:
AntKrotov authored and GitHub committed 2019-02-08 01:27:15 +03:00
1 parent d886a25860
commit c05d034ee0
4 files changed
+366 -501

No files matched your search

+170 -241
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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