* when we get near the limit of the maximum number of TOC entries that can

be generated for a single object file on AIX, automatically switch to
    an indirection scheme that uses much less TOC entries, but is slower to
    access global variables
  * manually merged infrastructure for target-specific code generation
    switches from JVM branch (-CTxxx switches)
  * -CTsmalltoc switch for AIX that forces the indirection scheme for TOC
    entries from the start in case the automatic one does not conserve
    a sufficient amount (or in case you bump up against the global TOC
    entries limit during linking)

git-svn-id: trunk@20963 -
This commit is contained in:
Jonas Maebe 2012-04-21 20:17:46 +00:00
parent a473cf14d6
commit 3380b58695
13 changed files with 306 additions and 111 deletions

View File

@ -62,6 +62,7 @@ interface
al_dwarf_abbrev,
al_dwarf_line,
al_picdata,
al_indirectpicdata,
al_resourcestrings,
{ Objective-C related sections }
al_objc_data,
@ -111,6 +112,7 @@ interface
'al_dwarf_abbrev',
'al_dwarf_line',
'al_picdata',
'al_indirectpicdata',
'al_resourcestrings',
'al_objc_data',
'al_objc_pools',
@ -163,6 +165,7 @@ interface
constructor create(const n:string);
destructor destroy;override;
{ asmsymbol }
function DefineAsmSymbolByClass(symclass: TAsmSymbolClass; const s : string;_bind:TAsmSymBind;_typ:Tasmsymtype) : TAsmSymbol;
function DefineAsmSymbol(const s : string;_bind:TAsmSymBind;_typ:Tasmsymtype) : TAsmSymbol;
function WeakRefAsmSymbol(const s : string) : TAsmSymbol;
function RefAsmSymbol(const s : string) : TAsmSymbol;
@ -181,6 +184,7 @@ interface
{ hash tables for reusing constant storage }
property ConstPools[APoolType:TConstPoolType]: THashSet read GetConstPools;
end;
TAsmDataClass = class of TAsmData;
TTCInitItem = class(TLinkedListItem)
sym: tsym;
@ -189,6 +193,10 @@ interface
constructor Create(asym: tsym; aoffset: aint; alabel: TAsmSymbol);
end;
const
casmdata: TAsmDataClass = TAsmData;
var
CAsmCFI : TAsmCFIClass;
current_asmdata : TAsmData;
@ -395,7 +403,7 @@ implementation
end;
function TAsmData.DefineAsmSymbol(const s : string;_bind:TAsmSymBind;_typ:Tasmsymtype) : TAsmSymbol;
function TAsmData.DefineAsmSymbolByClass(symclass: TAsmSymbolClass; const s : string;_bind:TAsmSymBind;_typ:Tasmsymtype) : TAsmSymbol;
var
hp : TAsmSymbol;
begin
@ -416,12 +424,18 @@ implementation
else
begin
{ Not found, insert it. }
hp:=TAsmSymbol.create(AsmSymbolDict,s,_bind,_typ);
hp:=symclass.create(AsmSymbolDict,s,_bind,_typ);
end;
result:=hp;
end;
function TAsmData.DefineAsmSymbol(const s : string;_bind:TAsmSymBind;_typ:Tasmsymtype) : TAsmSymbol;
begin
result:=DefineAsmSymbolByClass(TAsmSymbol,s,_bind,_typ);
end;
function TAsmData.RefAsmSymbol(const s : string) : TAsmSymbol;
begin
result:=TAsmSymbol(FAsmSymbolDict.Find(s));

View File

@ -551,7 +551,7 @@ implementation
deprecatedmsg:=nil;
_exports:=TLinkedList.Create;
dllscannerinputlist:=TFPHashList.Create;
asmdata:=TAsmData.create(realmodulename^);
asmdata:=casmdata.create(realmodulename^);
InitDebugInfo(self,false);
end;
@ -680,7 +680,7 @@ implementation
end;
if assigned(asmdata) then
begin
if current_asmdata=TAsmData(asmdata) then
if current_asmdata=asmdata then
current_asmdata:=nil;
asmdata.free;
asmdata:=nil;
@ -722,7 +722,7 @@ implementation
derefdataintflen:=0;
sourcefiles.free;
sourcefiles:=tinputfilemanager.create;
asmdata:=TAsmData.create(realmodulename^);
asmdata:=casmdata.create(realmodulename^);
InitDebugInfo(self,current_debuginfo_reset);
_exports.free;
_exports:=tlinkedlist.create;

View File

