aasm.pas 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This unit implements an abstract asmoutput class for all processor types
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. {# @abstract(This unit implements an abstract asm output class for all processor types)
  19. This unit implements an abstract assembler output class for all processors, these
  20. are then overriden for each assembler writer to actually write the data in these
  21. classes to an assembler file.
  22. }
  23. unit aasm;
  24. {$i fpcdefs.inc}
  25. interface
  26. uses
  27. cutils,cclasses,
  28. globtype,globals,systems;
  29. type
  30. tait = (
  31. ait_none,
  32. ait_direct,
  33. ait_string,
  34. ait_label,
  35. ait_comment,
  36. ait_instruction,
  37. ait_datablock,
  38. ait_symbol,
  39. ait_symbol_end, { needed to calc the size of a symbol }
  40. ait_const_32bit,
  41. ait_const_16bit,
  42. ait_const_8bit,
  43. ait_const_symbol,
  44. ait_real_80bit,
  45. ait_real_64bit,
  46. ait_real_32bit,
  47. ait_comp_64bit,
  48. ait_align,
  49. ait_section,
  50. { the following is only used by the win32 version of the compiler }
  51. { and only the GNU AS Win32 is able to write it }
  52. ait_const_rva,
  53. ait_stabn,
  54. ait_stabs,
  55. ait_force_line,
  56. ait_stab_function_name,
  57. ait_cut, { used to split into tiny assembler files }
  58. ait_regalloc, { for register,temp allocation debugging }
  59. ait_tempalloc,
  60. ait_marker,
  61. {$ifdef alpha}
  62. { the follow is for the DEC Alpha }
  63. ait_frame,
  64. ait_ent,
  65. {$endif alpha}
  66. {$ifdef m68k}
  67. ait_labeled_instruction,
  68. {$endif m68k}
  69. {$ifdef ia64}
  70. ait_bundle,
  71. ait_stop,
  72. {$endif ia64}
  73. {$ifdef SPARC}
  74. ait_labeled_instruction,
  75. {$endif SPARC}
  76. { never used, makes insertation of new ait_ easier to type }
  77. { lazy guy !!!! ;-) (FK) }
  78. ait_dummy);
  79. { ait_* types which don't result in executable code or which don't influence }
  80. { the way the program runs/behaves, but which may be encountered by the }
  81. { optimizer (= if it's sometimes added to the exprasm list). Update if you add }
  82. { a new ait type! }
  83. const
  84. SkipInstr = [ait_comment, ait_symbol,ait_force_line,ait_section
  85. {$ifdef GDB}
  86. ,ait_stabs, ait_stabn, ait_stab_function_name
  87. {$endif GDB}
  88. ,ait_regalloc, ait_tempalloc, ait_symbol_end
  89. ];
  90. { asm symbol functions }
  91. type
  92. TAsmsymbind=(AB_NONE,AB_EXTERNAL,AB_COMMON,AB_LOCAL,AB_GLOBAL);
  93. TAsmsymtype=(AT_NONE,AT_FUNCTION,AT_DATA,AT_SECTION);
  94. tasmsymbol = class(TNamedIndexItem)
  95. defbind,
  96. bind : TAsmsymbind;
  97. typ : TAsmsymtype;
  98. { the next fields are filled in the binary writer }
  99. section : tsection;
  100. idx : longint;
  101. address,
  102. size : longint;
  103. { this need to be incremented with every symbol loading into the
  104. paasmoutput, thus in loadsym/loadref/const_symbol (PFV) }
  105. refs : longint;
  106. {# Alternate symbol which can be used for 'renaming' needed for
  107. inlining }
  108. altsymbol : tasmsymbol;
  109. {# TRUE if the symbol is local for a procedure/function }
  110. proclocal : boolean;
  111. {# Is the symbol in the used list }
  112. inusedlist : boolean;
  113. { assembler pass label is set, used for detecting multiple labels }
  114. pass : byte;
  115. constructor create(const s:string;_bind:TAsmsymbind;_typ:Tasmsymtype);
  116. procedure reset;
  117. function is_used:boolean;
  118. procedure setaddress(_pass:byte;sec:tsection;offset,len:longint);
  119. procedure GenerateAltSymbol;
  120. end;
  121. tasmlabel = class(tasmsymbol)
  122. { this is set by the tai_label.Init }
  123. is_set,
  124. { is the label only there for getting an address (e.g. for i/o }
  125. { checks -> true) or is it a jump target (false) }
  126. is_addr : boolean;
  127. labelnr : longint;
  128. constructor create;
  129. constructor createdata;
  130. constructor createaddr;
  131. function getname:string;override;
  132. end;
  133. { the short name makes typing easier }
  134. tai = class(tlinkedlistitem)
  135. { pointer to record with optimizer info about this tai object }
  136. optinfo : pointer;
  137. fileinfo : tfileposinfo;
  138. typ : tait;
  139. constructor Create;
  140. end;
  141. tai_string = class(tai)
  142. str : pchar;
  143. { extra len so the string can contain an \0 }
  144. len : longint;
  145. constructor Create(const _str : string);
  146. constructor Create_pchar(_str : pchar);
  147. constructor Create_length_pchar(_str : pchar;length : longint);
  148. destructor Destroy;override;
  149. end;
  150. { generates a common label }
  151. tai_symbol = class(tai)
  152. is_global : boolean;
  153. sym : tasmsymbol;
  154. size : longint;
  155. constructor Create(_sym:tasmsymbol;siz:longint);
  156. constructor Createname(const _name : string;siz:longint);
  157. constructor Createname_global(const _name : string;siz:longint);
  158. constructor Createdataname(const _name : string;siz:longint);
  159. constructor Createdataname_global(const _name : string;siz:longint);
  160. end;
  161. tai_symbol_end = class(tai)
  162. sym : tasmsymbol;
  163. constructor Create(_sym:tasmsymbol);
  164. constructor Createname(const _name : string);
  165. end;
  166. tai_label = class(tai)
  167. is_global : boolean;
  168. l : tasmlabel;
  169. constructor Create(_l : tasmlabel);
  170. end;
  171. tai_direct = class(tai)
  172. str : pchar;
  173. constructor Create(_str : pchar);
  174. destructor Destroy; override;
  175. end;
  176. { to insert a comment into the generated assembler file }
  177. tai_asm_comment = class(tai)
  178. str : pchar;
  179. constructor Create(_str : pchar);
  180. destructor Destroy; override;
  181. end;
  182. { Insert a section/segment directive }
  183. tai_section = class(tai)
  184. sec : tsection;
  185. constructor Create(s : tsection);
  186. end;
  187. { generates an uninitializised data block }
  188. tai_datablock = class(tai)
  189. is_global : boolean;
  190. sym : tasmsymbol;
  191. size : longint;
  192. constructor Create(const _name : string;_size : longint);
  193. constructor Create_global(const _name : string;_size : longint);
  194. end;
  195. { generates a long integer (32 bit) }
  196. tai_const = class(tai)
  197. value : longint;
  198. constructor Create_32bit(_value : longint);
  199. constructor Create_16bit(_value : word);
  200. constructor Create_8bit(_value : byte);
  201. end;
  202. tai_const_symbol = class(tai)
  203. sym : tasmsymbol;
  204. offset : longint;
  205. constructor Create(_sym:tasmsymbol);
  206. constructor Create_offset(_sym:tasmsymbol;ofs:longint);
  207. constructor Create_rva(_sym:tasmsymbol);
  208. constructor Createname(const name:string);
  209. constructor Createname_offset(const name:string;ofs:longint);
  210. constructor Createname_rva(const name:string);
  211. end;
  212. { generates a single (32 bit real) }
  213. tai_real_32bit = class(tai)
  214. value : ts32real;
  215. constructor Create(_value : ts32real);
  216. end;
  217. { generates a double (64 bit real) }
  218. tai_real_64bit = class(tai)
  219. value : ts64real;
  220. constructor Create(_value : ts64real);
  221. end;
  222. { generates an extended (80 bit real) }
  223. tai_real_80bit = class(tai)
  224. value : ts80real;
  225. constructor Create(_value : ts80real);
  226. end;
  227. { generates an comp (integer over 64 bits) }
  228. tai_comp_64bit = class(tai)
  229. value : ts64comp;
  230. constructor Create(_value : ts64comp);
  231. end;
  232. { insert a cut to split into several smaller files }
  233. tcutplace=(cut_normal,cut_begin,cut_end);
  234. tai_cut = class(tai)
  235. place : tcutplace;
  236. constructor Create;
  237. constructor Create_begin;
  238. constructor Create_end;
  239. end;
  240. TMarker = (NoPropInfoStart, NoPropInfoEnd,
  241. AsmBlockStart, AsmBlockEnd,
  242. InlineStart,InlineEnd
  243. );
  244. tai_marker = class(tai)
  245. Kind: TMarker;
  246. Constructor Create(_Kind: TMarker);
  247. end;
  248. taitempalloc = class(tai)
  249. allocation : boolean;
  250. temppos,
  251. tempsize : longint;
  252. constructor alloc(pos,size:longint);
  253. constructor dealloc(pos,size:longint);
  254. end;
  255. { for each processor define the best precision }
  256. { bestreal is defined in globals }
  257. {$ifdef i386}
  258. const
  259. ait_bestreal = ait_real_80bit;
  260. type
  261. tai_bestreal = tai_real_80bit;
  262. {$endif i386}
  263. {$ifdef m68k}
  264. const
  265. ait_bestreal = ait_real_32bit;
  266. type
  267. tai_bestreal = tai_real_32bit;
  268. {$endif m68k}
  269. taasmoutput = class(tlinkedlist)
  270. function getlasttaifilepos : pfileposinfo;
  271. end;
  272. const
  273. { maximum of aasmoutput lists there will be }
  274. maxoutputlists = 10;
  275. var
  276. { temporary lists }
  277. exprasmlist,
  278. { default lists }
  279. datasegment,codesegment,bsssegment,
  280. debuglist,withdebuglist,consts,
  281. importssection,exportssection,
  282. resourcesection,rttilist,
  283. resourcestringlist : taasmoutput;
  284. { asm symbol list }
  285. asmsymbollist : tdictionary;
  286. usedasmsymbollist : tsinglelist;
  287. const
  288. nextaltnr : longint = 1;
  289. nextlabelnr : longint = 1;
  290. countlabelref : boolean = true;
  291. {# create a new assembler label }
  292. procedure getlabel(var l : tasmlabel);
  293. { make l as a new label and flag is_addr }
  294. procedure getaddrlabel(var l : tasmlabel);
  295. { make l as a new label and flag is_data }
  296. procedure getdatalabel(var l : tasmlabel);
  297. {# return a label number }
  298. procedure getlabelnr(var l : longint);
  299. function newasmsymbol(const s : string) : tasmsymbol;
  300. function newasmsymboltype(const s : string;_bind:TAsmSymBind;_typ:TAsmsymtype) : tasmsymbol;
  301. function getasmsymbol(const s : string) : tasmsymbol;
  302. function renameasmsymbol(const sold, snew : string):tasmsymbol;
  303. procedure CreateUsedAsmSymbolList;
  304. procedure DestroyUsedAsmSymbolList;
  305. procedure UsedAsmSymbolListInsert(p:tasmsymbol);
  306. procedure UsedAsmSymbolListReset;
  307. procedure UsedAsmSymbolListResetAltSym;
  308. procedure UsedAsmSymbolListCheckUndefined;
  309. implementation
  310. uses
  311. {$ifdef delphi}
  312. sysutils,
  313. {$else}
  314. strings,
  315. {$endif}
  316. fmodule,verbose;
  317. {****************************************************************************
  318. TAI
  319. ****************************************************************************}
  320. constructor tai.Create;
  321. begin
  322. optinfo := nil;
  323. fileinfo:=aktfilepos;
  324. end;
  325. {****************************************************************************
  326. TAI_SECTION
  327. ****************************************************************************}
  328. constructor tai_section.Create(s : tsection);
  329. begin
  330. inherited Create;
  331. typ:=ait_section;
  332. sec:=s;
  333. end;
  334. {****************************************************************************
  335. TAI_DATABLOCK
  336. ****************************************************************************}
  337. constructor tai_datablock.Create(const _name : string;_size : longint);
  338. begin
  339. inherited Create;
  340. typ:=ait_datablock;
  341. sym:=newasmsymboltype(_name,AB_LOCAL,AT_DATA);
  342. { keep things aligned }
  343. if _size<=0 then
  344. _size:=4;
  345. size:=_size;
  346. is_global:=false;
  347. end;
  348. constructor tai_datablock.Create_global(const _name : string;_size : longint);
  349. begin
  350. inherited Create;
  351. typ:=ait_datablock;
  352. sym:=newasmsymboltype(_name,AB_GLOBAL,AT_DATA);
  353. { keep things aligned }
  354. if _size<=0 then
  355. _size:=4;
  356. size:=_size;
  357. is_global:=true;
  358. end;
  359. {****************************************************************************
  360. TAI_SYMBOL
  361. ****************************************************************************}
  362. constructor tai_symbol.Create(_sym:tasmsymbol;siz:longint);
  363. begin
  364. inherited Create;
  365. typ:=ait_symbol;
  366. sym:=_sym;
  367. size:=siz;
  368. is_global:=(sym.defbind=AB_GLOBAL);
  369. end;
  370. constructor tai_symbol.Createname(const _name : string;siz:longint);
  371. begin
  372. inherited Create;
  373. typ:=ait_symbol;
  374. sym:=newasmsymboltype(_name,AB_LOCAL,AT_FUNCTION);
  375. size:=siz;
  376. is_global:=false;
  377. end;
  378. constructor tai_symbol.Createname_global(const _name : string;siz:longint);
  379. begin
  380. inherited Create;
  381. typ:=ait_symbol;
  382. sym:=newasmsymboltype(_name,AB_GLOBAL,AT_FUNCTION);
  383. size:=siz;
  384. is_global:=true;
  385. end;
  386. constructor tai_symbol.Createdataname(const _name : string;siz:longint);
  387. begin
  388. inherited Create;
  389. typ:=ait_symbol;
  390. sym:=newasmsymboltype(_name,AB_LOCAL,AT_DATA);
  391. size:=siz;
  392. is_global:=false;
  393. end;
  394. constructor tai_symbol.Createdataname_global(const _name : string;siz:longint);
  395. begin
  396. inherited Create;
  397. typ:=ait_symbol;
  398. sym:=newasmsymboltype(_name,AB_GLOBAL,AT_DATA);
  399. size:=siz;
  400. is_global:=true;
  401. end;
  402. {****************************************************************************
  403. TAI_SYMBOL
  404. ****************************************************************************}
  405. constructor tai_symbol_end.Create(_sym:tasmsymbol);
  406. begin
  407. inherited Create;
  408. typ:=ait_symbol_end;
  409. sym:=_sym;
  410. end;
  411. constructor tai_symbol_end.Createname(const _name : string);
  412. begin
  413. inherited Create;
  414. typ:=ait_symbol_end;
  415. sym:=newasmsymboltype(_name,AB_GLOBAL,AT_NONE);
  416. end;
  417. {****************************************************************************
  418. TAI_CONST
  419. ****************************************************************************}
  420. constructor tai_const.Create_32bit(_value : longint);
  421. begin
  422. inherited Create;
  423. typ:=ait_const_32bit;
  424. value:=_value;
  425. end;
  426. constructor tai_const.Create_16bit(_value : word);
  427. begin
  428. inherited Create;
  429. typ:=ait_const_16bit;
  430. value:=_value;
  431. end;
  432. constructor tai_const.Create_8bit(_value : byte);
  433. begin
  434. inherited Create;
  435. typ:=ait_const_8bit;
  436. value:=_value;
  437. end;
  438. {****************************************************************************
  439. TAI_CONST_SYMBOL_OFFSET
  440. ****************************************************************************}
  441. constructor tai_const_symbol.Create(_sym:tasmsymbol);
  442. begin
  443. inherited Create;
  444. typ:=ait_const_symbol;
  445. sym:=_sym;
  446. offset:=0;
  447. { update sym info }
  448. inc(sym.refs);
  449. end;
  450. constructor tai_const_symbol.Create_offset(_sym:tasmsymbol;ofs:longint);
  451. begin
  452. inherited Create;
  453. typ:=ait_const_symbol;
  454. sym:=_sym;
  455. offset:=ofs;
  456. { update sym info }
  457. inc(sym.refs);
  458. end;
  459. constructor tai_const_symbol.Create_rva(_sym:tasmsymbol);
  460. begin
  461. inherited Create;
  462. typ:=ait_const_rva;
  463. sym:=_sym;
  464. offset:=0;
  465. { update sym info }
  466. inc(sym.refs);
  467. end;
  468. constructor tai_const_symbol.Createname(const name:string);
  469. begin
  470. inherited Create;
  471. typ:=ait_const_symbol;
  472. sym:=newasmsymbol(name);
  473. offset:=0;
  474. { update sym info }
  475. inc(sym.refs);
  476. end;
  477. constructor tai_const_symbol.Createname_offset(const name:string;ofs:longint);
  478. begin
  479. inherited Create;
  480. typ:=ait_const_symbol;
  481. sym:=newasmsymbol(name);
  482. offset:=ofs;
  483. { update sym info }
  484. inc(sym.refs);
  485. end;
  486. constructor tai_const_symbol.Createname_rva(const name:string);
  487. begin
  488. inherited Create;
  489. typ:=ait_const_rva;
  490. sym:=newasmsymbol(name);
  491. offset:=0;
  492. { update sym info }
  493. inc(sym.refs);
  494. end;
  495. {****************************************************************************
  496. TAI_real_32bit
  497. ****************************************************************************}
  498. constructor tai_real_32bit.Create(_value : ts32real);
  499. begin
  500. inherited Create;
  501. typ:=ait_real_32bit;
  502. value:=_value;
  503. end;
  504. {****************************************************************************
  505. TAI_real_64bit
  506. ****************************************************************************}
  507. constructor tai_real_64bit.Create(_value : ts64real);
  508. begin
  509. inherited Create;
  510. typ:=ait_real_64bit;
  511. value:=_value;
  512. end;
  513. {****************************************************************************
  514. TAI_real_80bit
  515. ****************************************************************************}
  516. constructor tai_real_80bit.Create(_value : ts80real);
  517. begin
  518. inherited Create;
  519. typ:=ait_real_80bit;
  520. value:=_value;
  521. end;
  522. {****************************************************************************
  523. Tai_comp_64bit
  524. ****************************************************************************}
  525. constructor tai_comp_64bit.Create(_value : ts64comp);
  526. begin
  527. inherited Create;
  528. typ:=ait_comp_64bit;
  529. value:=_value;
  530. end;
  531. {****************************************************************************
  532. TAI_STRING
  533. ****************************************************************************}
  534. constructor tai_string.Create(const _str : string);
  535. begin
  536. inherited Create;
  537. typ:=ait_string;
  538. getmem(str,length(_str)+1);
  539. strpcopy(str,_str);
  540. len:=length(_str);
  541. end;
  542. constructor tai_string.Create_pchar(_str : pchar);
  543. begin
  544. inherited Create;
  545. typ:=ait_string;
  546. str:=_str;
  547. len:=strlen(_str);
  548. end;
  549. constructor tai_string.Create_length_pchar(_str : pchar;length : longint);
  550. begin
  551. inherited Create;
  552. typ:=ait_string;
  553. str:=_str;
  554. len:=length;
  555. end;
  556. destructor tai_string.destroy;
  557. begin
  558. { you can have #0 inside the strings so }
  559. if str<>nil then
  560. freemem(str,len+1);
  561. inherited Destroy;
  562. end;
  563. {****************************************************************************
  564. TAI_LABEL
  565. ****************************************************************************}
  566. constructor tai_label.create(_l : tasmlabel);
  567. begin
  568. inherited Create;
  569. typ:=ait_label;
  570. l:=_l;
  571. l.is_set:=true;
  572. is_global:=(l.defbind=AB_GLOBAL);
  573. end;
  574. {****************************************************************************
  575. TAI_DIRECT
  576. ****************************************************************************}
  577. constructor tai_direct.Create(_str : pchar);
  578. begin
  579. inherited Create;
  580. typ:=ait_direct;
  581. str:=_str;
  582. end;
  583. destructor tai_direct.destroy;
  584. begin
  585. strdispose(str);
  586. inherited Destroy;
  587. end;
  588. {****************************************************************************
  589. TAI_ASM_COMMENT comment to be inserted in the assembler file
  590. ****************************************************************************}
  591. constructor tai_asm_comment.Create(_str : pchar);
  592. begin
  593. inherited Create;
  594. typ:=ait_comment;
  595. str:=_str;
  596. end;
  597. destructor tai_asm_comment.destroy;
  598. begin
  599. strdispose(str);
  600. inherited Destroy;
  601. end;
  602. {****************************************************************************
  603. TAI_CUT
  604. ****************************************************************************}
  605. constructor tai_cut.Create;
  606. begin
  607. inherited Create;
  608. typ:=ait_cut;
  609. place:=cut_normal;
  610. end;
  611. constructor tai_cut.Create_begin;
  612. begin
  613. inherited Create;
  614. typ:=ait_cut;
  615. place:=cut_begin;
  616. end;
  617. constructor tai_cut.Create_end;
  618. begin
  619. inherited Create;
  620. typ:=ait_cut;
  621. place:=cut_end;
  622. end;
  623. {****************************************************************************
  624. Tai_Marker
  625. ****************************************************************************}
  626. Constructor Tai_Marker.Create(_Kind: TMarker);
  627. Begin
  628. Inherited Create;
  629. typ := ait_marker;
  630. Kind := _Kind;
  631. End;
  632. {*****************************************************************************
  633. TaiTempAlloc
  634. *****************************************************************************}
  635. constructor taitempalloc.alloc(pos,size:longint);
  636. begin
  637. inherited Create;
  638. typ:=ait_tempalloc;
  639. allocation:=true;
  640. temppos:=pos;
  641. tempsize:=size;
  642. end;
  643. constructor taitempalloc.dealloc(pos,size:longint);
  644. begin
  645. inherited Create;
  646. typ:=ait_tempalloc;
  647. allocation:=false;
  648. temppos:=pos;
  649. tempsize:=size;
  650. end;
  651. {*****************************************************************************
  652. AsmSymbol
  653. *****************************************************************************}
  654. constructor tasmsymbol.create(const s:string;_bind:TAsmsymbind;_typ:Tasmsymtype);
  655. begin;
  656. inherited createname(s);
  657. reset;
  658. defbind:=_bind;
  659. typ:=_typ;
  660. inusedlist:=false;
  661. pass:=255;
  662. { mainly used to remove unused labels from the codesegment }
  663. refs:=0;
  664. end;
  665. procedure tasmsymbol.GenerateAltSymbol;
  666. begin
  667. if not assigned(altsymbol) then
  668. begin
  669. altsymbol:=tasmsymbol.create(name+'_'+tostr(nextaltnr),defbind,typ);
  670. { also copy the amount of references }
  671. altsymbol.refs:=refs;
  672. inc(nextaltnr);
  673. end;
  674. end;
  675. procedure tasmsymbol.reset;
  676. begin
  677. { reset section info }
  678. section:=sec_none;
  679. address:=0;
  680. size:=0;
  681. idx:=-1;
  682. pass:=255;
  683. bind:=AB_EXTERNAL;
  684. proclocal:=false;
  685. end;
  686. function tasmsymbol.is_used:boolean;
  687. begin
  688. is_used:=(refs>0);
  689. end;
  690. procedure tasmsymbol.setaddress(_pass:byte;sec:tsection;offset,len:longint);
  691. begin
  692. if (_pass=pass) then
  693. begin
  694. Message1(asmw_e_duplicate_label,name);
  695. exit;
  696. end;
  697. pass:=_pass;
  698. section:=sec;
  699. address:=offset;
  700. size:=len;
  701. { when the bind was reset to External, set it back to the default
  702. bind it got when defined }
  703. if (bind=AB_EXTERNAL) and (defbind<>AB_NONE) then
  704. bind:=defbind;
  705. end;
  706. {*****************************************************************************
  707. AsmLabel
  708. *****************************************************************************}
  709. constructor tasmlabel.create;
  710. begin;
  711. labelnr:=nextlabelnr;
  712. inc(nextlabelnr);
  713. inherited create(target_asm.labelprefix+tostr(labelnr),AB_LOCAL,AT_FUNCTION);
  714. proclocal:=true;
  715. is_set:=false;
  716. is_addr := false;
  717. end;
  718. constructor tasmlabel.createdata;
  719. begin;
  720. labelnr:=nextlabelnr;
  721. inc(nextlabelnr);
  722. if (cs_create_smart in aktmoduleswitches) or
  723. target_asm.labelprefix_only_inside_procedure then
  724. inherited create('_$'+current_module.modulename^+'$_L'+tostr(labelnr),AB_GLOBAL,AT_DATA)
  725. else
  726. inherited create(target_asm.labelprefix+tostr(labelnr),AB_LOCAL,AT_DATA);
  727. is_set:=false;
  728. is_addr := false;
  729. { write it always }
  730. refs:=1;
  731. end;
  732. constructor tasmlabel.createaddr;
  733. begin;
  734. create;
  735. is_addr := true;
  736. end;
  737. function tasmlabel.getname:string;
  738. begin
  739. getname:=inherited getname;
  740. inc(refs);
  741. end;
  742. {*****************************************************************************
  743. AsmSymbolList helpers
  744. *****************************************************************************}
  745. function newasmsymbol(const s : string) : tasmsymbol;
  746. var
  747. hp : tasmsymbol;
  748. begin
  749. hp:=tasmsymbol(asmsymbollist.search(s));
  750. if not assigned(hp) then
  751. begin
  752. { Not found, insert it as an External }
  753. hp:=tasmsymbol.create(s,AB_EXTERNAL,AT_FUNCTION);
  754. asmsymbollist.insert(hp);
  755. end;
  756. newasmsymbol:=hp;
  757. end;
  758. function newasmsymboltype(const s : string;_bind:TAsmSymBind;_typ:Tasmsymtype) : tasmsymbol;
  759. var
  760. hp : tasmsymbol;
  761. begin
  762. hp:=tasmsymbol(asmsymbollist.search(s));
  763. if assigned(hp) then
  764. hp.defbind:=_bind
  765. else
  766. begin
  767. { Not found, insert it as an External }
  768. hp:=tasmsymbol.create(s,_bind,_typ);
  769. asmsymbollist.insert(hp);
  770. end;
  771. newasmsymboltype:=hp;
  772. end;
  773. function getasmsymbol(const s : string) : tasmsymbol;
  774. begin
  775. getasmsymbol:=tasmsymbol(asmsymbollist.search(s));
  776. end;
  777. { renames an asmsymbol }
  778. function renameasmsymbol(const sold, snew : string):tasmsymbol;
  779. begin
  780. renameasmsymbol:=tasmsymbol(asmsymbollist.rename(sold,snew));
  781. end;
  782. {*****************************************************************************
  783. Used AsmSymbolList
  784. *****************************************************************************}
  785. procedure CreateUsedAsmSymbolList;
  786. begin
  787. if assigned(usedasmsymbollist) then
  788. internalerror(78455782);
  789. usedasmsymbollist:=TSingleList.create;
  790. end;
  791. procedure DestroyUsedAsmSymbolList;
  792. begin
  793. usedasmsymbollist.destroy;
  794. usedasmsymbollist:=nil;
  795. end;
  796. procedure UsedAsmSymbolListInsert(p:tasmsymbol);
  797. begin
  798. if not p.inusedlist then
  799. usedasmsymbollist.insert(p);
  800. p.inusedlist:=true;
  801. end;
  802. procedure UsedAsmSymbolListReset;
  803. var
  804. hp : tasmsymbol;
  805. begin
  806. hp:=tasmsymbol(usedasmsymbollist.first);
  807. while assigned(hp) do
  808. begin
  809. with hp do
  810. begin
  811. reset;
  812. inusedlist:=false;
  813. end;
  814. hp:=tasmsymbol(hp.listnext);
  815. end;
  816. end;
  817. procedure UsedAsmSymbolListResetAltSym;
  818. var
  819. hp : tasmsymbol;
  820. begin
  821. hp:=tasmsymbol(usedasmsymbollist.first);
  822. while assigned(hp) do
  823. begin
  824. with hp do
  825. begin
  826. altsymbol:=nil;
  827. inusedlist:=false;
  828. end;
  829. hp:=tasmsymbol(hp.listnext);
  830. end;
  831. end;
  832. procedure UsedAsmSymbolListCheckUndefined;
  833. var
  834. hp : tasmsymbol;
  835. begin
  836. hp:=tasmsymbol(usedasmsymbollist.first);
  837. while assigned(hp) do
  838. begin
  839. with hp do
  840. begin
  841. if (refs>0) and
  842. (section=Sec_none) and
  843. not(bind in [AB_EXTERNAL,AB_COMMON]) then
  844. Message1(asmw_e_undefined_label,name);
  845. end;
  846. hp:=tasmsymbol(hp.listnext);
  847. end;
  848. end;
  849. {*****************************************************************************
  850. Label Helpers
  851. *****************************************************************************}
  852. procedure getlabel(var l : tasmlabel);
  853. begin
  854. l:=tasmlabel.create;
  855. asmsymbollist.insert(l);
  856. end;
  857. procedure getdatalabel(var l : tasmlabel);
  858. begin
  859. l:=tasmlabel.createdata;
  860. asmsymbollist.insert(l);
  861. end;
  862. procedure getaddrlabel(var l : tasmlabel);
  863. begin
  864. l:=tasmlabel.createaddr;
  865. asmsymbollist.insert(l);
  866. end;
  867. procedure getlabelnr(var l : longint);
  868. begin
  869. l:=nextlabelnr;
  870. inc(nextlabelnr);
  871. end;
  872. {*****************************************************************************
  873. TAAsmOutput
  874. *****************************************************************************}
  875. function taasmoutput.getlasttaifilepos : pfileposinfo;
  876. begin
  877. if assigned(last) then
  878. getlasttaifilepos:=@tai(last).fileinfo
  879. else
  880. getlasttaifilepos:=nil;
  881. end;
  882. end.
  883. {
  884. $Log$
  885. Revision 1.27 2002-05-18 13:34:04 peter
  886. * readded missing revisions
  887. Revision 1.25 2002/05/14 19:34:38 peter
  888. * removed old logs and updated copyright year
  889. Revision 1.24 2002/05/14 17:28:08 peter
  890. * synchronized cpubase between powerpc and i386
  891. * moved more tables from cpubase to cpuasm
  892. * tai_align_abstract moved to tainst, cpuasm must define
  893. the tai_align class now, which may be empty
  894. Revision 1.23 2002/04/15 18:54:34 carl
  895. - removed tcpuflags
  896. Revision 1.22 2002/04/07 13:18:19 carl
  897. + more documentation
  898. Revision 1.21 2002/04/07 10:17:40 carl
  899. - remove packenumfixed (requires version 1.0.2 or later to compile now!)
  900. + changing some comments so its commented automatically
  901. Revision 1.20 2002/03/24 19:04:31 carl
  902. + patch for SPARC from Mazen NEIFER
  903. }