summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authornickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2>2021-04-27 23:11:09 +0000
committernickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2>2021-04-27 23:11:09 +0000
commita491c935588745154b576226b73833bac78fcb6e (patch)
tree973289073fb5d21573a6be2b5cfeba9abd2a9472 /compiler
parent38b5e0606069cc5985e995e1da5b6855db67f507 (diff)
parentae5b0de491a91321675f73eae5db628d068f4e05 (diff)
downloadfpc-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')
-rw-r--r--compiler/MPWMake2
-rw-r--r--compiler/Makefile2
-rw-r--r--compiler/Makefile.fpc2
-rw-r--r--compiler/aarch64/agcpugas.pas44
-rw-r--r--compiler/aarch64/aoptcpu.pas22
-rw-r--r--compiler/aarch64/hlcgcpu.pas3
-rw-r--r--compiler/aarch64/ncpuinl.pas68
-rw-r--r--compiler/aasmtai.pas3
-rw-r--r--compiler/arm/aasmcpu.pas4
-rw-r--r--compiler/arm/cpubase.pas6
-rw-r--r--compiler/arm/narmset.pas18
-rw-r--r--compiler/arm/raarmgas.pas6
-rw-r--r--compiler/arm/rgcpu.pas9
-rw-r--r--compiler/assemble.pas10
-rw-r--r--compiler/globals.pas1
-rw-r--r--compiler/m68k/ag68kvasm.pas3
-rw-r--r--compiler/m68k/cpubase.pas8
-rw-r--r--compiler/m68k/r68kgri.inc16
-rw-r--r--compiler/m68k/r68ksri.inc36
-rw-r--r--compiler/m68k/ra68kmot.pas7
-rw-r--r--compiler/ncnv.pas48
-rw-r--r--compiler/ogcoff.pas4
-rw-r--r--compiler/ogelf.pas5
-rw-r--r--compiler/options.pas8
-rw-r--r--compiler/pass_1.pas1
-rw-r--r--compiler/pdecsub.pas3
-rw-r--r--compiler/pgenutil.pas3
-rw-r--r--compiler/pmodules.pas8
-rw-r--r--compiler/scanner.pas19
-rw-r--r--compiler/systems/t_bsd.pas6
-rw-r--r--compiler/systems/t_freertos.pas19
-rw-r--r--compiler/systems/t_nds.pas2
-rw-r--r--compiler/systems/t_sinclairql.pas19
-rw-r--r--compiler/utils/mk68kreg.pp4
-rw-r--r--compiler/wasm32/agllvmmc.pas62
-rw-r--r--compiler/wasm32/agwat.pas7
-rw-r--r--compiler/wasm32/nwasmflw.pas72
-rw-r--r--compiler/x86/aasmcpu.pas10
-rw-r--r--compiler/x86/nx86cnv.pas5
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