Bladeren bron

* 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 -

Jonas Maebe 13 jaren geleden
bovenliggende
commit
3380b58695

+ 16 - 2
compiler/aasmdata.pas

@@ -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));

+ 3 - 3
compiler/fmodule.pas

@@ -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;

+ 45 - 0
compiler/globals.pas

@@ -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;

+ 10 - 0
compiler/globtype.pas

@@ -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];

+ 4 - 0
compiler/msg/errore.msg

@@ -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

+ 1 - 1
compiler/msgidx.inc

@@ -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,

+ 73 - 67
compiler/msgtxt.inc

@@ -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'

+ 6 - 0
compiler/options.pas

@@ -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;

+ 1 - 2
compiler/powerpc/rappcgas.pas

@@ -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;

+ 1 - 2
compiler/powerpc64/rappcgas.pas

@@ -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;

+ 6 - 7
compiler/ppcgen/agppcgas.pas

@@ -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

+ 139 - 27
compiler/ppcgen/cgppc.pas

@@ -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.
 

+ 1 - 0
compiler/scanner.pas

@@ -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));