systems.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This unit contains information about the target systems supported
  5. (these are not processor specific)
  6. This program is free software; you can redistribute it and/or modify
  7. iu under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 3 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge- MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. unit systems;
  20. {$i fpcdefs.inc}
  21. interface
  22. type
  23. tendian = (endian_little,endian_big);
  24. {
  25. IMPORTANT NOTE:
  26. The value of this enumeration is stored in PPU files.
  27. Therefore adding new CPU targets should not change the
  28. values of the pre-existing targets. (CEC)
  29. FURTHERMORE : Make sure that this branch values, are
  30. consistant with the main branch version always.
  31. }
  32. tsystemcpu=
  33. (
  34. cpu_no, { 0 }
  35. cpu_i386, { 1 }
  36. cpu_m68k, { 2 }
  37. cpu_alpha, { 3 }
  38. cpu_powerpc, { 4 }
  39. cpu_sparc, { 5 }
  40. cpu_vm, { 6 }
  41. cpu_iA64, { 7 }
  42. cpu_x86_64, { 8 }
  43. cpu_mips, { 9 }
  44. cpu_arm { 10 }
  45. );
  46. tprocessors = (no_processor
  47. ,Class386,ClassP5,ClassP6
  48. ,MC68000,MC68100,MC68020
  49. ,PPC601,PPC604
  50. );
  51. TSection=(sec_none,
  52. sec_code,sec_data,sec_bss,
  53. sec_idata2,sec_idata4,sec_idata5,sec_idata6,sec_idata7,sec_edata,
  54. sec_stab,sec_stabstr,sec_common
  55. );
  56. tasmmode= (asmmode_none
  57. ,asmmode_i386_direct,asmmode_i386_att,asmmode_i386_intel
  58. ,asmmode_m68k_mot
  59. ,asmmode_alpha_direct
  60. ,asmmode_ppc_direct,asmmode_ppc_gas,asmmode_ppc_motorola
  61. );
  62. { IMPORTANT NOTE:
  63. the integer value of this enum is stored in PPU
  64. files to recognize the target, so if you add new targets
  65. allways add them at end PM
  66. FURTHERMORE : Make sure that this branch values are
  67. consistant with the main branch version always. (CEC)
  68. }
  69. type
  70. tsystem =
  71. (
  72. system_none, { 0 }
  73. obsolete_system_i386_GO32V1,{ 1 }
  74. system_i386_GO32V2, { 2 }
  75. system_i386_linux, { 3 }
  76. system_i386_OS2, { 4 }
  77. system_i386_Win32, { 5 }
  78. system_i386_freebsd, { 6 }
  79. system_m68k_Amiga, { 7 }
  80. system_m68k_Atari, { 8 }
  81. system_m68k_Mac, { 9 }
  82. system_m68k_linux, { 10 }
  83. system_m68k_PalmOS, { 11 }
  84. system_alpha_linux, { 12 }
  85. system_powerpc_linux, { 13 }
  86. system_powerpc_macos, { 14 }
  87. system_i386_sunos, { 15 }
  88. system_i386_beos, { 16 }
  89. system_i386_netbsd, { 17 }
  90. system_m68k_netbsd, { 18 }
  91. system_i386_Netware, { 19 }
  92. system_i386_qnx, { 20 }
  93. system_i386_wdosx, { 21 }
  94. system_sparc_sunos, { 22 }
  95. system_sparc_linux, { 23 }
  96. system_x86_64_linux { 24 }
  97. );
  98. tasm = (as_none
  99. ,as_i386_as,as_i386_as_aout,as_i386_asw,as_i386_aswdosx,
  100. as_i386_nasmcoff,as_i386_nasmwin32,as_i386_nasmwdosx,
  101. as_i386_nasmelf,as_i386_nasmobj,
  102. as_i386_tasm,as_i386_masm,
  103. as_i386_dbg,as_i386_coff,as_i386_pecoff,as_i386_elf32,as_i386_pecoffwdosx
  104. ,as_m68k_as,as_m68k_gas,as_m68k_mit,as_m68k_mot,
  105. as_m68k_mpw,as_m68k_palm
  106. ,as_alpha_as
  107. ,as_powerpc_as,as_powerpc_mpw,
  108. as_SPARC_as,as_SPARC_elf32
  109. );
  110. tld = (ld_none,
  111. ld_i386_GO32V1,ld_i386_GO32V2,ld_i386_linux,
  112. ld_i386_OS2,ld_i386_Win32,ld_i386_freebsd,
  113. ld_i386_Netware,ld_i386_sunos,ld_i386_beos,
  114. ld_i386_coff,ld_i386_pecoff,ld_i386_Wdosx,
  115. ld_m68k_Amiga,ld_m68k_Atari,ld_m68k_Mac,
  116. ld_m68k_linux,ld_m68k_PalmOS,ld_m68k_freebsd,
  117. ld_alpha_linux,
  118. ld_x86_64_linux,
  119. ld_powerpc_linux,ld_powerpc_macos,
  120. ld_SPARC_SunOs,ld_SPARC_linux
  121. );
  122. tar = (ar_none
  123. ,ar_gnu_ar,ar_gnu_arw
  124. );
  125. tres = (res_none
  126. ,res_gnu_windres,res_emxbind
  127. );
  128. tscripttype = (script_none
  129. ,script_dos,script_unix,script_amiga
  130. );
  131. {*****************************************************************************
  132. Structures
  133. *****************************************************************************}
  134. type
  135. palignmentinfo = ^talignmentinfo;
  136. talignmentinfo = packed record
  137. procalign,
  138. loopalign,
  139. jumpalign,
  140. constalignmin,
  141. constalignmax,
  142. varalignmin,
  143. varalignmax,
  144. localalignmin,
  145. localalignmax,
  146. paraalign,
  147. recordalignmin,
  148. recordalignmax,
  149. maxCrecordalign : longint;
  150. end;
  151. pasminfo = ^tasminfo;
  152. tasminfo = packed record
  153. id : tasm;
  154. idtxt : string[9];
  155. asmbin : string[8];
  156. asmcmd : string[50];
  157. supported_target : tsystem;
  158. outputbinary,
  159. allowdirect,
  160. externals,
  161. needar,
  162. labelprefix_only_inside_procedure : boolean;
  163. labelprefix : string[3];
  164. comment : string[2];
  165. secnames : array[TSection] of string[20];
  166. end;
  167. parinfo = ^tarinfo;
  168. tarinfo = packed record
  169. id : tar;
  170. arcmd : string[50];
  171. end;
  172. presinfo = ^tresinfo;
  173. tresinfo = packed record
  174. id : tres;
  175. resbin : string[8];
  176. rescmd : string[50];
  177. end;
  178. tsystemflags = (tf_none,
  179. tf_under_development,
  180. tf_need_export,tf_needs_isconsole
  181. ,tf_code_small,tf_static_reg_based
  182. );
  183. psysteminfo = ^tsysteminfo;
  184. tsysteminfo = packed record
  185. system : tsystem;
  186. name : string[30];
  187. shortname : string[9];
  188. flags : set of tsystemflags;
  189. cpu : tsystemcpu;
  190. unit_env : string[12];
  191. extradefines : string[40];
  192. sourceext,
  193. pasext,
  194. exeext,
  195. defext,
  196. scriptext,
  197. smartext,
  198. unitext,
  199. unitlibext,
  200. asmext,
  201. objext,
  202. resext,
  203. resobjext : string[4];
  204. sharedlibext : string[10];
  205. staticlibext,
  206. staticlibprefix : string[4];
  207. sharedlibprefix : string[4];
  208. sharedClibext : string[10];
  209. staticClibext,
  210. staticClibprefix : string[4];
  211. sharedClibprefix : string[4];
  212. Cprefix : string[2];
  213. newline : string[2];
  214. dirsep : char;
  215. files_case_relevent : boolean;
  216. assem : tasm;
  217. assemextern : tasm; { external assembler, used by -a }
  218. link : tld;
  219. linkextern : tld; { external linker, used by -s }
  220. ar : tar;
  221. res : tres;
  222. script : tscripttype;
  223. endian : tendian;
  224. alignment : talignmentinfo;
  225. {
  226. Offset from the argument pointer register to the first
  227. argument's address. On some machines it may depend on
  228. the data type of the function.
  229. (see also FIRST_PARM_OFFSET in GCC source)
  230. }
  231. first_parm_offset : longint;
  232. heapsize,
  233. stacksize : longint;
  234. DllScanSupported : boolean;
  235. use_function_relative_addresses : boolean;
  236. end;
  237. pasmmodeinfo = ^tasmmodeinfo;
  238. tasmmodeinfo = packed record
  239. id : tasmmode;
  240. idtxt : string[8];
  241. end;
  242. const
  243. { alias for supported_target field in tasminfo }
  244. system_any = system_none;
  245. var
  246. targetinfos : array[tsystem] of psysteminfo;
  247. asminfos : array[tasm] of pasminfo;
  248. arinfos : array[tar] of parinfo;
  249. resinfos : array[tres] of presinfo;
  250. asmmodeinfos : array[tasmmode] of pasmmodeinfo;
  251. source_info : tsysteminfo;
  252. target_cpu : tsystemcpu;
  253. target_info : tsysteminfo;
  254. target_asm : tasminfo;
  255. target_ar : tarinfo;
  256. target_res : tresinfo;
  257. target_path : string[12]; { for rtl/<X>/,fcl/<X>/, etc. }
  258. function set_target(t:tsystem):boolean;
  259. function set_target_asm(t:tasm):boolean;
  260. function set_target_ar(t:tar):boolean;
  261. function set_target_res(t:tres):boolean;
  262. function set_target_by_string(const s : string) : boolean;
  263. function set_target_asm_by_string(const s : string) : boolean;
  264. function set_asmmode_by_string(const s:string;var t:tasmmode):boolean;
  265. procedure set_source_info(const ti : tsysteminfo);
  266. procedure UpdateAlignment(var d:talignmentinfo;const s:talignmentinfo);
  267. procedure RegisterTarget(const r:tsysteminfo);
  268. procedure RegisterAsmMode(const r:tasmmodeinfo);
  269. procedure RegisterRes(const r:tresinfo);
  270. procedure RegisterAr(const r:tarinfo);
  271. procedure InitSystems;
  272. implementation
  273. uses
  274. cutils;
  275. {****************************************************************************
  276. Target setting
  277. ****************************************************************************}
  278. function set_target(t:tsystem):boolean;
  279. begin
  280. set_target:=false;
  281. if assigned(targetinfos[t]) then
  282. begin
  283. target_info:=targetinfos[t]^;
  284. set_target_asm(target_info.assem);
  285. set_target_ar(target_info.ar);
  286. set_target_res(target_info.res);
  287. target_path:=lower(target_info.shortname);
  288. target_cpu:=target_info.cpu;
  289. set_target:=true;
  290. exit;
  291. end;
  292. end;
  293. function set_target_asm(t:tasm):boolean;
  294. begin
  295. set_target_asm:=false;
  296. if assigned(asminfos[t]) then
  297. begin
  298. target_asm:=asminfos[t]^;
  299. set_target_asm:=true;
  300. exit;
  301. end;
  302. end;
  303. function set_target_ar(t:tar):boolean;
  304. begin
  305. set_target_ar:=false;
  306. if assigned(arinfos[t]) then
  307. begin
  308. target_ar:=arinfos[t]^;
  309. set_target_ar:=true;
  310. exit;
  311. end;
  312. end;
  313. function set_target_res(t:tres):boolean;
  314. begin
  315. set_target_res:=false;
  316. if assigned(resinfos[t]) then
  317. begin
  318. target_res:=resinfos[t]^;
  319. set_target_res:=true;
  320. exit;
  321. end;
  322. end;
  323. function set_target_by_string(const s : string) : boolean;
  324. var
  325. hs : string;
  326. t : tsystem;
  327. begin
  328. set_target_by_string:=false;
  329. { this should be case insensitive !! PM }
  330. hs:=upper(s);
  331. for t:=low(tsystem) to high(tsystem) do
  332. if assigned(targetinfos[t]) and
  333. (upper(targetinfos[t]^.shortname)=hs) then
  334. begin
  335. set_target_by_string:=set_target(t);
  336. exit;
  337. end;
  338. end;
  339. function set_target_asm_by_string(const s : string) : boolean;
  340. var
  341. hs : string;
  342. t : tasm;
  343. begin
  344. set_target_asm_by_string:=false;
  345. { this should be case insensitive !! PM }
  346. hs:=upper(s);
  347. for t:=low(tasm) to high(tasm) do
  348. if assigned(asminfos[t]) and
  349. (asminfos[t]^.idtxt=hs) then
  350. begin
  351. set_target_asm_by_string:=set_target_asm(t);
  352. exit;
  353. end;
  354. end;
  355. function set_asmmode_by_string(const s:string;var t:tasmmode):boolean;
  356. var
  357. hs : string;
  358. ht : tasmmode;
  359. begin
  360. set_asmmode_by_string:=false;
  361. { this should be case insensitive !! PM }
  362. hs:=upper(s);
  363. for ht:=low(tasmmode) to high(tasmmode) do
  364. if assigned(asmmodeinfos[ht]) and
  365. (asmmodeinfos[ht]^.idtxt=hs) then
  366. begin
  367. t:=asmmodeinfos[ht]^.id;
  368. set_asmmode_by_string:=true;
  369. end;
  370. end;
  371. procedure UpdateAlignment(var d:talignmentinfo;const s:talignmentinfo);
  372. begin
  373. with d do
  374. begin
  375. { general update rules:
  376. minimum: if higher then update
  377. maximum: if lower then update or if undefined then update }
  378. if s.procalign>procalign then
  379. procalign:=s.procalign;
  380. if s.loopalign>loopalign then
  381. loopalign:=s.loopalign;
  382. if s.jumpalign>jumpalign then
  383. jumpalign:=s.jumpalign;
  384. if s.constalignmin>constalignmin then
  385. constalignmin:=s.constalignmin;
  386. if (constalignmax=0) or
  387. ((s.constalignmax>0) and (s.constalignmax<constalignmax)) then
  388. constalignmax:=s.constalignmax;
  389. if s.varalignmin>varalignmin then
  390. varalignmin:=s.varalignmin;
  391. if (varalignmax=0) or
  392. ((s.varalignmax>0) and (s.varalignmax<varalignmax)) then
  393. varalignmax:=s.varalignmax;
  394. if s.localalignmin>localalignmin then
  395. localalignmin:=s.localalignmin;
  396. if (localalignmax=0) or
  397. ((s.localalignmax>0) and (s.localalignmax<localalignmax)) then
  398. localalignmax:=s.localalignmax;
  399. if s.paraalign>paraalign then
  400. paraalign:=s.paraalign;
  401. if s.recordalignmin>recordalignmin then
  402. recordalignmin:=s.recordalignmin;
  403. if (recordalignmax=0) or
  404. ((s.recordalignmax>0) and (s.recordalignmax<recordalignmax)) then
  405. recordalignmax:=s.recordalignmax;
  406. if (maxCrecordalign=0) or
  407. ((s.maxCrecordalign>0) and (s.maxCrecordalign<maxCrecordalign)) then
  408. maxCrecordalign:=s.maxCrecordalign;
  409. end;
  410. end;
  411. {****************************************************************************
  412. Target registration
  413. ****************************************************************************}
  414. procedure RegisterTarget(const r:tsysteminfo);
  415. var
  416. t : tsystem;
  417. begin
  418. t:=r.system;
  419. if assigned(targetinfos[t]) then
  420. writeln('Warning: Target is already registered!')
  421. else
  422. Getmem(targetinfos[t],sizeof(tsysteminfo));
  423. targetinfos[t]^:=r;
  424. end;
  425. procedure RegisterAsmmode(const r:tasmmodeinfo);
  426. var
  427. t : tasmmode;
  428. begin
  429. t:=r.id;
  430. if assigned(asmmodeinfos[t]) then
  431. writeln('Warning: Asmmode is already registered!')
  432. else
  433. Getmem(asmmodeinfos[t],sizeof(tasmmodeinfo));
  434. asmmodeinfos[t]^:=r;
  435. end;
  436. procedure RegisterRes(const r:tresinfo);
  437. var
  438. t : tres;
  439. begin
  440. t:=r.id;
  441. if assigned(resinfos[t]) then
  442. writeln('Warning: resourcecompiler is already registered!')
  443. else
  444. Getmem(resinfos[t],sizeof(tresinfo));
  445. resinfos[t]^:=r;
  446. end;
  447. procedure RegisterAr(const r:tarinfo);
  448. var
  449. t : tar;
  450. begin
  451. t:=r.id;
  452. if assigned(arinfos[t]) then
  453. writeln('Warning: ar is already registered!')
  454. else
  455. Getmem(arinfos[t],sizeof(tarinfo));
  456. arinfos[t]^:=r;
  457. end;
  458. procedure DeregisterInfos;
  459. var
  460. assem : tasm;
  461. target : tsystem;
  462. ar : tar;
  463. asmmode : tasmmode;
  464. res : tres;
  465. begin
  466. for target:=low(tsystem) to high(tsystem) do
  467. if assigned(targetinfos[target]) then
  468. begin
  469. freemem(targetinfos[target],sizeof(tsysteminfo));
  470. targetinfos[target]:=nil;
  471. end;
  472. for assem:=low(tasm) to high(tasm) do
  473. if assigned(asminfos[assem]) then
  474. begin
  475. freemem(asminfos[assem],sizeof(tasminfo));
  476. asminfos[assem]:=nil;
  477. end;
  478. for ar:=low(tar) to high(tar) do
  479. if assigned(arinfos[ar]) then
  480. begin
  481. freemem(arinfos[ar],sizeof(tarinfo));
  482. arinfos[ar]:=nil;
  483. end;
  484. for res:=low(tres) to high(tres) do
  485. if assigned(resinfos[res]) then
  486. begin
  487. freemem(resinfos[res],sizeof(tresinfo));
  488. resinfos[res]:=nil;
  489. end;
  490. for asmmode:=low(tasmmode) to high(tasmmode) do
  491. if assigned(asmmodeinfos[asmmode]) then
  492. begin
  493. freemem(asmmodeinfos[asmmode],sizeof(tasmmodeinfo));
  494. asmmodeinfos[asmmode]:=nil;
  495. end;
  496. end;
  497. {****************************************************************************
  498. Initialization of default target
  499. ****************************************************************************}
  500. procedure default_target(t:tsystem);
  501. begin
  502. set_target(t);
  503. if source_info.name='' then
  504. source_info:=target_info;
  505. end;
  506. procedure set_source_info(const ti : tsysteminfo);
  507. begin
  508. { can't use message() here (PFV) }
  509. if source_info.name<>'' then
  510. Writeln('Warning: Source OS Redefined!');
  511. source_info:=ti;
  512. end;
  513. procedure InitSystems;
  514. begin
  515. { Now default target, this is dependent on the i386 or m68k define,
  516. when the define is the same as the current cpu then we use the source
  517. os, else we pick a default }
  518. {$ifdef i386}
  519. {$ifdef cpu86}
  520. default_target(source_info.system);
  521. {$else cpu86}
  522. default_target(target_i386_linux);
  523. {$endif cpu86}
  524. {$endif i386}
  525. {$ifdef x86_64}
  526. {$ifdef cpu86_64}
  527. default_target(source_info.system);
  528. {$else cpu86_64}
  529. default_target(target_x86_64_linux);
  530. {$endif cpu86_64}
  531. {$endif x86_64}
  532. {$ifdef m68k}
  533. {$ifdef cpu68}
  534. default_target(source_info.target);
  535. {$else cpu68}
  536. default_target(target_m68k_linux);
  537. {$endif cpu68}
  538. {$endif m68k}
  539. {$ifdef alpha}
  540. {$ifdef cpualpha}
  541. default_target(source_info.system);
  542. {$else cpualpha}
  543. default_target(target_alpha_linux);
  544. {$endif cpualpha}
  545. {$endif alpha}
  546. {$ifdef powerpc}
  547. {$ifdef cpuppc}
  548. default_target(source_info.system);
  549. {$else cpuppc}
  550. default_target(system_powerpc_linux);
  551. {$endif cpuppc}
  552. {$endif powerpc}
  553. {$IFDEF sparc}
  554. default_target(system_sparc_linux);
  555. {$ENDIF sparc}
  556. end;
  557. initialization
  558. source_info.name:='';
  559. finalization
  560. DeregisterInfos;
  561. end.
  562. {
  563. $Log$
  564. Revision 1.49 2002-07-28 20:45:22 florian
  565. + added direct assembler reader for PowerPC
  566. Revision 1.48 2002/07/26 21:15:42 florian
  567. * rewrote the system handling
  568. Revision 1.47 2002/07/04 20:43:02 florian
  569. * first x86-64 patches
  570. Revision 1.46 2002/07/01 18:46:29 peter
  571. * internal linker
  572. * reorganized aasm layer
  573. Revision 1.45 2002/05/18 13:34:21 peter
  574. * readded missing revisions
  575. Revision 1.44 2002/05/16 19:46:45 carl
  576. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  577. + try to fix temp allocation (still in ifdef)
  578. + generic constructor calls
  579. + start of tassembler / tmodulebase class cleanup
  580. Revision 1.42 2002/05/06 19:52:04 carl
  581. + added more patches from Mazen for SPARC port
  582. Revision 1.41 2002/04/24 16:08:30 carl
  583. * fix compilation problem
  584. Revision 1.40 2002/04/20 21:32:26 carl
  585. + generic FPC_CHECKPOINTER
  586. + first parameter offset in stack now portable
  587. * rename some constants
  588. + move some cpu stuff to other units
  589. - remove unused constents
  590. * fix stacksize for some targets
  591. * fix generic size problems which depend now on EXTEND_SIZE constant
  592. Revision 1.39 2002/04/15 19:08:22 carl
  593. + target_info.size_of_pointer -> pointer_size
  594. + some cleanup of unused types/variables
  595. Revision 1.38 2002/04/14 16:56:30 carl
  596. - remove duplicate comment
  597. }