diff --git a/programs/develop/oberon07/Compiler.kex b/programs/develop/oberon07/Compiler.kex index a378875ae2..c3149a0f5f 100644 Binary files a/programs/develop/oberon07/Compiler.kex and b/programs/develop/oberon07/Compiler.kex differ diff --git a/programs/develop/oberon07/Source/AMD64.ob07 b/programs/develop/oberon07/Source/AMD64.ob07 index 858880bef4..c1fa1f65c0 100644 --- a/programs/develop/oberon07/Source/AMD64.ob07 +++ b/programs/develop/oberon07/Source/AMD64.ob07 @@ -666,6 +666,7 @@ VAR reg: INTEGER; max: INTEGER; loop: INTEGER; + param2: INTEGER; BEGIN loop := 1; @@ -730,9 +731,36 @@ BEGIN |CODE.opCALL, CODE.opCALLP, CODE.opCALLI, CODE.opWIN64CALL, CODE.opWIN64CALLP, CODE.opWIN64CALLI, - CODE.opSYSVCALL, CODE.opSYSVCALLP, CODE.opSYSVCALLI: + CODE.opSYSVCALL, CODE.opSYSVCALLP, CODE.opSYSVCALLI, + + CODE.opSAVES, CODE.opRSET, CODE.opRSETR, + CODE.opRSETL, CODE.opRSET1, + CODE.opEQS .. CODE.opGES, + CODE.opEQS2 .. CODE.opGES2, + CODE.opEQSW .. CODE.opGESW, + CODE.opEQSW2 .. CODE.opGESW2, + CODE.opCOPY, CODE.opMOVE, CODE.opCOPYA, + CODE.opCOPYS, CODE.opCOPYS2, CODE.opROT, + CODE.opNEW, CODE.opDISP, CODE.opISREC, + CODE.opIS, CODE.opTYPEGR, CODE.opTYPEGP, + CODE.opCASET, CODE.opDIV, + CODE.opDIVL, CODE.opMOD, + CODE.opMODL, CODE.opLENGTH, CODE.opLENGTHW: leaf := FALSE + |CODE.opDIVR, CODE.opMODR: + param2 := cur.param2; + IF param2 >= 1 THEN + param2 := X86.log2(param2) + ELSIF param2 <= -1 THEN + param2 := X86.log2(-param2) + ELSE + param2 := -1 + END; + IF param2 < 0 THEN + leaf := FALSE + END + ELSE END; @@ -1425,6 +1453,14 @@ BEGIN ELSE ASSERT(R.top + 1 <= n); PushAll(n) + END + + |CODE.opACC: + IF (R.top # 0) OR (R.stk[0] # rax) THEN + PushAll(0); + GetRegA; + pop(rax); + DEC(R.pushed) END |CODE.opJNZ: diff --git a/programs/develop/oberon07/Source/CODE.ob07 b/programs/develop/oberon07/Source/CODE.ob07 index cd8465e342..e42b630338 100644 --- a/programs/develop/oberon07/Source/CODE.ob07 +++ b/programs/develop/oberon07/Source/CODE.ob07 @@ -89,6 +89,8 @@ CONST opALIGN16* = 236; opPOPSP* = 237; opWIN64CALL* = 238; opWIN64CALLI* = 239; opWIN64CALLP* = 240; opLOOP* = 241; opENDLOOP* = 242; opSYSVCALL* = 243; opSYSVCALLI* = 244; opSYSVCALLP* = 245; opSYSVALIGN16* = 246; opWIN64ALIGN16* = 247; + + opACC* = 248; opSADR_PARAM* = 1000; opLOAD64_PARAM* = 1001; opLLOAD64_PARAM* = 1002; opGLOAD64_PARAM* = 1003; diff --git a/programs/develop/oberon07/Source/STATEMENTS.ob07 b/programs/develop/oberon07/Source/STATEMENTS.ob07 index e279c8b53b..ef9886c11a 100644 --- a/programs/develop/oberon07/Source/STATEMENTS.ob07 +++ b/programs/develop/oberon07/Source/STATEMENTS.ob07 @@ -1860,7 +1860,8 @@ VAR IF e.obj = eCONST THEN CODE.AddCmd(CODE.opCONST, ORD(ARITH.getBool(e.value))) - END; + END; + CODE.AddCmd0(CODE.opACC); CODE.AddJmpCmd(CODE.opJZ, label); CODE.drop END @@ -1983,7 +1984,8 @@ VAR e.obj := eEXPR; IF e1.obj = eCONST THEN CODE.AddCmd(CODE.opCONST, ORD(ARITH.getBool(e1.value))) - END + END; + CODE.AddCmd0(CODE.opACC) END END @@ -2055,7 +2057,8 @@ VAR IF e.obj = eCONST THEN CODE.AddCmd(CODE.opCONST, ORD(ARITH.getBool(e.value))) - END; + END; + CODE.AddCmd0(CODE.opACC); CODE.AddJmpCmd(CODE.opJNZ, label); CODE.drop END @@ -2122,7 +2125,8 @@ VAR e.obj := eEXPR; IF e1.obj = eCONST THEN CODE.AddCmd(CODE.opCONST, ORD(ARITH.getBool(e1.value))) - END + END; + CODE.AddCmd0(CODE.opACC) END END diff --git a/programs/develop/oberon07/Source/STRINGS.ob07 b/programs/develop/oberon07/Source/STRINGS.ob07 index 3533c3d51f..b33e4bbcdf 100644 --- a/programs/develop/oberon07/Source/STRINGS.ob07 +++ b/programs/develop/oberon07/Source/STRINGS.ob07 @@ -1,7 +1,7 @@ (* BSD 2-Clause License - Copyright (c) 2018, Anton Krotov + Copyright (c) 2018, 2019, Anton Krotov All rights reserved. *) @@ -255,19 +255,19 @@ BEGIN |0C1X..0DFX: u := LSL(ORD(c) - 0C0H, 6); IF i + 1 < srclen THEN - u := u + ROR(LSL(ORD(src[i + 1]), 26), 26); - INC(i) + INC(i); + INC(u, ORD(BITS(ORD(src[i])) * {0..5})) END |0E1X..0EFX: u := LSL(ORD(c) - 0E0H, 12); - IF i + 1 < srclen THEN - u := u + ROR(LSL(ORD(src[i + 1]), 26), 20); - INC(i) + IF i + 1 < srclen THEN + INC(i); + INC(u, ORD(BITS(ORD(src[i])) * {0..5}) * 64) END; IF i + 1 < srclen THEN - u := u + ROR(LSL(ORD(src[i + 1]), 26), 26); - INC(i) + INC(i); + INC(u, ORD(BITS(ORD(src[i])) * {0..5})) END (* |0F1X..0F7X: diff --git a/programs/develop/oberon07/Source/X86.ob07 b/programs/develop/oberon07/Source/X86.ob07 index 88711d6488..6dee89a4fc 100644 --- a/programs/develop/oberon07/Source/X86.ob07 +++ b/programs/develop/oberon07/Source/X86.ob07 @@ -308,6 +308,12 @@ BEGIN END setcc; +PROCEDURE xor (reg1, reg2: INTEGER); +BEGIN + OutByte2(31H, 0C0H + reg2 * 8 + reg1) // xor reg1, reg2 +END xor; + + PROCEDURE drop; BEGIN REG.Drop(R) @@ -937,7 +943,7 @@ BEGIN ELSIF a = -1 THEN neg(reg1) ELSIF a = 0 THEN - OutByte2(31H, 0C0H + reg1 * 9) // xor reg1, reg1 + xor(reg1, reg1) ELSE IF n > 0 THEN IF a < 0 THEN @@ -1080,7 +1086,7 @@ BEGIN reg1 := REG.GetAnyReg(R); setcc(cc + 16, reg1); andrc(reg1, 1) - END; + END |CODE.opGT, CODE.opGE, CODE.opLT, CODE.opLE, CODE.opEQ, CODE.opNE: @@ -1128,6 +1134,14 @@ BEGIN setcc(setne, reg1) END; andrc(reg1, 1) + + |CODE.opACC: + IF (R.top # 0) OR (R.stk[0] # eax) THEN + PushAll(0); + GetRegA; + pop(eax); + DEC(R.pushed) + END |CODE.opDROP: UnOp(reg1); @@ -1344,7 +1358,7 @@ BEGIN |CODE.opDIVS: BinOp(reg1, reg2); - OutByte2(31H, 0C0H + reg2 * 8 + reg1); // xor reg1, reg2 + xor(reg1, reg2); drop |CODE.opDIVSC: @@ -1478,7 +1492,7 @@ BEGIN BinOp(reg1, reg2); cmprc(reg1, 32); OutByte2(72H, 4); // jb L - OutByte2(31H, 0C0H + reg1 * 9); // xor reg1, reg1 + xor(reg1, reg1); jmp(label); //L: OutByte3(0FH, 0A3H, 0C0H + reg2 + 8 * reg1); // bt reg2, reg1 @@ -1493,7 +1507,7 @@ BEGIN reg2 := REG.GetAnyReg(R); cmprc(reg1, 32); OutByte2(72H, 4); // jb L - OutByte2(31H, 0C0H + reg1 * 9); // xor reg1, reg1 + xor(reg1, reg1); jmp(label); //L: movrc(reg2, param2); @@ -1631,7 +1645,7 @@ BEGIN IF ABS(a) = 1 THEN UnOp(reg1); - OutByte2(31H, 0C0H + reg1 * 9) // xor reg1, reg1 + xor(reg1, reg1) ELSE IF n > 0 THEN UnOp(reg1); @@ -2226,8 +2240,8 @@ BEGIN push(esp) ELSE pushc(0) - END; - + END; + IF pic THEN reg1 := REG.GetAnyReg(R); Pic(reg1, BIN.PICCODE, entry);