@ -113,6 +113,7 @@ interface
tsettings = packed record
alignment : talignmentinfo;
globalswitches : tglobalswitches;
targetswitches : ttargetswitches;
moduleswitches : tmoduleswitches;
localswitches : tlocalswitches;
modeswitches : tmodeswitches;
@ -360,6 +361,7 @@ interface
maxCrecordalign : 0;
);
globalswitches : [cs_check_unit_name,cs_link_static];
targetswitches : [];
moduleswitches : [cs_extsyntax,cs_implicit_exceptions];
localswitches : [cs_check_io,cs_typed_const_writable,cs_pointermath];
modeswitches : fpcmodeswitches;
@ -481,6 +483,7 @@ interface
function UpdateOptimizerStr(s:string;var a:toptimizerswitches):boolean;
function UpdateWpoStr(s: string; var a: twpoptimizerswitches): boolean;
function UpdateDebugStr(s:string;var a:tdebugswitches):boolean;
function UpdateTargetSwitchStr(s: string; var a: ttargetswitches): boolean;
function IncludeFeature(const s : string) : boolean;
function SetMinFPConstPrec(const s: string; var a: tfloattype) : boolean;
@ -1328,6 +1331,48 @@ implementation
end;
function UpdateTargetSwitchStr(s: string; var a: ttargetswitches): boolean;
var
tok : string;
doset,
found : boolean;
opt : ttargetswitch;
begin
result:=true;
uppervar(s);
repeat
tok:=GetToken(s,',');
if tok='' then
break;
if Copy(tok,1,2)='NO' then
begin
delete(tok,1,2);
doset:=false;
end
else
doset:=true;
found:=false;
for opt:=low(ttargetswitch) to high(ttargetswitch) do
begin
if TargetSwitchStr[opt]=tok then
begin
found:=true;
break;
end;
end;
if found then
begin
if doset then
include(a,opt)
else
exclude(a,opt);
end
else
result:=false;
until false;
end;
function IncludeFeature(const s : string) : boolean;
var
i : tfeature;

View File

