aasm.pas 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121
  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. unit aasm;
  19. interface
  20. uses
  21. globtype,systems,cobjects,globals;
  22. type
  23. tait = (
  24. ait_none,
  25. ait_direct,
  26. ait_string,
  27. ait_label,
  28. ait_comment,
  29. ait_instruction,
  30. ait_datablock,
  31. ait_symbol,
  32. ait_symbol_end, { needed to calc the size of a symbol }
  33. ait_const_32bit,
  34. ait_const_16bit,
  35. ait_const_8bit,
  36. ait_const_symbol,
  37. ait_real_80bit,
  38. ait_real_64bit,
  39. ait_real_32bit,
  40. ait_comp_64bit,
  41. ait_align,
  42. ait_section,
  43. { the following is only used by the win32 version of the compiler }
  44. { and only the GNU AS Win32 is able to write it }
  45. ait_const_rva,
  46. ait_stabn,
  47. ait_stabs,
  48. ait_force_line,
  49. ait_stab_function_name,
  50. ait_cut, { used to split into tiny assembler files }
  51. ait_regalloc, { for register,temp allocation debugging }
  52. ait_tempalloc,
  53. ait_marker,
  54. { the follow is for the DEC Alpha }
  55. ait_frame,
  56. ait_ent,
  57. {$ifdef m68k}
  58. ait_labeled_instruction,
  59. {$endif m68k}
  60. { never used, makes insertation of new ait_ easier to type }
  61. { lazy guy !!!! ;-) (FK) }
  62. ait_dummy);
  63. tcpuflags = (cf_64bitaddr);
  64. tcpuflagset = set of tcpuflags;
  65. { ait_* types which don't result in executable code or which don't influence }
  66. { the way the program runs/behaves, but which may be encountered by the }
  67. { optimizer (= if it's sometimes added to the exprasm list). Update if you add }
  68. { a new ait type! }
  69. const
  70. SkipInstr = [ait_comment, ait_symbol,ait_force_line,ait_section
  71. {$ifdef GDB}
  72. ,ait_stabs, ait_stabn, ait_stab_function_name
  73. {$endif GDB}
  74. ,ait_regalloc, ait_tempalloc, ait_symbol_end
  75. ];
  76. { asm symbol functions }
  77. type
  78. TAsmsymbind=(AB_NONE,AB_EXTERNAL,AB_COMMON,AB_LOCAL,AB_GLOBAL);
  79. TAsmsymtype=(AT_NONE,AT_FUNCTION,AT_DATA,AT_SECTION);
  80. pasmsymbol = ^tasmsymbol;
  81. tasmsymbol = object(tnamedindexobject)
  82. orgbind,
  83. bind : TAsmsymbind;
  84. typ : TAsmsymtype;
  85. proclocal : boolean;
  86. { this need to be incremented with every symbol loading into the
  87. paasmoutput, thus in loadsym/loadref/const_symbol (PFV) }
  88. refs : longint;
  89. { the next fields are filled in the binary writer }
  90. idx : longint;
  91. section : tsection;
  92. address,
  93. size : longint;
  94. { alternate symbol which can be used for 'renaming' needed for
  95. inlining }
  96. altsymbol : pasmsymbol;
  97. constructor init(const s:string;_bind:TAsmsymbind;_typ:Tasmsymtype);
  98. procedure reset;
  99. function is_used:boolean;
  100. procedure setbind(t:tasmsymbind);
  101. procedure setaddress(sec:tsection;offset,len:longint);
  102. procedure GenerateAltSymbol;
  103. end;
  104. pasmlabel = ^tasmlabel;
  105. tasmlabel = object(tasmsymbol)
  106. labelnr : longint;
  107. { this is set by the pai_label.init }
  108. is_set,
  109. { is the label only there for getting an address (e.g. for i/o }
  110. { checks -> true) or is it a jump target (false) }
  111. is_addr : boolean;
  112. constructor init;
  113. constructor initdata;
  114. constructor initaddr;
  115. function name:string;virtual;
  116. end;
  117. pasmsymbollist = ^tasmsymbollist;
  118. tasmsymbollist = object(tdictionary)
  119. end;
  120. { the short name makes typing easier }
  121. pai = ^tai;
  122. tai = object(tlinkedlist_item)
  123. typ : tait;
  124. { pointer to record with optimizer info about this tai object }
  125. optinfo : pointer;
  126. fileinfo : tfileposinfo;
  127. constructor init;
  128. end;
  129. pai_string = ^tai_string;
  130. tai_string = object(tai)
  131. str : pchar;
  132. { extra len so the string can contain an \0 }
  133. len : longint;
  134. constructor init(const _str : string);
  135. constructor init_pchar(_str : pchar);
  136. constructor init_length_pchar(_str : pchar;length : longint);
  137. destructor done;virtual;
  138. end;
  139. { generates a common label }
  140. pai_symbol = ^tai_symbol;
  141. tai_symbol = object(tai)
  142. sym : pasmsymbol;
  143. is_global : boolean;
  144. size : longint;
  145. constructor init(_sym:PAsmSymbol;siz:longint);
  146. constructor initname(const _name : string;siz:longint);
  147. constructor initname_global(const _name : string;siz:longint);
  148. constructor initdataname(const _name : string;siz:longint);
  149. constructor initdataname_global(const _name : string;siz:longint);
  150. end;
  151. pai_symbol_end = ^tai_symbol_end;
  152. tai_symbol_end = object(tai)
  153. sym : pasmsymbol;
  154. constructor init(_sym:PAsmSymbol);
  155. constructor initname(const _name : string);
  156. end;
  157. pai_label = ^tai_label;
  158. tai_label = object(tai)
  159. l : pasmlabel;
  160. is_global : boolean;
  161. constructor init(_l : pasmlabel);
  162. end;
  163. pai_direct = ^tai_direct;
  164. tai_direct = object(tai)
  165. str : pchar;
  166. constructor init(_str : pchar);
  167. destructor done; virtual;
  168. end;
  169. { to insert a comment into the generated assembler file }
  170. pai_asm_comment = ^tai_asm_comment;
  171. tai_asm_comment = object(tai)
  172. str : pchar;
  173. constructor init(_str : pchar);
  174. destructor done; virtual;
  175. end;
  176. { alignment for operator }
  177. {$ifdef i386}
  178. pai_align_abstract = ^tai_align_abstract;
  179. tai_align_abstract = object(tai)
  180. {$else i386}
  181. pai_align = ^tai_align;
  182. tai_align = object(tai)
  183. {$endif i386}
  184. buf : array[0..63] of char; { buf used for fill }
  185. aligntype : byte; { 1 = no align, 2 = word align, 4 = dword align }
  186. fillsize : byte; { real size to fill }
  187. fillop : byte; { value to fill with - optional }
  188. use_op : boolean;
  189. constructor init(b:byte);
  190. constructor init_op(b: byte; _op: byte);
  191. function getfillbuf:pchar;
  192. end;
  193. { Insert a section/segment directive }
  194. pai_section = ^tai_section;
  195. tai_section = object(tai)
  196. sec : tsection;
  197. constructor init(s : tsection);
  198. end;
  199. { generates an uninitializised data block }
  200. pai_datablock = ^tai_datablock;
  201. tai_datablock = object(tai)
  202. sym : pasmsymbol;
  203. size : longint;
  204. is_global : boolean;
  205. constructor init(const _name : string;_size : longint);
  206. constructor init_global(const _name : string;_size : longint);
  207. end;
  208. { generates a long integer (32 bit) }
  209. pai_const = ^tai_const;
  210. tai_const = object(tai)
  211. value : longint;
  212. constructor init_32bit(_value : longint);
  213. constructor init_16bit(_value : word);
  214. constructor init_8bit(_value : byte);
  215. end;
  216. pai_const_symbol = ^tai_const_symbol;
  217. tai_const_symbol = object(tai)
  218. sym : pasmsymbol;
  219. offset : longint;
  220. constructor init(_sym:PAsmSymbol);
  221. constructor init_offset(_sym:PAsmSymbol;ofs:longint);
  222. constructor init_rva(_sym:PAsmSymbol);
  223. constructor initname(const name:string);
  224. constructor initname_offset(const name:string;ofs:longint);
  225. constructor initname_rva(const name:string);
  226. end;
  227. { generates a single (32 bit real) }
  228. pai_real_32bit = ^tai_real_32bit;
  229. tai_real_32bit = object(tai)
  230. value : ts32real;
  231. constructor init(_value : ts32real);
  232. end;
  233. { generates a double (64 bit real) }
  234. pai_real_64bit = ^tai_real_64bit;
  235. tai_real_64bit = object(tai)
  236. value : ts64real;
  237. constructor init(_value : ts64real);
  238. end;
  239. { generates an extended (80 bit real) }
  240. pai_real_80bit = ^tai_real_80bit;
  241. tai_real_80bit = object(tai)
  242. value : ts80real;
  243. constructor init(_value : ts80real);
  244. end;
  245. { generates an comp (integer over 64 bits) }
  246. pai_comp_64bit = ^tai_comp_64bit;
  247. tai_comp_64bit = object(tai)
  248. value : ts64comp;
  249. constructor init(_value : ts64comp);
  250. end;
  251. { insert a cut to split into several smaller files }
  252. tcutplace=(cut_normal,cut_begin,cut_end);
  253. pai_cut = ^tai_cut;
  254. tai_cut = object(tai)
  255. place : tcutplace;
  256. constructor init;
  257. constructor init_begin;
  258. constructor init_end;
  259. end;
  260. TMarker = (NoPropInfoStart, NoPropInfoEnd,
  261. AsmBlockStart, AsmBlockEnd,
  262. InlineStart,InlineEnd);
  263. pai_marker = ^tai_marker;
  264. tai_marker = object(tai)
  265. Kind: TMarker;
  266. Constructor init(_Kind: TMarker);
  267. end;
  268. paitempalloc = ^taitempalloc;
  269. taitempalloc = object(tai)
  270. allocation : boolean;
  271. temppos,
  272. tempsize : longint;
  273. constructor alloc(pos,size:longint);
  274. constructor dealloc(pos,size:longint);
  275. end;
  276. { for each processor define the best precision }
  277. { bestreal is defined in globals }
  278. {$ifdef i386}
  279. const
  280. ait_bestreal = ait_real_80bit;
  281. type
  282. pai_bestreal = pai_real_80bit;
  283. tai_bestreal = tai_real_80bit;
  284. {$endif i386}
  285. {$ifdef m68k}
  286. const
  287. ait_bestreal = ait_real_32bit;
  288. type
  289. pai_bestreal = pai_real_32bit;
  290. tai_bestreal = tai_real_32bit;
  291. {$endif m68k}
  292. paasmoutput = ^taasmoutput;
  293. taasmoutput = object(tlinkedlist)
  294. function getlasttaifilepos : pfileposinfo;
  295. end;
  296. const
  297. { maximum of aasmoutput lists there will be }
  298. maxoutputlists = 10;
  299. var
  300. { temporary lists }
  301. exprasmlist,
  302. { default lists }
  303. datasegment,codesegment,bsssegment,
  304. debuglist,withdebuglist,consts,
  305. importssection,exportssection,
  306. resourcesection,rttilist,
  307. resourcestringlist : paasmoutput;
  308. { asm symbol list }
  309. asmsymbollist : pasmsymbollist;
  310. const
  311. nextaltnr : longint = 1;
  312. nextlabelnr : longint = 1;
  313. countlabelref : boolean = true;
  314. { make l as a new label }
  315. procedure getlabel(var l : pasmlabel);
  316. { make l as a new label and flag is_addr }
  317. procedure getaddrlabel(var l : pasmlabel);
  318. { make l as a new label and flag is_data }
  319. procedure getdatalabel(var l : pasmlabel);
  320. {just get a label number }
  321. procedure getlabelnr(var l : longint);
  322. function newasmsymbol(const s : string) : pasmsymbol;
  323. function newasmsymboltype(const s : string;_bind:TAsmSymBind;_typ:TAsmsymtype) : pasmsymbol;
  324. function getasmsymbol(const s : string) : pasmsymbol;
  325. function renameasmsymbol(const sold, snew : string):pasmsymbol;
  326. procedure ResetAsmsymbolList;
  327. procedure ResetAsmSymbolListAltSymbol;
  328. procedure CheckAsmSymbolListUndefined;
  329. implementation
  330. uses
  331. strings,files,verbose;
  332. {****************************************************************************
  333. TAI
  334. ****************************************************************************}
  335. constructor tai.init;
  336. begin
  337. optinfo := nil;
  338. fileinfo:=aktfilepos;
  339. end;
  340. {****************************************************************************
  341. TAI_SECTION
  342. ****************************************************************************}
  343. constructor tai_section.init(s : tsection);
  344. begin
  345. inherited init;
  346. typ:=ait_section;
  347. sec:=s;
  348. end;
  349. {****************************************************************************
  350. TAI_DATABLOCK
  351. ****************************************************************************}
  352. constructor tai_datablock.init(const _name : string;_size : longint);
  353. begin
  354. inherited init;
  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.init_global(const _name : string;_size : longint);
  364. begin
  365. inherited init;
  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.init(_sym:PAsmSymbol;siz:longint);
  378. begin
  379. inherited init;
  380. typ:=ait_symbol;
  381. sym:=_sym;
  382. size:=siz;
  383. is_global:=(sym^.bind=AB_GLOBAL);
  384. end;
  385. constructor tai_symbol.initname(const _name : string;siz:longint);
  386. begin
  387. inherited init;
  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.initname_global(const _name : string;siz:longint);
  394. begin
  395. inherited init;
  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.initdataname(const _name : string;siz:longint);
  402. begin
  403. inherited init;
  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.initdataname_global(const _name : string;siz:longint);
  410. begin
  411. inherited init;
  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.init(_sym:PAsmSymbol);
  421. begin
  422. inherited init;
  423. typ:=ait_symbol_end;
  424. sym:=_sym;
  425. end;
  426. constructor tai_symbol_end.initname(const _name : string);
  427. begin
  428. inherited init;
  429. typ:=ait_symbol_end;
  430. sym:=newasmsymboltype(_name,AB_GLOBAL,AT_NONE);
  431. end;
  432. {****************************************************************************
  433. TAI_CONST
  434. ****************************************************************************}
  435. constructor tai_const.init_32bit(_value : longint);
  436. begin
  437. inherited init;
  438. typ:=ait_const_32bit;
  439. value:=_value;
  440. end;
  441. constructor tai_const.init_16bit(_value : word);
  442. begin
  443. inherited init;
  444. typ:=ait_const_16bit;
  445. value:=_value;
  446. end;
  447. constructor tai_const.init_8bit(_value : byte);
  448. begin
  449. inherited init;
  450. typ:=ait_const_8bit;
  451. value:=_value;
  452. end;
  453. {****************************************************************************
  454. TAI_CONST_SYMBOL_OFFSET
  455. ****************************************************************************}
  456. constructor tai_const_symbol.init(_sym:PAsmSymbol);
  457. begin
  458. inherited init;
  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.init_offset(_sym:PAsmSymbol;ofs:longint);
  466. begin
  467. inherited init;
  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.init_rva(_sym:PAsmSymbol);
  475. begin
  476. inherited init;
  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.initname(const name:string);
  484. begin
  485. inherited init;
  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.initname_offset(const name:string;ofs:longint);
  493. begin
  494. inherited init;
  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.initname_rva(const name:string);
  502. begin
  503. inherited init;
  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.init(_value : ts32real);
  514. begin
  515. inherited init;
  516. typ:=ait_real_32bit;
  517. value:=_value;
  518. end;
  519. {****************************************************************************
  520. TAI_real_64bit
  521. ****************************************************************************}
  522. constructor tai_real_64bit.init(_value : ts64real);
  523. begin
  524. inherited init;
  525. typ:=ait_real_64bit;
  526. value:=_value;
  527. end;
  528. {****************************************************************************
  529. TAI_real_80bit
  530. ****************************************************************************}
  531. constructor tai_real_80bit.init(_value : ts80real);
  532. begin
  533. inherited init;
  534. typ:=ait_real_80bit;
  535. value:=_value;
  536. end;
  537. {****************************************************************************
  538. Tai_comp_64bit
  539. ****************************************************************************}
  540. constructor tai_comp_64bit.init(_value : ts64comp);
  541. begin
  542. inherited init;
  543. typ:=ait_comp_64bit;
  544. value:=_value;
  545. end;
  546. {****************************************************************************
  547. TAI_STRING
  548. ****************************************************************************}
  549. constructor tai_string.init(const _str : string);
  550. begin
  551. inherited init;
  552. typ:=ait_string;
  553. getmem(str,length(_str)+1);
  554. strpcopy(str,_str);
  555. len:=length(_str);
  556. end;
  557. constructor tai_string.init_pchar(_str : pchar);
  558. begin
  559. inherited init;
  560. typ:=ait_string;
  561. str:=_str;
  562. len:=strlen(_str);
  563. end;
  564. constructor tai_string.init_length_pchar(_str : pchar;length : longint);
  565. begin
  566. inherited init;
  567. typ:=ait_string;
  568. str:=_str;
  569. len:=length;
  570. end;
  571. destructor tai_string.done;
  572. begin
  573. { you can have #0 inside the strings so }
  574. if str<>nil then
  575. freemem(str,len+1);
  576. inherited done;
  577. end;
  578. {****************************************************************************
  579. TAI_LABEL
  580. ****************************************************************************}
  581. constructor tai_label.init(_l : pasmlabel);
  582. begin
  583. inherited init;
  584. typ:=ait_label;
  585. l:=_l;
  586. l^.is_set:=true;
  587. is_global:=(l^.bind=AB_GLOBAL);
  588. end;
  589. {****************************************************************************
  590. TAI_DIRECT
  591. ****************************************************************************}
  592. constructor tai_direct.init(_str : pchar);
  593. begin
  594. inherited init;
  595. typ:=ait_direct;
  596. str:=_str;
  597. end;
  598. destructor tai_direct.done;
  599. begin
  600. strdispose(str);
  601. inherited done;
  602. end;
  603. {****************************************************************************
  604. TAI_ASM_COMMENT comment to be inserted in the assembler file
  605. ****************************************************************************}
  606. constructor tai_asm_comment.init(_str : pchar);
  607. begin
  608. inherited init;
  609. typ:=ait_comment;
  610. str:=_str;
  611. end;
  612. destructor tai_asm_comment.done;
  613. begin
  614. strdispose(str);
  615. inherited done;
  616. end;
  617. {****************************************************************************
  618. TAI_ALIGN
  619. ****************************************************************************}
  620. {$ifdef i386}
  621. constructor tai_align_abstract.init(b: byte);
  622. {$else i386}
  623. constructor tai_align.init(b: byte);
  624. {$endif i386}
  625. begin
  626. inherited init;
  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.init_op(b: byte; _op: byte);
  638. {$else i386}
  639. constructor tai_align.init_op(b: byte; _op: byte);
  640. {$endif i386}
  641. begin
  642. inherited init;
  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.init;
  665. begin
  666. inherited init;
  667. typ:=ait_cut;
  668. place:=cut_normal;
  669. end;
  670. constructor tai_cut.init_begin;
  671. begin
  672. inherited init;
  673. typ:=ait_cut;
  674. place:=cut_begin;
  675. end;
  676. constructor tai_cut.init_end;
  677. begin
  678. inherited init;
  679. typ:=ait_cut;
  680. place:=cut_end;
  681. end;
  682. {****************************************************************************
  683. Tai_Marker
  684. ****************************************************************************}
  685. Constructor Tai_Marker.Init(_Kind: TMarker);
  686. Begin
  687. Inherited Init;
  688. typ := ait_marker;
  689. Kind := _Kind;
  690. End;
  691. {*****************************************************************************
  692. TaiTempAlloc
  693. *****************************************************************************}
  694. constructor taitempalloc.alloc(pos,size:longint);
  695. begin
  696. inherited init;
  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 init;
  705. typ:=ait_tempalloc;
  706. allocation:=false;
  707. temppos:=pos;
  708. tempsize:=size;
  709. end;
  710. {*****************************************************************************
  711. AsmSymbol
  712. *****************************************************************************}
  713. constructor tasmsymbol.init(const s:string;_bind:TAsmsymbind;_typ:Tasmsymtype);
  714. begin;
  715. {$IFDEF NEWST}
  716. inherited init(s);
  717. {$ELSE}
  718. inherited initname(s);
  719. {$ENDIF NEWST}
  720. reset;
  721. orgbind:=_bind;
  722. bind:=_bind;
  723. typ:=_typ;
  724. end;
  725. procedure tasmsymbol.GenerateAltSymbol;
  726. begin
  727. if not assigned(altsymbol) then
  728. begin
  729. new(altsymbol,init(name+'_'+tostr(nextaltnr),bind,typ));
  730. { also copy the amount of references }
  731. altsymbol^.refs:=refs;
  732. inc(nextaltnr);
  733. end;
  734. end;
  735. procedure tasmsymbol.reset;
  736. begin
  737. { reset section info }
  738. section:=sec_none;
  739. address:=0;
  740. size:=0;
  741. idx:=-1;
  742. bind:=AB_EXTERNAL;
  743. proclocal:=false;
  744. { mainly used to remove unused labels from the codesegment }
  745. refs:=0;
  746. end;
  747. function tasmsymbol.is_used:boolean;
  748. begin
  749. is_used:=(refs>0);
  750. end;
  751. procedure tasmsymbol.setbind(t:tasmsymbind);
  752. begin
  753. bind:=t;
  754. orgbind:=t;
  755. end;
  756. procedure tasmsymbol.setaddress(sec:tsection;offset,len:longint);
  757. begin
  758. section:=sec;
  759. address:=offset;
  760. size:=len;
  761. { when the typ was reset to External, set it back to the original
  762. type it got when defined }
  763. if (bind=AB_EXTERNAL) and (orgbind<>AB_NONE) then
  764. bind:=orgbind;
  765. end;
  766. {*****************************************************************************
  767. AsmLabel
  768. *****************************************************************************}
  769. constructor tasmlabel.init;
  770. begin;
  771. labelnr:=nextlabelnr;
  772. inc(nextlabelnr);
  773. inherited init(target_asm.labelprefix+tostr(labelnr),AB_LOCAL,AT_FUNCTION);
  774. proclocal:=true;
  775. is_set:=false;
  776. is_addr := false;
  777. end;
  778. constructor tasmlabel.initdata;
  779. begin;
  780. labelnr:=nextlabelnr;
  781. inc(nextlabelnr);
  782. if (cs_create_smart in aktmoduleswitches) then
  783. inherited init('_$'+current_module^.modulename^+'$_L'+tostr(labelnr),AB_GLOBAL,AT_DATA)
  784. else
  785. inherited init(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.initaddr;
  792. begin;
  793. init;
  794. is_addr := true;
  795. end;
  796. function tasmlabel.name:string;
  797. begin
  798. name:=inherited name;
  799. inc(refs);
  800. end;
  801. {*****************************************************************************
  802. AsmSymbolList helpers
  803. *****************************************************************************}
  804. function newasmsymbol(const s : string) : pasmsymbol;
  805. var
  806. hp : pasmsymbol;
  807. begin
  808. hp:=pasmsymbol(asmsymbollist^.search(s));
  809. if assigned(hp) then
  810. begin
  811. newasmsymbol:=hp;
  812. exit;
  813. end;
  814. { Not found, insert it as an External }
  815. hp:=new(pasmsymbol,init(s,AB_EXTERNAL,AT_FUNCTION));
  816. asmsymbollist^.insert(hp);
  817. newasmsymbol:=hp;
  818. end;
  819. function newasmsymboltype(const s : string;_bind:TAsmSymBind;_typ:Tasmsymtype) : pasmsymbol;
  820. var
  821. hp : pasmsymbol;
  822. begin
  823. hp:=pasmsymbol(asmsymbollist^.search(s));
  824. if assigned(hp) then
  825. hp^.setbind(_bind)
  826. else
  827. begin
  828. { Not found, insert it as an External }
  829. hp:=new(pasmsymbol,init(s,_bind,_typ));
  830. asmsymbollist^.insert(hp);
  831. end;
  832. newasmsymboltype:=hp;
  833. end;
  834. function getasmsymbol(const s : string) : pasmsymbol;
  835. begin
  836. getasmsymbol:=pasmsymbol(asmsymbollist^.search(s));
  837. end;
  838. { renames an asmsymbol }
  839. function renameasmsymbol(const sold, snew : string):pasmsymbol;
  840. begin
  841. renameasmsymbol:=pasmsymbol(asmsymbollist^.rename(sold,snew));
  842. end;
  843. procedure ResetAsmSym(p:Pnamedindexobject);{$ifndef FPC}far;{$endif}
  844. begin
  845. pasmsymbol(p)^.reset;
  846. end;
  847. procedure ResetAsmsymbolList;
  848. begin
  849. asmsymbollist^.foreach({$ifndef TP}@{$endif}resetasmsym);
  850. end;
  851. procedure ResetAltSym(p:Pnamedindexobject);{$ifndef FPC}far;{$endif}
  852. begin
  853. pasmsymbol(p)^.altsymbol:=nil;
  854. end;
  855. procedure ResetAsmSymbolListAltSymbol;
  856. begin
  857. asmsymbollist^.foreach({$ifndef TP}@{$endif}resetaltsym);
  858. end;
  859. procedure checkundefinedasmsym(p:Pnamedindexobject);{$ifndef FPC}far;{$endif}
  860. begin
  861. if (pasmsymbol(p)^.refs>0) and
  862. (pasmsymbol(p)^.section=Sec_none) and
  863. (pasmsymbol(p)^.bind<>AB_EXTERNAL) then
  864. Message1(asmw_e_undefined_label,pasmsymbol(p)^.name);
  865. end;
  866. procedure CheckAsmSymbolListUndefined;
  867. begin
  868. asmsymbollist^.foreach({$ifndef TP}@{$endif}checkundefinedasmsym);
  869. end;
  870. {*****************************************************************************
  871. Label Helpers
  872. *****************************************************************************}
  873. procedure getlabel(var l : pasmlabel);
  874. begin
  875. l:=new(pasmlabel,init);
  876. asmsymbollist^.insert(l);
  877. end;
  878. procedure getdatalabel(var l : pasmlabel);
  879. begin
  880. l:=new(pasmlabel,initdata);
  881. asmsymbollist^.insert(l);
  882. end;
  883. procedure getaddrlabel(var l : pasmlabel);
  884. begin
  885. l:=new(pasmlabel,initaddr);
  886. asmsymbollist^.insert(l);
  887. end;
  888. procedure RegenerateLabel(var l : pasmlabel);
  889. begin
  890. if l^.proclocal then
  891. getlabel(pasmlabel(l^.altsymbol))
  892. else
  893. getdatalabel(pasmlabel(l^.altsymbol));
  894. end;
  895. procedure getlabelnr(var l : longint);
  896. begin
  897. l:=nextlabelnr;
  898. inc(nextlabelnr);
  899. end;
  900. {*****************************************************************************
  901. TAAsmOutput
  902. *****************************************************************************}
  903. function taasmoutput.getlasttaifilepos : pfileposinfo;
  904. begin
  905. if assigned(last) then
  906. getlasttaifilepos:=@pai(last)^.fileinfo
  907. else
  908. getlasttaifilepos:=nil;
  909. end;
  910. end.
  911. {
  912. $Log$
  913. Revision 1.4 2000-07-21 15:14:01 jonas
  914. + added is_addr field for labels, if they are only used for getting the address
  915. (e.g. for io checks) and corresponding getaddrlabel() procedure
  916. Revision 1.3 2000/07/13 12:08:24 michael
  917. + patched to 1.1.0 with former 1.09patch from peter
  918. Revision 1.2 2000/07/13 11:32:28 michael
  919. + removed logs
  920. }