diff options
| author | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2021-04-27 23:11:09 +0000 |
|---|---|---|
| committer | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2021-04-27 23:11:09 +0000 |
| commit | a491c935588745154b576226b73833bac78fcb6e (patch) | |
| tree | 973289073fb5d21573a6be2b5cfeba9abd2a9472 /compiler | |
| parent | 38b5e0606069cc5985e995e1da5b6855db67f507 (diff) | |
| parent | ae5b0de491a91321675f73eae5db628d068f4e05 (diff) | |
| download | fpc-unicodekvm.tar.gz | |
* synchronized with trunkunicodekvm
git-svn-id: https://svn.freepascal.org/svn/fpc/branches/unicodekvm@49282 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler')
39 files changed, 440 insertions, 135 deletions
diff --git a/compiler/MPWMake b/compiler/MPWMake index 8591f382fc..90ce41fe10 100644 --- a/compiler/MPWMake +++ b/compiler/MPWMake @@ -1 +1 @@ -# Make file for MPW make.
# To run it, use:
# Make <target> -f MPWMake > Makeout ; Makeout
# where <target> should be replaced with actual make target.
#############################################
# TIPS (TODO move to Wiki or something
#
# Defined variables: No quoting
# Command lines: quote paths, dont quote option strings, since
# they might contain several options, which must be separated.
# Recursive call to Make:
# - give options as -d XXX="{XXX}"
# - in same dir, remember to ensure to have different Makeout files,
# e g Makeout2.
#
# NOTE Currently cycle is stopped after three rounds, no diff is checked.
FPC = {FPCDIR}bin:ppcppc
# Default language for the compiler (english):
FPCLANG = e
MSGFILE = :msg:error{FPCLANG}.msg
msg2inc Ä :utils:msg2inc.pp
{FPC} -FE: -WT :utils:msg2inc.pp
# The msgtxt.inc only depends on the error?.msg file, not on msg2inc,
# because that one will be new almost everytime
msgtxt.inc Ä {MSGFILE}
Make msg2inc -f MPWMake > Makeout3 ; Makeout3
msg2inc {MSGFILE} msg msg
msg Ä msgtxt.inc
compiler Ä msg
Set Exit 0
NewFolder :powerpc:units: ³ Dev:Null
NewFolder :powerpc:units:powerpc-macos: ³ Dev:Null
Set Exit 1
"{FPC}" {OPT} "-Fu{RTLDIR}" -Fu:systems: -Fu:powerpc: -Fu:ppcgen -dGDB -dBROWSERLOG -dNOOPT ¶
-dpowerpc -WT -FE: -FU:powerpc:units:powerpc-macos: pp.pas
Rename -y pp ppcppc
clean Ä utils_clean
Set Exit 0
Delete -y :powerpc:units:powerpc-macos
Delete -y ppcppc oldfpc msg2inc
Delete -y Å.xcoff
Set Exit 1
cycleclean Ä
Set Exit 0
Delete -y :powerpc:units:powerpc-macos
Set Exit 1
install Ä
If {FPCDIR} == ''
Set -e FPCDIR `GetFileName -wd -m 'Select where to install the FreePascal folder'`FreePascal:
Set -e Commands "{Commands},{FPCDIR}bin:"
Echo "Set -e FPCDIR ¶'{FPCDIR}¶'" > "{MPW}Startup Items:FPC Startup"
Echo 'Set -e Commands "{Commands},{FPCDIR}bin:"' >> "{MPW}Startup Items:FPC Startup"
End
Set Exit 0
NewFolder "{FPCDIR}" ³ Dev:Null
NewFolder "{FPCDIR}bin:" ³ Dev:Null
Set Exit 1
Duplicate -y :ppcppc :utils:ppudump :utils:ppufiles :utils:ppumove ¶
:utils:fpc "{FPCDIR}bin:"
Echo "# Configuration file for Free Pascal for MPW" > "{FPCDIR}bin:fpc.cfg"
Echo "-Fu¶'{FPCDIR}units:rtl:¶'" >> "{FPCDIR}bin:fpc.cfg"
Echo "-l" >> "{FPCDIR}bin:fpc.cfg"
Echo "-vi" >> "{FPCDIR}bin:fpc.cfg"
cycle Ä
Directory ::rtl:macos
Make clean -f MPWMake > Makeout ; Makeout
Make all -d FPC="{FPC}" -d OPT="{OPT}" -f MPWMake > Makeout ; Makeout
Directory :::compiler
Make clean -f MPWMake > Makeout2 ; Makeout2
Make compiler -d FPC="{FPC}" -d OPT="{OPT}" -d RTLDIR=::rtl:units:powerpc-macos -f MPWMake > Makeout2 ; Makeout2
#
Echo '******************** SECOND ROUND *********************'
Rename -y ppcppc oldfpc
Directory ::rtl:macos
Make clean -f MPWMake > Makeout ; Makeout
Make all -d FPC=:::compiler:oldfpc -d OPT="{OPT}" -f MPWMake > Makeout ; Makeout
Directory :::compiler
Make cycleclean -f MPWMake > Makeout2 ; Makeout2
Make compiler -d FPC=oldfpc -d OPT="{OPT}" -d RTLDIR=::rtl:units:powerpc-macos -f MPWMake > Makeout2 ; Makeout2
#
Echo '********************* THIRD ROUND *********************'
Rename -y ppcppc oldfpc
Directory ::rtl:macos
Make clean -f MPWMake > Makeout ; Makeout
Make all -d FPC=:::compiler:oldfpc -d OPT="{OPT}" -f MPWMake > Makeout ; Makeout
Directory :::compiler
Make cycleclean -f MPWMake > Makeout2 ; Makeout2
Make compiler -d FPC=oldfpc -d OPT="{OPT}" -d RTLDIR=::rtl:units:powerpc-macos -f MPWMake > Makeout2 ; Makeout2
#
Make utils_clean -f MPWMake > Makeout2 ; Makeout2
Make utils_all -d FPC=::oldfpc -d OPT="{OPT}" -d RTLDIR=:::rtl:units:powerpc-macos -f MPWMake > Makeout2 ; Makeout2
utils_all Ä
Directory :utils
Set Exit 0
NewFolder :units: ³ Dev:Null
NewFolder :units:powerpc-macos: ³ Dev:Null
Set Exit 1
"{FPC}" {OPT} "-Fu{RTLDIR}" -FE: -FU:units:powerpc-macos -Fu:: -WT ppudump.pp
"{FPC}" {OPT} "-Fu{RTLDIR}" -FE: -FU:units:powerpc-macos -Fu:: -WT ppufiles.pp
"{FPC}" {OPT} "-Fu{RTLDIR}" -FE: -FU:units:powerpc-macos -Fu:: -WT ppumove.pp
Duplicate -y fpc.mpw fpc
Directory ::
utils_clean Ä
Directory :utils
Set Exit 0
Delete -y :units:powerpc-macos
Delete -y fpc ppudump ppufiles ppumove msg2inc
Delete -y Å.xcoff
Set Exit 1
Directory ::
\ No newline at end of file +# Make file for MPW make.
# To run it, use:
# Make <target> -f MPWMake > Makeout ; Makeout
# where <target> should be replaced with actual make target.
#############################################
# TIPS (TODO move to Wiki or something
#
# Defined variables: No quoting
# Command lines: quote paths, dont quote option strings, since
# they might contain several options, which must be separated.
# Recursive call to Make:
# - give options as -d XXX="{XXX}"
# - in same dir, remember to ensure to have different Makeout files,
# e g Makeout2.
#
# NOTE Currently cycle is stopped after three rounds, no diff is checked.
FPC = {FPCDIR}bin:ppcppc
# Default language for the compiler (english):
FPCLANG = e
MSGFILE = :msg:error{FPCLANG}.msg
msg2inc Ä :utils:msg2inc.pp
{FPC} -FE: -WT :utils:msg2inc.pp
# The msgtxt.inc only depends on the error?.msg file, not on msg2inc,
# because that one will be new almost everytime
msgtxt.inc Ä {MSGFILE}
Make msg2inc -f MPWMake > Makeout3 ; Makeout3
msg2inc {MSGFILE} msg msg
msg Ä msgtxt.inc
compiler Ä msg
Set Exit 0
NewFolder :powerpc:units: ³ Dev:Null
NewFolder :powerpc:units:powerpc-macos: ³ Dev:Null
Set Exit 1
"{FPC}" {OPT} "-Fu{RTLDIR}" -Fu:systems: -Fu:powerpc: -Fu:ppcgen -dGDB -dNOOPT ¶
-dpowerpc -WT -FE: -FU:powerpc:units:powerpc-macos: pp.pas
Rename -y pp ppcppc
clean Ä utils_clean
Set Exit 0
Delete -y :powerpc:units:powerpc-macos
Delete -y ppcppc oldfpc msg2inc
Delete -y Å.xcoff
Set Exit 1
cycleclean Ä
Set Exit 0
Delete -y :powerpc:units:powerpc-macos
Set Exit 1
install Ä
If {FPCDIR} == ''
Set -e FPCDIR `GetFileName -wd -m 'Select where to install the FreePascal folder'`FreePascal:
Set -e Commands "{Commands},{FPCDIR}bin:"
Echo "Set -e FPCDIR ¶'{FPCDIR}¶'" > "{MPW}Startup Items:FPC Startup"
Echo 'Set -e Commands "{Commands},{FPCDIR}bin:"' >> "{MPW}Startup Items:FPC Startup"
End
Set Exit 0
NewFolder "{FPCDIR}" ³ Dev:Null
NewFolder "{FPCDIR}bin:" ³ Dev:Null
Set Exit 1
Duplicate -y :ppcppc :utils:ppudump :utils:ppufiles :utils:ppumove ¶
:utils:fpc "{FPCDIR}bin:"
Echo "# Configuration file for Free Pascal for MPW" > "{FPCDIR}bin:fpc.cfg"
Echo "-Fu¶'{FPCDIR}units:rtl:¶'" >> "{FPCDIR}bin:fpc.cfg"
Echo "-l" >> "{FPCDIR}bin:fpc.cfg"
Echo "-vi" >> "{FPCDIR}bin:fpc.cfg"
cycle Ä
Directory ::rtl:macos
Make clean -f MPWMake > Makeout ; Makeout
Make all -d FPC="{FPC}" -d OPT="{OPT}" -f MPWMake > Makeout ; Makeout
Directory :::compiler
Make clean -f MPWMake > Makeout2 ; Makeout2
Make compiler -d FPC="{FPC}" -d OPT="{OPT}" -d RTLDIR=::rtl:units:powerpc-macos -f MPWMake > Makeout2 ; Makeout2
#
Echo '******************** SECOND ROUND *********************'
Rename -y ppcppc oldfpc
Directory ::rtl:macos
Make clean -f MPWMake > Makeout ; Makeout
Make all -d FPC=:::compiler:oldfpc -d OPT="{OPT}" -f MPWMake > Makeout ; Makeout
Directory :::compiler
Make cycleclean -f MPWMake > Makeout2 ; Makeout2
Make compiler -d FPC=oldfpc -d OPT="{OPT}" -d RTLDIR=::rtl:units:powerpc-macos -f MPWMake > Makeout2 ; Makeout2
#
Echo '********************* THIRD ROUND *********************'
Rename -y ppcppc oldfpc
Directory ::rtl:macos
Make clean -f MPWMake > Makeout ; Makeout
Make all -d FPC=:::compiler:oldfpc -d OPT="{OPT}" -f MPWMake > Makeout ; Makeout
Directory :::compiler
Make cycleclean -f MPWMake > Makeout2 ; Makeout2
Make compiler -d FPC=oldfpc -d OPT="{OPT}" -d RTLDIR=::rtl:units:powerpc-macos -f MPWMake > Makeout2 ; Makeout2
#
Make utils_clean -f MPWMake > Makeout2 ; Makeout2
Make utils_all -d FPC=::oldfpc -d OPT="{OPT}" -d RTLDIR=:::rtl:units:powerpc-macos -f MPWMake > Makeout2 ; Makeout2
utils_all Ä
Directory :utils
Set Exit 0
NewFolder :units: ³ Dev:Null
NewFolder :units:powerpc-macos: ³ Dev:Null
Set Exit 1
"{FPC}" {OPT} "-Fu{RTLDIR}" -FE: -FU:units:powerpc-macos -Fu:: -WT ppudump.pp
"{FPC}" {OPT} "-Fu{RTLDIR}" -FE: -FU:units:powerpc-macos -Fu:: -WT ppufiles.pp
"{FPC}" {OPT} "-Fu{RTLDIR}" -FE: -FU:units:powerpc-macos -Fu:: -WT ppumove.pp
Duplicate -y fpc.mpw fpc
Directory ::
utils_clean Ä
Directory :utils
Set Exit 0
Delete -y :units:powerpc-macos
Delete -y fpc ppudump ppufiles ppumove msg2inc
Delete -y Å.xcoff
Set Exit 1
Directory ::
diff --git a/compiler/Makefile b/compiler/Makefile index f19c59109b..ffc63cc2b8 100644 --- a/compiler/Makefile +++ b/compiler/Makefile @@ -581,7 +581,7 @@ endif endif endif endif -override LOCALOPT+=-d$(CPC_TARGET) -dGDB -dBROWSERLOG +override LOCALOPT+=-d$(CPC_TARGET) -dGDB ifdef LLVM ifeq ($(findstring $(PPC_TARGET),x86_64 aarch64 arm),) $(error The $(PPC_TARGET) architecture is not (yet) supported by the FPC/LLVM code generator) diff --git a/compiler/Makefile.fpc b/compiler/Makefile.fpc index 7082b7d7e9..7d484654bc 100644 --- a/compiler/Makefile.fpc +++ b/compiler/Makefile.fpc @@ -323,7 +323,7 @@ endif endif # set correct defines (-d$(CPU_TARGET) is automatically added in makefile.fpc) -override LOCALOPT+=-d$(CPC_TARGET) -dGDB -dBROWSERLOG +override LOCALOPT+=-d$(CPC_TARGET) -dGDB #include LLVM define/directory if requested ifdef LLVM diff --git a/compiler/aarch64/agcpugas.pas b/compiler/aarch64/agcpugas.pas index 2487fa1cb1..8026765fc3 100644 --- a/compiler/aarch64/agcpugas.pas +++ b/compiler/aarch64/agcpugas.pas @@ -41,10 +41,12 @@ unit agcpugas; TAArch64Assembler=class(TGNUassembler) constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override; + function MakeCmdLine: TCmdStr; override; end; TAArch64AppleAssembler=class(TAppleGNUassembler) constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override; + function MakeCmdLine: TCmdStr; override; end; TAArch64ClangGASAssembler=class(TAArch64Assembler) @@ -53,6 +55,7 @@ unit agcpugas; protected function sectionflags(secflags:TSectionFlags):string;override; public + function MakeCmdLine: TCmdStr; override; procedure WriteAsmList; override; end; @@ -65,6 +68,18 @@ unit agcpugas; const cputype_to_gas_march : array[tcputype] of string = ( '', // cpu_none + '', // armv8 is not accepted by GNU assembler + 'armv8-a', + 'armv8.1-a', + 'armv8.2-a', + 'armv8.3-a', + 'armv8.4-a', + 'armv8.5-a', + 'armv8.6-a' + ); + + cputype_to_clang_march : array[tcputype] of string = ( + '', // cpu_none 'armv8', 'armv8-a', 'armv8.1-a', @@ -94,6 +109,15 @@ unit agcpugas; InstrWriter := TAArch64InstrWriter.create(self); end; + function TAArch64Assembler.MakeCmdLine: TCmdStr; + begin + result:=inherited MakeCmdLine; + if cputype_to_gas_march[current_settings.cputype] <> '' then + Replace(result,'$MARCHOPT','-march='+cputype_to_gas_march[current_settings.cputype]) + else + Replace(result,'$MARCHOPT',''); + end; + {****************************************************************************} { Apple AArch64 Assembler writer } {****************************************************************************} @@ -105,10 +129,24 @@ unit agcpugas; end; + function TAArch64AppleAssembler.MakeCmdLine: TCmdStr; + begin + result:=inherited MakeCmdLine; + if cputype_to_gas_march[current_settings.cputype] <> '' then + Replace(result,'$MARCHOPT','-march='+cputype_to_gas_march[current_settings.cputype]) + else + Replace(result,'$MARCHOPT',''); + end; + {****************************************************************************} { CLang AArch64 Assembler writer } {****************************************************************************} + function TAArch64ClangGASAssembler.MakeCmdLine: TCmdStr; + begin + result:=inherited MakeCmdLine; + end; + procedure TAArch64ClangGASAssembler.TransformSEHDirectives(list:TAsmList); function convert_unwinddata(list:tasmlist):tdynamicarray; @@ -773,7 +811,7 @@ unit agcpugas; id : as_gas; idtxt : 'AS'; asmbin : 'as'; - asmcmd : '-o $OBJ $EXTRAOPT $ASM'; + asmcmd : '-o $OBJ $MARCHOPT $EXTRAOPT $ASM'; supported_targets : [system_aarch64_freebsd,system_aarch64_linux,system_aarch64_android]; flags : [af_needar,af_smartlink_sections]; labelprefix : '.L'; @@ -787,7 +825,7 @@ unit agcpugas; id : as_clang_asdarwin; idtxt : 'CLANG'; asmbin : 'clang'; - asmcmd : '-x assembler -c -target $TRIPLET -o $OBJ $EXTRAOPT -x assembler $ASM'; + asmcmd : '-x assembler -c -target $TRIPLET -o $OBJ $MARCHOPT $EXTRAOPT -x assembler $ASM'; supported_targets : [system_aarch64_ios,system_aarch64_darwin]; flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_llvm,af_supports_hlcfi]; labelprefix : 'L'; @@ -801,7 +839,7 @@ unit agcpugas; id : as_clang_gas; idtxt : 'CLANG'; asmbin : 'clang'; - asmcmd : '-x assembler -c -target $TRIPLET -o $OBJ $EXTRAOPT -x assembler $ASM'; + asmcmd : '-x assembler -c -target $TRIPLET -o $OBJ $MARCHOPT $EXTRAOPT -x assembler $ASM'; supported_targets : [system_aarch64_win64]; flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_llvm,af_supports_hlcfi]; labelprefix : '.L'; diff --git a/compiler/aarch64/aoptcpu.pas b/compiler/aarch64/aoptcpu.pas index 4ef898284e..dc5e327cf2 100644 --- a/compiler/aarch64/aoptcpu.pas +++ b/compiler/aarch64/aoptcpu.pas @@ -379,15 +379,23 @@ Implementation taicpu(hp1).oper[0]^.reg, taicpu(p).oper[1]^.reg, shifterop); + { Make sure the register used in the shifting is tracked all + the way through, otherwise it may become deallocated while + it's still live and cause incorrect optimisations later } + if (taicpu(hp1).oper[0]^.reg <> taicpu(p).oper[1]^.reg) then + begin + TransferUsedRegs(TmpUsedRegs); + UpdateUsedRegs(TmpUsedRegs, tai(p.Next)); + ALlocRegBetween(taicpu(p).oper[1]^.reg, p, hp1, TmpUsedRegs); + end; + taicpu(hp2).fileinfo:=taicpu(hp1).fileinfo; asml.insertbefore(hp2, hp1); - GetNextInstruction(p, hp2); - asml.remove(p); - asml.remove(hp1); - p.free; - hp1.free; - p:=hp2; - DebugMsg('Peephole FoldShiftProcess done', p); + + RemoveInstruction(hp1); + RemoveCurrentp(p); + + DebugMsg('Peephole FoldShiftProcess done', hp2); Result:=true; break; end; diff --git a/compiler/aarch64/hlcgcpu.pas b/compiler/aarch64/hlcgcpu.pas index 593c202ef8..9de4e55ad7 100644 --- a/compiler/aarch64/hlcgcpu.pas +++ b/compiler/aarch64/hlcgcpu.pas @@ -210,7 +210,8 @@ implementation if slopt in [SL_SETZERO,SL_SETMAX] then inherited else if not(sreg.bitlen in [32,64]) or - (sreg.startbit<>0) then + (sreg.startbit<>0) or + (getsubreg(fromreg)<getsubreg(sreg.subsetreg)) then begin makeregssamesize(list,def_cgsize(fromsize),sreg.subsetregsize,fromreg,sreg.subsetreg,fromreg,toreg); list.concat(taicpu.op_reg_reg_const_const(A_BFI,toreg,fromreg,sreg.startbit,sreg.bitlen)) diff --git a/compiler/aarch64/ncpuinl.pas b/compiler/aarch64/ncpuinl.pas index a2e5f1352f..1ea4537b3b 100644 --- a/compiler/aarch64/ncpuinl.pas +++ b/compiler/aarch64/ncpuinl.pas @@ -1,7 +1,7 @@ { Copyright (c) 1998-2002 by Florian Klaempfl - Generates ARM inline nodes + Generates AAarch64 inline nodes 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 @@ -35,6 +35,8 @@ interface function first_sqrt_real: tnode; override; function first_round_real: tnode; override; function first_trunc_real: tnode; override; + function first_int_real: tnode; override; + function first_frac_real: tnode; override; function first_fma : tnode; override; procedure second_abs_real; override; procedure second_sqr_real; override; @@ -42,6 +44,8 @@ interface procedure second_abs_long; override; procedure second_round_real; override; procedure second_trunc_real; override; + procedure second_int_real; override; + procedure second_frac_real; override; procedure second_get_frame; override; procedure second_fma; override; procedure second_prefetch; override; @@ -108,16 +112,31 @@ implementation end; - function taarch64inlinenode.first_fma : tnode; - begin - if ((is_double(resultdef)) or (is_single(resultdef))) then - begin - expectloc:=LOC_MMREGISTER; - Result:=nil; - end - else - Result:=inherited first_fma; - end; + function taarch64inlinenode.first_int_real : tnode; + begin + expectloc:=LOC_MMREGISTER; + result:=nil; + end; + + + function taarch64inlinenode.first_frac_real : tnode; + begin + expectloc:=LOC_MMREGISTER; + result:=nil; + end; + + + function taarch64inlinenode.first_fma : tnode; + begin + if ((is_double(resultdef)) or (is_single(resultdef))) then + begin + expectloc:=LOC_MMREGISTER; + Result:=nil; + end + else + Result:=inherited first_fma; + end; + procedure taarch64inlinenode.second_abs_real; begin @@ -187,6 +206,33 @@ implementation end; + procedure taarch64inlinenode.second_int_real; + var + hreg: tregister; + begin + secondpass(left); + hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true); + location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef)); + location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FRINTZ,location.register,left.location.register)); + cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList); + end; + + + procedure taarch64inlinenode.second_frac_real; + var + hreg: tregister; + begin + secondpass(left); + hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true); + location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef)); + location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FRINTZ,location.register,left.location.register)); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_FSUB,location.register,left.location.register,location.register)); + cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList); + end; + + procedure taarch64inlinenode.second_get_frame; begin location_reset(location,LOC_CREGISTER,OS_ADDR); diff --git a/compiler/aasmtai.pas b/compiler/aasmtai.pas index 84049cae9a..fec178a2cf 100644 --- a/compiler/aasmtai.pas +++ b/compiler/aasmtai.pas @@ -402,7 +402,7 @@ interface { supported by recent clang-based assemblers for data-in-code } asd_data_region, asd_end_data_region, { ARM } - asd_thumb_func,asd_code, + asd_thumb_func,asd_code,asd_force_thumb, { restricts the assembler only to those instructions, which are available on the specified CPU; this represents directives such as NASM's 'CPU 686' or MASM/TASM's '.686p'. Might not be supported by @@ -452,6 +452,7 @@ interface { ARM } 'thumb_func', 'code', + 'force_thumb', 'cpu', { for the OMF object format } 'omf_line', diff --git a/compiler/arm/aasmcpu.pas b/compiler/arm/aasmcpu.pas index 443681430a..c8cb8ff3ce 100644 --- a/compiler/arm/aasmcpu.pas +++ b/compiler/arm/aasmcpu.pas @@ -1621,6 +1621,9 @@ implementation end; end; +{$push} +{ Disable range and overflow checking here } +{$R-}{$Q-} procedure fix_invalid_imms(list: TAsmList); var curtai: tai; @@ -1669,6 +1672,7 @@ implementation end; end; +{$pop} procedure gather_it_info(list: TAsmList); var diff --git a/compiler/arm/cpubase.pas b/compiler/arm/cpubase.pas index 9432c122c7..08189c4202 100644 --- a/compiler/arm/cpubase.pas +++ b/compiler/arm/cpubase.pas @@ -605,6 +605,9 @@ unit cpubase; end; +{$push} +{ Disable range and overflow checking here } +{$R-}{$Q-} function is_thumb32_imm(d: aint): boolean; var t : aint; @@ -639,9 +642,6 @@ unit cpubase; end; end; -{$push} -{ Disable range and overflow checking here } -{$R-}{$Q-} function is_continuous_mask(d : aword;var lsb, width: byte) : boolean; var msb : byte; diff --git a/compiler/arm/narmset.pas b/compiler/arm/narmset.pas index 4d0c2cb5ca..9c0d668134 100644 --- a/compiler/arm/narmset.pas +++ b/compiler/arm/narmset.pas @@ -191,15 +191,23 @@ implementation procedure genitem_thumb2(list:TAsmList;t : pcaselabel); var - i : aint; + i : int64; begin if assigned(t^.less) then genitem_thumb2(list,t^.less); { fill possible hole } - for i:=last.svalue+1 to t^._low.svalue-1 do - list.concat(Tai_const.Create_rel_sym(aitconst_half16bit,tablelabel,elselabel)); - for i:=t^._low.svalue to t^._high.svalue do - list.concat(Tai_const.Create_rel_sym(aitconst_half16bit,tablelabel,blocklabel(t^.blockid))); + i:=last.svalue+1; + while i<=t^._low.svalue-1 do + begin + list.concat(Tai_const.Create_rel_sym(aitconst_half16bit,tablelabel,elselabel)); + i:=i+1; + end; + i:=t^._low.svalue; + while i<=t^._high.svalue do + begin + list.concat(Tai_const.Create_rel_sym(aitconst_half16bit,tablelabel,blocklabel(t^.blockid))); + i:=i+1; + end; last:=t^._high.svalue; if assigned(t^.greater) then genitem_thumb2(list,t^.greater); diff --git a/compiler/arm/raarmgas.pas b/compiler/arm/raarmgas.pas index ef7a26a2fd..56ba931571 100644 --- a/compiler/arm/raarmgas.pas +++ b/compiler/arm/raarmgas.pas @@ -151,6 +151,7 @@ Unit raarmgas; function tarmattreader.is_targetdirective(const s: string): boolean; begin case s of + '.force_thumb', '.thumb_func', '.code', '.thumb_set': @@ -1464,6 +1465,11 @@ Unit raarmgas; begin consume(AS_TARGET_DIRECTIVE); curList.concat(tai_directive.create(asd_thumb_func,'')); + end; + '.force_thumb': + begin + consume(AS_TARGET_DIRECTIVE); + curList.concat(tai_directive.create(asd_force_thumb,'')); end else inherited HandleTargetDirective; diff --git a/compiler/arm/rgcpu.pas b/compiler/arm/rgcpu.pas index 65a7fda72f..7fa6c16e2d 100644 --- a/compiler/arm/rgcpu.pas +++ b/compiler/arm/rgcpu.pas @@ -400,10 +400,11 @@ unit rgcpu; level := 0; while assigned(hp) do begin - if IsIT(taicpu(hp).opcode) then - break - else if hp.typ=ait_instruction then - inc(level); + if hp.typ=ait_instruction then + if IsIT(taicpu(hp).opcode) then + break + else + inc(level); hp:=tai(hp.Previous); end; diff --git a/compiler/assemble.pas b/compiler/assemble.pas index aab41ccc2b..a3798d1bdc 100644 --- a/compiler/assemble.pas +++ b/compiler/assemble.pas @@ -1403,8 +1403,8 @@ Implementation len:=p-pstart; if len>255 then internalerror(200509187); - move(pstart^,hs[1],len); hs[0]:=chr(len); + move(pstart^,hs[1],len); sym:=objdata.symbolref(hs); { Second symbol? } if assigned(relocsym) then @@ -1719,6 +1719,11 @@ Implementation {$ifdef ARM} asd_thumb_func: ObjData.ThumbFunc:=true; + asd_force_thumb: + begin + ObjData.ThumbFunc:=true; + Code16:=true; + end; asd_code: begin { ai_directive(hp).name can be only 16 or 32, this is checked by the reader } @@ -1924,6 +1929,9 @@ Implementation asd_thumb_func: { ignore for now, but should be added} ; + asd_force_thumb: + { ignore for now, but should be added} + ; asd_code: { ignore for now, but should be added} ; diff --git a/compiler/globals.pas b/compiler/globals.pas index f26979d83b..ab570352a6 100644 --- a/compiler/globals.pas +++ b/compiler/globals.pas @@ -416,6 +416,7 @@ interface {$if defined(m68k)} { Sinclair QL specific } sinclairql_metadata_format: string[4] = 'QHDR'; + sinclairql_vlink_experimental: boolean = false; { temporary } {$endif defined(m68k)} { default name of the C-style "main" procedure of the library/program } diff --git a/compiler/m68k/ag68kvasm.pas b/compiler/m68k/ag68kvasm.pas index a37e24fe35..7c1a7bf9bc 100644 --- a/compiler/m68k/ag68kvasm.pas +++ b/compiler/m68k/ag68kvasm.pas @@ -96,8 +96,7 @@ unit ag68kvasm; result:=asminfo^.asmcmd; case target_info.system of - { a.out doesn't support named sections, a.out is limited - (no named sections) lets use ELF for interoperability } + { a.out doesn't support named sections, lets use ELF for interoperability } system_m68k_amiga, system_m68k_atari, system_m68k_sinclairql: objtype:='-Felf'; diff --git a/compiler/m68k/cpubase.pas b/compiler/m68k/cpubase.pas index 6ecf62ec53..cf592f19a2 100644 --- a/compiler/m68k/cpubase.pas +++ b/compiler/m68k/cpubase.pas @@ -331,6 +331,10 @@ implementation {$i r68kstd.inc} ); + std_regfullname_table : TRegNameTable = ( + {$i r68kstdf.inc} + ); + regnumber_index : array[tregisterindex] of tregisterindex = ( {$i r68krni.inc} ); @@ -484,6 +488,10 @@ implementation function std_regnum_search(const s:string):Tregister; begin result:=regnumber_table[findreg_by_name_table(s,std_regname_table,std_regname_index)]; + if result=NR_NO then + begin + result:=regnumber_table[findreg_by_name_table(s,std_regfullname_table,std_regname_index)]; + end; end; diff --git a/compiler/m68k/r68kgri.inc b/compiler/m68k/r68kgri.inc index 0e386d3f1a..31c8bf302e 100644 --- a/compiler/m68k/r68kgri.inc +++ b/compiler/m68k/r68kgri.inc @@ -16,30 +16,30 @@ 56, 57, 34, +3, 1, 2, -3, +6, 4, 5, -6, +9, 7, 8, -9, 12, -11, 10, +11, +15, 13, 14, -15, +18, 16, 17, -18, +21, 19, 20, -21, 24, -23, 22, +23, 38, 25, 26, diff --git a/compiler/m68k/r68ksri.inc b/compiler/m68k/r68ksri.inc index 47fd3b2f30..0f66a7b772 100644 --- a/compiler/m68k/r68ksri.inc +++ b/compiler/m68k/r68ksri.inc @@ -1,46 +1,46 @@ { don't edit, this file is generated from m68kreg.dat } 0, -43, 42, -45, +43, 44, -47, +45, 46, -49, +47, 48, -51, +49, 50, -53, +51, 52, -55, +53, 54, -57, +55, 56, +57, 34, -1, 3, +1, 2, -5, -4, 6, -7, +4, +5, 9, +7, 8, -11, 12, 10, -13, +11, 15, +13, 14, -17, -16, 18, -19, +16, +17, 21, +19, 20, -23, 24, 22, +23, 38, 25, 26, diff --git a/compiler/m68k/ra68kmot.pas b/compiler/m68k/ra68kmot.pas index ba7f0a3b4e..184a9742ae 100644 --- a/compiler/m68k/ra68kmot.pas +++ b/compiler/m68k/ra68kmot.pas @@ -216,6 +216,11 @@ const actasmregister:=std_regnum_search(lower(s)); if actasmregister<>NR_NO then begin + { this is a hack. if the reg is valid, and its string doesn't + contain a dot, we make sure it's a full size reg (KB) } + if (getregtype(actasmregister) in [R_ADDRESSREGISTER,R_INTREGISTER]) and + (Pos('.',s) = 0) then + setsubreg(actasmregister,R_SUBWHOLE); result:=true; actasmtoken:=AS_REGISTER; end; @@ -1196,7 +1201,7 @@ const while actasmtoken <> AS_SEPARATOR do Consume(actasmtoken); end; - exit; + exit; end; { // (reg,reg .. // } Consume(AS_COMMA); diff --git a/compiler/ncnv.pas b/compiler/ncnv.pas index 4182b2d3ad..5f5cb3f4cb 100644 --- a/compiler/ncnv.pas +++ b/compiler/ncnv.pas @@ -1630,6 +1630,10 @@ implementation include(flags,nf_is_currency); typecheckpass(left); end; + { comp is handled by the fpu but not a floating type point } + if is_fpucomp(resultdef) and not(is_fpucomp(left.resultdef)) and + not (nf_explicit in flags) then + Message(type_w_convert_real_2_comp); end else include(flags,nf_is_currency); @@ -2948,6 +2952,11 @@ implementation gotsint:=true; result:=docheckremoveinttypeconvs(tunarynode(n).left); end; + shrn: + begin + result:=wasoriginallysmallerint(tbinarynode(n).left) and + docheckremoveinttypeconvs(tbinarynode(n).right); + end; notn: result:=docheckremoveinttypeconvs(tunarynode(n).left); addn,muln,divn,modn,andn,shln: @@ -2981,15 +2990,26 @@ implementation { remove int type conversions and set the result to the given type } - procedure doremoveinttypeconvs(var n: tnode; todef: tdef; forceunsigned: boolean; signedtype,unsignedtype : tdef); + procedure doremoveinttypeconvs(level : dword;var n: tnode; todef: tdef; forceunsigned: boolean; signedtype,unsignedtype : tdef); var newblock: tblocknode; newstatements: tstatementnode; originaldivtree: tnode; tempnode: ttempcreatenode; begin + { we may not recurse into shr nodes: + + dword1:=dword1+((dword2+dword3) shr 2); + + while we can remove an extension on the addition, we cannot remove it from the shr + } + if (n.nodetype=shrn) and (level<>0) then + begin + inserttypeconv_internal(n,todef); + exit; + end; case n.nodetype of - subn,addn,muln,divn,modn,xorn,andn,orn,shln: + subn,addn,muln,divn,modn,xorn,andn,orn,shln,shrn: begin exclude(n.flags,nf_internal); if not forceunsigned and @@ -2998,8 +3018,8 @@ implementation originaldivtree:=nil; if n.nodetype in [divn,modn] then originaldivtree:=n.getcopy; - doremoveinttypeconvs(tbinarynode(n).left,signedtype,false,signedtype,unsignedtype); - doremoveinttypeconvs(tbinarynode(n).right,signedtype,false,signedtype,unsignedtype); + doremoveinttypeconvs(level+1,tbinarynode(n).left,signedtype,false,signedtype,unsignedtype); + doremoveinttypeconvs(level+1,tbinarynode(n).right,signedtype,false,signedtype,unsignedtype); n.resultdef:=signedtype; if n.nodetype in [divn,modn] then begin @@ -3026,8 +3046,8 @@ implementation end else begin - doremoveinttypeconvs(tbinarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype); - doremoveinttypeconvs(tbinarynode(n).right,unsignedtype,forceunsigned,signedtype,unsignedtype); + doremoveinttypeconvs(level+1,tbinarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype); + doremoveinttypeconvs(level+1,tbinarynode(n).right,unsignedtype,forceunsigned,signedtype,unsignedtype); n.resultdef:=unsignedtype; end; //if ((n.nodetype=andn) and (tbinarynode(n).left.nodetype=ordconstn) and @@ -3044,12 +3064,12 @@ implementation if not forceunsigned and is_signed(n.resultdef) then begin - doremoveinttypeconvs(tunarynode(n).left,signedtype,false,signedtype,unsignedtype); + doremoveinttypeconvs(level+1,tunarynode(n).left,signedtype,false,signedtype,unsignedtype); n.resultdef:=signedtype; end else begin - doremoveinttypeconvs(tunarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype); + doremoveinttypeconvs(level+1,tunarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype); n.resultdef:=unsignedtype; end; end; @@ -3344,22 +3364,22 @@ implementation to 64 bit } if (resultdef.size <= 4) and is_64bitint(left.resultdef) and - (left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln]) and + (left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln,shrn]) and checkremovebiginttypeconvs(left,foundsint,[s8bit,u8bit,s16bit,u16bit,s32bit,u32bit],int64(low(longint)),high(cardinal)) then - doremoveinttypeconvs(left,generrordef,not foundsint,s32inttype,u32inttype); + doremoveinttypeconvs(0,left,generrordef,not foundsint,s32inttype,u32inttype); {$if defined(cpu16bitalu)} if (resultdef.size <= 2) and (is_32bitint(left.resultdef) or is_64bitint(left.resultdef)) and - (left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln]) and + (left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln,shrn]) and checkremovebiginttypeconvs(left,foundsint,[s8bit,u8bit,s16bit,u16bit],int64(low(smallint)),high(word)) then - doremoveinttypeconvs(left,generrordef,not foundsint,s16inttype,u16inttype); + doremoveinttypeconvs(0,left,generrordef,not foundsint,s16inttype,u16inttype); {$endif defined(cpu16bitalu)} {$if defined(cpu8bitalu)} if (resultdef.size<left.resultdef.size) and is_integer(left.resultdef) and - (left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln]) and + (left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln,shrn]) and checkremovebiginttypeconvs(left,foundsint,[s8bit,u8bit],int64(low(shortint)),high(byte)) then - doremoveinttypeconvs(left,generrordef,not foundsint,s8inttype,u8inttype); + doremoveinttypeconvs(0,left,generrordef,not foundsint,s8inttype,u8inttype); {$endif defined(cpu8bitalu)} { the above simplification may have left a redundant equal typeconv (e.g. int32 to int32). If that's the case, we remove it } diff --git a/compiler/ogcoff.pas b/compiler/ogcoff.pas index 879eb0ca25..e5d9fd0844 100644 --- a/compiler/ogcoff.pas +++ b/compiler/ogcoff.pas @@ -2063,6 +2063,8 @@ const pemagic : array[0..3] of byte = ( FCoffSyms.Read(bosym,sizeof(bosym)); if bosym.Name.Offset.Zeroes<>0 then begin + { Added for sake of global data analysis } + strname[0]:=#0; move(bosym.Name.ShortName,strname[1],8); strname[9]:=#0; strname[0]:=chr(strlen(@strname[1])); @@ -2081,6 +2083,8 @@ const pemagic : array[0..3] of byte = ( FCoffSyms.Read(sym,sizeof(sym)); if plongint(@sym.name)^<>0 then begin + { Added for sake of global data analysis } + strname[0]:=#0; move(sym.name,strname[1],8); strname[9]:=#0; strname[0]:=chr(strlen(@strname[1])); diff --git a/compiler/ogelf.pas b/compiler/ogelf.pas index bb77186427..e21123c8c6 100644 --- a/compiler/ogelf.pas +++ b/compiler/ogelf.pas @@ -672,7 +672,10 @@ implementation if assigned(objreloc) then begin objreloc.size:=len; - if reltype in [RELOC_RELATIVE{$ifdef x86},RELOC_PLT32{$endif}{$ifdef x86_64},RELOC_TLSGD,RELOC_GOTPCREL{$endif}] then + { RELOC_GOTPCREL, RELOC_REX_GOTPCRELX, RELOC_GOTPCRELX] need special handling + this is done in x86/aasmcpu unit } + if reltype in [RELOC_RELATIVE{$ifdef x86},RELOC_PLT32{$endif} + {$ifdef x86_64}, RELOC_GOTPCREL, RELOC_REX_GOTPCRELX, RELOC_GOTPCRELX,RELOC_TLSGD{$endif}] then dec(data,len); if ElfTarget.relocs_use_addend then begin diff --git a/compiler/options.pas b/compiler/options.pas index d10709ed21..990e92dda8 100644 --- a/compiler/options.pas +++ b/compiler/options.pas @@ -140,6 +140,7 @@ const suppported_targets_x_smallr = systems_linux + systems_solaris + systems_android + + systems_openbsd + [system_i386_haiku,system_x86_64_haiku] + [system_i386_beos] + [system_m68k_amiga]; @@ -2760,6 +2761,13 @@ begin IllegalPara(opt); end; {$if defined(m68k)} + 'L': + begin + if (target_info.system in [system_m68k_sinclairql]) then + sinclairql_vlink_experimental:=true + else + IllegalPara(opt); + end; 'Q': begin if (target_info.system in [system_m68k_sinclairql]) then diff --git a/compiler/pass_1.pas b/compiler/pass_1.pas index 2ac00dbc43..4d543a8e31 100644 --- a/compiler/pass_1.pas +++ b/compiler/pass_1.pas @@ -189,6 +189,7 @@ implementation { should the node be replaced? } if assigned(hp) then begin + hp.flags := hp.flags + (p.flags * [nf_usercode_entry]); p.free; { switch to new node } p:=hp; diff --git a/compiler/pdecsub.pas b/compiler/pdecsub.pas index b7ce1fda75..5dcb4ad8a7 100644 --- a/compiler/pdecsub.pas +++ b/compiler/pdecsub.pas @@ -1959,7 +1959,8 @@ var pt : tnode; {$endif WITHDMT} begin - if (not assigned(pd.owner.defowner) or + if assigned(pd.owner) and + (not assigned(pd.owner.defowner) or not is_java_class_or_interface(tdef(pd.owner.defowner))) and (po_external in pd.procoptions) then Message2(parser_e_proc_dir_conflict,'EXTERNAL','"VIRTUAL"'); diff --git a/compiler/pgenutil.pas b/compiler/pgenutil.pas index 4804995dbb..1829ce335a 100644 --- a/compiler/pgenutil.pas +++ b/compiler/pgenutil.pas @@ -813,6 +813,9 @@ uses st : TSymtable; i : longint; begin + { since commit 48986 deflist might have NIL entries } + if not assigned(def) then + exit; case def.typ of procdef: tprocdef(def).forwarddef:=false; diff --git a/compiler/pmodules.pas b/compiler/pmodules.pas index 60f93e6ae4..9094500eb5 100644 --- a/compiler/pmodules.pas +++ b/compiler/pmodules.pas @@ -614,10 +614,14 @@ implementation i: longint; def: tdef; sym: tsym; + tmpidx: Integer; begin for i:=current_module.localsymtable.deflist.count-1 downto 0 do begin def:=tdef(current_module.localsymtable.deflist[i]); + { since commit 48986 deflist might have NIL entries } + if not assigned(def) then + continue; { this also frees def, as the defs are owned by the symtable } if not def.is_registered and not(df_not_registered_no_free in def.defoptions) then @@ -630,6 +634,10 @@ implementation tprocdef(def).procsym.is_registered then tprocsym(tprocdef(def).procsym).ProcdefList.Remove(def); current_module.localsymtable.deletedef(def); + { this prevents a dangling pointer and use after free } + tmpidx:=current_module.deflist.IndexOfItem(def,FromEnd); + if tmpidx<>-1 then + current_module.deflist[tmpidx]:=nil; end; end; { from high to low so we hopefully have moves of less data } diff --git a/compiler/scanner.pas b/compiler/scanner.pas index b33f7a73c5..9632471f24 100644 --- a/compiler/scanner.pas +++ b/compiler/scanner.pas @@ -4883,12 +4883,21 @@ type inc(yylexcount); substitutemacro(pattern,mac.buftext,mac.buflen, mac.fileinfo.line,mac.fileinfo.fileindex); - { handle empty macros } + { handle empty macros } if c=#0 then - reload; - readtoken(false); - { that's all folks } - dec(yylexcount); + begin + reload; + { avoid macro nesting error in case of + a sequence of empty macros, see #38802 } + dec(yylexcount); + readtoken(false); + end + else + begin + readtoken(false); + { that's all folks } + dec(yylexcount); + end; exit; end else diff --git a/compiler/systems/t_bsd.pas b/compiler/systems/t_bsd.pas index 915e57be82..99a4b8ca97 100644 --- a/compiler/systems/t_bsd.pas +++ b/compiler/systems/t_bsd.pas @@ -482,12 +482,14 @@ begin (tf_smartlink_sections in target_info.flags) then GCSectionsStr:='--gc-sections'; - if(cs_profile in current_settings.moduleswitches) or + if (cs_profile in current_settings.moduleswitches) or ((Info.DynamicLinker<>'') and ((not SharedLibFiles.Empty) or (target_info.system in systems_openbsd))) then - DynLinkStr:='-dynamic-linker='+Info.DynamicLinker; + DynLinkStr:='-dynamic-linker='+Info.DynamicLinker; + if rlinkpath<>'' then + DynLinkStr:=DynLinkStr+' --rpath-link '+rlinkpath; if CShared Then begin DynLinKStr:=DynLinkStr+' --shared' diff --git a/compiler/systems/t_freertos.pas b/compiler/systems/t_freertos.pas index 027d29f15c..2c815cfbed 100644 --- a/compiler/systems/t_freertos.pas +++ b/compiler/systems/t_freertos.pas @@ -955,6 +955,8 @@ var t: Text; hp: TCmdStrListItem; filepath: TCmdStr; + i,j: integer; + lib: AnsiString; {$endif XTENSA} begin {$ifdef XTENSA} @@ -1139,6 +1141,20 @@ begin if ioresult<>0 then exit; + { extract libraries from linker options and add to static libraries list } + Info.ExtraOptions:=trim(Info.ExtraOptions); + i := pos('-l', Info.ExtraOptions); + while i > 0 do + begin + j:=pos(' ',Info.ExtraOptions); + if j=0 then + j:=length(Info.ExtraOptions)+1; + lib:=copy(Info.ExtraOptions,i+2,j-i-2); + AddStaticCLibrary(lib); + delete(Info.ExtraOptions,i,j); + trim(Info.ExtraOptions); + i := pos('-l', Info.ExtraOptions); + end; hp:=TCmdStrListItem(StaticLibFiles.First); while assigned(hp) do begin @@ -1256,8 +1272,7 @@ begin Replace(cmdstr,'$GCSECTIONS',GCSectionsStr); Replace(cmdstr,'$DYNLINK',DynLinkStr); end; - if success and not(cs_link_nolink in current_settings.globalswitches) then - success:=DoExec(FindUtil(utilsprefix+BinStr),cmdstr,true,false); + success:=DoExec(FindUtil(utilsprefix+BinStr),cmdstr,true,false); { Remove ReponseFile } if success and not(cs_link_nolink in current_settings.globalswitches) then diff --git a/compiler/systems/t_nds.pas b/compiler/systems/t_nds.pas index 2ee6a516cd..1cc0afb5fd 100644 --- a/compiler/systems/t_nds.pas +++ b/compiler/systems/t_nds.pas @@ -57,7 +57,7 @@ begin SharedLibFiles.doubles:=true; StaticLibFiles.doubles:=true; // set arm9 as default apptype - if (apptype <> app_arm9) or (apptype <> app_arm7) then + if (apptype <> app_arm9) and (apptype <> app_arm7) then apptype:=app_arm9; end; diff --git a/compiler/systems/t_sinclairql.pas b/compiler/systems/t_sinclairql.pas index 1e16e4ebab..444fd3aa5b 100644 --- a/compiler/systems/t_sinclairql.pas +++ b/compiler/systems/t_sinclairql.pas @@ -115,7 +115,7 @@ begin end else begin - ExeCmd[1]:='vlink -b rawseg -q $FLAGS $GCSECTIONS $OPT $STRIP $MAP -o $EXE -T $RES'; + ExeCmd[1]:='vlink $QLFLAGS $FLAGS $GCSECTIONS $OPT $STRIP $MAP -o $EXE -T $RES'; end; end; end; @@ -245,6 +245,7 @@ var DynLinkStr : string; GCSectionsStr : string; FlagsStr : string; + QLFlagsStr: string; MapStr : string; ExeName: string; fd,fs: file; @@ -258,6 +259,7 @@ var QLHeader: TQLHeader; XTccData: TXTccData; BinSize: longint; + RelocSize: longint; DataSpace: DWord; begin StripStr:=''; @@ -276,6 +278,10 @@ begin begin if create_smartlink_sections then GCSectionsStr:='-gc-all'; + if sinclairql_vlink_experimental then + QLFlagsStr:='-b sinclairql -q -'+lower(sinclairql_metadata_format)+' -stack='+tostr(StackSize) + else + QLFlagsStr:='-b rawseg -q'; end; ExeName:=current_module.exefilename; @@ -292,18 +298,20 @@ begin Replace(cmdstr,'$STRIP',StripStr); Replace(cmdstr,'$GCSECTIONS',GCSectionsStr); Replace(cmdstr,'$DYNLINK',DynLinkStr); + Replace(cmdstr,'$QLFLAGS',QLFlagsStr); MakeSinclairQLExe:=DoExec(BinStr,CmdStr,true,false); { Kludge: With the above linker script, vlink will produce two files. The main binary and the relocation info. Here we copy the two together. (KB) } - if MakeSinclairQLExe then + if MakeSinclairQLExe and not sinclairql_vlink_experimental then begin QLHeader:=DefaultQLHeader; XTccData:=DefaultXTccData; BinSize:=0; + RelocSize:=0; bufsize:=16384; {$push} {$i-} @@ -321,13 +329,18 @@ begin assign(fd,ExeName); rewrite(fd,1); + assign(fs,ExeName+'.'+ProgramHeaderName+'.rel'+ProgramHeaderName); + reset(fs,1); + RelocSize := FileSize(fs); + close(fs); + assign(fs,ExeName+'.'+ProgramHeaderName); reset(fs,1); BinSize := FileSize(fs); { We assume .bss size is total size indicated by linker minus emmited binary. DataSpace size is .bss + stack space } - DataSpace := NToBE(DWord(HeaderSize - BinSize + StackSize)); + DataSpace := NToBE(DWord(max((HeaderSize - BinSize) - RelocSize + StackSize,0))); { Option: prepend QEmuLator and QPC2 v5 compatible header to EXE } if sinclairql_metadata_format='QHDR' then diff --git a/compiler/utils/mk68kreg.pp b/compiler/utils/mk68kreg.pp index 3cd6d19c40..59c9445811 100644 --- a/compiler/utils/mk68kreg.pp +++ b/compiler/utils/mk68kreg.pp @@ -133,7 +133,7 @@ begin i:=h; repeat j:=i+p; - if stdnames[std_regname_index[j]]>=stdnames[std_regname_index[i]] then + if stdfullnames[std_regname_index[j]]>=stdfullnames[std_regname_index[i]] then break; t:=std_regname_index[i]; std_regname_index[i]:=std_regname_index[j]; @@ -164,7 +164,7 @@ begin i:=h; repeat j:=i+p; - if gasnames[gas_regname_index[j]]>=gasnames[gas_regname_index[i]] then + if gasfullnames[gas_regname_index[j]]>=gasfullnames[gas_regname_index[i]] then break; t:=gas_regname_index[i]; gas_regname_index[i]:=gas_regname_index[j]; diff --git a/compiler/wasm32/agllvmmc.pas b/compiler/wasm32/agllvmmc.pas index 4468a56f27..de9e0a8b99 100644 --- a/compiler/wasm32/agllvmmc.pas +++ b/compiler/wasm32/agllvmmc.pas @@ -70,31 +70,36 @@ implementation procedure TLLVMMachineCodePlaygroundAssembler.WriteImports; var i : integer; + def : tdef; proc : tprocdef; list : TAsmList; cur_unit: tused_unit; begin for i:=0 to current_module.deflist.Count-1 do - if assigned(current_module.deflist[i]) and (tdef(current_module.deflist[i]).typ=procdef) then - begin - proc := tprocdef(current_module.deflist[i]); - if (po_external in proc.procoptions) and assigned(proc.import_dll) then - begin - //WriteProcDef(proc); - list:=TAsmList.Create; - thlcgwasm(hlcg).g_procdef(list,proc); - WriteTree(list); - list.free; - writer.AsmWrite(#9'.import_module'#9); - writer.AsmWrite(proc.mangledname); - writer.AsmWrite(', '); - writer.AsmWriteLn(proc.import_dll^); - writer.AsmWrite(#9'.import_name'#9); - writer.AsmWrite(proc.mangledname); - writer.AsmWrite(', '); - writer.AsmWriteLn(proc.import_name^); - end; - end; + begin + def:=tdef(current_module.deflist[i]); + { since commit 48986 deflist might have NIL entries } + if assigned(def) and (def.typ=procdef) then + begin + proc := tprocdef(def); + if (po_external in proc.procoptions) and assigned(proc.import_dll) then + begin + //WriteProcDef(proc); + list:=TAsmList.Create; + thlcgwasm(hlcg).g_procdef(list,proc); + WriteTree(list); + list.free; + writer.AsmWrite(#9'.import_module'#9); + writer.AsmWrite(proc.mangledname); + writer.AsmWrite(', '); + writer.AsmWriteLn(proc.import_dll^); + writer.AsmWrite(#9'.import_name'#9); + writer.AsmWrite(proc.mangledname); + writer.AsmWrite(', '); + writer.AsmWriteLn(proc.import_name^); + end; + end; + end; list:=TAsmList.Create; cur_unit:=tused_unit(usedunits.First); while assigned(cur_unit) do @@ -107,13 +112,16 @@ implementation list.Concat(tai_functype.create(make_mangledname('FINALIZE$',cur_unit.u.globalsymtable,''),TWasmFuncType.Create([],[]))); end; for i:=0 to cur_unit.u.deflist.Count-1 do - if assigned(cur_unit.u.deflist[i]) and (tdef(cur_unit.u.deflist[i]).typ = procdef) then - begin - proc := tprocdef(cur_unit.u.deflist[i]); - if (not proc.owner.iscurrentunit or (po_external in proc.procoptions)) and - ((proc.paras.Count=0) or (proc.has_paraloc_info in [callerside,callbothsides])) then - thlcgwasm(hlcg).g_procdef(list,proc); - end; + begin + def:=tdef(cur_unit.u.deflist[i]); + if assigned(def) and (tdef(def).typ = procdef) then + begin + proc := tprocdef(def); + if (not proc.owner.iscurrentunit or (po_external in proc.procoptions)) and + ((proc.paras.Count=0) or (proc.has_paraloc_info in [callerside,callbothsides])) then + thlcgwasm(hlcg).g_procdef(list,proc); + end; + end; cur_unit:=tused_unit(cur_unit.Next); end; WriteTree(list); diff --git a/compiler/wasm32/agwat.pas b/compiler/wasm32/agwat.pas index 7d40c64936..13684044dd 100644 --- a/compiler/wasm32/agwat.pas +++ b/compiler/wasm32/agwat.pas @@ -957,14 +957,17 @@ implementation procedure TWabtTextAssembler.WriteImports; var i : integer; + def : tdef; proc : tprocdef; sym : tsym; j : integer; psym : tprocsym; begin for i:=0 to current_module.deflist.Count-1 do begin - if tdef(current_module.deflist[i]).typ = procdef then begin - proc := tprocdef(current_module.deflist[i]); + def:=tdef(current_module.deflist[i]); + { since commit 48986 deflist might have NIL entries } + if assigned(def) and (def.typ=procdef) then begin + proc := tprocdef(def); if (po_external in proc.procoptions) and assigned(proc.import_dll) then begin writer.AsmWrite(#9'(import "'); writer.AsmWrite(proc.import_dll^); diff --git a/compiler/wasm32/nwasmflw.pas b/compiler/wasm32/nwasmflw.pas index aa82e0e700..84a230dc1b 100644 --- a/compiler/wasm32/nwasmflw.pas +++ b/compiler/wasm32/nwasmflw.pas @@ -49,6 +49,13 @@ interface procedure pass_generate_code;override; end; + { twasmraisenode } + + twasmraisenode = class(tcgraisenode) + public + function pass_1 : tnode;override; + end; + { twasmtryexceptnode } twasmtryexceptnode = class(tcgtryexceptnode) @@ -68,9 +75,9 @@ implementation uses verbose,globals,systems,globtype,constexp, symconst,symdef,symsym,aasmtai,aasmdata,aasmcpu,defutil,defcmp, - procinfo,cgbase,pass_1,pass_2,parabase, + procinfo,cgbase,pass_1,pass_2,parabase,compinnr, cpubase,cpuinfo, - nbas,nld,ncon,ncnv, + nbas,nld,ncon,ncnv,ncal,ninl,nmem,nadd, tgobj,paramgr, cgutils,hlcgobj,hlcgcpu; @@ -204,6 +211,66 @@ implementation end; {***************************************************************************** + twasmraisenode +*****************************************************************************} + + function twasmraisenode.pass_1 : tnode; + var + statements : tstatementnode; + //current_addr : tlabelnode; + raisenode : tcallnode; + begin + result:=internalstatements(statements); + + if assigned(left) then + begin + { first para must be a class } + firstpass(left); + { insert needed typeconvs for addr,frame } + if assigned(right) then + begin + { addr } + firstpass(right); + { frame } + if assigned(third) then + firstpass(third) + else + third:=cpointerconstnode.Create(0,voidpointertype); + end + else + begin + third:=cinlinenode.create(in_get_frame,false,nil); + //current_addr:=clabelnode.create(cnothingnode.create,clabelsym.create('$raiseaddr')); + //addstatement(statements,current_addr); + //right:=caddrnode.create(cloadnode.create(current_addr.labsym,current_addr.labsym.owner)); + right:=cnilnode.create; + + { raise address off by one so we are for sure inside the action area for the raise } + if tf_use_psabieh in target_info.flags then + right:=caddnode.create_internal(addn,right,cordconstnode.create(1,sizesinttype,false)); + end; + + raisenode:=ccallnode.createintern('fpc_raiseexception', + ccallparanode.create(third, + ccallparanode.create(right, + ccallparanode.create(left,nil))) + ); + include(raisenode.callnodeflags,cnf_call_never_returns); + addstatement(statements,raisenode); + end + else + begin + addstatement(statements,ccallnode.createintern('fpc_popaddrstack',nil)); + raisenode:=ccallnode.createintern('fpc_reraise',nil); + include(raisenode.callnodeflags,cnf_call_never_returns); + addstatement(statements,raisenode); + end; + left:=nil; + right:=nil; + third:=nil; + end; + +{***************************************************************************** twasmtryexceptnode *****************************************************************************} @@ -258,6 +325,7 @@ implementation initialization cifnode:=twasmifnode; cwhilerepeatnode:=twasmwhilerepeatnode; + craisenode:=twasmraisenode; ctryexceptnode:=twasmtryexceptnode; ctryfinallynode:=twasmtryfinallynode; end. diff --git a/compiler/x86/aasmcpu.pas b/compiler/x86/aasmcpu.pas index 43ed8b4fd2..41f57dad9d 100644 --- a/compiler/x86/aasmcpu.pas +++ b/compiler/x86/aasmcpu.pas @@ -3682,6 +3682,16 @@ implementation end; {$endif i386} objdata.writereloc(data,len,p,Reloctype); +{$ifdef x86_64} + { Computed offset is not yet correct for GOTPC relocation } + { RELOC_GOTPCREL, RELOC_REX_GOTPCRELX, RELOC_GOTPCRELX need special handling } + if assigned(p) and (RelocType in [RELOC_GOTPCREL, RELOC_REX_GOTPCRELX, RELOC_GOTPCRELX]) and + { These relocations seem to be used only for ELF + which always has relocs_use_addend set to true + so that it is the orgsize of the last relocation which needs to be fixed PM } + (insend<>objdata.CurrObjSec.size) then + dec(TObjRelocation(objdata.CurrObjSec.ObjRelocations.Last).orgsize,insend-objdata.CurrObjSec.size); +{$endif} end; diff --git a/compiler/x86/nx86cnv.pas b/compiler/x86/nx86cnv.pas index 91ea652eb4..805c8c5a96 100644 --- a/compiler/x86/nx86cnv.pas +++ b/compiler/x86/nx86cnv.pas @@ -72,11 +72,6 @@ implementation function tx86typeconvnode.first_real_to_real : tnode; begin first_real_to_real:=nil; - { comp isn't a floating type } - if (tfloatdef(resultdef).floattype=s64comp) and - (tfloatdef(left.resultdef).floattype<>s64comp) and - not (nf_explicit in flags) then - CGMessage(type_w_convert_real_2_comp); if use_vectorfpu(resultdef) then expectloc:=LOC_MMREGISTER else |
