diff --git a/source/AMD64.ob07 b/source/AMD64.ob07 index e7311d7..f73cd04 100644 --- a/source/AMD64.ob07 +++ b/source/AMD64.ob07 @@ -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 diff --git a/source/CODE.ob07 b/source/CODE.ob07 index 6453c72..fdb2bdb 100644 --- a/source/CODE.ob07 +++ b/source/CODE.ob07 @@ -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 diff --git a/source/PE32.ob07 b/source/PE32.ob07 index 16f74ea..7b729fd 100644 --- a/source/PE32.ob07 +++ b/source/PE32.ob07 @@ -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) diff --git a/source/X86.ob07 b/source/X86.ob07 index 67257c9..2ecf203 100644 --- a/source/X86.ob07 +++ b/source/X86.ob07 @@ -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