systems.pas 19 KB

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