@ -196,6 +196,13 @@ interface
);
tdebugswitches = set of tdebugswitch;
{ global target-specific switches }
ttargetswitch = (ts_none,
{ generate code that results in smaller TOCs than normal (AIX) }
ts_small_toc
);
ttargetswitches = set of ttargetswitch;
{ adding a new entry here requires also adding the appropriate define in
systemh.inc (FK)
@ -247,6 +254,9 @@ interface
DebugSwitchStr : array[tdebugswitch] of string[22] = ('',
'DWARFSETS','STABSABSINCLUDES','DWARFMETHODCLASSPREFIX');
TargetSwitchStr : array[ttargetswitch] of string[19] = ('',
'SMALLTOC');
{ switches being applied to all CPUs at the given level }
genericlevel1optimizerswitches = [cs_opt_level1];
genericlevel2optimizerswitches = [cs_opt_level2];

View File

@ -3233,6 +3233,10 @@ P*2CN_Generate nil-pointer checks (AIX-only)
**2CR_Verify object method call validity
**2Cs<n>_Set stack checking size to <n>
**2Ct_Stack checking (for testing only, see manual)
p*2CT<x>_Target-specific code generation options
P*2CT<x>_Target-specific code generation options
p*3CTsmalltoc_ Generate smaller TOCs at the expense of execution speed (AIX)
P*3CTsmalltoc_ Generate smaller TOCs at the expense of execution speed (AIX)
**2CX_Create also smartlinked library
**1d<x>_Defines the symbol <x>
**1D_Generate a DEF file

View File

@ -925,7 +925,7 @@ const
option_info=11024;
option_help_pages=11025;
MsgTxtSize = 63712;
MsgTxtSize = 63964;
MsgIdxMax : array[1..20] of longint=(
26,90,315,112,85,55,116,26,202,63,

View File

@ -1,7 +1,7 @@
{$ifdef Delphi}
const msgtxt : array[0..000265] of string[240]=(
const msgtxt : array[0..000266] of string[240]=(
{$else Delphi}
const msgtxt : array[0..000265,1..240] of char=(
const msgtxt : array[0..000266,1..240] of char=(
{$endif Delphi}
'01000_T_Compiler: $1'#000+
'01001_D_Compiler OS: $1'#000+
@ -1206,7 +1206,13 @@ const msgtxt : array[0..000265,1..240] of char=(
'**2CR_Verify object method call validity'#010+
'**2Cs<n>_Set stack checking size to <n>'#010+
'**2Ct_Stack checking (for testing only, see manual)'#010+
'**','2CX_Create also smartlinked library'#010+
'p*','2CT<x>_Target-specific code generation options'#010+
'P*2CT<x>_Target-specific code generation options'#010+
'p*3CTsmalltoc_ Generate smaller TOCs at the expense of execution speed'+
' (AIX)'#010+
'P*3CTsmalltoc_ Generate smaller TOCs at the expense of execution sp','e'+
'ed (AIX)'#010+
'**2CX_Create also smartlinked library'#010+
'**1d<x>_Defines the symbol <x>'#010+
'**1D_Generate a DEF file'#010+
'**2Dd<x>_Set description to <x>'#010+
@ -1214,53 +1220,53 @@ const msgtxt : array[0..000265,1..240] of char=(
'*O2Dw_PM application'#010+
'**1e<x>_Set path to executable'#010+
'**1E_Same as -Cn'#010+
'**1fPIC_Same as',' -Cg'#010+
'**1','fPIC_Same as -Cg'#010+
'**1F<x>_Set file names and paths:'#010+
'**2Fa<x>[,y]_(for a program) load units <x> and [y] before uses is par'+
'sed'#010+
'**2Fc<x>_Set input codepage to <x>'#010+
'**2FC<x>_Set RC compiler binary name to <x>'#010+
'**2Fd_Disable the compiler'#039's internal directory ','cache'#010+
'**2Fd_Disable the compiler'#039's interna','l directory cache'#010+
'**2FD<x>_Set the directory where to search for compiler utilities'#010+
'**2Fe<x>_Redirect error output to <x>'#010+
'**2Ff<x>_Add <x> to framework path (Darwin only)'#010+
'**2FE<x>_Set exe/unit output path to <x>'#010+
'**2Fi<x>_Add <x> to include path'#010+
'**2Fl<x','>_Add <x> to library path'#010+
'**2Fi<x>_Add <x> to include ','path'#010+
'**2Fl<x>_Add <x> to library path'#010+
'**2FL<x>_Use <x> as dynamic linker'#010+
'**2Fm<x>_Load unicode conversion table from <x>.txt in the compiler di'+
'r'#010+
'**2Fo<x>_Add <x> to object path'#010+
'**2Fr<x>_Load error message file <x>'#010+
'**2FR<x>_Set resource (.res) linker to',' <x>'#010+
'**2FR<x>_Set resource (.re','s) linker to <x>'#010+
'**2Fu<x>_Add <x> to unit path'#010+
'**2FU<x>_Set unit output path to <x>, overrides -FE'#010+
'**2FW<x>_Store generated whole-program optimization feedback in <x>'#010+
'**2Fw<x>_Load previously stored whole-program optimization feedback fr'+
'om <x>'#010+
'*g1g_Gen','erate debug information (default format for target)'#010+
'om ','<x>'#010+
'*g1g_Generate debug information (default format for target)'#010+
'*g2gc_Generate checks for pointers'#010+
'*g2gh_Use heaptrace unit (for memory leak/corruption debugging)'#010+
'*g2gl_Use line info unit (show more info with backtraces)'#010+
'*g2go<x>_Set debug information ','options'#010+
'*g2go<x>_Set debug ','information options'#010+
'*g3godwarfsets_ Enable DWARF '#039'set'#039' type debug information (bre'+
'aks gdb < 6.5)'#010+
'*g3gostabsabsincludes_ Store absolute/full include file paths in Stabs'+
#010+
'*g3godwarfmethodclassprefix_ Prefix method names in DWARF with class n'+
'ame'#010+
'*g2gp_Pres','erve case in stabs symbol names'#010+
'am','e'#010+
'*g2gp_Preserve case in stabs symbol names'#010+
'*g2gs_Generate Stabs debug information'#010+
'*g2gt_Trash local variables (to detect uninitialized uses)'#010+
'*g2gv_Generates programs traceable with Valgrind'#010+
'*g2gw_Generate DWARFv2 debug information (same as -gw2)'#010+
'*g2gw','2_Generate DWARFv2 debug information'#010+
'*g2gw_Generate DWARFv2 debug information (same as',' -gw2)'#010+
'*g2gw2_Generate DWARFv2 debug information'#010+
'*g2gw3_Generate DWARFv3 debug information'#010+
'*g2gw4_Generate DWARFv4 debug information (experimental)'#010+
'**1i_Information'#010+
'**2iD_Return compiler date'#010+
'**2iV_Return short compiler version'#010+
'**2iW_Return full compil','er version'#010+
'**2iW_Return',' full compiler version'#010+
'**2iSO_Return compiler OS'#010+
'**2iSP_Return compiler host processor'#010+
'**2iTO_Return target OS'#010+
@ -1268,78 +1274,78 @@ const msgtxt : array[0..000265,1..240] of char=(
'**1I<x>_Add <x> to include path'#010+
'**1k<x>_Pass <x> to the linker'#010+
'**1l_Write logo'#010+
'**1M<x>_Set language mode to <x','>'#010+
'**1M<x>_Set languag','e mode to <x>'#010+
'**2Mfpc_Free Pascal dialect (default)'#010+
'**2Mobjfpc_FPC mode with Object Pascal support'#010+
'**2Mdelphi_Delphi 7 compatibility mode'#010+
'**2Mtp_TP/BP 7.0 compatibility mode'#010+
'**2Mmacpas_Macintosh Pascal dialects compatibility mode'#010+
'**1n_Do not read the d','efault config files'#010+
'**1n_Do no','t read the default config files'#010+
'**1N<x>_Node tree optimizations'#010+
'**2Nu_Unroll loops'#010+
'**1o<x>_Change the name of the executable produced to <x>'#010+
'**1O<x>_Optimizations:'#010+
'**2O-_Disable optimizations'#010+
'**2O1_Level 1 optimizations (quick and debugger friendly)'#010+
'**','2O2_Level 2 optimizations (-O1 + quick optimizations)'#010+
'**2O1_Level 1 optimizations (quick and debugger ','friendly)'#010+
'**2O2_Level 2 optimizations (-O1 + quick optimizations)'#010+
'**2O3_Level 3 optimizations (-O2 + slow optimizations)'#010+
'**2Oa<x>=<y>_Set alignment'#010+
'**2Oo[NO]<x>_Enable or disable optimizations, see fpc -i for possible '+
'values'#010+
'**2Op<x>_Set target cpu for',' optimizing, see fpc -i for possible valu'+
'**2Op<x>_Set ta','rget cpu for optimizing, see fpc -i for possible valu'+
'es'#010+
'**2OW<x>_Generate whole-program optimization feedback for optimization'+
' <x>, see fpc -i for possible values'#010+
'**2Ow<x>_Perform whole-program optimization <x>, see fpc -i for possib'+
'le values'#010+
'**2Os_Opt','imize for size rather than speed'#010+
'le valu','es'#010+
'**2Os_Optimize for size rather than speed'#010+
'**1pg_Generate profile code for gprof (defines FPC_PROFILE)'#010+
'F*1P<x>_Target CPU / compiler related options:'#010+
'F*2PB_Show default compiler binary'#010+
'F*2PP_Show default target cpu'#010+
'F*2P<x>_Set target CPU (arm,i386,m6','8k,mips,mipsel,powerpc,powerpc64,'+
'F*2P<x>_Set target CPU ','(arm,i386,m68k,mips,mipsel,powerpc,powerpc64,'+
'sparc,x86_64'#010+
'**1R<x>_Assembler reading style:'#010+
'**2Rdefault_Use default assembler for target'#010+
'3*2Ratt_Read AT&T style assembler'#010+
'3*2Rintel_Read Intel style assembler'#010+
'6*2RMOT_Read motorola style assembler'#010+
'**1S<x>','_Syntax options:'#010+
'6*2RMOT_Read motorola style assem','bler'#010+
'**1S<x>_Syntax options:'#010+
'**2S2_Same as -Mobjfpc'#010+
'**2Sc_Support operators like C (*=,+=,/= and -=)'#010+
'**2Sa_Turn on assertions'#010+
'**2Sd_Same as -Mdelphi'#010+
'**2Se<x>_Error options. <x> is a combination of the following:'#010+
'**3*_<n> : Compiler halts after the <n> ','errors (default is 1)'#010+
'**3*_<n> : Compiler halts af','ter the <n> errors (default is 1)'#010+
'**3*_w : Compiler also halts after warnings'#010+
'**3*_n : Compiler also halts after notes'#010+
'**3*_h : Compiler also halts after hints'#010+
'**2Sg_Enable LABEL and GOTO (default in -Mtp and -Mdelphi)'#010+
'**2Sh_Use ansistrings by default ','instead of shortstrings'#010+
'**2Sh_Use ansistrings',' by default instead of shortstrings'#010+
'**2Si_Turn on inlining of procedures/functions declared as "inline"'#010+
'**2Sk_Load fpcylix unit'#010+
'**2SI<x>_Set interface style to <x>'#010+
'**3SIcom_COM compatible interface (default)'#010+
'**3SIcorba_CORBA compatible interface'#010+
'**2Sm_','Support macros like C (global)'#010+
'**3SIcorba_CORBA compatible inte','rface'#010+
'**2Sm_Support macros like C (global)'#010+
'**2So_Same as -Mtp'#010+
'**2Ss_Constructor name must be init (destructor must be done)'#010+
'**2Sx_Enable exception keywords (default in Delphi/ObjFPC modes)'#010+
'**2Sy_@<pointer> returns a typed pointer, same as $T+'#010+
'**1s_Do n','ot call assembler and linker'#010+
'**2Sy_@<pointer> returns a typed pointer, same as $','T+'#010+
'**1s_Do not call assembler and linker'#010+
'**2sh_Generate script to link on host'#010+
'**2st_Generate script to link on target'#010+
'**2sr_Skip register allocation phase (use with -alr)'#010+
'**1T<x>_Target operating system:'#010+
'3*2Tdarwin_Darwin/Mac OS X'#010+
'3*2Temx_OS/2 via EMX',' (including EMX/RSX extender)'#010+
'3*2Temx_','OS/2 via EMX (including EMX/RSX extender)'#010+
'3*2Tfreebsd_FreeBSD'#010+
'3*2Tgo32v2_Version 2 of DJ Delorie DOS extender'#010+
'3*2Tiphonesim_ iPhoneSimulator from iOS SDK 3.2+ (older versions: -Tda'+
'rwin)'#010+
'3*2Tlinux_Linux'#010+
'3*2Tnetbsd_NetBSD'#010+
'3*2Tnetware_Novell Netware Modul','e (clib)'#010+
'3*2Tnetware_Novell N','etware Module (clib)'#010+
'3*2Tnetwlibc_Novell Netware Module (libc)'#010+
'3*2Topenbsd_OpenBSD'#010+
'3*2Tos2_OS/2 / eComStation'#010+
@ -1347,8 +1353,8 @@ const msgtxt : array[0..000265,1..240] of char=(
'3*2Tsymbian_Symbian OS'#010+
'3*2Tsolaris_Solaris'#010+
'3*2Twatcom_Watcom compatible DOS extender'#010+
'3*2Twdosx_WDOSX DOS extender'#010+
'3*2T','win32_Windows 32 Bit'#010+
'3*2Twdosx_WDOSX DOS e','xtender'#010+
'3*2Twin32_Windows 32 Bit'#010+
'3*2Twince_Windows CE'#010+
'4*2Tdarwin_Darwin/Mac OS X'#010+
'4*2Tlinux_Linux'#010+
@ -1357,7 +1363,7 @@ const msgtxt : array[0..000265,1..240] of char=(
'6*2Tatari_Atari ST/STe/TT'#010+
'6*2Tlinux_Linux'#010+
'6*2Tpalmos_PalmOS'#010+
'A*2Tdarwin_Darwin/iPhoneOS/i','OS'#010+
'A*2Tdarwin_Darwi','n/iPhoneOS/iOS'#010+
'A*2Tlinux_Linux'#010+
'A*2Twince_Windows CE'#010+
'P*2Tamiga_AmigaOS'#010+
@ -1368,113 +1374,113 @@ const msgtxt : array[0..000265,1..240] of char=(
'S*2Tsolaris_Solaris'#010+
'S*2Tlinux_Linux'#010+
'**1u<x>_Undefines the symbol <x>'#010+
'**1U_Unit options:'#010+
'**2U','n_Do not check where the unit name matches the file name'#010+
'**1U_Unit o','ptions:'#010+
'**2Un_Do not check where the unit name matches the file name'#010+
'**2Ur_Generate release unit files (never automatically recompiled)'#010+
'**2Us_Compile a system unit'#010+
'**1v<x>_Be verbose. <x> is a combination of the following letters:'#010+
'**2*_e : Show errors ','(default) 0 : Show nothing (except errors'+
'**2*_e : ','Show errors (default) 0 : Show nothing (except errors'+
')'#010+
'**2*_w : Show warnings u : Show unit info'#010+
'**2*_n : Show notes t : Show tried/used files'#010+
'**2*_h : Show hints c : Show conditionals'#010+
'**2*_i : Show',' general info d : Show debug info'#010+
'*','*2*_i : Show general info d : Show debug info'#010+
'**2*_l : Show linenumbers r : Rhide/GCC compatibility mode'#010+
'**2*_s : Show time stamps q : Show message numbers'#010+
'**2*_a : Show everything x : Executable info (Win32 ','only'+
'**2*_a : Show everything x : Executable ','info (Win32 only'+
')'#010+
'**2*_b : Write file names messages p : Write tree.log with parse tre'+
'e'#010+
'**2*_ with full path v : Write fpcdebug.txt with'#010+
'**2*_ lots of debugging info'#010+
'**2*_m<x>,<y> : Don'#039't show messag','es numbered <x> and <y>'#010+
'**2*_m<x>,<y> : Don'#039't',' show messages numbered <x> and <y>'#010+
'F*1V<x>_Append '#039'-<x>'#039' to the used compiler binary name (e.g. f'+
'or version)'#010+
'**1W<x>_Target-specific options (targets)'#010+
'3*2WA_Specify native type application (Windows)'#010+
'4*2WA_Specify native type application (Windows)'#010+
'A*2W','A_Specify native type application (Windows)'#010+
'4*2WA_Specify native type application (W','indows)'#010+
'A*2WA_Specify native type application (Windows)'#010+
'3*2Wb_Create a bundle instead of a library (Darwin)'#010+
'P*2Wb_Create a bundle instead of a library (Darwin)'#010+
'p*2Wb_Create a bundle instead of a library (Darwin)'#010+
'A*2Wb_Create a bundle instead of a libra','ry (Darwin)'#010+
'A*2Wb_Create a bundle instea','d of a library (Darwin)'#010+
'4*2Wb_Create a bundle instead of a library (Darwin)'#010+
'3*2WB_Create a relocatable image (Windows, Symbian)'#010+
'3*2WBxxxx_Set image base to xxxx (Windows, Symbian)'#010+
'4*2WB_Create a relocatable image (Windows)'#010+
'4*2WBxxxx_Set image base to x','xxx (Windows)'#010+
'4*2WBxxxx_Set ima','ge base to xxxx (Windows)'#010+
'A*2WB_Create a relocatable image (Windows, Symbian)'#010+
'A*2WBxxxx_Set image base to xxxx (Windows, Symbian)'#010+
'3*2WC_Specify console type application (EMX, OS/2, Windows)'#010+
'4*2WC_Specify console type application (EMX, OS/2, Windows)'#010+
'A*','2WC_Specify console type application (Windows)'#010+
'4*2WC_Specify console type application (EMX, OS/2,',' Windows)'#010+
'A*2WC_Specify console type application (Windows)'#010+
'P*2WC_Specify console type application (Classic Mac OS)'#010+
'3*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+
'4*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+
'A*2WD_Use DEF','FILE to export functions of DLL or EXE (Windows)'#010+
'A','*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+
'3*2We_Use external resources (Darwin)'#010+
'4*2We_Use external resources (Darwin)'#010+
'A*2We_Use external resources (Darwin)'#010+
'P*2We_Use external resources (Darwin)'#010+
'p*2We_Use external resources (Darwin)'#010+
'3','*2WF_Specify full-screen type application (EMX, OS/2)'#010+
'p*2We_Use external resource','s (Darwin)'#010+
'3*2WF_Specify full-screen type application (EMX, OS/2)'#010+
'3*2WG_Specify graphic type application (EMX, OS/2, Windows)'#010+
'4*2WG_Specify graphic type application (EMX, OS/2, Windows)'#010+
'A*2WG_Specify graphic type application (Windows)'#010+
'P*2WG_Specify gra','phic type application (Classic Mac OS)'#010+
'P*2WG','_Specify graphic type application (Classic Mac OS)'#010+
'3*2Wi_Use internal resources (Darwin)'#010+
'4*2Wi_Use internal resources (Darwin)'#010+
'A*2Wi_Use internal resources (Darwin)'#010+
'P*2Wi_Use internal resources (Darwin)'#010+
'p*2Wi_Use internal resources (Darwin)'#010+
'3*2WI_Turn ','on/off the usage of import sections (Windows)'#010+
'p*2Wi_Use internal resources (Darwin)',#010+
'3*2WI_Turn on/off the usage of import sections (Windows)'#010+
'4*2WI_Turn on/off the usage of import sections (Windows)'#010+
'A*2WI_Turn on/off the usage of import sections (Windows)'#010+
'3*2WM<x>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Darwi'+
'3*2WM<x>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Dar','w'+
'in)'#010+
'4*2WM<x>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Darwi'+
'n)'#010+
'4*2WM<x','>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Dar'+
'win)'#010+
'p*2WM<x>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Darwi'+
'n)'#010+
'P*2WM<x>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Darwi'+
'n)'#010+
'3*2WN_Do not generate reloca','tion code, needed for debugging (Windows'+
'3*2WN_Do not gen','erate relocation code, needed for debugging (Windows'+
')'#010+
'4*2WN_Do not generate relocation code, needed for debugging (Windows)'#010+
'A*2WN_Do not generate relocation code, needed for debugging (Windows)'#010+
'A*2Wpxxxx_Specify the controller type, see fpc -i for poss','ible value'+
'A*2Wpxxxx_Specify the controller type, see fpc',' -i for possible value'+
's'#010+
'V*2Wpxxxx_Specify the controller type, see fpc -i for possible values'#010+
'3*2WP<x>_Minimum iOS deployment version: 3.0, 5.0.1, ... (iphonesim)'#010+
'A*2WP<x>_Minimum iOS deployment version: 3.0, 5.0.1, ... (Darwin)'#010+
'3*2WR_Generate relocati','on code (Windows)'#010+
'3*2WR_Gener','ate relocation code (Windows)'#010+
'4*2WR_Generate relocation code (Windows)'#010+
'A*2WR_Generate relocation code (Windows)'#010+
'P*2WT_Specify MPW tool type application (Classic Mac OS)'#010+
'**2WX_Enable executable stack (Linux)'#010+
'**1X_Executable options:'#010+
'**2Xc_Pass --shared/','-dynamic to the linker (BeOS, Darwin, FreeBSD, L'+
'**2Xc_Pa','ss --shared/-dynamic to the linker (BeOS, Darwin, FreeBSD, L'+
'inux)'#010+
'**2Xd_Do not use standard library search path (needed for cross compil'+
'e)'#010+
'**2Xe_Use external linker'#010+
'**2Xg_Create debuginfo in a separate file and add a debuglink section '+
'to executable'#010+
'**2','XD_Try to link units dynamically (defines FPC_LINK_DYNAMIC)'#010+
'to ex','ecutable'#010+
'**2XD_Try to link units dynamically (defines FPC_LINK_DYNAMIC)'#010+
'**2Xi_Use internal linker'#010+
'**2Xm_Generate link map'#010+
'**2XM<x>_Set the name of the '#039'main'#039' program routine (default i'+
's '#039'main'#039')'#010+
'F*2Xp<x>_First search for the compiler binary in the ','directory <x>'#010+
'F*2Xp<x>_First search for the compiler bi','nary in the directory <x>'#010+
'**2XP<x>_Prepend the binutils names with the prefix <x>'#010+
'**2Xr<x>_Set the linker'#039's rlink-path to <x> (needed for cross comp'+
'ile, see the ld manual for more information) (BeOS, Linux)'#010+
'**2XR<x>_Prepend <x> to all linker search pat','hs (BeOS, Darwin, FreeB'+
'**2XR<x>_Prepend <x> to all linke','r search paths (BeOS, Darwin, FreeB'+
'SD, Linux, Mac OS, Solaris)'#010+
'**2Xs_Strip all symbols from executable'#010+
'**2XS_Try to link units statically (default, defines FPC_LINK_STATIC)'#010+
'**2Xt_Link with static libraries (-static is passed to linker)'#010+
'**2XX_Try to sma','rtlink units (defines FPC_LINK_SMART)'#010+
'**2X','X_Try to smartlink units (defines FPC_LINK_SMART)'#010+
'**1*_'#010+
'**1?_Show this help'#010+
'**1h_Shows this help without waiting'

View File

@ -936,6 +936,12 @@ begin
exclude(init_settings.moduleswitches,cs_create_smart)
Else
include(init_settings.moduleswitches,cs_create_smart);
'T' :
begin
if not UpdateTargetSwitchStr(copy(more,j+1,length(more)),init_settings.targetswitches) then
IllegalPara(opt);
break;
end;
else
IllegalPara(opt);
end;

View File

@ -185,8 +185,7 @@ Unit rappcgas;
{ replace global symbol reference with TOC entry name
for AIX }
if target_info.system in systems_aix then
oper.opr.ref.symbol:=
tcgppcgen(cg).get_aix_toc_sym(oper.opr.ref.symbol.name,asmsym2indsymflags(oper.opr.ref.symbol));
tcgppcgen(cg).get_aix_toc_sym(nil,oper.opr.ref.symbol.name,asmsym2indsymflags(oper.opr.ref.symbol),oper.opr.ref,true);
oper.opr.ref.refaddr:=addr_pic_no_got;
end;
Consume_RParen;

View File

@ -196,8 +196,7 @@ begin
{ replace global symbol reference with TOC entry name
for AIX }
if target_info.system in systems_aix then
oper.opr.ref.symbol:=
tcgppcgen(cg).get_aix_toc_sym(oper.opr.ref.symbol.name,asmsym2indsymflags(oper.opr.ref.symbol));
tcgppcgen(cg).get_aix_toc_sym(nil,oper.opr.ref.symbol.name,asmsym2indsymflags(oper.opr.ref.symbol),oper.opr.ref,true);
oper.opr.ref.refaddr:=addr_pic_no_got;
end;
Consume_RParen;

View File

@ -152,18 +152,17 @@ unit agppcgas;
s:=s+tostr(offset);
end;
if (refaddr in verbose_refaddrs) then
if not(refaddr in [addr_no,addr_pic_no_got]) then
begin
s := s+')';
if not(target_info.system in [system_powerpc_darwin,system_powerpc64_darwin]) then
if (refaddr in verbose_refaddrs) and
not(target_info.system in [system_powerpc_darwin,system_powerpc64_darwin]) then
s := s+refaddr2str[refaddr];
end;
{$ifdef cpu64bitaddr}
if (refaddr = addr_pic) then
if (target_info.system <> system_powerpc64_linux) then
s := s + ')'
else
s := s + ')@got';
if (refaddr=addr_pic) and
(target_info.system=system_powerpc64_linux) then
s := s + '@got';
{$endif cpu64bitaddr}
if (index=NR_NO) then

View File

@ -67,7 +67,7 @@ unit cgppc;
procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: TCGSize; src, dst: TRegister); override;
procedure g_stackpointer_alloc(list : TAsmList;localsize : longint);override;
function get_aix_toc_sym(const symname: string; const flags: tindsymflags):tasmsymbol;
procedure get_aix_toc_sym(list: TAsmList; const symname: string; const flags: tindsymflags; out ref: treference; force_direct_toc: boolean);
procedure g_load_check_simple(list: TAsmList; const ref: treference; size: aint);
procedure g_external_wrapper(list: TAsmList; pd: TProcDef; const externalname: string); override;
protected
@ -98,9 +98,34 @@ unit cgppc;
function load_got_symbol(list : TAsmList; const symbol : string; const flags: tindsymflags) : tregister;
end;
TPPCAsmData = class(TAsmData)
private
{ number of entries in the TOC }
fdirecttocentries,
{ number of fake TOC subsections we have created }
ftocsections,
{ number of fake TOC entries in the current TOC subsection }
fcurrenttocentries: longint;
public
procedure GetNextSmallTocEntry(out tocnr, entrynr: longint);
property DirectTOCEntries: longint read fdirecttocentries write fdirecttocentries;
end;
TTOCAsmSymbol = class(TAsmSymbol)
private
{ we split the toc into several sections of 32KB each, this number
indicates which subsection this symbol is defined in }
ftocsecnr: longint;
public
property TocSecNr: longint read ftocsecnr;
end;
const
TOpCmp2AsmCond: Array[topcmp] of TAsmCondFlag = (C_NONE,C_EQ,C_GT,
C_LT,C_GE,C_LE,C_NE,C_LE,C_LT,C_GE,C_GT);
TocSecBaseName = 'toc_table';
{$ifdef extdebug}
@ -800,17 +825,16 @@ unit cgppc;
ref: treference;
begin
if target_info.system=system_powerpc64_linux then
l:=current_asmdata.getasmsymbol(symbol)
begin
l:=current_asmdata.getasmsymbol(symbol);
reference_reset_symbol(ref,l,0,sizeof(pint));
ref.base:=NR_RTOC;
ref.refaddr:=addr_pic;
end
else if target_info.system in systems_aix then
l:=get_aix_toc_sym(symbol,flags)
get_aix_toc_sym(list,symbol,flags,ref,false)
else
internalerror(2007102010);
reference_reset_symbol(ref,l,0,sizeof(pint));
ref.base:=NR_RTOC;
if target_info.system in systems_aix then
ref.refaddr:=addr_pic_no_got
else
ref.refaddr:=addr_pic;
result := getaddressregister(list);
{$ifdef cpu64bitaddr}
@ -821,30 +845,100 @@ unit cgppc;
end;
function tcgppcgen.get_aix_toc_sym(const symname: string; const flags: tindsymflags): tasmsymbol;
procedure tcgppcgen.get_aix_toc_sym(list: TAsmList; const symname: string; const flags: tindsymflags; out ref: treference; force_direct_toc: boolean);
const
{ The TOC on AIX is limited to 32KB worth of entries on AIX. If you need
more entries, you have to add a level of indirection. In some cases,
it's not possible to do this (e.g. assembler code). So by default, we
use direct TOC entries until we're 500 from the maximum, and then start
using indirect TOC entries. }
AutoDirectTOCLimit = (high(smallint) div sizeof(pint)) - 500;
var
tmpref: treference;
{ can have more than 16384 (32 bit) or 8192 (64 bit) toc entries and, as
as consequence, toc subsections -> 5 extra characters for the number}
tocsecname: string[length('tocsubtable')+5];
nlsymname: string;
newsymname: ansistring;
sym: TAsmSymbol;
tocsym: TTOCAsmSymbol;
tocnr,
entrynr: longint;
tmpreg: tregister;
begin
{ all global symbol accesses always must be done via the TOC }
nlsymname:='LC..'+symname;
result:=current_asmdata.getasmsymbol(nlsymname);
if not assigned(result) then
reference_reset_symbol(ref,current_asmdata.getasmsymbol(nlsymname),0,sizeof(pint));
if (assigned(ref.symbol) and
not(ref.symbol is TTOCAsmSymbol)) or
(not(ts_small_toc in current_settings.targetswitches) and
(TPPCAsmData(current_asmdata).DirectTOCEntries<AutoDirectTOCLimit)) or
force_direct_toc then
begin
new_section(current_asmdata.AsmLists[al_picdata],sec_toc,'',sizeof(pint));
result:=current_asmdata.DefineAsmSymbol(nlsymname,AB_LOCAL,AT_DATA);
current_asmdata.asmlists[al_picdata].concat(tai_symbol.create(result,0));
{ do not assign the result of these statements to result: the access
must be done via the LC..symname symbol; these are just to define
the symbol that's being accessed as either weak or not }
if not(is_weak in flags) then
current_asmdata.RefAsmSymbol(symname)
else if is_data in flags then
current_asmdata.WeakRefAsmSymbol(symname)
else
current_asmdata.WeakRefAsmSymbol('.'+symname);
newsymname:=ReplaceForbiddenAsmSymbolChars(symname);
current_asmdata.asmlists[al_picdata].concat(tai_directive.Create(asd_toc_entry,newsymname+'[TC],'+newsymname));
ref.refaddr:=addr_pic_no_got;
ref.base:=NR_RTOC;
if not assigned(ref.symbol) then
begin
TPPCAsmData(current_asmdata).DirectTOCEntries:=TPPCAsmData(current_asmdata).DirectTOCEntries+1;
new_section(current_asmdata.AsmLists[al_picdata],sec_toc,'',sizeof(pint));
ref.symbol:=current_asmdata.DefineAsmSymbol(nlsymname,AB_LOCAL,AT_DATA);
current_asmdata.asmlists[al_picdata].concat(tai_symbol.create(ref.symbol,0));
{ do not assign the result of these statements to ref.symbol: the
access must be done via the LC..symname symbol; these are just
to define the symbol that's being accessed as either weak or
not }
if not(is_weak in flags) then
current_asmdata.RefAsmSymbol(symname)
else if is_data in flags then
current_asmdata.WeakRefAsmSymbol(symname)
else
current_asmdata.WeakRefAsmSymbol('.'+symname);
newsymname:=ReplaceForbiddenAsmSymbolChars(symname);
current_asmdata.asmlists[al_picdata].concat(tai_directive.Create(asd_toc_entry,newsymname+'[TC],'+newsymname));
end;
end
else
begin
if not assigned(ref.symbol) then
begin
TPPCAsmData(current_asmdata).GetNextSmallTocEntry(tocnr,entrynr);
{ new TOC entry? }
if entrynr=0 then
begin
{ create new toc entry that contains the address of the next
table of addresses }
get_aix_toc_sym(list,'tocsubtable'+tostr(tocnr),[is_data],tmpref,true);
sym:=tmpref.symbol;
{ base address for this batch of toc table entries that we'll
put in a data block instead }
new_section(current_asmdata.AsmLists[al_indirectpicdata],sec_rodata,'',sizeof(pint));
sym:=current_asmdata.DefineAsmSymbol('tocsubtable'+tostr(tocnr),AB_LOCAL,AT_DATA);
current_asmdata.asmlists[al_indirectpicdata].concat(tai_symbol.create(sym,0));
end;
{ add the reference to the actual symbol inside the tocsubtable }
if not(is_weak in flags) then
current_asmdata.RefAsmSymbol(symname)
else if is_data in flags then
current_asmdata.WeakRefAsmSymbol(symname)
else
current_asmdata.WeakRefAsmSymbol('.'+symname);
tocsym:=TTOCAsmSymbol(current_asmdata.DefineAsmSymbolByClass(TTOCAsmSymbol,nlsymname,AB_LOCAL,AT_DATA));
ref.symbol:=tocsym;
tocsym.ftocsecnr:=tocnr;
current_asmdata.asmlists[al_indirectpicdata].concat(tai_symbol.create(tocsym,0));
newsymname:=ReplaceForbiddenAsmSymbolChars(symname);
sym:=current_asmdata.RefAsmSymbol(newsymname);
current_asmdata.asmlists[al_indirectpicdata].concat(tai_const.Create_sym(sym));
end;
{ first load the address of the table from the TOC }
get_aix_toc_sym(list,'tocsubtable'+tostr(TTOCAsmSymbol(ref.symbol).ftocsecnr),[is_data],tmpref,true);
tmpreg:=getaddressregister(list);
a_load_ref_reg(list,OS_ADDR,OS_ADDR,tmpref,tmpreg);
{ and now set up the address of the entry, relative to the start of
the table }
ref.base:=tmpreg;
ref.refaddr:=addr_pic;
ref.relsymbol:=current_asmdata.GetAsmSymbol('tocsubtable'+tostr(TTOCAsmSymbol(ref.symbol).ftocsecnr));
end;
end;
@ -989,7 +1083,8 @@ unit cgppc;
if (((target_info.system = system_powerpc64_linux) and
(cs_create_pic in current_settings.moduleswitches)) or
(target_info.system in systems_aix)) and
(assigned(ref.symbol)) then
(assigned(ref.symbol) and
not assigned(ref.relsymbol)) then
begin
tmpreg := load_got_symbol(list, ref.symbol.name, asmsym2indsymflags(ref.symbol));
if (ref.base = NR_NO) then
@ -1149,5 +1244,22 @@ unit cgppc;
end;
{ TPPCAsmData }
procedure TPPCAsmData.GetNextSmallTocEntry(out tocnr, entrynr: longint);
begin
if fcurrenttocentries>(high(word) div sizeof(pint)) then
begin
fcurrenttocentries:=0;
inc(ftocsections);
end;
tocnr:=ftocsections;
entrynr:=fcurrenttocentries;
inc(fcurrenttocentries);
end;
begin
casmdata:=TPPCAsmData;
end.

View File

@ -2259,6 +2259,7 @@ In case not, the value returned can be arbitrary.
alignment.recordalignmax:=tokenreadlongint;
alignment.maxCrecordalign:=tokenreadlongint;
tokenreadset(globalswitches,sizeof(globalswitches));
tokenreadset(targetswitches,sizeof(targetswitches));
tokenreadset(moduleswitches,sizeof(moduleswitches));
tokenreadset(localswitches,sizeof(localswitches));
tokenreadset(modeswitches,sizeof(modeswitches));