aasm.pas 34 KB

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