aasm.pas 34 KB

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