diff options
author | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2021-04-18 01:58:34 +0000 |
---|---|---|
committer | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2021-04-18 01:58:34 +0000 |
commit | 38b5e0606069cc5985e995e1da5b6855db67f507 (patch) | |
tree | 3396f758ef2cea5a0760aa73a6578a35c4fcac87 /compiler | |
parent | c99242579a36e85923993a66ac396d7bb3747221 (diff) | |
parent | 003a6cf3bbb6833d60fdf0df1ad4d75449951a8e (diff) | |
download | fpc-38b5e0606069cc5985e995e1da5b6855db67f507.tar.gz |
* synchronized with trunk
git-svn-id: https://svn.freepascal.org/svn/fpc/branches/unicodekvm@49224 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler')
74 files changed, 971 insertions, 247 deletions
diff --git a/compiler/Makefile b/compiler/Makefile index d04f0b1b1a..f19c59109b 100644 --- a/compiler/Makefile +++ b/compiler/Makefile @@ -2,7 +2,7 @@ # Don't edit, this file is generated by FPCMake Version 2.0.0 # default: all -MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-darwin aarch64-win64 aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc +MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc BSDs = freebsd netbsd openbsd darwin dragonfly UNIXs = linux $(BSDs) solaris qnx haiku aix LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari @@ -352,7 +352,7 @@ override PACKAGE_VERSION=3.3.1 unexport FPC_VERSION FPC_COMPILERINFO CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr jvm i8086 aarch64 sparc64 riscv32 riscv64 xtensa z80 wasm32 ALLTARGETS=$(CYCLETARGETS) -NO_NATIVE_COMPILER_OS_LIST=amstradcpc embedded freertos gba macosclassic msdos msxdos nds palmos symbian watcom wii win16 zxspectrum +NO_NATIVE_COMPILER_OS_LIST=amstradcpc embedded freertos gba macosclassic msdos msxdos nds palmos sinclairql symbian watcom wii win16 zxspectrum NO_NATIVE_COMPILER_CPU_LIST=avr i8086 jvm z80 wasm32 ifneq ($(CPU_SOURCE),$(CPU_TARGET)) ifneq ($(findstring $(CPU_TARGET),$(NO_NATIVE_COMPILER_CPU_LIST)),) @@ -910,6 +910,9 @@ endif ifeq ($(FULL_TARGET),aarch64-linux) override TARGET_DIRS+=utils endif +ifeq ($(FULL_TARGET),aarch64-freebsd) +override TARGET_DIRS+=utils +endif ifeq ($(FULL_TARGET),aarch64-darwin) override TARGET_DIRS+=utils endif @@ -1225,6 +1228,9 @@ endif ifeq ($(FULL_TARGET),aarch64-linux) override TARGET_PROGRAMS+=pp endif +ifeq ($(FULL_TARGET),aarch64-freebsd) +override TARGET_PROGRAMS+=pp +endif ifeq ($(FULL_TARGET),aarch64-darwin) override TARGET_PROGRAMS+=pp endif @@ -1541,6 +1547,9 @@ endif ifeq ($(FULL_TARGET),aarch64-linux) override COMPILER_INCLUDEDIR+=$(CPC_TARGET) endif +ifeq ($(FULL_TARGET),aarch64-freebsd) +override COMPILER_INCLUDEDIR+=$(CPC_TARGET) +endif ifeq ($(FULL_TARGET),aarch64-darwin) override COMPILER_INCLUDEDIR+=$(CPC_TARGET) endif @@ -1856,6 +1865,9 @@ endif ifeq ($(FULL_TARGET),aarch64-linux) override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR) endif +ifeq ($(FULL_TARGET),aarch64-freebsd) +override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR) +endif ifeq ($(FULL_TARGET),aarch64-darwin) override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR) endif @@ -2171,6 +2183,9 @@ endif ifeq ($(FULL_TARGET),aarch64-linux) override COMPILER_TARGETDIR+=$(CPU_UNITDIR)/bin/$(FULL_TARGET) endif +ifeq ($(FULL_TARGET),aarch64-freebsd) +override COMPILER_TARGETDIR+=$(CPU_UNITDIR)/bin/$(FULL_TARGET) +endif ifeq ($(FULL_TARGET),aarch64-darwin) override COMPILER_TARGETDIR+=$(CPU_UNITDIR)/bin/$(FULL_TARGET) endif @@ -2486,6 +2501,9 @@ endif ifeq ($(FULL_TARGET),aarch64-linux) override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET) endif +ifeq ($(FULL_TARGET),aarch64-freebsd) +override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET) +endif ifeq ($(FULL_TARGET),aarch64-darwin) override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET) endif @@ -3563,6 +3581,9 @@ endif ifeq ($(FULL_TARGET),aarch64-linux) REQUIRE_PACKAGES_RTL=1 endif +ifeq ($(FULL_TARGET),aarch64-freebsd) +REQUIRE_PACKAGES_RTL=1 +endif ifeq ($(FULL_TARGET),aarch64-darwin) REQUIRE_PACKAGES_RTL=1 endif @@ -3758,6 +3779,19 @@ override COMPILER_UNITTARGETDIR=$(COMPILER_TARGETDIR) override UNITTARGETDIRPREFIX=$(TARGETDIRPREFIX) endif endif +ifdef SYSROOTPATH +override FPCOPT+=-XR$(SYSROOTPATH) +else +ifeq ($(OS_TARGET),$(OS_SOURCE)) +ifneq ($(findstring $(OS_TARGET),darwin),) +ifneq ($(findstring $(CPU_TARGET),aarch64),) +ifneq ($(wildcard /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk),) +override FPCOPT+=-XR/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk +endif +endif +endif +endif +endif ifdef CREATESHARED override FPCOPT+=-Cg endif @@ -4533,6 +4567,9 @@ endif ifeq ($(FULL_TARGET),aarch64-linux) TARGET_DIRS_UTILS=1 endif +ifeq ($(FULL_TARGET),aarch64-freebsd) +TARGET_DIRS_UTILS=1 +endif ifeq ($(FULL_TARGET),aarch64-darwin) TARGET_DIRS_UTILS=1 endif diff --git a/compiler/Makefile.fpc b/compiler/Makefile.fpc index 2d88dc892d..7082b7d7e9 100644 --- a/compiler/Makefile.fpc +++ b/compiler/Makefile.fpc @@ -38,7 +38,7 @@ CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr ALLTARGETS=$(CYCLETARGETS) # All OS targets that do not support native compiler -NO_NATIVE_COMPILER_OS_LIST=amstradcpc embedded freertos gba macosclassic msdos msxdos nds palmos symbian watcom wii win16 zxspectrum +NO_NATIVE_COMPILER_OS_LIST=amstradcpc embedded freertos gba macosclassic msdos msxdos nds palmos sinclairql symbian watcom wii win16 zxspectrum # All CPU targets that do not support native compiler NO_NATIVE_COMPILER_CPU_LIST=avr i8086 jvm z80 wasm32 diff --git a/compiler/aarch64/a64att.inc b/compiler/aarch64/a64att.inc index 599cd2a372..96c1b8318c 100644 --- a/compiler/aarch64/a64att.inc +++ b/compiler/aarch64/a64att.inc @@ -397,5 +397,32 @@ 'lsr', 'ror', 'neg', -'ins' +'ins', +'ldclr', +'ldeor', +'ldset', +'ldsmax', +'ldsmin', +'ldumax', +'ldumin', +'stadd', +'stclr', +'steor', +'stset', +'stsmax', +'stsmin', +'stumax', +'stumin', +'swp', +'swpa', +'swpal', +'swpl', +'ldadd', +'ldadda', +'ldaddal', +'ldaddl', +'cas', +'casa', +'casal', +'casl' ); diff --git a/compiler/aarch64/a64atts.inc b/compiler/aarch64/a64atts.inc index 1b7f1f18ea..61e446cdaa 100644 --- a/compiler/aarch64/a64atts.inc +++ b/compiler/aarch64/a64atts.inc @@ -397,5 +397,32 @@ attsufNONE, attsufNONE, attsufNONE, attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, attsufNONE ); diff --git a/compiler/aarch64/a64ins.dat b/compiler/aarch64/a64ins.dat index 1e528be8b6..9d46a4ad9e 100644 --- a/compiler/aarch64/a64ins.dat +++ b/compiler/aarch64/a64ins.dat @@ -798,3 +798,60 @@ [INS] +; Large System Extensions + + +[LDCLR] + +[LDEOR] + +[LDSET] + +[LDSMAX] + +[LDSMIN] + +[LDUMAX] + +[LDUMIN] + +[STADD] + +[STCLR] + +[STEOR] + +[STSET] + +[STSMAX] + +[STSMIN] + +[STUMAX] + +[STUMIN] + +[SWP] + +[SWPA] + +[SWPAL] + +[SWPL] + +[LDADD] + +[LDADDA] + +[LDADDAL] + +[LDADDL] + +[CAS] + +[CASA] + +[CASAL] + +[CASL] + diff --git a/compiler/aarch64/a64op.inc b/compiler/aarch64/a64op.inc index 55cf0ed0a4..6b0ddbcf82 100644 --- a/compiler/aarch64/a64op.inc +++ b/compiler/aarch64/a64op.inc @@ -397,5 +397,32 @@ A_LSL, A_LSR, A_ROR, A_NEG, -A_INS +A_INS, +A_LDCLR, +A_LDEOR, +A_LDSET, +A_LDSMAX, +A_LDSMIN, +A_LDUMAX, +A_LDUMIN, +A_STADD, +A_STCLR, +A_STEOR, +A_STSET, +A_STSMAX, +A_STSMIN, +A_STUMAX, +A_STUMIN, +A_SWP, +A_SWPA, +A_SWPAL, +A_SWPL, +A_LDADD, +A_LDADDA, +A_LDADDAL, +A_LDADDL, +A_CAS, +A_CASA, +A_CASAL, +A_CASL ); diff --git a/compiler/aarch64/aasmcpu.pas b/compiler/aarch64/aasmcpu.pas index 49e66eb606..60726b3ffe 100644 --- a/compiler/aarch64/aasmcpu.pas +++ b/compiler/aarch64/aasmcpu.pas @@ -882,10 +882,27 @@ implementation else result:=sr_complex; end; + A_LDADD, + A_LDADDA, + A_LDADDAL, + A_LDADDL, + + A_SWP, + A_SWPA, + A_SWPAL, + A_SWPL, + + A_CAS, + A_CASA, + A_CASAL, + A_CASL, + + A_STADD, A_LDAR, A_LDAXR, A_LDXR, A_LDXP, + A_STLR, A_STLXR, A_STLXP, @@ -1044,6 +1061,13 @@ implementation { check for pre/post indexed in spilling_get_operation_type_ref } result:=operand_read; end; + A_MOVK: + begin + if opnr=0 then + result:=operand_readwrite + else + result:=operand_read; + end; {$ifdef EXTDEBUG} { play save to avoid hard to find bugs, better fail at compile time } A_ADD, @@ -1078,7 +1102,6 @@ implementation A_LSR, A_LSRV, A_MOV, - A_MOVK, A_MOVN, A_MOVZ, A_MSUB, diff --git a/compiler/aarch64/agcpugas.pas b/compiler/aarch64/agcpugas.pas index d6fd59ac76..2487fa1cb1 100644 --- a/compiler/aarch64/agcpugas.pas +++ b/compiler/aarch64/agcpugas.pas @@ -65,7 +65,14 @@ unit agcpugas; const cputype_to_gas_march : array[tcputype] of string = ( '', // cpu_none - 'armv8' + 'armv8', + 'armv8-a', + 'armv8.1-a', + 'armv8.2-a', + 'armv8.3-a', + 'armv8.4-a', + 'armv8.5-a', + 'armv8.6-a' ); implementation @@ -767,7 +774,7 @@ unit agcpugas; idtxt : 'AS'; asmbin : 'as'; asmcmd : '-o $OBJ $EXTRAOPT $ASM'; - supported_targets : [system_aarch64_linux,system_aarch64_android]; + supported_targets : [system_aarch64_freebsd,system_aarch64_linux,system_aarch64_android]; flags : [af_needar,af_smartlink_sections]; labelprefix : '.L'; labelmaxlen : -1; @@ -782,7 +789,7 @@ unit agcpugas; asmbin : 'clang'; asmcmd : '-x assembler -c -target $TRIPLET -o $OBJ $EXTRAOPT -x assembler $ASM'; supported_targets : [system_aarch64_ios,system_aarch64_darwin]; - flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_llvm]; + flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_llvm,af_supports_hlcfi]; labelprefix : 'L'; labelmaxlen : -1; comment : '# '; @@ -796,7 +803,7 @@ unit agcpugas; asmbin : 'clang'; asmcmd : '-x assembler -c -target $TRIPLET -o $OBJ $EXTRAOPT -x assembler $ASM'; supported_targets : [system_aarch64_win64]; - flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_llvm]; + flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_llvm,af_supports_hlcfi]; labelprefix : '.L'; labelmaxlen : -1; comment : '// '; diff --git a/compiler/aarch64/cgcpu.pas b/compiler/aarch64/cgcpu.pas index 9579181ddf..270fc53933 100644 --- a/compiler/aarch64/cgcpu.pas +++ b/compiler/aarch64/cgcpu.pas @@ -588,7 +588,7 @@ implementation leftover_a: word; begin {$ifdef extdebug} - list.concat(tai_comment.Create(strpnew('Generating constant ' + tostr(a)))); + list.concat(tai_comment.Create(strpnew('Generating constant ' + tostr(a) + ' / $' + hexstr(a, 16)))); {$endif extdebug} case a of { Small positive number } @@ -623,7 +623,7 @@ implementation Exit; end; - { This determines whether this write can be peformed with an ORR followed by MOVK + { This determines whether this write can be performed with an ORR followed by MOVK by copying the 2nd word to the 4th word for the ORR constant, then overwriting the 4th word (unless the word is. The alternative would require 3 instructions } leftover_a := word(a shr 48); @@ -644,14 +644,15 @@ implementation called for a and it returned False. Reduces processing time. [Kit] } if (manipulated_a <> a) and is_shifter_const(manipulated_a, size) then begin + { Encode value as: + orr reg,xzr,manipulated_a + movk reg,#(leftover_a),lsl #48 + } list.concat(taicpu.op_reg_reg_const(A_ORR, reg, makeregsize(NR_XZR, size), manipulated_a)); - if (leftover_a <> 0) then - begin - shifterop_reset(so); - so.shiftmode := SM_LSL; - so.shiftimm := 48; - list.concat(taicpu.op_reg_const_shifterop(A_MOVK, reg, leftover_a, so)); - end; + shifterop_reset(so); + so.shiftmode := SM_LSL; + so.shiftimm := 48; + list.concat(taicpu.op_reg_const_shifterop(A_MOVK, reg, leftover_a, so)); Exit; end; @@ -664,7 +665,7 @@ implementation stored as the first 16 bits followed by a shifter constant } case a of TCgInt($FFFF0000FFFF0000)..TCgInt($FFFF0000FFFFFFFF): - doinverted := False + doinverted := False; else begin doinverted := True; @@ -1335,8 +1336,13 @@ implementation OP_NEG, OP_NOT: begin - list.concat(taicpu.op_reg_reg(TOpCG2AsmOpReg[op],dst,src)); - maybeadjustresult(list,op,size,dst); + if (op=OP_NOT) and (size in [OS_8,OS_S8]) then + list.concat(taicpu.op_reg_reg_const(A_EOR,dst,src,255)) + else + begin + list.concat(taicpu.op_reg_reg(TOpCG2AsmOpReg[op],dst,src)); + maybeadjustresult(list,op,size,dst); + end; end else a_op_reg_reg_reg(list,op,size,src,dst,dst); diff --git a/compiler/aarch64/cpuinfo.pas b/compiler/aarch64/cpuinfo.pas index 87d0b22412..a6dd66f323 100644 --- a/compiler/aarch64/cpuinfo.pas +++ b/compiler/aarch64/cpuinfo.pas @@ -37,7 +37,14 @@ Type { possible supported processors for this target } tcputype = (cpu_none, - cpu_armv8 + cpu_armv8, + cpu_armv8a, + cpu_armv81a, + cpu_armv82a, + cpu_armv83a, + cpu_armv84a, + cpu_armv85a, + cpu_armv86a ); Type @@ -97,8 +104,15 @@ Const pocall_interrupt ]; - cputypestr : array[tcputype] of string[8] = ('', - 'ARMV8' + cputypestr : array[tcputype] of string[9] = ('', + 'ARMV8', + 'ARMV8-A', + 'ARMV8.1-A', + 'ARMV8.2-A', + 'ARMV8.3-A', + 'ARMV8.4-A', + 'ARMV8.5-A', + 'ARMV8.6-A' ); fputypestr : array[tfputype] of string[9] = ('', @@ -121,6 +135,33 @@ Const level3optimizerswitches = genericlevel3optimizerswitches + level2optimizerswitches + [{,cs_opt_loopunroll}]; level4optimizerswitches = genericlevel4optimizerswitches + level3optimizerswitches + []; +type + tcpuflags = + (CPUAARCH64_HAS_LSE { CPU supports Large System Extensions } + ); + + tfpuflags = + (CPUAARCH64_HAS_VFP { CPU supports VFP } + ); + +const + cpu_capabilities : array[tcputype] of set of tcpuflags = + ( { cpu_none } [], + { cpu_armv8 } [], + { cpu_armv8a } [], + { cpu_armv81a } [CPUAARCH64_HAS_LSE], + { cpu_armv82a } [CPUAARCH64_HAS_LSE], + { cpu_armv83a } [CPUAARCH64_HAS_LSE], + { cpu_armv84a } [CPUAARCH64_HAS_LSE], + { cpu_armv85a } [CPUAARCH64_HAS_LSE], + { cpu_armv86a } [CPUAARCH64_HAS_LSE] + ); + + fpu_capabilities : array[tfputype] of set of tfpuflags = + ( { fpu_none } [], + { fpu_vfp } [CPUAARCH64_HAS_VFP] + ); + Implementation end. diff --git a/compiler/aarch64/cputarg.pas b/compiler/aarch64/cputarg.pas index 06bd7547df..05af1c3e75 100644 --- a/compiler/aarch64/cputarg.pas +++ b/compiler/aarch64/cputarg.pas @@ -35,6 +35,9 @@ implementation Targets **************************************} + {$ifndef NOTARGETBSD} + ,t_bsd + {$endif} {$ifndef NOTARGETLINUX} ,t_linux {$endif} diff --git a/compiler/aarch64/rgcpu.pas b/compiler/aarch64/rgcpu.pas index 268c0913fa..875cc04ee9 100644 --- a/compiler/aarch64/rgcpu.pas +++ b/compiler/aarch64/rgcpu.pas @@ -1,7 +1,7 @@ { Copyright (c) 1998-2002 by Florian Klaempfl - This unit implements the SPARC specific class for the register + This unit implements the AArch64 specific class for the register allocator This program is free software; you can redistribute it and/or modify @@ -87,8 +87,8 @@ implementation begin helplist:=TAsmList.create; - if getregtype(tempreg)=R_INTREGISTER then - hreg:=tempreg + if (getregtype(tempreg)=R_INTREGISTER) then + hreg:=getregisterinline(helplist,[R_SUBWHOLE]) else hreg:=cg.getaddressregister(helplist); @@ -100,6 +100,8 @@ implementation else helpins:=spilling_create_store(tempreg,tmpref); helplist.concat(helpins); + if (getregtype(tempreg)=R_INTREGISTER) then + ungetregisterinline(helplist,hreg); add_cpu_interferences(helpins); list.insertlistafter(pos,helplist); helplist.free; diff --git a/compiler/aopt.pas b/compiler/aopt.pas index ca766e609f..425970cdc8 100644 --- a/compiler/aopt.pas +++ b/compiler/aopt.pas @@ -219,8 +219,9 @@ Unit aopt; p := hp1; End { merge allocations/deallocations } - else if assigned(findregalloc(tai_regalloc(p).reg, tai(p.next))) - and getnextinstruction(p,hp1) and + else if assigned(findregalloc(tai_regalloc(p).reg, tai(p.next))) and + getnextinstruction(p,hp1) and + (not(RegLoadedWithNewValue(tai_regalloc(p).Reg, hp1)) or InstructionLoadsFromReg(tai_regalloc(p).Reg, hp1)) and { don't merge deallocations/allocation which mark a new use of register, this enables more possibilities for the peephole optimizer } not(tai_regalloc(p).keep) then diff --git a/compiler/arm/aasmcpu.pas b/compiler/arm/aasmcpu.pas index 1bcc492c69..443681430a 100644 --- a/compiler/arm/aasmcpu.pas +++ b/compiler/arm/aasmcpu.pas @@ -166,14 +166,14 @@ uses IF_ARMv7M = $00F00000; IF_ARMv7EM = $01000000; - IF_FPMASK = $F0000000; - IF_FPA = $10000000; - IF_VFPv2 = $20000000; - IF_VFPv3 = $40000000; - IF_VFPv4 = $80000000; + IF_FPMASK = $00000F00; + IF_FPA = $00000100; + IF_VFPv2 = $00000200; + IF_VFPv3 = $00000400; + IF_VFPv4 = $00000800; { if the instruction can change in a second pass } - IF_PASS2 = longint($80000000); + IF_PASS2 = $80000000; type TInsTabCache=array[TasmOp] of longint; @@ -278,7 +278,7 @@ uses private { arm version info } fArmVMask, - fArmMask : longint; + fArmMask : longword; { next fields are filled in pass1, so pass2 is faster } inssize : shortint; insoffset : longint; diff --git a/compiler/arm/agarmgas.pas b/compiler/arm/agarmgas.pas index 182ff8a5de..29df8b7ca5 100644 --- a/compiler/arm/agarmgas.pas +++ b/compiler/arm/agarmgas.pas @@ -484,7 +484,7 @@ unit agarmgas; asmbin : 'clang'; asmcmd : '-x assembler -c -target $TRIPLET -o $OBJ $EXTRAOPT -x assembler $ASM'; supported_targets : [system_arm_ios]; - flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_llvm]; + flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_llvm,af_supports_hlcfi]; labelprefix : 'L'; labelmaxlen : -1; comment : '# '; diff --git a/compiler/arm/cgcpu.pas b/compiler/arm/cgcpu.pas index 082ebf7985..7235bd17ce 100644 --- a/compiler/arm/cgcpu.pas +++ b/compiler/arm/cgcpu.pas @@ -787,10 +787,11 @@ unit cgcpu; shifterop : tshifterop; bitsset : byte; negative : boolean; - first : boolean; + first, doshiftadd: boolean; b, cycles : byte; maxeffort : byte; + leftmostbit,i,shiftvalue: DWord; begin result:=true; cycles:=0; @@ -800,7 +801,6 @@ unit cgcpu; if negative then inc(cycles); multiplier:=dword(abs(a)); - bitsset:=popcnt(multiplier and $fffffffe); { heuristics to estimate how much instructions are reasonable to replace the mul, this is currently based on XScale timings } @@ -824,6 +824,30 @@ unit cgcpu; if ((dword(a) and $ffff8000)=0) or ((dword(a) and $ffff8000)=$ffff8000) then dec(maxeffort); + { "symmetric" bit pattern like $10101010 where + res:=a*$10101010 can be simplified into + + temp:=a*$1010 + res:=temp+temp shl 16 + } + doshiftadd:=false; + leftmostbit:=BsrDWord(multiplier); + shiftvalue:=0; + if (maxeffort>1) and (leftmostbit>2) then + begin + for i:=2 to 31 do + if (multiplier shr i)=(multiplier and ($ffffffff shr (32-i))) then + begin + doshiftadd:=true; + shiftvalue:=i; + dec(maxeffort); + multiplier:=multiplier shr shiftvalue; + break; + end; + end; + + bitsset:=popcnt(multiplier and $fffffffe); + { most simple cases } if a=1 then a_load_reg_reg(list,OS_32,OS_32,src,dst) @@ -857,6 +881,11 @@ unit cgcpu; first:=false; dec(multiplier,1 shl shifterop.shiftimm); end; + if doshiftadd then + begin + shifterop.shiftimm:=shiftvalue; + list.concat(taicpu.op_reg_reg_reg_shifterop(A_ADD,dst,dst,dst,shifterop)); + end; if negative then list.concat(taicpu.op_reg_reg_const(A_RSB,dst,dst,0)); end @@ -889,6 +918,11 @@ unit cgcpu; end; first:=false; end; + if doshiftadd then + begin + shifterop.shiftimm:=shiftvalue; + list.concat(taicpu.op_reg_reg_reg_shifterop(A_ADD,dst,dst,dst,shifterop)); + end; if negative then list.concat(taicpu.op_reg_reg_const(A_RSB,dst,dst,0)); end diff --git a/compiler/avr/aoptcpu.pas b/compiler/avr/aoptcpu.pas index 3a99b9864b..7d55ca8763 100644 --- a/compiler/avr/aoptcpu.pas +++ b/compiler/avr/aoptcpu.pas @@ -179,7 +179,7 @@ Implementation exit; end; p := taicpu(hp); - Result := ((p.opcode in [A_LDI,A_MOV,A_LDS]) and (reg=p.oper[0]^.reg) and ((p.oper[1]^.typ<>top_reg) or (reg<>p.oper[0]^.reg))) or + Result := ((p.opcode in [A_LDI,A_MOV,A_LDS]) and (reg=p.oper[0]^.reg) and ((p.oper[1]^.typ<>top_reg) or (reg<>p.oper[1]^.reg))) or ((p.opcode in [A_LD,A_LDD,A_LPM]) and (reg=p.oper[0]^.reg) and not(RegInRef(reg,p.oper[1]^.ref^))) or ((p.opcode in [A_MOVW]) and ((reg=p.oper[0]^.reg) or (TRegister(ord(reg)+1)=p.oper[0]^.reg)) and not(reg=p.oper[1]^.reg) and not(TRegister(ord(reg)+1)=p.oper[1]^.reg)) or ((p.opcode in [A_POP]) and (reg=p.oper[0]^.reg)); diff --git a/compiler/cclasses.pas b/compiler/cclasses.pas index 345549fe45..b1c9e8091a 100644 --- a/compiler/cclasses.pas +++ b/compiler/cclasses.pas @@ -23,9 +23,7 @@ unit cclasses; {$i fpcdefs.inc} -{$ifndef VER2_0} - {$define CCLASSESINLINE} -{$endif} +{$define CCLASSESINLINE} interface @@ -88,14 +86,14 @@ type procedure Put(Index: Integer; Item: Pointer); procedure SetCapacity(NewCapacity: Integer); procedure SetCount(NewCount: Integer); - Procedure RaiseIndexError(Index : Integer);{$ifndef VER2_6}noreturn;{$endif VER2_6} + Procedure RaiseIndexError(Index : Integer);noreturn; property List: PPointerList read FList; public destructor Destroy; override; function Add(Item: Pointer): Integer; procedure Clear; procedure Delete(Index: Integer); - class procedure Error(const Msg: string; Data: PtrInt);{$ifndef VER2_6}noreturn;{$endif VER2_6} + class procedure Error(const Msg: string; Data: PtrInt);noreturn; procedure Exchange(Index1, Index2: Integer); function Expand: TFPList; function Extract(item: Pointer): Pointer; @@ -227,7 +225,7 @@ type function HashOfIndex(Index: Integer): LongWord; function GetNextCollision(Index: Integer): Integer; procedure Delete(Index: Integer); - class procedure Error(const Msg: string; Data: PtrInt);{$ifndef VER2_6}noreturn;{$endif VER2_6} + class procedure Error(const Msg: string; Data: PtrInt);noreturn; function Expand: TFPHashList; function Extract(item: Pointer): Pointer; function IndexOf(Item: Pointer): Integer; @@ -718,7 +716,7 @@ implementation TFPObjectList (Copied from rtl/objpas/classes/lists.inc) *****************************************************************************} -procedure TFPList.RaiseIndexError(Index : Integer);{$ifndef VER2_6}noreturn;{$endif VER2_6} +procedure TFPList.RaiseIndexError(Index : Integer);noreturn; begin Error(SListIndexError, Index); end; @@ -814,7 +812,7 @@ begin end; end; -class procedure TFPList.Error(const Msg: string; Data: PtrInt);{$ifndef VER2_6}noreturn;{$endif VER2_6} +class procedure TFPList.Error(const Msg: string; Data: PtrInt);noreturn; begin Raise EListError.CreateFmt(Msg,[Data]) at get_caller_addr(get_frame), get_caller_frame(get_frame); end; @@ -1541,7 +1539,7 @@ begin Self.Delete(Result); end; -class procedure TFPHashList.Error(const Msg: string; Data: PtrInt);{$ifndef VER2_6}noreturn;{$endif VER2_6} +class procedure TFPHashList.Error(const Msg: string; Data: PtrInt);noreturn; begin Raise EListError.CreateFmt(Msg,[Data]) at get_caller_addr(get_frame), get_caller_frame(get_frame); end; diff --git a/compiler/cfidwarf.pas b/compiler/cfidwarf.pas index fd5ff4c4dd..cfb7e07fa3 100644 --- a/compiler/cfidwarf.pas +++ b/compiler/cfidwarf.pas @@ -670,6 +670,8 @@ implementation inherited; exit; end; + if not(af_supports_hlcfi in target_asm.flags) then + exit; list.concat(tai_cfi_op_none.create(cfi_startproc)); end; @@ -681,6 +683,8 @@ implementation inherited; exit; end; + if not(af_supports_hlcfi in target_asm.flags) then + exit; list.concat(tai_cfi_op_none.create(cfi_endproc)); end; @@ -692,6 +696,8 @@ implementation inherited; exit; end; + if not(af_supports_hlcfi in target_asm.flags) then + exit; list.concat(tai_cfi_op_reg.create(cfi_undefined,NR_RETURN_ADDRESS_REG)); end; @@ -703,6 +709,8 @@ implementation inherited; exit; end; + if not(af_supports_hlcfi in target_asm.flags) then + exit; list.concat(tai_cfi_op_reg_val.create(cfi_offset,reg,ofs)); end; @@ -714,6 +722,8 @@ implementation inherited; exit; end; + if not(af_supports_hlcfi in target_asm.flags) then + exit; list.concat(tai_cfi_op_reg.create(cfi_restore,reg)); end; @@ -725,6 +735,8 @@ implementation inherited; exit; end; + if not(af_supports_hlcfi in target_asm.flags) then + exit; list.concat(tai_cfi_op_reg.create(cfi_def_cfa_register,reg)); end; @@ -736,6 +748,8 @@ implementation inherited; exit; end; + if not(af_supports_hlcfi in target_asm.flags) then + exit; list.concat(tai_cfi_op_val.create(cfi_def_cfa_offset,ofs)); end; diff --git a/compiler/comptty.pas b/compiler/comptty.pas index 7df5dc991a..a444cca61a 100644 --- a/compiler/comptty.pas +++ b/compiler/comptty.pas @@ -30,19 +30,19 @@ function IsATTY(var t : text) : Boolean; const (* This allows compile-time removal of the colouring functionality under not supported platforms *) -{$if defined(linux) or defined(MSWINDOWS) or defined(OS2) or defined(GO32V2) or defined(WATCOM)} +{$if defined(linux) or defined(MSWINDOWS) or defined(OS2) or defined(GO32V2) or defined(WATCOM) or defined(DARWIN)} TTYCheckSupported = true; -{$else defined(linux) or defined(MSWINDOWS) or defined(OS2) or defined(GO32V2) or defined(WATCOM)} +{$else defined(linux) or defined(MSWINDOWS) or defined(OS2) or defined(GO32V2) or defined(WATCOM) or defined(DARWIN)} TTYCheckSupported = false; -{$endif defined(linux) or defined(MSWINDOWS) or defined(OS2) or defined(GO32V2) or defined(WATCOM)} +{$endif defined(linux) or defined(MSWINDOWS) or defined(OS2) or defined(GO32V2) or defined(WATCOM) or defined(DARWIN)} implementation -{$ifdef linux} +{$if defined(linux) or defined(darwin)} uses termio; -{$endif linux} +{$endif defined(linux) or defined(darwin)} {$ifdef mswindows} uses windows; @@ -60,12 +60,12 @@ const CachedIsATTY : Boolean = false; IsATTYValue : Boolean = false; -{$ifdef linux} +{$if defined(linux) or defined(darwin)} function LinuxIsATTY(var t : text) : Boolean; inline; begin LinuxIsATTY:=termio.IsATTY(t)=1; end; -{$endif linux} +{$endif defined(linux) or defined(darwin)} {$ifdef MSWINDOWS} const @@ -152,9 +152,9 @@ begin if not(CachedIsATTY) then begin (* If none of the supported values is defined, false is returned by default. *) -{$ifdef linux} +{$if defined(linux) or defined(darwin)} IsATTYValue:=LinuxIsATTY(t); -{$endif linux} +{$endif defined(linux) or defined(darwin)} {$ifdef MSWINDOWS} IsATTYValue:=WindowsIsATTY(t); {$endif MSWINDOWS} diff --git a/compiler/constexp.pas b/compiler/constexp.pas index e1a0f6a11e..502d540c31 100644 --- a/compiler/constexp.pas +++ b/compiler/constexp.pas @@ -90,7 +90,7 @@ implementation { use a separate procedure here instead of calling internalerrorproc directly because - procedure variables cannot have a noreturn directive - having a procedure and a procedure variable with the same name in the interfaces of different units is confusing } -procedure internalerror(i:longint);{$ifndef VER2_6}noreturn;{$endif VER2_6} +procedure internalerror(i:longint);noreturn; begin internalerrorproc(i); @@ -196,10 +196,6 @@ try_qword: result.overflow:=true; end; -{ workaround for 2.6.x bug } -{$ifdef VER2_6} - {$push} {$Q-} -{$endif VER2_6} function sub_from(const a:Tconstexprint;b:qword):Tconstexprint; const abs_low_int64=qword(9223372036854775808); {abs(low(int64)) -> overflow error} @@ -244,10 +240,6 @@ try_qword: ov: result.overflow:=true; end; -{ workaround for 2.6.x bug } -{$ifdef VER2_6} - {$pop} -{$endif VER2_6} operator + (const a,b:Tconstexprint):Tconstexprint; diff --git a/compiler/cscript.pas b/compiler/cscript.pas index 0ecb4eff7d..121e0deb07 100644 --- a/compiler/cscript.pas +++ b/compiler/cscript.pas @@ -91,6 +91,7 @@ type TLinkRes = Class (TScript) section: string[30]; fRealResponseFile: Boolean; + fForceUseForwardSlash: Boolean; constructor Create(const ScriptName : TCmdStr; RealResponseFile: Boolean); procedure Add(const s:TCmdStr); procedure AddFileName(const s:TCmdStr); @@ -497,6 +498,7 @@ constructor TLinkRes.Create(const ScriptName: TCmdStr; RealResponseFile: Boolean begin inherited Create(ScriptName); fRealResponseFile:=RealResponseFile; + fForceUseForwardSlash:=false; end; procedure TLinkRes.Add(const s:TCmdStr); @@ -506,6 +508,9 @@ begin end; procedure TLinkRes.AddFileName(const s:TCmdStr); +var + ls: TCmdStr; + i: longint; begin if section<>'' then begin @@ -514,23 +519,31 @@ begin end; if s<>'' then begin + ls:=s; + if fForceUseForwardSlash then + { Fix separator } + for i:=1 to length(ls) do + if (ls[i]=source_info.dirsep) then + ls[i]:='/'; { GNU ld only supports double quotes in the response file. } if fRealResponseFile and - (s[1]='''') and + (ls[1]='''') and (((cs_link_on_target in current_settings.globalswitches) and (target_info.script=script_unix)) or (not(cs_link_on_target in current_settings.globalswitches) and (source_info.script=script_unix))) then inherited add(UnixRequoteWithDoubleQuotes(s)) - else if not(s[1] in ['a'..'z','A'..'Z','/','\','.','"']) then + else if not(ls[1] in ['a'..'z','A'..'Z','/','\','.','"']) then begin - if cs_link_on_target in current_settings.globalswitches then - inherited Add('.'+target_info.DirSep+s) + if fForceUseForwardSlash then + inherited Add('./'+ls) + else if (cs_link_on_target in current_settings.globalswitches) then + inherited Add('.'+target_info.DirSep+ls) else - inherited Add('.'+source_info.DirSep+s); + inherited Add('.'+source_info.DirSep+ls); end else - inherited Add(s); + inherited Add(ls); end; end; diff --git a/compiler/cutils.pas b/compiler/cutils.pas index d75b3cd486..1e9b077548 100644 --- a/compiler/cutils.pas +++ b/compiler/cutils.pas @@ -117,12 +117,6 @@ interface } function isabspowerof2(const value : Tconstexprint;out power : longint) : boolean; function nextpowerof2(value : int64; out power: longint) : int64; -{$ifdef VER2_6} { only 2.7.1+ has a popcnt function in the system unit } - function PopCnt(AValue : Byte): Byte; - function PopCnt(AValue : Word): Word; - function PopCnt(AValue : DWord): DWord; - function PopCnt(Const AValue : QWord): QWord; -{$endif VER2_6} function backspace_quote(const s:string;const qchars:Tcharset):string; function octal_quote(const s:string;const qchars:Tcharset):string; @@ -1015,48 +1009,6 @@ implementation end; end; -{$ifdef VER2_6} - const - PopCntData : array[0..15] of byte = (0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4); - - function PopCnt(AValue : Byte): Byte; - begin - Result:=PopCntData[AValue and $f]+PopCntData[(AValue shr 4) and $f]; - end; - - - function PopCnt(AValue : Word): Word; - var - i : SizeInt; - begin - Result:=0; - for i:=0 to 3 do - begin - inc(Result,PopCntData[AValue and $f]); - AValue:=AValue shr 4; - end; - end; - - - function PopCnt(AValue : DWord): DWord; - var - i : SizeInt; - begin - Result:=0; - for i:=0 to 7 do - begin - inc(Result,PopCntData[AValue and $f]); - AValue:=AValue shr 4; - end; - end; - - - function PopCnt(Const AValue : QWord): QWord; - begin - Result:=PopCnt(lo(AValue))+PopCnt(hi(AValue)) - end; - {$endif VER2_6} - function backspace_quote(const s:string;const qchars:Tcharset):string; diff --git a/compiler/fpcdefs.inc b/compiler/fpcdefs.inc index 7a577c082a..0bfcce1fa0 100644 --- a/compiler/fpcdefs.inc +++ b/compiler/fpcdefs.inc @@ -313,6 +313,8 @@ {$define cpurefshaveindexreg} {$define SUPPORT_GET_FRAME} {$define SUPPORT_SAFECALL} + {$define cpucapabilities} + {$define fpucapabilities} {$endif aarch64} {$ifdef riscv32} diff --git a/compiler/i386/i386prop.inc b/compiler/i386/i386prop.inc index 1ab49ea6bc..5f178968a6 100644 --- a/compiler/i386/i386prop.inc +++ b/compiler/i386/i386prop.inc @@ -223,7 +223,7 @@ (Ch: [Ch_All]), (Ch: [Ch_Mop2, Ch_Rop1]), (Ch: [Ch_Mop2, Ch_Rop1]), -(Ch: [Ch_All]), +(Ch: [Ch_Mop2, Ch_Rop1]), (Ch: [Ch_All]), (Ch: [Ch_All]), (Ch: [Ch_All]), @@ -269,9 +269,9 @@ (Ch: [Ch_RWESP, Ch_WFlags]), (Ch: [Ch_RWESP, Ch_WFlags]), (Ch: [Ch_RWESP, Ch_WFLAGS]), -(Ch: [Ch_All]), -(Ch: [Ch_All]), -(Ch: [Ch_All]), +(Ch: [Ch_Mop2, Ch_Rop1]), +(Ch: [Ch_Rop1]), +(Ch: [Ch_Rop1]), (Ch: [Ch_All]), (Ch: [Ch_All]), (Ch: [Ch_All]), @@ -463,10 +463,10 @@ (Ch: [Ch_Mop2, Ch_Rop1]), (Ch: [Ch_All]), (Ch: [Ch_All]), -(Ch: [Ch_All]), -(Ch: [Ch_All]), -(Ch: [Ch_All]), -(Ch: [Ch_All]), +(Ch: [Ch_Rop1]), +(Ch: [Ch_Rop1]), +(Ch: [Ch_Rop1]), +(Ch: [Ch_Rop1]), (Ch: [Ch_All]), (Ch: [Ch_All]), (Ch: [Ch_All]), diff --git a/compiler/i8086/i8086prop.inc b/compiler/i8086/i8086prop.inc index ece412229d..510b4c6d0f 100644 --- a/compiler/i8086/i8086prop.inc +++ b/compiler/i8086/i8086prop.inc @@ -223,7 +223,7 @@ (Ch: [Ch_All]), (Ch: [Ch_Mop2, Ch_Rop1]), (Ch: [Ch_Mop2, Ch_Rop1]), -(Ch: [Ch_All]), +(Ch: [Ch_Mop2, Ch_Rop1]), (Ch: [Ch_All]), (Ch: [Ch_All]), (Ch: [Ch_All]), @@ -269,9 +269,9 @@ (Ch: [Ch_RWESP, Ch_WFlags]), (Ch: [Ch_RWESP, Ch_WFlags]), (Ch: [Ch_RWESP, Ch_WFLAGS]), -(Ch: [Ch_All]), -(Ch: [Ch_All]), -(Ch: [Ch_All]), +(Ch: [Ch_Mop2, Ch_Rop1]), +(Ch: [Ch_Rop1]), +(Ch: [Ch_Rop1]), (Ch: [Ch_All]), (Ch: [Ch_All]), (Ch: [Ch_All]), @@ -463,10 +463,10 @@ (Ch: [Ch_Mop2, Ch_Rop1]), (Ch: [Ch_All]), (Ch: [Ch_All]), -(Ch: [Ch_All]), -(Ch: [Ch_All]), -(Ch: [Ch_All]), -(Ch: [Ch_All]), +(Ch: [Ch_Rop1]), +(Ch: [Ch_Rop1]), +(Ch: [Ch_Rop1]), +(Ch: [Ch_Rop1]), (Ch: [Ch_All]), (Ch: [Ch_All]), (Ch: [Ch_All]), diff --git a/compiler/m68k/ag68kvasm.pas b/compiler/m68k/ag68kvasm.pas index d95c7b53be..a37e24fe35 100644 --- a/compiler/m68k/ag68kvasm.pas +++ b/compiler/m68k/ag68kvasm.pas @@ -96,12 +96,11 @@ unit ag68kvasm; result:=asminfo^.asmcmd; case target_info.system of - { a.out doesn't support named sections } - system_m68k_amiga: objtype:='-Felf'; - { atari never had a standard object format, a.out is limited, vasm/vlink author recommends vobj } + { a.out doesn't support named sections, a.out is limited + (no named sections) lets use ELF for interoperability } + system_m68k_amiga, system_m68k_atari, - { same with the QL } - system_m68k_sinclairql: objtype:='-Fvobj'; + system_m68k_sinclairql: objtype:='-Felf'; else internalerror(2016052601); end; diff --git a/compiler/m68k/cpunode.pas b/compiler/m68k/cpunode.pas index 4cdfef41af..15445380b7 100644 --- a/compiler/m68k/cpunode.pas +++ b/compiler/m68k/cpunode.pas @@ -30,25 +30,21 @@ unit cpunode; uses { generic nodes } ncgbas,ncgld,ncgflw,ncgcnv,ncgmem,ncgcon,ncgcal,ncgset,ncginl,ncgmat,ncgadd, + { symtable } + symcpu, + aasmdef, { to be able to only parts of the generic code, the processor specific nodes must be included after the generic one (FK) } - n68kadd, - n68kcal, -// nppccon, -// nppcflw, - n68kmem, - n68kset, - n68kinl, -// nppcopt, - { this not really a node } -// nppcobj, - n68kmat, - n68kcnv, - { symtable } - symcpu, - aasmdef - ; + n68kadd, + n68kcal, + n68kmem, + n68kset, + n68kinl, + n68kmat, + n68kcnv, + n68kutil + ; end. diff --git a/compiler/m68k/n68kutil.pas b/compiler/m68k/n68kutil.pas new file mode 100644 index 0000000000..4c70154bc1 --- /dev/null +++ b/compiler/m68k/n68kutil.pas @@ -0,0 +1,74 @@ +{ + Copyright (c) 2021 by Karoly Balogh + + m68k version of some node tree helper routines + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + **************************************************************************** +} +unit n68kutil; + +{$i fpcdefs.inc} + +interface + + uses + cclasses,ngenutil; + + type + t68knodeutils = class(tnodeutils) + class procedure InsertObjectInfo; override; + end; + +implementation + + uses + verbose, + systems, + globals, + fmodule, + aasmbase,aasmdata,aasmtai,aasmcpu,aasmcnst, + symdef,symtype; + + + class procedure t68knodeutils.InsertObjectInfo; + var + tcb: ttai_typedconstbuilder; + s: shortstring; + sym: tasmsymbol; + def: tdef; + begin + inherited InsertObjectInfo; + if (not current_module.is_unit) and (target_info.system in [system_m68k_sinclairql]) then + begin + { insert the main program name into the object. this will be set as default job name by the system unit } + tcb:=ctai_typedconstbuilder.create([tcalo_new_section]); + s:=char(length(current_module.realmodulename^))+current_module.realmodulename^+#0; + def:=carraydef.getreusable(cansichartype,length(s)); + tcb.maybe_begin_aggregate(def); + tcb.emit_tai(Tai_string.Create(s),def); + tcb.maybe_end_aggregate(def); + sym:=current_asmdata.DefineAsmSymbol('__fpc_program_name',AB_GLOBAL,AT_DATA,def); + current_asmdata.asmlists[al_globals].concatlist( + tcb.get_final_asmlist(sym,def,sec_rodata,'__fpc_program_name',const_align(current_settings.alignment.constalignmax)) + ); + tcb.free; + end; + end; + +begin + cnodeutils:=t68knodeutils; +end. diff --git a/compiler/mips/aoptcpu.pas b/compiler/mips/aoptcpu.pas index ebc2742ba9..350829e9de 100644 --- a/compiler/mips/aoptcpu.pas +++ b/compiler/mips/aoptcpu.pas @@ -206,11 +206,11 @@ unit aoptcpu; var p: taicpu; begin - p:=taicpu(hp); result:=false; if not ((assigned(hp)) and (hp.typ=ait_instruction)) then exit; + p:=taicpu(hp); case p.opcode of { These instructions do not write into a register at all } A_NOP, diff --git a/compiler/ncal.pas b/compiler/ncal.pas index 1b838b35ff..d1c4c37cbe 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -1986,7 +1986,8 @@ implementation procedure tcallnode.add_init_statement(n:tnode); var - lastinitstatement : tstatementnode; + lastinitstatement, before_firstpass : tstatementnode; + was_first_statement : boolean; begin if not assigned(n) then exit; @@ -1999,6 +2000,7 @@ implementation exit; end; lastinitstatement:=laststatement(callinitblock); + was_first_statement:=(lastinitstatement=callinitblock.statements); { all these nodes must be immediately typechecked, because this routine } { can be called from pass_1 (i.e., after typecheck has already run) and } { moreover, the entire blocks themselves are also only typechecked in } @@ -2006,7 +2008,10 @@ implementation { typecheck pass for simplify purposes (not yet perfect, because the } { statementnodes themselves are not typechecked this way) } addstatement(lastinitstatement,n); + before_firstpass:=lastinitstatement; firstpass(tnode(lastinitstatement)); + if was_first_statement and (lastinitstatement<>before_firstpass) then + callinitblock.statements:=lastinitstatement; { Update expectloc for callinitblock } callinitblock.expectloc:=lastinitstatement.expectloc; end; @@ -2014,7 +2019,8 @@ implementation procedure tcallnode.add_done_statement(n:tnode); var - lastdonestatement : tstatementnode; + lastdonestatement, before_firstpass : tstatementnode; + was_first_statement : boolean; begin if not assigned(n) then exit; @@ -2027,9 +2033,13 @@ implementation exit; end; lastdonestatement:=laststatement(callcleanupblock); + was_first_statement:=(lastdonestatement=callcleanupblock.statements); { see comments in add_init_statement } addstatement(lastdonestatement,n); + before_firstpass:=lastdonestatement; firstpass(tnode(lastdonestatement)); + if was_first_statement and (lastdonestatement<>before_firstpass) then + callcleanupblock.statements:=lastdonestatement; { Update expectloc for callcleanupblock } callcleanupblock.expectloc:=lastdonestatement.expectloc; end; diff --git a/compiler/ncgld.pas b/compiler/ncgld.pas index 86fbaed98b..78224ccc6e 100644 --- a/compiler/ncgld.pas +++ b/compiler/ncgld.pas @@ -718,10 +718,13 @@ implementation empty value is assigned But not when the result is in the flags, then - loading the left node afterwards can destroy the flags. + loading the left node afterwards can destroy the flags. + + Neither if right contains conditional nodes: this might cause problems with + temp. nodes with init code used by CSE, see e.g. #38129 } if not(right.expectloc in [LOC_FLAGS,LOC_JUMP]) and - (node_complexity(right)>node_complexity(left)) then + (node_complexity(right)>node_complexity(left)) and not(has_conditional_nodes(right)) then begin secondpass(right); if codegenerror then diff --git a/compiler/ncnv.pas b/compiler/ncnv.pas index 5fa5ce714b..4182b2d3ad 100644 --- a/compiler/ncnv.pas +++ b/compiler/ncnv.pas @@ -942,7 +942,7 @@ implementation {An attempt to convert the result of a floating point division (with the / operator) to an integer type will fail. Give a hint to use the div operator.} - if (node.nodetype=slashn) and (def.typ=orddef) then + if (node.nodetype=slashn) and (def.typ=orddef) and not(is_currency(def)) then cgmessage(type_h_use_div_for_int); {In expressions like int64:=longint+longint, an integer overflow could be avoided by simply converting the operands to int64 first. Give a hint to do this.} diff --git a/compiler/optdeadstore.pas b/compiler/optdeadstore.pas index 7cd7d8ca25..2c325f0213 100644 --- a/compiler/optdeadstore.pas +++ b/compiler/optdeadstore.pas @@ -24,6 +24,7 @@ unit optdeadstore; {$i fpcdefs.inc} { $define DEBUG_DEADSTORE} +{ $define EXTDEBUG_DEADSTORE} interface @@ -71,7 +72,8 @@ unit optdeadstore; (tparavarsym(tloadnode(a.left).symtableentry).varspez in [vs_const,vs_value])) or ((tloadnode(a.left).symtableentry.typ=staticvarsym) and (tloadnode(a.left).symtable.symtabletype=staticsymtable) and - (current_procinfo.procdef.proctypeoption<>potype_unitinit) + (current_procinfo.procdef.proctypeoption<>potype_unitinit) and + not(vsa_different_scope in tstaticvarsym(tloadnode(a.left).symtableentry).varsymaccess) ) ) and ((a.right.nodetype in [niln,stringconstn,pointerconstn,setconstn,guidconstn]) or @@ -108,13 +110,24 @@ unit optdeadstore; var changed: boolean; begin +{$ifdef EXTDEBUG_DEADSTORE} + writeln('******************* Tree before deadstore elimination **********************'); + printnode(rootnode); + writeln('****************************************************************************'); +{$endif EXTDEBUG_DEADSTORE} if not(pi_dfaavailable in current_procinfo.flags) then internalerror(2013110201); + changed:=false; if not current_procinfo.has_nestedprocs then + foreachnodestatic(pm_postprocess, rootnode, @deadstoreelim, @changed); +{$ifdef DEBUG_DEADSTORE} + if changed then begin - changed:=false; - foreachnodestatic(pm_postprocess, rootnode, @deadstoreelim, @changed); + writeln('******************** Tree after deadstore elimination **********************'); + printnode(rootnode); + writeln('****************************************************************************'); end; +{$endif DEBUG_DEADSTORE} result:=rootnode; end; diff --git a/compiler/options.pas b/compiler/options.pas index 022d634071..d10709ed21 100644 --- a/compiler/options.pas +++ b/compiler/options.pas @@ -600,7 +600,8 @@ const WriteLn(xmloutput,' <controllertypes>'); for controllertype:=low(tcontrollertype) to high(tcontrollertype) do if embedded_controllers[controllertype].ControllerTypeStr<>'' then - WriteLn(xmloutput,' <controllertype name="',embedded_controllers[controllertype].ControllerTypeStr,'"/>'); + WriteLn(xmloutput,' <controllertype name="',embedded_controllers[controllertype].ControllerTypeStr, + '" controllerunit="',embedded_controllers[controllertype].controllerunitstr, '"/>'); WriteLn(xmloutput,' </controllertypes>'); end; {$POP} @@ -3591,7 +3592,7 @@ begin system_m68k_amiga: target_unsup_features:=[f_dynlibs]; system_m68k_sinclairql: - target_unsup_features:=[f_threading,f_dynlibs,f_commandargs,f_exitcode]; + target_unsup_features:=[f_threading,f_dynlibs]; system_z80_zxspectrum: target_unsup_features:=[f_threading,f_dynlibs{,f_fileio,f_textio},f_commandargs,f_exitcode]; system_z80_msxdos: @@ -4449,10 +4450,10 @@ begin Message(option_w_unsupported_debug_format); { switch assembler if it's binary and we got -a on the cmdline } - if ((cs_asm_leave in init_settings.globalswitches) and - (af_outputbinary in target_asm.flags)) or - { if -s is passed, we shouldn't call the internal assembler } - (cs_asm_extern in init_settings.globalswitches) then + if (af_outputbinary in target_asm.flags) and + ((cs_asm_leave in init_settings.globalswitches) or + { if -s is passed, we shouldn't call the internal assembler } + (cs_asm_extern in init_settings.globalswitches)) then begin Message(option_switch_bin_to_src_assembler); {$ifdef llvm} @@ -4663,6 +4664,20 @@ begin def_system_macro('CPUTHUMB2'); {$endif arm} +{$ifdef aarch64} + case target_info.system of + system_aarch64_darwin: + begin + if not option.CPUSetExplicitly then + init_settings.cputype:=cpu_armv84a; + if not option.OptCPUSetExplicitly then + init_settings.optimizecputype:=cpu_armv84a; + end; + else + ; + end; +{$endif aarch64} + {$if defined(riscv32) or defined(riscv64)} { RISC-V defaults } if (target_info.abi = abi_riscv_hf) then diff --git a/compiler/pdecvar.pas b/compiler/pdecvar.pas index 360cf1aff1..446542e519 100644 --- a/compiler/pdecvar.pas +++ b/compiler/pdecvar.pas @@ -861,9 +861,24 @@ implementation if assigned(current_module) and current_module.in_interface then begin if readprocdef.proctypeoption=potype_propgetter then - readprocdef.register_def; + readprocdef.register_def + else + readprocdef.free; if writeprocdef.proctypeoption=potype_propsetter then - writeprocdef.register_def; + writeprocdef.register_def + else + writeprocdef.free; + end + else + begin + if readprocdef.proctypeoption=potype_propgetter then + readprocdef.maybe_put_in_symtable_stack + else + readprocdef.free; + if writeprocdef.proctypeoption=potype_propsetter then + writeprocdef.maybe_put_in_symtable_stack + else + writeprocdef.free; end; result:=p; diff --git a/compiler/pexpr.pas b/compiler/pexpr.pas index a36bef1900..28483ebd95 100644 --- a/compiler/pexpr.pas +++ b/compiler/pexpr.pas @@ -1319,6 +1319,7 @@ implementation isclassref:boolean; isrecordtype:boolean; isobjecttype:boolean; + ishelpertype:boolean; begin if sym=nil then begin @@ -1340,12 +1341,18 @@ implementation isclassref:=(p1.resultdef.typ=classrefdef); isrecordtype:=(p1.nodetype=typen) and (p1.resultdef.typ=recorddef); isobjecttype:=(p1.nodetype=typen) and is_object(p1.resultdef); + ishelpertype:=is_objectpascal_helper(tdef(sym.owner.defowner)) and + (p1.nodetype=typen) and + not is_objectpascal_helper(p1.resultdef) + {and + not (cnf_inherited in callflags)}; end else begin isclassref:=false; isrecordtype:=false; isobjecttype:=false; + ishelpertype:=false; end; if assigned(spezcontext) and not (sym.typ=procsym) then @@ -1366,7 +1373,8 @@ implementation isclassref or ( (isobjecttype or - isrecordtype) and + isrecordtype or + ishelpertype) and not (cnf_inherited in callflags) ) ) and @@ -1422,8 +1430,10 @@ implementation abstract class using the type name of that class. We must not provide a warning if we use a "class of" variable of that type though as we don't know the - type of the class } - if (tcallnode(p1).procdefinition.proctypeoption=potype_constructor) and + type of the class + Note: structh might be Nil in case of a type helper } + if assigned(structh) and + (tcallnode(p1).procdefinition.proctypeoption=potype_constructor) and (oo_is_abstract in structh.objectoptions) and assigned(tcallnode(p1).methodpointer) and (tcallnode(p1).methodpointer.nodetype=loadvmtaddrn) then diff --git a/compiler/powerpc/aoptcpu.pas b/compiler/powerpc/aoptcpu.pas index 55ae8b671d..90b29175d5 100644 --- a/compiler/powerpc/aoptcpu.pas +++ b/compiler/powerpc/aoptcpu.pas @@ -28,10 +28,10 @@ Interface {$i fpcdefs.inc} -uses cpubase, aoptobj, aoptcpub, aopt, aasmtai,aasmdata, aasmcpu; +uses cpubase, cgbase, aoptobj, aoptcpub, aopt, aasmtai,aasmdata, aasmcpu, aoptppc; Type - TCpuAsmOptimizer = class(TAsmOptimizer) + TCpuAsmOptimizer = class(TPPCAsmOptimizer) { uses the same constructor as TAopObj } function PeepHoleOptPass1Cpu(var p: tai): boolean; override; @@ -44,7 +44,7 @@ Type Implementation uses - cutils, verbose, cgbase, cgcpu, cgobj; + cutils, verbose, cgcpu, cgobj; function TCpuAsmOptimizer.cmpi_mfcr_opt(p, next1, next2: taicpu): boolean; var diff --git a/compiler/powerpc64/aoptcpu.pas b/compiler/powerpc64/aoptcpu.pas index bd96f25524..6f9e840304 100644 --- a/compiler/powerpc64/aoptcpu.pas +++ b/compiler/powerpc64/aoptcpu.pas @@ -27,10 +27,10 @@ interface {$I fpcdefs.inc} -uses cpubase, aoptobj, aoptcpub, aopt; +uses cpubase, aoptobj, aoptcpub, aopt, aoptppc; type - TCpuAsmOptimizer = class(TAsmOptimizer) + TCpuAsmOptimizer = class(TPPCAsmOptimizer) { uses the same constructor as TAopObj } end; diff --git a/compiler/pparautl.pas b/compiler/pparautl.pas index 4608decce3..b139cd785d 100644 --- a/compiler/pparautl.pas +++ b/compiler/pparautl.pas @@ -780,6 +780,7 @@ implementation forwardfound : boolean; symentry: TSymEntry; item : tlinkedlistitem; + tmpidx: Integer; begin forwardfound:=false; @@ -1092,6 +1093,10 @@ implementation { Release current procdef } currpd.owner.deletedef(currpd); + { this prevents a dangling pointer and use after free } + tmpidx:=current_module.deflist.IndexOfItem(currpd,FromEnd); + if tmpidx<>-1 then + current_module.deflist[tmpidx]:=nil; currpd:=fwpd; end else diff --git a/compiler/ppcgen/aoptppc.pas b/compiler/ppcgen/aoptppc.pas new file mode 100644 index 0000000000..6c2dcbb7db --- /dev/null +++ b/compiler/ppcgen/aoptppc.pas @@ -0,0 +1,85 @@ +{ + Copyright (c) 1998-2002 by Jonas Maebe, member of the Free Pascal + Development Team + + This unit implements the generic PowerPC optimizer object + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + **************************************************************************** +} +Unit aoptppc; + +Interface + +{$i fpcdefs.inc} + +uses cpubase, cgbase, aopt, aasmtai; + +Type + TPPCAsmOptimizer = class(TAsmOptimizer) + function RegLoadedWithNewValue(reg : tregister; hp : tai) : boolean; override; + End; + +Implementation + + uses + cutils, verbose, cgcpu, cgobj, aasmcpu; + + function TPPCAsmOptimizer.RegLoadedWithNewValue(reg: tregister; hp: tai): boolean; + var + p: taicpu; + begin + Result := false; + if not(assigned(hp) and (hp.typ = ait_instruction)) then + exit; + + p := taicpu(hp); + if not(p.ops > 0) then + exit; + + case p.opcode of + A_CMP, + A_CMPI, + A_CMPL, + A_CMPLI: + begin + result:=reg=NR_CR; + exit; + end; + A_STB, + { the register forming the address is modified so no new value is loaded } + A_STBU, + A_STBUX, + A_STBX, + A_STH, + A_STHBRX, + A_STHU, + A_STHUX, + A_STHX, + A_STMW: + exit; + else + ; + end; + case p.oper[0]^.typ of + top_reg: + Result := (p.oper[0]^.reg = reg) ; + else + ; + end; + end; + +End. diff --git a/compiler/scanner.pas b/compiler/scanner.pas index 649d2bc75a..b33f7a73c5 100644 --- a/compiler/scanner.pas +++ b/compiler/scanner.pas @@ -1649,6 +1649,7 @@ type mac: tmacro; macrocount, len: integer; + foundmacro: boolean; begin if not eval then begin @@ -1657,6 +1658,7 @@ type end; mac:=nil; + foundmacro:=false; { Substitue macros and compiler variables with their content/value. For real macros also do recursive substitution. } macrocount:=0; @@ -1684,6 +1686,7 @@ type move(mac.buftext^,hs[1],len); searchstr:=upcase(hs); mac.is_used:=true; + foundmacro:=true; end else begin @@ -1702,9 +1705,9 @@ type result:=texprvalue.try_parse_number(searchstr); if not assigned(result) then begin - if assigned(mac) and (searchstr='FALSE') then + if foundmacro and (searchstr='FALSE') then result:=texprvalue.create_bool(false) - else if assigned(mac) and (searchstr='TRUE') then + else if foundmacro and (searchstr='TRUE') then result:=texprvalue.create_bool(true) else if (m_mac in current_settings.modeswitches) and (not assigned(mac) or not mac.defined) and diff --git a/compiler/sparcgen/aoptcpu.pas b/compiler/sparcgen/aoptcpu.pas index 3d4b14d4d7..7bedafe480 100644 --- a/compiler/sparcgen/aoptcpu.pas +++ b/compiler/sparcgen/aoptcpu.pas @@ -107,11 +107,11 @@ unit aoptcpu; var p: taicpu; begin - p:=taicpu(hp); result:=false; if not ((assigned(hp)) and (hp.typ=ait_instruction)) then exit; + p:=taicpu(hp); case p.opcode of { These instructions do not write into a register at all } A_NOP, diff --git a/compiler/systems.inc b/compiler/systems.inc index 0f3758e722..446d6a5f4e 100644 --- a/compiler/systems.inc +++ b/compiler/systems.inc @@ -203,7 +203,8 @@ system_aarch64_darwin, { 111 } system_z80_amstradcpc, { 112 } system_m68k_sinclairql, { 113 } - system_wasm32_wasi { 114 } + system_wasm32_wasi, { 114 } + system_aarch64_freebsd { 115 } ); type diff --git a/compiler/systems.pas b/compiler/systems.pas index 0bd714dd40..895f33a1a9 100644 --- a/compiler/systems.pas +++ b/compiler/systems.pas @@ -78,6 +78,7 @@ interface ,af_no_stabs { assembler is part of the LLVM toolchain } ,af_llvm + ,af_supports_hlcfi ); pasminfo = ^tasminfo; @@ -263,7 +264,8 @@ interface system_x86_6432_linux,system_mipseb_linux,system_mipsel_linux,system_aarch64_linux, system_riscv32_linux,system_riscv64_linux,system_xtensa_linux]; systems_dragonfly = [system_x86_64_dragonfly]; - systems_freebsd = [system_i386_freebsd, + systems_freebsd = [system_aarch64_freebsd, + system_i386_freebsd, system_x86_64_freebsd]; systems_netbsd = [system_i386_netbsd, system_m68k_netbsd, @@ -442,7 +444,7 @@ interface { all systems where a value parameter passed by reference must be copied on the caller side rather than on the callee side } - systems_caller_copy_addr_value_para = [system_aarch64_ios,system_aarch64_darwin,system_aarch64_linux]; + systems_caller_copy_addr_value_para = [system_aarch64_ios,system_aarch64_darwin,system_aarch64_linux,system_aarch64_win64,system_aarch64_freebsd]; { pointer checking (requires special code in FPC_CHECKPOINTER, and can never work for libc-based targets or any other program @@ -1133,6 +1135,10 @@ begin {$ifdef cpuaarch64} default_target(source_info.system); {$else cpuaarch64} + {$ifdef freebsd} + {$define default_target_set} + default_target(system_aarch64_freebsd); + {$endif freebsd} {$if defined(ios)} {$define default_target_set} default_target(system_aarch64_ios); diff --git a/compiler/systems/i_bsd.pas b/compiler/systems/i_bsd.pas index ca0ad0e3a0..99e92809fd 100644 --- a/compiler/systems/i_bsd.pas +++ b/compiler/systems/i_bsd.pas @@ -33,6 +33,82 @@ unit i_bsd; systems; const + system_aarch64_freebsd_info : tsysteminfo = + ( + system : system_aarch64_freebsd; + name : 'FreeBSD for aarch64'; + shortname : 'FreeBSD'; + flags : [tf_needs_symbol_size, + tf_needs_symbol_type, + tf_files_case_sensitive, + tf_requires_proper_alignment,tf_safecall_exceptions, + tf_smartlink_sections,tf_pic_uses_got, + tf_has_winlike_resources +{$ifdef llvm} + ,tf_use_psabieh +{$endif llvm} + ,tf_supports_hidden_symbols + ]; + cpu : cpu_aarch64; + unit_env : 'BSDUNITS'; + extradefines : 'UNIX;HASUNIX;BSD'; + exeext : ''; + defext : '.def'; + scriptext : '.sh'; + smartext : '.sl'; + unitext : '.ppu'; + unitlibext : '.ppl'; + asmext : '.s'; + objext : '.o'; + resext : '.res'; + resobjext : '.or'; + sharedlibext : '.so'; + staticlibext : '.a'; + staticlibprefix : 'libp'; + sharedlibprefix : 'lib'; + sharedClibext : '.so'; + staticClibext : '.a'; + staticClibprefix : 'lib'; + sharedClibprefix : 'lib'; + importlibprefix : 'libimp'; + importlibext : '.a'; + Cprefix : ''; + newline : #10; + dirsep : '/'; + assem : as_gas; + assemextern : as_gas; + link : ld_none; + linkextern : ld_bsd; + ar : ar_gnu_ar; + res : res_elf; + dbg : dbg_dwarf2; //dbg_stabs; + script : script_unix; + endian : endian_little; + alignment : + ( + procalign : 8; + loopalign : 4; + jumpalign : 0; + jumpalignskipmax : 0; + coalescealign : 0; + coalescealignskipmax: 0; + constalignmin : 0; + constalignmax : 16; + varalignmin : 0; + varalignmax : 16; + localalignmin : 4; + localalignmax : 16; + recordalignmin : 0; + recordalignmax : 16; + maxCrecordalign : 16 + ); + first_parm_offset : 16; + stacksize : 8*1024*1024; + stackalign : 16; + abi : abi_default; + llvmdatalayout : 'e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128' + ); + system_i386_freebsd_info : tsysteminfo = ( system : system_i386_FreeBSD; @@ -726,6 +802,11 @@ unit i_bsd; implementation initialization +{$ifdef cpuaarch64} + {$ifdef FreeBSD} + set_source_info(system_aarch64_freebsd_info); + {$endif FreeBSD} +{$endif cpuaarch64} {$ifdef cpui386} {$ifdef FreeBSD} set_source_info(system_i386_FreeBSD_info); diff --git a/compiler/systems/i_emx.pas b/compiler/systems/i_emx.pas index b77304850a..b0bb34bd0e 100644 --- a/compiler/systems/i_emx.pas +++ b/compiler/systems/i_emx.pas @@ -112,12 +112,10 @@ unit i_emx; initialization {$ifdef CPUI386} {$ifdef EMX} - {$IFNDEF VER1_0} set_source_info(system_i386_emx_info); { OS/2 via EMX can be run under DOS as well } if (OS_Mode=osDOS) or (OS_Mode=osDPMI) then source_info.scriptext := '.bat'; - {$ENDIF VER1_0} {$endif EMX} {$endif CPUI386} end. diff --git a/compiler/systems/i_os2.pas b/compiler/systems/i_os2.pas index 60d2100449..ea379b3a94 100644 --- a/compiler/systems/i_os2.pas +++ b/compiler/systems/i_os2.pas @@ -115,9 +115,6 @@ initialization {$IFNDEF EMX} set_source_info(system_i386_os2_info); {$ENDIF EMX} - {$IFDEF VER1_0} - set_source_info(system_i386_os2_info); - {$ENDIF VER1_0} {$endif os2} {$endif CPUI386} end. diff --git a/compiler/systems/i_wasi.pas b/compiler/systems/i_wasi.pas index 5102135f86..47a1477f5f 100644 --- a/compiler/systems/i_wasi.pas +++ b/compiler/systems/i_wasi.pas @@ -94,15 +94,15 @@ unit i_wasi; jumpalignskipmax : 0; coalescealign : 0; coalescealignskipmax: 0; - constalignmin : 0; - constalignmax : 4; + constalignmin : 4; + constalignmax : 16; varalignmin : 4; - varalignmax : 4; + varalignmax : 16; localalignmin : 4; - localalignmax : 4; + localalignmax : 16; recordalignmin : 0; - recordalignmax : 2; - maxCrecordalign : 4 + recordalignmax : 16; + maxCrecordalign : 16 ); first_parm_offset : 0; stacksize : 262144; diff --git a/compiler/systems/t_amiga.pas b/compiler/systems/t_amiga.pas index 03a2896952..431dbdc69c 100644 --- a/compiler/systems/t_amiga.pas +++ b/compiler/systems/t_amiga.pas @@ -131,7 +131,8 @@ begin { Open link.res file } LinkRes:=TLinkRes.Create(outputexedir+Info.ResName,true); - + if UseVLink and (source_info.dirsep <> '/') then + LinkRes.fForceUseForwardSlash:=true; { Write path to search libraries } HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First); while assigned(HPath) do diff --git a/compiler/systems/t_atari.pas b/compiler/systems/t_atari.pas index 0cf5e3359a..ed93d9f72f 100644 --- a/compiler/systems/t_atari.pas +++ b/compiler/systems/t_atari.pas @@ -104,6 +104,8 @@ begin { Open link.res file } LinkRes:=TLinkRes.Create(outputexedir+Info.ResName,true); + if UseVLink and (source_info.dirsep <> '/') then + LinkRes.fForceUseForwardSlash:=true; { Write path to search libraries } HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First); diff --git a/compiler/systems/t_bsd.pas b/compiler/systems/t_bsd.pas index 3fafadece6..915e57be82 100644 --- a/compiler/systems/t_bsd.pas +++ b/compiler/systems/t_bsd.pas @@ -693,6 +693,11 @@ end; initialization RegisterLinker(ld_bsd,TLinkerBSD); +{$ifdef aarch64} + RegisterImport(system_aarch64_freebsd,timportlibbsd); + RegisterExport(system_aarch64_freebsd,texportlibbsd); + RegisterTarget(system_aarch64_freebsd_info); +{$endif aarch64} {$ifdef x86_64} RegisterImport(system_x86_64_dragonfly,timportlibbsd); RegisterExport(system_x86_64_dragonfly,texportlibbsd); diff --git a/compiler/systems/t_darwin.pas b/compiler/systems/t_darwin.pas index d94d6bbee9..690b96ddc6 100644 --- a/compiler/systems/t_darwin.pas +++ b/compiler/systems/t_darwin.pas @@ -557,9 +557,8 @@ implementation end; success:=DoExec(BinStr,CmdStr,true,false); - if (success and - (extdbgbinstr<>'') and - (cs_link_nolink in current_settings.globalswitches)) then + if success and + (extdbgbinstr<>'') then success:=DoExec(extdbgbinstr,extdbgcmdstr,false,false); { Remove ReponseFile } diff --git a/compiler/systems/t_linux.pas b/compiler/systems/t_linux.pas index 7145003bce..a2d48b7641 100644 --- a/compiler/systems/t_linux.pas +++ b/compiler/systems/t_linux.pas @@ -140,9 +140,14 @@ begin {$else} {$ifdef powerpc64} if target_info.abi<>abi_powerpc_elfv2 then - LibrarySearchPath.AddLibraryPath(sysrootpath,'=/lib64;=/usr/lib64;=/usr/X11R6/lib64',true) + LibrarySearchPath.AddLibraryPath(sysrootpath,'=/usr/X11R6/lib64',true) else - LibrarySearchPath.AddLibraryPath(sysrootpath,'=/lib64;=/usr/lib/powerpc64le-linux-gnu;=/usr/X11R6/powerpc64le-linux-gnu',true); + LibrarySearchPath.AddLibraryPath(sysrootpath,'=/usr/lib/powerpc64le-linux-gnu;=/usr/X11R6/powerpc64le-linux-gnu',true); + LibrarySearchPath.AddLibraryPath(sysrootpath,'=/usr/lib',true); + LibrarySearchPath.AddLibraryPath(sysrootpath,'=/usr/lib64',true); + { /lib64 should be the really first, so add it before everything else } + LibrarySearchPath.AddLibraryPath(sysrootpath,'=/lib',true); + LibrarySearchPath.AddLibraryPath(sysrootpath,'=/lib64',true); {$else powerpc64} LibrarySearchPath.AddLibraryPath(sysrootpath,'=/lib;=/usr/lib;=/usr/X11R6/lib',true); {$endif powerpc64} diff --git a/compiler/systems/t_morph.pas b/compiler/systems/t_morph.pas index 16c4926625..5a2360c42e 100644 --- a/compiler/systems/t_morph.pas +++ b/compiler/systems/t_morph.pas @@ -98,6 +98,8 @@ begin { Open link.res file } LinkRes:=TLinkRes.Create(outputexedir+Info.ResName,true); + if UseVLink and (source_info.dirsep <> '/') then + LinkRes.fForceUseForwardSlash:=true; { Write path to search libraries } HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First); diff --git a/compiler/systems/t_msxdos.pas b/compiler/systems/t_msxdos.pas index 04c49df622..0d7475dca2 100644 --- a/compiler/systems/t_msxdos.pas +++ b/compiler/systems/t_msxdos.pas @@ -141,6 +141,8 @@ function TLinkerMSXDOS.WriteResponseFile_Vlink: Boolean; { Open link.res file } LinkRes:=TLinkRes.Create(outputexedir+Info.ResName,true); + if (source_info.dirsep <> '/') then + LinkRes.fForceUseForwardSlash:=true; LinkRes.Add('INPUT ('); diff --git a/compiler/systems/t_sinclairql.pas b/compiler/systems/t_sinclairql.pas index 42da38a77b..1e16e4ebab 100644 --- a/compiler/systems/t_sinclairql.pas +++ b/compiler/systems/t_sinclairql.pas @@ -144,6 +144,8 @@ begin { Open link.res file } LinkRes:=TLinkRes.Create(outputexedir+Info.ResName,true); + if UseVLink and (source_info.dirsep <> '/') then + LinkRes.fForceUseForwardSlash:=true; { Write path to search libraries } HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First); diff --git a/compiler/systems/t_zxspectrum.pas b/compiler/systems/t_zxspectrum.pas index 6c055000ed..e4adc0d334 100644 --- a/compiler/systems/t_zxspectrum.pas +++ b/compiler/systems/t_zxspectrum.pas @@ -140,6 +140,8 @@ function TLinkerZXSpectrum.WriteResponseFile_Vlink: Boolean; { Open link.res file } LinkRes:=TLinkRes.Create(outputexedir+Info.ResName,true); + if (source_info.dirsep <> '/') then + LinkRes.fForceUseForwardSlash:=true; LinkRes.Add('INPUT ('); diff --git a/compiler/utils/Makefile b/compiler/utils/Makefile index 62c1653283..28b6c0d7c5 100644 --- a/compiler/utils/Makefile +++ b/compiler/utils/Makefile @@ -2,7 +2,7 @@ # Don't edit, this file is generated by FPCMake Version 2.0.0 # default: all -MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-darwin aarch64-win64 aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc +MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc BSDs = freebsd netbsd openbsd darwin dragonfly UNIXs = linux $(BSDs) solaris qnx haiku aix LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari @@ -611,6 +611,9 @@ endif ifeq ($(FULL_TARGET),aarch64-linux) override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins msg2inc mkx86inl mkz80ins endif +ifeq ($(FULL_TARGET),aarch64-freebsd) +override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins msg2inc mkx86inl mkz80ins +endif ifeq ($(FULL_TARGET),aarch64-darwin) override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins msg2inc mkx86inl mkz80ins endif @@ -926,6 +929,9 @@ endif ifeq ($(FULL_TARGET),aarch64-linux) override CLEAN_UNITS+=ppu crc endif +ifeq ($(FULL_TARGET),aarch64-freebsd) +override CLEAN_UNITS+=ppu crc +endif ifeq ($(FULL_TARGET),aarch64-darwin) override CLEAN_UNITS+=ppu crc endif @@ -1242,6 +1248,9 @@ endif ifeq ($(FULL_TARGET),aarch64-linux) override COMPILER_UNITDIR+=.. endif +ifeq ($(FULL_TARGET),aarch64-freebsd) +override COMPILER_UNITDIR+=.. +endif ifeq ($(FULL_TARGET),aarch64-darwin) override COMPILER_UNITDIR+=.. endif @@ -1557,6 +1566,9 @@ endif ifeq ($(FULL_TARGET),aarch64-linux) override COMPILER_SOURCEDIR+=.. endif +ifeq ($(FULL_TARGET),aarch64-freebsd) +override COMPILER_SOURCEDIR+=.. +endif ifeq ($(FULL_TARGET),aarch64-darwin) override COMPILER_SOURCEDIR+=.. endif @@ -2636,6 +2648,9 @@ endif ifeq ($(FULL_TARGET),aarch64-linux) REQUIRE_PACKAGES_RTL=1 endif +ifeq ($(FULL_TARGET),aarch64-freebsd) +REQUIRE_PACKAGES_RTL=1 +endif ifeq ($(FULL_TARGET),aarch64-darwin) REQUIRE_PACKAGES_RTL=1 endif @@ -2831,6 +2846,19 @@ override COMPILER_UNITTARGETDIR=$(COMPILER_TARGETDIR) override UNITTARGETDIRPREFIX=$(TARGETDIRPREFIX) endif endif +ifdef SYSROOTPATH +override FPCOPT+=-XR$(SYSROOTPATH) +else +ifeq ($(OS_TARGET),$(OS_SOURCE)) +ifneq ($(findstring $(OS_TARGET),darwin),) +ifneq ($(findstring $(CPU_TARGET),aarch64),) +ifneq ($(wildcard /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk),) +override FPCOPT+=-XR/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk +endif +endif +endif +endif +endif ifdef CREATESHARED override FPCOPT+=-Cg endif diff --git a/compiler/utils/ppuutils/ppudump.pp b/compiler/utils/ppuutils/ppudump.pp index 5b277f9560..d96a79623c 100644 --- a/compiler/utils/ppuutils/ppudump.pp +++ b/compiler/utils/ppuutils/ppudump.pp @@ -234,7 +234,8 @@ const { 111 } 'Darwin-AArch64', { 112 } 'AmstradCPC-Z80', { 113 } 'SinclairQL-m68k', - { 114 } 'WASI-WASM32' + { 114 } 'WASI-WASM32', + { 115 } 'FreeBSD-AArch64' ); const diff --git a/compiler/verbose.pas b/compiler/verbose.pas index bc48697a02..414d01710a 100644 --- a/compiler/verbose.pas +++ b/compiler/verbose.pas @@ -89,7 +89,7 @@ interface function ErrorCount:longint; procedure SetErrorFlags(const s:string); procedure GenerateError; - procedure Internalerror(i:longint);{$ifndef VER2_6}noreturn;{$endif VER2_6} + procedure Internalerror(i:longint);noreturn; procedure Comment(l:longint;s:ansistring); function MessageStr(w:longint):TMsgStr; procedure Message(w:longint;onqueue:tmsgqueueevent=nil); @@ -583,7 +583,7 @@ implementation end; - procedure internalerror(i : longint);{$ifndef VER2_6}noreturn;{$endif VER2_6} + procedure internalerror(i : longint);noreturn; begin UpdateStatus; do_internalerror(i); diff --git a/compiler/wasm32/agllvmmc.pas b/compiler/wasm32/agllvmmc.pas index bcc843e191..4468a56f27 100644 --- a/compiler/wasm32/agllvmmc.pas +++ b/compiler/wasm32/agllvmmc.pas @@ -210,11 +210,11 @@ implementation if (exponent=(1 shl exponent_bits)-1) then begin if fraction=0 then - result:=result+'inf' + result:=result+'infinity' else begin result:=result+'nan'; - if fraction<>((int64(1) shl fraction_bits)-1) then + if fraction<>(int64(1) shl (fraction_bits-1)) then result:=result+':0x'+HexStr(fraction,fraction_hexdigits); end; end diff --git a/compiler/wasm32/cpupara.pas b/compiler/wasm32/cpupara.pas index 80ee9a075d..f5646d0bf4 100644 --- a/compiler/wasm32/cpupara.pas +++ b/compiler/wasm32/cpupara.pas @@ -99,7 +99,7 @@ implementation recorddef : begin { Delphi stdcall passes records on the stack for call by value } - result:=(varspez=vs_const) or (def.size=0); + result:=(varspez=vs_const) or (not (def.size in [1,2,4,8])); end; arraydef : begin diff --git a/compiler/wasm32/cpupi.pas b/compiler/wasm32/cpupi.pas index ecbaba5e63..884b096f9b 100644 --- a/compiler/wasm32/cpupi.pas +++ b/compiler/wasm32/cpupi.pas @@ -36,6 +36,7 @@ interface tcpuprocinfo=class(tcgprocinfo) public + function calc_stackframe_size : longint;override; procedure setup_eh; override; procedure postprocess_code; override; procedure set_first_temp_offset;override; @@ -77,6 +78,12 @@ implementation tcpuprocinfo *****************************************************************************} + function tcpuprocinfo.calc_stackframe_size: longint; + begin + { the stack frame in WebAssembly should always have a 16-byte alignment } + Result:=Align(inherited calc_stackframe_size,16); + end; + procedure tcpuprocinfo.setup_eh; begin cexceptionstatehandler:=twasmexceptionstatehandler; diff --git a/compiler/wasm32/nwasminl.pas b/compiler/wasm32/nwasminl.pas index b24a6d2516..4a456b263f 100644 --- a/compiler/wasm32/nwasminl.pas +++ b/compiler/wasm32/nwasminl.pas @@ -34,6 +34,7 @@ interface twasminlinenode = class(tcginlinenode) private + procedure second_high; override; procedure second_memory_size; procedure second_memory_grow; procedure second_unreachable; @@ -52,13 +53,72 @@ implementation aasmbase,aasmdata,aasmcpu, cgbase,cgutils, hlcgobj,hlcgcpu, - defutil,pass_2, + defutil,pass_2,verbose, symtype,symdef; {***************************************************************************** twasminlinenode *****************************************************************************} + procedure twasminlinenode.second_high; + var + hightype: TWasmBasicType; + begin + secondpass(left); + if not(is_dynamic_array(left.resultdef)) then + Internalerror(2019122801); + { determine the WasmBasicType of the result } + if is_64bit(resultdef) then + hightype:=wbt_i64 + else + hightype:=wbt_i32; + { length in dynamic arrays is at offset -sizeof(pint) } + thlcgwasm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location); + { 64-bit pointer values need a <>0 comparison to produce a 32-bit int on the stack (0 or 1) for the 'if' instruction. + 32-bit pointer values don't need it, because 'if' already expects and pops a 32-bit int and checks for <>0. } + if is_64bit(left.resultdef) then + begin + thlcgwasm(hlcg).a_load_const_stack(current_asmdata.CurrAsmList,left.resultdef,0,R_INTREGISTER); + thlcgwasm(hlcg).a_cmp_stack_stack(current_asmdata.CurrAsmList,left.resultdef,OC_NE); + end; + { if not nil } + current_asmdata.CurrAsmList.Concat(taicpu.op_functype(a_if,TWasmFuncType.Create([],[hightype]))); + thlcgwasm(hlcg).incblock; + thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1); + { volatility of the dyn. array refers to the volatility of the + string pointer, not of the string data } + thlcgwasm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location); + { length in dynamic arrays is at offset -ossinttype.size } + thlcgwasm(hlcg).a_op_const_stack(current_asmdata.CurrAsmList,OP_SUB,left.resultdef,ossinttype.size); + { load length } + if ossinttype.size=8 then + current_asmdata.CurrAsmList.Concat(taicpu.op_const(a_i64_load,0)) + else + current_asmdata.CurrAsmList.Concat(taicpu.op_const(a_i32_load,0)); + { else } + current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_else)); + thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1); + { high=-1 } + thlcgwasm(hlcg).a_load_const_stack(current_asmdata.CurrAsmList,resultdef,-1,R_INTREGISTER); + { endif } + current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_end_if)); + thlcgwasm(hlcg).decblock; + + location_reset(location,LOC_REGISTER,def_cgsize(resultdef)); +{$if not defined(cpu64bitalu) and not defined(cpuhighleveltarget)} + if location.size in [OS_64,OS_S64] then + begin + location.register64.reglo := cg.getintregister(current_asmdata.CurrAsmList,OS_32); + location.register64.reghi := cg.getintregister(current_asmdata.CurrAsmList,OS_32); + end + else +{$endif} + location.register := hlcg.getintregister(current_asmdata.CurrAsmList,resultdef); + + thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location); + end; + + procedure twasminlinenode.second_memory_size; begin current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_memory_size)); diff --git a/compiler/x86/agx86att.pas b/compiler/x86/agx86att.pas index d9845c9c47..f91b44228b 100644 --- a/compiler/x86/agx86att.pas +++ b/compiler/x86/agx86att.pas @@ -514,7 +514,7 @@ interface asmbin : 'clang'; asmcmd : '-x assembler -c -target $TRIPLET -o $OBJ $EXTRAOPT -x assembler $ASM'; supported_targets : [system_x86_64_darwin,system_x86_64_iphonesim]; - flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_no_stabs,af_llvm]; + flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_no_stabs,af_llvm,af_supports_hlcfi]; labelprefix : 'L'; labelmaxlen : -1; comment : '# '; @@ -593,7 +593,7 @@ interface asmbin : 'clang'; asmcmd : '-x assembler -c -target $TRIPLET -o $OBJ $EXTRAOPT -x assembler $ASM'; supported_targets : [system_i386_darwin,system_i386_iphonesim]; - flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_no_stabs,af_llvm]; + flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_no_stabs,af_llvm,af_supports_hlcfi]; labelprefix : 'L'; labelmaxlen : -1; comment : '# '; diff --git a/compiler/x86/aoptx86.pas b/compiler/x86/aoptx86.pas index 44e2363b91..a6141d8895 100644 --- a/compiler/x86/aoptx86.pas +++ b/compiler/x86/aoptx86.pas @@ -2380,6 +2380,7 @@ unit aoptx86; mov mem, %reg" } + AllocRegBetween(taicpu(hp1).oper[1]^.reg,p,hp1,usedregs); taicpu(p).loadreg(1, taicpu(hp1).oper[1]^.reg); DebugMsg(SPeepholeOptimization + 'MovMov2Mov 3 done',p); RemoveInstruction(hp1); @@ -6132,7 +6133,7 @@ unit aoptx86; DebugMsg(SPeepholeOptimization+'JccMovJmpMov2MovSetcc',p); { remove last label } RemoveInstruction(hp5); - { remove second albel } + { remove second label } RemoveInstruction(hp3); { if align is present remove it } if GetNextInstruction(hp2,hp3) and (hp3.typ=ait_align) then diff --git a/compiler/x86/cpubase.pas b/compiler/x86/cpubase.pas index 7f56482e87..7f80c4ea50 100644 --- a/compiler/x86/cpubase.pas +++ b/compiler/x86/cpubase.pas @@ -473,6 +473,8 @@ implementation cgsize2subreg:=R_SUBMMY; OS_M512: cgsize2subreg:=R_SUBMMZ; + OS_S128, + OS_128, OS_NO: { error message should have been thrown already before, so avoid only an internal error } diff --git a/compiler/x86/nx86inl.pas b/compiler/x86/nx86inl.pas index c26cbd5a32..09d351c853 100644 --- a/compiler/x86/nx86inl.pas +++ b/compiler/x86/nx86inl.pas @@ -1075,8 +1075,9 @@ implementation ((tcallparanode(tcallparanode(left).right).left.location.value-setbase) div bitsperop)*tcgsize2size[opsize]); cg.a_op_const_ref(current_asmdata.CurrAsmList,cgop,opsize,l,tcallparanode(left).left.location.reference); end; + LOC_CSUBSETREG, LOC_CREGISTER : - cg.a_op_const_reg(current_asmdata.CurrAsmList,cgop,tcallparanode(left).left.location.size,l,tcallparanode(left).left.location.register); + hlcg.a_op_const_loc(current_asmdata.CurrAsmList,cgop,tcallparanode(left).left.resultdef,l,tcallparanode(left).left.location); else internalerror(200405022); end; diff --git a/compiler/x86/rgx86.pas b/compiler/x86/rgx86.pas index 27d34fbd5e..d099b272f6 100644 --- a/compiler/x86/rgx86.pas +++ b/compiler/x86/rgx86.pas @@ -407,8 +407,10 @@ implementation { 32 bit operations on 32 bit registers on x86_64 can result in zeroing the upper 32 bits of the register. This does not happen with memory operations, so we have to perform these calculations - in registers. } - if (opsize=S_L) then + in registers. + + However, for instructions not modifying registers, this is not a problem } + if (opsize=S_L) and (opcode<>A_CMP) and (opcode<>A_TEST) and (opcode<>A_BT) then replaceoper:=-1; {$endif x86_64} diff --git a/compiler/x86/x86ins.dat b/compiler/x86/x86ins.dat index 4eb3b58b5d..e71830362b 100644 --- a/compiler/x86/x86ins.dat +++ b/compiler/x86/x86ins.dat @@ -1267,7 +1267,7 @@ mmxreg,mmxrm \2\x0F\xDB\110 PENT,MMX,SM xmmreg,xmmrm \361\2\x0F\xDB\110 WILLAMETTE,SSE2,SM [PANDN] -(Ch_All) +(Ch_Mop2, Ch_Rop1) mmxreg,mmxrm \2\x0F\xDF\110 PENT,MMX,SM xmmreg,xmmrm \361\2\x0F\xDF\110 WILLAMETTE,SSE2,SM @@ -1475,16 +1475,16 @@ void \1\x9D X86_64 void \326\1\x9D X86_64 [POR] -(Ch_All) +(Ch_Mop2, Ch_Rop1) mmxreg,mmxrm \2\x0F\xEB\110 PENT,MMX,SM xmmreg,xmmrm \361\2\x0F\xEB\110 WILLAMETTE,SSE2,SM [PREFETCH,prefetchX] -(Ch_All) +(Ch_Rop1) mem \2\x0F\x0D\200 PENT,3DNOW,SM [PREFETCHW,prefetchwX] -(Ch_All) +(Ch_Rop1) mem \2\x0F\x0D\201 PENT,3DNOW,SM [PSLLD] @@ -2516,19 +2516,19 @@ mem \2\x0F\xAE\200 P6,SSE,FPU ; [PREFETCHNTA] -(Ch_All) +(Ch_Rop1) mem \2\x0F\x18\200 KATMAI [PREFETCHT0] -(Ch_All) +(Ch_Rop1) mem \2\x0F\x18\201 KATMAI [PREFETCHT1] -(Ch_All) +(Ch_Rop1) mem \2\x0F\x18\202 KATMAI [PREFETCHT2] -(Ch_All) +(Ch_Rop1) mem \2\x0F\x18\203 KATMAI [SFENCE] diff --git a/compiler/x86_64/x8664pro.inc b/compiler/x86_64/x8664pro.inc index e34b9973b2..70ad99ddbc 100644 --- a/compiler/x86_64/x8664pro.inc +++ b/compiler/x86_64/x8664pro.inc @@ -214,7 +214,7 @@ (Ch: [Ch_All]), (Ch: [Ch_Mop2, Ch_Rop1]), (Ch: [Ch_Mop2, Ch_Rop1]), -(Ch: [Ch_All]), +(Ch: [Ch_Mop2, Ch_Rop1]), (Ch: [Ch_All]), (Ch: [Ch_All]), (Ch: [Ch_All]), @@ -257,9 +257,9 @@ (Ch: [Ch_RWESP, Ch_WFlags]), (Ch: [Ch_RWESP, Ch_WFLAGS]), (Ch: [Ch_RWESP, Ch_WFlags]), -(Ch: [Ch_All]), -(Ch: [Ch_All]), -(Ch: [Ch_All]), +(Ch: [Ch_Mop2, Ch_Rop1]), +(Ch: [Ch_Rop1]), +(Ch: [Ch_Rop1]), (Ch: [Ch_All]), (Ch: [Ch_All]), (Ch: [Ch_All]), @@ -449,10 +449,10 @@ (Ch: [Ch_Mop2, Ch_Rop1]), (Ch: [Ch_All]), (Ch: [Ch_All]), -(Ch: [Ch_All]), -(Ch: [Ch_All]), -(Ch: [Ch_All]), -(Ch: [Ch_All]), +(Ch: [Ch_Rop1]), +(Ch: [Ch_Rop1]), +(Ch: [Ch_Rop1]), +(Ch: [Ch_Rop1]), (Ch: [Ch_All]), (Ch: [Ch_All]), (Ch: [Ch_All]), diff --git a/compiler/xtensa/aoptcpu.pas b/compiler/xtensa/aoptcpu.pas index c3c593cc0a..8b81397db6 100644 --- a/compiler/xtensa/aoptcpu.pas +++ b/compiler/xtensa/aoptcpu.pas @@ -143,14 +143,13 @@ Implementation var p: taicpu; begin - p := taicpu(hp); Result := false; - if not ((assigned(hp)) and (hp.typ = ait_instruction)) then - exit; - - if Result then + if not(assigned(hp) and (hp.typ = ait_instruction)) then exit; + p := taicpu(hp); + if not (p.ops >0) then + exit; case p.opcode of A_B, A_SSI,A_SSIU,A_SSX,A_SSXU, diff --git a/compiler/xtensa/ncpuinl.pas b/compiler/xtensa/ncpuinl.pas index aa4e6bb615..3e11a87349 100644 --- a/compiler/xtensa/ncpuinl.pas +++ b/compiler/xtensa/ncpuinl.pas @@ -26,10 +26,10 @@ unit ncpuinl; interface uses - node,ninl,ncginl, aasmbase; + node,ninl,ncginl,aasmbase; type - tcpuinlineNode = class(tcginlinenode) + tcpuinlinenode = class(tcginlinenode) function first_abs_real: tnode; override; procedure second_abs_long; override; procedure second_abs_real; override; @@ -37,13 +37,14 @@ unit ncpuinl; procedure second_fma; override; function first_minmax: tnode; override; procedure second_minmax; override; + procedure second_prefetch; override; end; implementation uses cpuinfo, - verbose,globals, + verbose,globals,globtype, compinnr, aasmdata, aasmcpu, @@ -52,7 +53,7 @@ unit ncpuinl; hlcgobj, pass_2, cgbase, cgobj, cgutils, - ncal, + ncal,nutils, cpubase; procedure tcpuinlinenode.second_abs_long; @@ -182,7 +183,7 @@ unit ncpuinl; end; - procedure tcpuinlineNode.second_minmax; + procedure tcpuinlinenode.second_minmax; var paraarray : array[1..2] of tnode; i: Integer; @@ -231,6 +232,34 @@ unit ncpuinl; end; + procedure tcpuinlinenode.second_prefetch; + var + ref : treference; + r : tregister; + checkpointer_used : boolean; + begin + { do not call Checkpointer for left node } + checkpointer_used:=(cs_checkpointer in current_settings.localswitches); + if checkpointer_used then + node_change_local_switch(left,cs_checkpointer,false); + secondpass(left); + if checkpointer_used then + node_change_local_switch(left,cs_checkpointer,false); + case left.location.loc of + LOC_CREFERENCE, + LOC_REFERENCE: + begin + r:=cg.getintregister(current_asmdata.CurrAsmList,OS_ADDR); + cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.location.reference,r); + reference_reset_base(ref,r,0,location.reference.temppos,left.location.reference.alignment,location.reference.volatility); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_DPFR,ref.base,ref.offset)); + end; + else + { nothing to prefetch }; + end; + end; + + begin cinlinenode:=tcpuinlinenode; end. |