{ $Id$ Copyright (c) 1998-2002 by Florian Klaempfl This unit contains information about the target systems supported (these are not processor specific) This program is free software; you can redistribute it and/or modify iu under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge- MA 02139, USA. **************************************************************************** } unit systems; {$i fpcdefs.inc} interface type tendian = (endian_little,endian_big); (* IMPORTANT NOTE: The value of this enumeration is stored in PPU files. Therefore adding new CPU targets should not change the values of the pre-existing targets. (CEC) FURTHERMORE : Make sure that this branch values, are consistant with the main branch version always. *) tsystemcpu= ( cpu_no, { 0 } cpu_i386, { 1 } cpu_m68k, { 2 } cpu_alpha, { 3 } cpu_powerpc, { 4 } cpu_sparc, { 5 } cpu_vm, { 6 } cpu_iA64, { 7 } cpu_x86_64, { 8 } cpu_mips, { 9 } cpu_arm { 10 } ); TSection=(sec_none, sec_code,sec_data,sec_bss, sec_idata2,sec_idata4,sec_idata5,sec_idata6,sec_idata7,sec_edata, sec_stab,sec_stabstr,sec_common ); tasmmode= (asmmode_none { direct output with minimal parsing } ,asmmode_direct { standard assembler (cpu dependant) with full parsing } ,asmmode_standard ,asmmode_i386_att ,asmmode_i386_intel ,asmmode_ppc_gas ,asmmode_ppc_motorola ); (* IMPORTANT NOTE: the integer value of this enum is stored in PPU files to recognize the target, so if you add new targets allways add them at end PM FURTHERMORE : Make sure that this branch values are consistant with the main branch version always. (CEC) *) type tsystem = ( system_none, { 0 } obsolete_system_i386_GO32V1,{ 1 } system_i386_GO32V2, { 2 } system_i386_linux, { 3 } system_i386_OS2, { 4 } system_i386_Win32, { 5 } system_i386_freebsd, { 6 } system_m68k_Amiga, { 7 } system_m68k_Atari, { 8 } system_m68k_Mac, { 9 } system_m68k_linux, { 10 } system_m68k_PalmOS, { 11 } system_alpha_linux, { 12 } system_powerpc_linux, { 13 } system_powerpc_macos, { 14 } system_i386_sunos, { 15 } system_i386_beos, { 16 } system_i386_netbsd, { 17 } system_m68k_netbsd, { 18 } system_i386_Netware, { 19 } system_i386_qnx, { 20 } system_i386_wdosx, { 21 } system_sparc_sunos, { 22 } system_sparc_linux, { 23 } target_i386_openbsd, { 24 } target_m68k_openbsd, { 25 } system_x86_64_linux, { 26 } system_powerpc_macosx { 27 } ); tasm = (as_none ,as_gas { standard gnu assembler } ,as_i386_as_aout ,as_i386_asw ,as_i386_nasmcoff ,as_i386_nasmwin32 ,as_i386_nasmwdosx ,as_i386_nasmelf ,as_i386_nasmobj ,as_i386_tasm ,as_i386_masm ,as_i386_coff ,as_i386_pecoff ,as_i386_elf32 ,as_i386_pecoffwdosx ,as_m68k_mit ,as_powerpc_mpw ,as_x86_64_as ); tar = (ar_none ,ar_gnu_ar,ar_gnu_arw,ar_mpw_ar ); tres = (res_none ,res_gnu_windres,res_emxbind ,res_m68k_palmos,res_m68k_mpw ,res_powerpc_mpw ); tscripttype = (script_none ,script_dos,script_unix,script_amiga ); {***************************************************************************** Structures *****************************************************************************} type { Abstract linker class which is implemented in link module } TAbstractLinker = class end; TAbstractLinkerClass = class of TABstractLinker; { Abstract assembler class which is implemented in assemble module } TAbstractAssembler = class end; TAbstractAssemblerClass = class of TAbstractAssembler; palignmentinfo = ^talignmentinfo; talignmentinfo = packed record procalign, loopalign, jumpalign, constalignmin, constalignmax, varalignmin, varalignmax, localalignmin, localalignmax, paraalign, recordalignmin, recordalignmax, maxCrecordalign : longint; end; pasminfo = ^tasminfo; tasminfo = packed record id : tasm; idtxt : string[9]; asmbin : string[8]; asmcmd : string[50]; supported_target : tsystem; outputbinary, allowdirect, needar, labelprefix_only_inside_procedure : boolean; labelprefix : string[3]; comment : string[2]; secnames : array[TSection] of string[20]; end; parinfo = ^tarinfo; tarinfo = packed record id : tar; arcmd : string[50]; end; presinfo = ^tresinfo; tresinfo = packed record id : tres; resbin : string[8]; rescmd : string[50]; end; tsystemflags = (tf_none, tf_under_development, tf_need_export,tf_needs_isconsole ,tf_code_small,tf_static_reg_based ); psysteminfo = ^tsysteminfo; tsysteminfo = packed record system : tsystem; name : string[30]; shortname : string[9]; flags : set of tsystemflags; cpu : tsystemcpu; unit_env : string[12]; extradefines : string[40]; sourceext, pasext, exeext, defext, scriptext, smartext, unitext, unitlibext, asmext, objext, resext, resobjext : string[4]; sharedlibext : string[10]; staticlibext, staticlibprefix : string[4]; sharedlibprefix : string[4]; sharedClibext : string[10]; staticClibext, staticClibprefix : string[4]; sharedClibprefix : string[4]; Cprefix : string[2]; newline : string[2]; dirsep : char; files_case_relevent : boolean; assem : tasm; assemextern : tasm; { external assembler, used by -a } link : tabstractlinkerclass; linkextern : tabstractlinkerclass; { external linker, used by -s } ar : tar; res : tres; script : tscripttype; endian : tendian; alignment : talignmentinfo; { Offset from the argument pointer register to the first argument's address. On some machines it may depend on the data type of the function. (see also FIRST_PARM_OFFSET in GCC source) } first_parm_offset : longint; heapsize, stacksize : longint; DllScanSupported : boolean; use_function_relative_addresses : boolean; end; pasmmodeinfo = ^tasmmodeinfo; tasmmodeinfo = packed record id : tasmmode; idtxt : string[8]; end; const { alias for supported_target field in tasminfo } system_any = system_none; var targetinfos : array[tsystem] of psysteminfo; asminfos : array[tasm] of pasminfo; arinfos : array[tar] of parinfo; resinfos : array[tres] of presinfo; asmmodeinfos : array[tasmmode] of pasmmodeinfo; source_info : tsysteminfo; target_cpu : tsystemcpu; target_info : tsysteminfo; target_asm : tasminfo; target_ar : tarinfo; target_res : tresinfo; target_path : string[12]; { for rtl//,fcl//, etc. } function set_target(t:tsystem):boolean; function set_target_asm(t:tasm):boolean; function set_target_ar(t:tar):boolean; function set_target_res(t:tres):boolean; function set_target_by_string(const s : string) : boolean; function set_target_asm_by_string(const s : string) : boolean; function set_asmmode_by_string(const s:string;var t:tasmmode):boolean; procedure set_source_info(const ti : tsysteminfo); procedure UpdateAlignment(var d:talignmentinfo;const s:talignmentinfo); procedure RegisterTarget(const r:tsysteminfo); procedure RegisterAsmMode(const r:tasmmodeinfo); procedure RegisterRes(const r:tresinfo); procedure RegisterAr(const r:tarinfo); { Register the external linker. This routine is called to setup the class to use for the linker. It returns the tsysteminfo structure updated with the correct linker class for external linking. } procedure RegisterExternalLinker(var system_info: tsysteminfo; c:TAbstractLinkerClass); { Register the internal linker. This routine is called to setup the class to use for the linker. It returns the tsysteminfo structure updated with the correct linker class for internal linking. If internal linking is not supported, this class can be set to nil. } procedure RegisterInternalLinker(var system_info : tsysteminfo; c:TAbstractLinkerClass); procedure InitSystems; implementation uses cutils; {**************************************************************************** Target setting ****************************************************************************} function set_target(t:tsystem):boolean; begin set_target:=false; if assigned(targetinfos[t]) then begin target_info:=targetinfos[t]^; set_target_asm(target_info.assem); set_target_ar(target_info.ar); set_target_res(target_info.res); target_path:=lower(target_info.shortname); target_cpu:=target_info.cpu; set_target:=true; exit; end; end; function set_target_asm(t:tasm):boolean; begin set_target_asm:=false; if assigned(asminfos[t]) then begin target_asm:=asminfos[t]^; set_target_asm:=true; exit; end; end; function set_target_ar(t:tar):boolean; begin set_target_ar:=false; if assigned(arinfos[t]) then begin target_ar:=arinfos[t]^; set_target_ar:=true; exit; end; end; function set_target_res(t:tres):boolean; begin set_target_res:=false; if assigned(resinfos[t]) then begin target_res:=resinfos[t]^; set_target_res:=true; exit; end; end; function set_target_by_string(const s : string) : boolean; var hs : string; t : tsystem; begin set_target_by_string:=false; { this should be case insensitive !! PM } hs:=upper(s); for t:=low(tsystem) to high(tsystem) do if assigned(targetinfos[t]) and (upper(targetinfos[t]^.shortname)=hs) then begin set_target_by_string:=set_target(t); exit; end; end; function set_target_asm_by_string(const s : string) : boolean; var hs : string; t : tasm; begin set_target_asm_by_string:=false; { this should be case insensitive !! PM } hs:=upper(s); for t:=low(tasm) to high(tasm) do if assigned(asminfos[t]) and (asminfos[t]^.idtxt=hs) then begin set_target_asm_by_string:=set_target_asm(t); exit; end; end; function set_asmmode_by_string(const s:string;var t:tasmmode):boolean; var hs : string; ht : tasmmode; begin set_asmmode_by_string:=false; { this should be case insensitive !! PM } hs:=upper(s); for ht:=low(tasmmode) to high(tasmmode) do if assigned(asmmodeinfos[ht]) and (asmmodeinfos[ht]^.idtxt=hs) then begin t:=asmmodeinfos[ht]^.id; set_asmmode_by_string:=true; end; end; procedure UpdateAlignment(var d:talignmentinfo;const s:talignmentinfo); begin with d do begin { general update rules: minimum: if higher then update maximum: if lower then update or if undefined then update } if s.procalign>procalign then procalign:=s.procalign; if s.loopalign>loopalign then loopalign:=s.loopalign; if s.jumpalign>jumpalign then jumpalign:=s.jumpalign; if s.constalignmin>constalignmin then constalignmin:=s.constalignmin; if (constalignmax=0) or ((s.constalignmax>0) and (s.constalignmaxvaralignmin then varalignmin:=s.varalignmin; if (varalignmax=0) or ((s.varalignmax>0) and (s.varalignmaxlocalalignmin then localalignmin:=s.localalignmin; if (localalignmax=0) or ((s.localalignmax>0) and (s.localalignmaxparaalign then paraalign:=s.paraalign; if s.recordalignmin>recordalignmin then recordalignmin:=s.recordalignmin; if (recordalignmax=0) or ((s.recordalignmax>0) and (s.recordalignmax0) and (s.maxCrecordalign'' then Writeln('Warning: Source OS Redefined!'); source_info:=ti; end; procedure InitSystems; begin { Now default target, this is dependent on the i386 or m68k define, when the define is the same as the current cpu then we use the source os, else we pick a default } {$ifdef i386} {$ifdef cpu86} default_target(source_info.system); {$else cpu86} default_target(system_i386_linux); {$endif cpu86} {$endif i386} {$ifdef x86_64} {$ifdef cpu86_64} default_target(source_info.system); {$else cpu86_64} default_target(system_x86_64_linux); {$endif cpu86_64} {$endif x86_64} {$ifdef m68k} {$ifdef cpu68} default_target(source_info.target); {$else cpu68} default_target(system_m68k_linux); {$endif cpu68} {$endif m68k} {$ifdef alpha} {$ifdef cpualpha} default_target(source_info.system); {$else cpualpha} default_target(system_alpha_linux); {$endif cpualpha} {$endif alpha} {$ifdef powerpc} {$ifdef cpuppc} default_target(source_info.system); {$else cpuppc} default_target(system_powerpc_linux); {$endif cpuppc} {$endif powerpc} {$IFDEF sparc} default_target(system_sparc_linux); {$ENDIF sparc} end; initialization source_info.name:=''; finalization DeregisterInfos; end. { $Log$ Revision 1.59 2003-01-12 15:42:23 peter * m68k pathexist update from 1.0.x * palmos res update from 1.0.x Revision 1.58 2003/01/05 13:36:53 florian * x86-64 compiles + very basic support for float128 type (x86-64 only) Revision 1.57 2002/10/05 12:43:29 carl * fixes for Delphi 6 compilation (warning : Some features do not work under Delphi) Revision 1.56 2002/10/03 21:18:29 carl * correct tsystem enumeration Revision 1.55 2002/09/07 18:05:51 florian * first part of PowerPC fixes Revision 1.54 2002/08/20 21:40:44 florian + target macos for ppc added + frame work for mpw assembler output Revision 1.53 2002/08/18 09:13:02 florian * small fixes to the alpha stuff Revision 1.52 2002/08/13 21:40:57 florian * more fixes for ppc calling conventions Revision 1.51 2002/08/12 15:08:40 carl + stab register indexes for powerpc (moved from gdb to cpubase) + tprocessor enumeration moved to cpuinfo + linker in target_info is now a class * many many updates for m68k (will soon start to compile) - removed some ifdef or correct them for correct cpu Revision 1.50 2002/08/10 14:46:31 carl + moved target_cpu_string to cpuinfo * renamed asmmode enum. * assembler reader has now less ifdef's * move from nppcmem.pas -> ncgmem.pas vec. node. Revision 1.49 2002/07/28 20:45:22 florian + added direct assembler reader for PowerPC Revision 1.48 2002/07/26 21:15:42 florian * rewrote the system handling Revision 1.47 2002/07/04 20:43:02 florian * first x86-64 patches Revision 1.46 2002/07/01 18:46:29 peter * internal linker * reorganized aasm layer Revision 1.45 2002/05/18 13:34:21 peter * readded missing revisions Revision 1.44 2002/05/16 19:46:45 carl + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand + try to fix temp allocation (still in ifdef) + generic constructor calls + start of tassembler / tmodulebase class cleanup Revision 1.42 2002/05/06 19:52:04 carl + added more patches from Mazen for SPARC port Revision 1.41 2002/04/24 16:08:30 carl * fix compilation problem Revision 1.40 2002/04/20 21:32:26 carl + generic FPC_CHECKPOINTER + first parameter offset in stack now portable * rename some constants + move some cpu stuff to other units - remove unused constents * fix stacksize for some targets * fix generic size problems which depend now on EXTEND_SIZE constant Revision 1.39 2002/04/15 19:08:22 carl + target_info.size_of_pointer -> pointer_size + some cleanup of unused types/variables Revision 1.38 2002/04/14 16:56:30 carl - remove duplicate comment }