aasm.pas 31 KB

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