diff --git a/programs/develop/oberon07/Compiler b/programs/develop/oberon07/Compiler index 6ffa7ec6cb..a865f8db08 100644 Binary files a/programs/develop/oberon07/Compiler and b/programs/develop/oberon07/Compiler differ diff --git a/programs/develop/oberon07/Compiler.exe b/programs/develop/oberon07/Compiler.exe index afb8854fc9..917767902d 100644 Binary files a/programs/develop/oberon07/Compiler.exe and b/programs/develop/oberon07/Compiler.exe differ diff --git a/programs/develop/oberon07/Compiler.kex b/programs/develop/oberon07/Compiler.kex index c2c4aba794..fb9f76c67b 100644 Binary files a/programs/develop/oberon07/Compiler.kex and b/programs/develop/oberon07/Compiler.kex differ diff --git a/programs/develop/oberon07/doc/x86.txt b/programs/develop/oberon07/doc/x86.txt index ee813fbf79..7f67425c45 100644 --- a/programs/develop/oberon07/doc/x86.txt +++ b/programs/develop/oberon07/doc/x86.txt @@ -208,7 +208,7 @@ UTF-8 с BOM-сигнатурой. При объявлении процедурных типов и глобальных процедур, после ключевого слова PROCEDURE может быть указан флаг соглашения о вызове: [stdcall], -[cdecl], [ccall], [windows], [linux], [oberon]. Например: +[cdecl], [fastcall], [ccall], [windows], [linux], [oberon]. Например: PROCEDURE [ccall] MyProc (x, y, z: INTEGER): INTEGER; diff --git a/programs/develop/oberon07/source/AMD64.ob07 b/programs/develop/oberon07/source/AMD64.ob07 index 09d171f778..5c0dfab521 100644 --- a/programs/develop/oberon07/source/AMD64.ob07 +++ b/programs/develop/oberon07/source/AMD64.ob07 @@ -1,7 +1,7 @@ (* BSD 2-Clause License - Copyright (c) 2018-2021, Anton Krotov + Copyright (c) 2018-2022, Anton Krotov All rights reserved. *) @@ -681,7 +681,7 @@ VAR opcode, param1, param2, param3, a, b, c, n, label, L, i, cc: INTEGER; - reg1, reg2, xmm: INTEGER; + reg1, reg2, reg3, xmm: INTEGER; float: REAL; @@ -1288,9 +1288,38 @@ BEGIN not(reg1) |IL.opCOPY: - PushAll(2); - pushc(param2); - CallRTL(IL._move) + IF (0 < param2) & (param2 <= 256) THEN + BinOp(reg1, reg2); + reg3 := GetAnyReg(); + FOR n := 0 TO param2 - param2 MOD 8 - 1 BY 8 DO + movrm(reg3, reg1, n); + movmr(reg2, n, reg3) + END; + n := param2 - param2 MOD 8; + IF param2 MOD 8 >= 4 THEN + movrm32(reg3, reg1, n); + movmr32(reg2, n, reg3); + INC(n, 4); + DEC(param2, 4) + END; + IF param2 MOD 8 >= 2 THEN + X86.movrm16(reg3, reg1, n); + X86.movmr16(reg2, n, reg3); + INC(n, 2); + DEC(param2, 2) + END; + IF param2 MOD 8 = 1 THEN + X86.movrm8(reg3, reg1, n); + X86.movmr8(reg2, n, reg3); + END; + drop; + drop; + drop + ELSE + PushAll(2); + pushc(param2); + CallRTL(IL._move) + END |IL.opMOVE: PushAll(3); diff --git a/programs/develop/oberon07/source/Compiler.ob07 b/programs/develop/oberon07/source/Compiler.ob07 index 277ac009d4..b849c52d20 100644 --- a/programs/develop/oberon07/source/Compiler.ob07 +++ b/programs/develop/oberon07/source/Compiler.ob07 @@ -1,7 +1,7 @@ (* BSD 2-Clause License - Copyright (c) 2018-2021, Anton Krotov + Copyright (c) 2018-2022, Anton Krotov All rights reserved. *) @@ -215,7 +215,7 @@ BEGIN C.Ln; C.String("Akron Oberon Compiler v"); C.Int(UTILS.vMajor); C.String("."); C.Int2(UTILS.vMinor); C.String(" ("); C.Int(UTILS.bit_depth); C.StringLn("-bit) " + UTILS.Date); - C.StringLn("Copyright (c) 2018-2021, Anton Krotov"); + C.StringLn("Copyright (c) 2018-2022, Anton Krotov"); IF inname = "" THEN C.Ln; diff --git a/programs/develop/oberon07/source/ERRORS.ob07 b/programs/develop/oberon07/source/ERRORS.ob07 index c9056bdb2b..ca95f1eb0a 100644 --- a/programs/develop/oberon07/source/ERRORS.ob07 +++ b/programs/develop/oberon07/source/ERRORS.ob07 @@ -1,7 +1,7 @@ (* BSD 2-Clause License - Copyright (c) 2018-2021, Anton Krotov + Copyright (c) 2018-2022, Anton Krotov All rights reserved. *) @@ -154,6 +154,7 @@ BEGIN |123: str := "illegal flag" |124: str := "unknown flag" |125: str := "flag not supported" + |126: str := "type of formal parameter should not be REAL" END; C.StringLn(str); C.String(" file: "); C.StringLn(fname); diff --git a/programs/develop/oberon07/source/IL.ob07 b/programs/develop/oberon07/source/IL.ob07 index 72430a489d..ba668813ed 100644 --- a/programs/develop/oberon07/source/IL.ob07 +++ b/programs/develop/oberon07/source/IL.ob07 @@ -1,7 +1,7 @@ (* BSD 2-Clause License - Copyright (c) 2018-2021, Anton Krotov + Copyright (c) 2018-2022, Anton Krotov All rights reserved. *) @@ -15,6 +15,8 @@ CONST call_stack* = 0; call_win64* = 1; call_sysv* = 2; + call_fast1* = 3; + call_fast2* = 4; begin_loop* = 1; end_loop* = 2; @@ -80,7 +82,7 @@ CONST opTYPEGD* = 207; opCALLI* = 208; opPUSHIP* = 209; opSAVEIP* = 210; opEQIP* = 211; opNEIP* = 212; opSAVE16C* = 213; opWCHR* = 214; opHANDLER* = 215; - opSYSVCALL* = 216; opSYSVCALLI* = 217; opSYSVCALLP* = 218; opFNAME* = 219; + opSYSVCALL* = 216; opSYSVCALLI* = 217; opSYSVCALLP* = 218; opFNAME* = 219; opFASTCALL* = 220; opSADR_PARAM* = -1; opLOAD64_PARAM* = -2; opLLOAD64_PARAM* = -3; opGLOAD64_PARAM* = -4; @@ -800,8 +802,21 @@ BEGIN END LeaveC; +PROCEDURE fastcall (VAR callconv: INTEGER); +BEGIN + IF callconv = call_fast1 THEN + AddCmd(opFASTCALL, 1); + callconv := call_stack + ELSIF callconv = call_fast2 THEN + AddCmd(opFASTCALL, 2); + callconv := call_stack + END +END fastcall; + + PROCEDURE Call* (proc, callconv, fparams: INTEGER); BEGIN + fastcall(callconv); CASE callconv OF |call_stack: Jmp(opCALL, proc) |call_win64: Jmp(opWIN64CALL, proc) @@ -813,6 +828,7 @@ END Call; PROCEDURE CallImp* (proc: LISTS.ITEM; callconv, fparams: INTEGER); BEGIN + fastcall(callconv); CASE callconv OF |call_stack: Jmp(opCALLI, proc(IMPORT_PROC).label) |call_win64: Jmp(opWIN64CALLI, proc(IMPORT_PROC).label) @@ -824,6 +840,7 @@ END CallImp; PROCEDURE CallP* (callconv, fparams: INTEGER); BEGIN + fastcall(callconv); CASE callconv OF |call_stack: AddCmd0(opCALLP) |call_win64: AddCmd(opWIN64CALLP, fparams) diff --git a/programs/develop/oberon07/source/PARS.ob07 b/programs/develop/oberon07/source/PARS.ob07 index fe9a0a31ea..17d1ab30e3 100644 --- a/programs/develop/oberon07/source/PARS.ob07 +++ b/programs/develop/oberon07/source/PARS.ob07 @@ -1,7 +1,7 @@ (* BSD 2-Clause License - Copyright (c) 2018-2021, Anton Krotov + Copyright (c) 2018-2022, Anton Krotov All rights reserved. *) @@ -445,6 +445,7 @@ VAR vPar: BOOLEAN; dim: INTEGER; t0, t1: PROG._TYPE; + pos: POSITION; BEGIN vPar := parser.sym = SCAN.lxVAR; @@ -462,6 +463,7 @@ VAR ExpectSym(parser, SCAN.lxIDENT) ELSIF parser.sym = SCAN.lxCOLON THEN Next(parser); + getpos(parser, pos); dim := 0; WHILE parser.sym = SCAN.lxARRAY DO INC(dim); @@ -482,7 +484,9 @@ VAR t0 := t1; DEC(dim) END; - + IF _type.call IN {PROG.fastcall, PROG._fastcall} THEN + check(t1.typ # PROG.tREAL, pos, 126) + END; PROG.setParams(_type, t1); Next(parser); exit := TRUE @@ -550,6 +554,8 @@ BEGIN sf := PROG.sf_code ELSIF parser.lex.ident.s = "oberon" THEN sf := PROG.sf_oberon + ELSIF parser.lex.ident.s = "fastcall" THEN + sf := PROG.sf_fastcall ELSIF parser.lex.ident.s = "noalign" THEN sf := PROG.sf_noalign ELSE @@ -583,6 +589,8 @@ BEGIN res := PROG.systemv |PROG.sf_code: res := PROG.code + |PROG.sf_fastcall: + res := PROG.fastcall |PROG.sf_oberon: IF TARGETS.OS IN {TARGETS.osWIN32, TARGETS.osLINUX32, TARGETS.osKOS} THEN res := PROG.default32 @@ -1106,6 +1114,8 @@ VAR enter := IL.Enter(label, -(LSL(ORD(fparams), 5) + proc._type.parSize)) ELSIF codeProc THEN + ELSIF call IN {PROG.fastcall, PROG._fastcall} THEN + enter := IL.Enter(label, proc._type.parSize) ELSE enter := IL.Enter(label, 0) END; diff --git a/programs/develop/oberon07/source/PROG.ob07 b/programs/develop/oberon07/source/PROG.ob07 index 925e4e48e3..5147c1a783 100644 --- a/programs/develop/oberon07/source/PROG.ob07 +++ b/programs/develop/oberon07/source/PROG.ob07 @@ -1,7 +1,7 @@ (* BSD 2-Clause License - Copyright (c) 2018-2021, Anton Krotov + Copyright (c) 2018-2022, Anton Krotov All rights reserved. *) @@ -51,17 +51,18 @@ CONST systemv* = 14; _systemv* = systemv + 1; default16* = 16; _default16* = default16 + 1; code* = 18; _code* = code + 1; + fastcall* = 20; _fastcall* = fastcall + 1; noalign* = 22; - callee_clean_up* = {default32, _default32, stdcall, _stdcall, default64, _default64}; + callee_clean_up* = {default32, _default32, stdcall, _stdcall, default64, _default64, fastcall, _fastcall}; sf_stdcall* = 0; sf_oberon* = 1; sf_cdecl* = 2; sf_ccall* = 3; sf_win64* = 4; sf_systemv* = 5; sf_windows* = 6; sf_linux* = 7; - sf_code* = 8; - sf_noalign* = 9; + sf_code* = 8; sf_fastcall* = 9; + sf_noalign* = 10; - proc_flags* = {sf_stdcall, sf_cdecl, sf_ccall, sf_win64, sf_systemv, sf_windows, sf_linux, sf_code, sf_oberon}; + proc_flags* = {sf_stdcall, sf_cdecl, sf_ccall, sf_win64, sf_systemv, sf_windows, sf_linux, sf_code, sf_oberon, sf_fastcall}; rec_flags* = {sf_noalign}; STACK_FRAME = 2; @@ -1219,9 +1220,9 @@ BEGIN program.options := options; CASE TARGETS.OS OF - |TARGETS.osWIN32: program.sysflags := {sf_oberon, sf_windows, sf_stdcall, sf_cdecl, sf_ccall, sf_noalign} - |TARGETS.osLINUX32: program.sysflags := {sf_oberon, sf_linux, sf_stdcall, sf_cdecl, sf_ccall, sf_noalign} - |TARGETS.osKOS: program.sysflags := {sf_oberon, sf_stdcall, sf_cdecl, sf_ccall, sf_noalign} + |TARGETS.osWIN32: program.sysflags := {sf_oberon, sf_windows, sf_stdcall, sf_cdecl, sf_ccall, sf_fastcall, sf_noalign} + |TARGETS.osLINUX32: program.sysflags := {sf_oberon, sf_linux, sf_stdcall, sf_cdecl, sf_ccall, sf_fastcall, sf_noalign} + |TARGETS.osKOS: program.sysflags := {sf_oberon, sf_stdcall, sf_cdecl, sf_ccall, sf_fastcall, sf_noalign} |TARGETS.osWIN64: program.sysflags := {sf_oberon, sf_windows, sf_win64, sf_systemv, sf_ccall, sf_noalign} |TARGETS.osLINUX64: program.sysflags := {sf_oberon, sf_linux, sf_win64, sf_systemv, sf_ccall, sf_noalign} |TARGETS.osNONE: program.sysflags := {sf_code} diff --git a/programs/develop/oberon07/source/STATEMENTS.ob07 b/programs/develop/oberon07/source/STATEMENTS.ob07 index cb6cfa4ffa..d3d940e281 100644 --- a/programs/develop/oberon07/source/STATEMENTS.ob07 +++ b/programs/develop/oberon07/source/STATEMENTS.ob07 @@ -1,7 +1,7 @@ (* BSD 2-Clause License - Copyright (c) 2018-2021, Anton Krotov + Copyright (c) 2018-2022, Anton Krotov All rights reserved. *) @@ -954,9 +954,10 @@ BEGIN PExpression(parser, e); PARS.check(isInt(e), pos, 66); IF e.obj = eCONST THEN - LoadConst(e) - END; - IL.AddCmd0(IL.opMOVE) + IL.AddCmd(IL.opCOPY, ARITH.Int(e.value)) + ELSE + IL.AddCmd0(IL.opMOVE) + END |PROG.sysCOPY: FOR i := 1 TO 2 DO @@ -974,9 +975,10 @@ BEGIN PExpression(parser, e); PARS.check(isInt(e), pos, 66); IF e.obj = eCONST THEN - LoadConst(e) - END; - IL.AddCmd0(IL.opMOVE) + IL.AddCmd(IL.opCOPY, ARITH.Int(e.value)) + ELSE + IL.AddCmd0(IL.opMOVE) + END |PROG.sysCODE: REPEAT @@ -1619,6 +1621,15 @@ BEGIN callconv := IL.call_sysv; fparSize := LSL(ORD(PROG.getFloatParamsPos(procType, PROG.MAXSYSVPARAM - 1, int, flt)), 5) + parSize; stk_par := MAX(0, int - 6) + MAX(0, flt - 8) + ELSIF cconv IN {PROG.fastcall, PROG._fastcall} THEN + IF parSize = 0 THEN + callconv := IL.call_stack + ELSIF parSize = 1 THEN + callconv := IL.call_fast1 + ELSIF parSize >= 2 THEN + callconv := IL.call_fast2 + END; + fparSize := 0 ELSE callconv := IL.call_stack; fparSize := 0 diff --git a/programs/develop/oberon07/source/UTILS.ob07 b/programs/develop/oberon07/source/UTILS.ob07 index b5f722d6ca..de0fd80a6b 100644 --- a/programs/develop/oberon07/source/UTILS.ob07 +++ b/programs/develop/oberon07/source/UTILS.ob07 @@ -1,7 +1,7 @@ (* BSD 2-Clause License - Copyright (c) 2018-2021, Anton Krotov + Copyright (c) 2018-2022, Anton Krotov All rights reserved. *) @@ -23,8 +23,8 @@ CONST max32* = 2147483647; vMajor* = 1; - vMinor* = 54; - Date* = "20-dec-2021"; + vMinor* = 56; + Date* = "21-jun-2022"; FILE_EXT* = ".ob07"; RTL_NAME* = "RTL"; diff --git a/programs/develop/oberon07/source/X86.ob07 b/programs/develop/oberon07/source/X86.ob07 index 7707771637..7212465645 100644 --- a/programs/develop/oberon07/source/X86.ob07 +++ b/programs/develop/oberon07/source/X86.ob07 @@ -1,7 +1,7 @@ (* BSD 2-Clause License - Copyright (c) 2018-2021, Anton Krotov + Copyright (c) 2018-2022, Anton Krotov All rights reserved. *) @@ -666,7 +666,7 @@ BEGIN END _movrm; -PROCEDURE movmr (reg1, offs, reg2: INTEGER); (* mov dword[reg1+offs], reg2_8 *) +PROCEDURE movmr (reg1, offs, reg2: INTEGER); (* mov dword[reg1+offs], reg2 *) BEGIN _movrm(reg2, reg1, offs, 32, TRUE) END movmr; @@ -730,7 +730,7 @@ PROCEDURE translate (pic: BOOLEAN; stroffs: INTEGER); VAR cmd, next: COMMAND; - reg1, reg2, fr: INTEGER; + reg1, reg2, reg3, fr: INTEGER; n, a, b, label, cc: INTEGER; @@ -775,6 +775,14 @@ BEGIN drop; ASSERT(R.top = -1) + |IL.opFASTCALL: + IF param2 = 1 THEN + pop(ecx) + ELSIF param2 = 2 THEN + pop(ecx); + pop(edx) + END + |IL.opPRECALL: PushAll(0); IF (param2 # 0) & (fr >= 0) THEN @@ -832,6 +840,15 @@ BEGIN SetLabel(param1); + IF cmd.param3 > 0 THEN + pop(eax); + IF cmd.param3 >= 2 THEN + push(edx) + END; + push(ecx); + push(eax) + END; + push(ebp); mov(ebp, esp); @@ -1708,9 +1725,32 @@ BEGIN L: *) |IL.opCOPY: - PushAll(2); - pushc(param2); - CallRTL(pic, IL._move) + IF (0 < param2) & (param2 <= 64) THEN + BinOp(reg1, reg2); + reg3 := GetAnyReg(); + FOR n := 0 TO param2 - param2 MOD 4 - 1 BY 4 DO + movrm(reg3, reg1, n); + movmr(reg2, n, reg3) + END; + n := param2 - param2 MOD 4; + IF param2 MOD 4 >= 2 THEN + movrm16(reg3, reg1, n); + movmr16(reg2, n, reg3); + INC(n, 2); + DEC(param2, 2) + END; + IF param2 MOD 4 = 1 THEN + movrm8(reg3, reg1, n); + movmr8(reg2, n, reg3); + END; + drop; + drop; + drop + ELSE + PushAll(2); + pushc(param2); + CallRTL(pic, IL._move) + END |IL.opMOVE: PushAll(3);