aasm.pas 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  1. {
  2. $Id$
  3. Copyright (c) 1996-98 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. {$ifdef newcg}
  66. const
  67. SkipInstr = [ait_comment, ait_align, ait_symbol
  68. {$ifdef GDB}
  69. ,ait_stabs, ait_stabn, ait_stab_function_name
  70. {$endif GDB}
  71. ,ait_regalloc, ait_tempalloc
  72. ];
  73. {$endif newcg}
  74. { asm symbol functions }
  75. type
  76. TAsmsymtype=(AS_EXTERNAL,AS_LOCAL,AS_GLOBAL);
  77. pasmsymbol = ^tasmsymbol;
  78. tasmsymbol = object(tnamedindexobject)
  79. typ : TAsmsymtype;
  80. { this need te incremented with every symbol loading into the
  81. paasmoutput, thus in loadsym/loadref/const_symbol (PFV) }
  82. refs : longint;
  83. { the next fields are filled in the binary writer }
  84. idx : longint;
  85. section : tsection;
  86. address,
  87. size : longint;
  88. constructor init(const s:string;_typ:TAsmsymtype);
  89. procedure reset;
  90. function is_used:boolean;
  91. procedure setaddress(sec:tsection;offset,len:longint);
  92. end;
  93. pasmlabel = ^tasmlabel;
  94. tasmlabel = object(tasmsymbol)
  95. labelnr : longint;
  96. { this is set by the pai_label.init }
  97. is_set : boolean;
  98. constructor init;
  99. constructor initdata;
  100. function name:string;virtual;
  101. end;
  102. pasmsymbollist = ^tasmsymbollist;
  103. tasmsymbollist = object(tdictionary)
  104. end;
  105. { the short name makes typing easier }
  106. pai = ^tai;
  107. tai = object(tlinkedlist_item)
  108. typ : tait;
  109. { pointer to record with optimizer info about this tai object }
  110. optinfo : pointer;
  111. fileinfo : tfileposinfo;
  112. constructor init;
  113. end;
  114. pai_string = ^tai_string;
  115. tai_string = object(tai)
  116. str : pchar;
  117. { extra len so the string can contain an \0 }
  118. len : longint;
  119. constructor init(const _str : string);
  120. constructor init_pchar(_str : pchar);
  121. constructor init_length_pchar(_str : pchar;length : longint);
  122. destructor done;virtual;
  123. end;
  124. { generates a common label }
  125. pai_symbol = ^tai_symbol;
  126. tai_symbol = object(tai)
  127. sym : pasmsymbol;
  128. is_global : boolean;
  129. size : longint;
  130. constructor init(_sym:PAsmSymbol;siz:longint);
  131. constructor initname(const _name : string;siz:longint);
  132. constructor initname_global(const _name : string;siz:longint);
  133. end;
  134. pai_symbol_end = ^tai_symbol_end;
  135. tai_symbol_end = object(tai)
  136. sym : pasmsymbol;
  137. constructor init(_sym:PAsmSymbol);
  138. constructor initname(const _name : string);
  139. end;
  140. pai_label = ^tai_label;
  141. tai_label = object(tai)
  142. l : pasmlabel;
  143. is_global : boolean;
  144. constructor init(_l : pasmlabel);
  145. end;
  146. pai_direct = ^tai_direct;
  147. tai_direct = object(tai)
  148. str : pchar;
  149. constructor init(_str : pchar);
  150. destructor done; virtual;
  151. end;
  152. { to insert a comment into the generated assembler file }
  153. pai_asm_comment = ^tai_asm_comment;
  154. tai_asm_comment = object(tai)
  155. str : pchar;
  156. constructor init(_str : pchar);
  157. destructor done; virtual;
  158. end;
  159. { alignment for operator }
  160. {$ifndef alignreg}
  161. pai_align = ^tai_align;
  162. tai_align = object(tai)
  163. {$else alignreg}
  164. pai_align_abstract = ^tai_align_abstract;
  165. tai_align_abstract = object(tai)
  166. {$endif alignreg}
  167. aligntype : byte; { 1 = no align, 2 = word align, 4 = dword align }
  168. fillsize : byte; { real size to fill }
  169. fillop : byte; { value to fill with - optional }
  170. use_op : boolean;
  171. constructor init(b:byte);
  172. constructor init_op(b: byte; _op: byte);
  173. end;
  174. { Insert a section/segment directive }
  175. pai_section = ^tai_section;
  176. tai_section = object(tai)
  177. sec : tsection;
  178. constructor init(s : tsection);
  179. end;
  180. { generates an uninitializised data block }
  181. pai_datablock = ^tai_datablock;
  182. tai_datablock = object(tai)
  183. sym : pasmsymbol;
  184. size : longint;
  185. is_global : boolean;
  186. constructor init(const _name : string;_size : longint);
  187. constructor init_global(const _name : string;_size : longint);
  188. end;
  189. { generates a long integer (32 bit) }
  190. pai_const = ^tai_const;
  191. tai_const = object(tai)
  192. value : longint;
  193. constructor init_32bit(_value : longint);
  194. constructor init_16bit(_value : word);
  195. constructor init_8bit(_value : byte);
  196. end;
  197. pai_const_symbol = ^tai_const_symbol;
  198. tai_const_symbol = object(tai)
  199. sym : pasmsymbol;
  200. offset : longint;
  201. constructor init(_sym:PAsmSymbol);
  202. constructor init_offset(_sym:PAsmSymbol;ofs:longint);
  203. constructor init_rva(_sym:PAsmSymbol);
  204. constructor initname(const name:string);
  205. constructor initname_offset(const name:string;ofs:longint);
  206. constructor initname_rva(const name:string);
  207. end;
  208. { generates a single (32 bit real) }
  209. pai_real_32bit = ^tai_real_32bit;
  210. tai_real_32bit = object(tai)
  211. value : ts32real;
  212. constructor init(_value : ts32real);
  213. end;
  214. { generates a double (64 bit real) }
  215. pai_real_64bit = ^tai_real_64bit;
  216. tai_real_64bit = object(tai)
  217. value : ts64real;
  218. constructor init(_value : ts64real);
  219. end;
  220. { generates an extended (80 bit real) }
  221. pai_real_80bit = ^tai_real_80bit;
  222. tai_real_80bit = object(tai)
  223. value : ts80real;
  224. constructor init(_value : ts80real);
  225. end;
  226. { generates an comp (integer over 64 bits) }
  227. pai_comp_64bit = ^tai_comp_64bit;
  228. tai_comp_64bit = object(tai)
  229. value : ts64comp;
  230. constructor init(_value : ts64comp);
  231. end;
  232. { insert a cut to split into several smaller files }
  233. tcutplace=(cut_normal,cut_begin,cut_end);
  234. pai_cut = ^tai_cut;
  235. tai_cut = object(tai)
  236. place : tcutplace;
  237. constructor init;
  238. constructor init_begin;
  239. constructor init_end;
  240. end;
  241. TMarker = (NoPropInfoStart, NoPropInfoEnd, AsmBlockStart, AsmBlockEnd);
  242. pai_marker = ^tai_marker;
  243. tai_marker = object(tai)
  244. Kind: TMarker;
  245. Constructor init(_Kind: TMarker);
  246. end;
  247. paitempalloc = ^taitempalloc;
  248. taitempalloc = object(tai)
  249. allocation : boolean;
  250. temppos,
  251. tempsize : longint;
  252. constructor alloc(pos,size:longint);
  253. constructor dealloc(pos,size:longint);
  254. end;
  255. { for each processor define the best precision }
  256. { bestreal is defined in globals }
  257. {$ifdef i386}
  258. const
  259. ait_bestreal = ait_real_80bit;
  260. type
  261. pai_bestreal = pai_real_80bit;
  262. tai_bestreal = tai_real_80bit;
  263. {$endif i386}
  264. {$ifdef m68k}
  265. const
  266. ait_bestreal = ait_real_32bit;
  267. type
  268. pai_bestreal = pai_real_32bit;
  269. tai_bestreal = tai_real_32bit;
  270. {$endif m68k}
  271. paasmoutput = ^taasmoutput;
  272. taasmoutput = object(tlinkedlist)
  273. function getlasttaifilepos : pfileposinfo;
  274. end;
  275. const
  276. { maximum of aasmoutput lists there will be }
  277. maxoutputlists = 10;
  278. var
  279. { temporary lists }
  280. exprasmlist,
  281. { default lists }
  282. datasegment,codesegment,bsssegment,
  283. debuglist,consts,
  284. importssection,exportssection,
  285. resourcesection,rttilist,
  286. resourcestringlist : paasmoutput;
  287. { asm symbol list }
  288. asmsymbollist : pasmsymbollist;
  289. const
  290. nextlabelnr : longint = 1;
  291. countlabelref : boolean = true;
  292. { make l as a new label }
  293. procedure getlabel(var l : pasmlabel);
  294. { make l as a new label and flag is_data }
  295. procedure getdatalabel(var l : pasmlabel);
  296. { free a label }
  297. procedure freelabel(var l : pasmlabel);
  298. {just get a label number }
  299. procedure getlabelnr(var l : longint);
  300. function newasmsymbol(const s : string) : pasmsymbol;
  301. function newasmsymboltyp(const s : string;_typ:TAsmSymType) : pasmsymbol;
  302. function getasmsymbol(const s : string) : pasmsymbol;
  303. function renameasmsymbol(const sold, snew : string):pasmsymbol;
  304. procedure ResetAsmsymbolList;
  305. implementation
  306. uses
  307. strings,files,verbose;
  308. {****************************************************************************
  309. TAI
  310. ****************************************************************************}
  311. constructor tai.init;
  312. begin
  313. optinfo := nil;
  314. fileinfo:=aktfilepos;
  315. end;
  316. {****************************************************************************
  317. TAI_SECTION
  318. ****************************************************************************}
  319. constructor tai_section.init(s : tsection);
  320. begin
  321. inherited init;
  322. typ:=ait_section;
  323. sec:=s;
  324. end;
  325. {****************************************************************************
  326. TAI_DATABLOCK
  327. ****************************************************************************}
  328. constructor tai_datablock.init(const _name : string;_size : longint);
  329. begin
  330. inherited init;
  331. typ:=ait_datablock;
  332. sym:=newasmsymboltyp(_name,AS_LOCAL);
  333. size:=_size;
  334. is_global:=false;
  335. end;
  336. constructor tai_datablock.init_global(const _name : string;_size : longint);
  337. begin
  338. inherited init;
  339. typ:=ait_datablock;
  340. sym:=newasmsymboltyp(_name,AS_GLOBAL);
  341. size:=_size;
  342. is_global:=true;
  343. end;
  344. {****************************************************************************
  345. TAI_SYMBOL
  346. ****************************************************************************}
  347. constructor tai_symbol.init(_sym:PAsmSymbol;siz:longint);
  348. begin
  349. inherited init;
  350. typ:=ait_symbol;
  351. sym:=_sym;
  352. size:=siz;
  353. is_global:=(sym^.typ=AS_GLOBAL);
  354. end;
  355. constructor tai_symbol.initname(const _name : string;siz:longint);
  356. begin
  357. inherited init;
  358. typ:=ait_symbol;
  359. sym:=newasmsymboltyp(_name,AS_LOCAL);
  360. size:=siz;
  361. is_global:=false;
  362. end;
  363. constructor tai_symbol.initname_global(const _name : string;siz:longint);
  364. begin
  365. inherited init;
  366. typ:=ait_symbol;
  367. sym:=newasmsymboltyp(_name,AS_GLOBAL);
  368. size:=siz;
  369. is_global:=true;
  370. end;
  371. {****************************************************************************
  372. TAI_SYMBOL
  373. ****************************************************************************}
  374. constructor tai_symbol_end.init(_sym:PAsmSymbol);
  375. begin
  376. inherited init;
  377. typ:=ait_symbol_end;
  378. sym:=_sym;
  379. end;
  380. constructor tai_symbol_end.initname(const _name : string);
  381. begin
  382. inherited init;
  383. typ:=ait_symbol_end;
  384. sym:=newasmsymboltyp(_name,AS_GLOBAL);
  385. end;
  386. {****************************************************************************
  387. TAI_CONST
  388. ****************************************************************************}
  389. constructor tai_const.init_32bit(_value : longint);
  390. begin
  391. inherited init;
  392. typ:=ait_const_32bit;
  393. value:=_value;
  394. end;
  395. constructor tai_const.init_16bit(_value : word);
  396. begin
  397. inherited init;
  398. typ:=ait_const_16bit;
  399. value:=_value;
  400. end;
  401. constructor tai_const.init_8bit(_value : byte);
  402. begin
  403. inherited init;
  404. typ:=ait_const_8bit;
  405. value:=_value;
  406. end;
  407. {****************************************************************************
  408. TAI_CONST_SYMBOL_OFFSET
  409. ****************************************************************************}
  410. constructor tai_const_symbol.init(_sym:PAsmSymbol);
  411. begin
  412. inherited init;
  413. typ:=ait_const_symbol;
  414. sym:=_sym;
  415. offset:=0;
  416. { update sym info }
  417. inc(sym^.refs);
  418. end;
  419. constructor tai_const_symbol.init_offset(_sym:PAsmSymbol;ofs:longint);
  420. begin
  421. inherited init;
  422. typ:=ait_const_symbol;
  423. sym:=_sym;
  424. offset:=ofs;
  425. { update sym info }
  426. inc(sym^.refs);
  427. end;
  428. constructor tai_const_symbol.init_rva(_sym:PAsmSymbol);
  429. begin
  430. inherited init;
  431. typ:=ait_const_rva;
  432. sym:=_sym;
  433. offset:=0;
  434. { update sym info }
  435. inc(sym^.refs);
  436. end;
  437. constructor tai_const_symbol.initname(const name:string);
  438. begin
  439. inherited init;
  440. typ:=ait_const_symbol;
  441. sym:=newasmsymbol(name);
  442. offset:=0;
  443. { update sym info }
  444. inc(sym^.refs);
  445. end;
  446. constructor tai_const_symbol.initname_offset(const name:string;ofs:longint);
  447. begin
  448. inherited init;
  449. typ:=ait_const_symbol;
  450. sym:=newasmsymbol(name);
  451. offset:=ofs;
  452. { update sym info }
  453. inc(sym^.refs);
  454. end;
  455. constructor tai_const_symbol.initname_rva(const name:string);
  456. begin
  457. inherited init;
  458. typ:=ait_const_rva;
  459. sym:=newasmsymbol(name);
  460. offset:=0;
  461. { update sym info }
  462. inc(sym^.refs);
  463. end;
  464. {****************************************************************************
  465. TAI_real_32bit
  466. ****************************************************************************}
  467. constructor tai_real_32bit.init(_value : ts32real);
  468. begin
  469. inherited init;
  470. typ:=ait_real_32bit;
  471. value:=_value;
  472. end;
  473. {****************************************************************************
  474. TAI_real_64bit
  475. ****************************************************************************}
  476. constructor tai_real_64bit.init(_value : ts64real);
  477. begin
  478. inherited init;
  479. typ:=ait_real_64bit;
  480. value:=_value;
  481. end;
  482. {****************************************************************************
  483. TAI_real_80bit
  484. ****************************************************************************}
  485. constructor tai_real_80bit.init(_value : ts80real);
  486. begin
  487. inherited init;
  488. typ:=ait_real_80bit;
  489. value:=_value;
  490. end;
  491. {****************************************************************************
  492. Tai_comp_64bit
  493. ****************************************************************************}
  494. constructor tai_comp_64bit.init(_value : ts64comp);
  495. begin
  496. inherited init;
  497. typ:=ait_comp_64bit;
  498. value:=_value;
  499. end;
  500. {****************************************************************************
  501. TAI_STRING
  502. ****************************************************************************}
  503. constructor tai_string.init(const _str : string);
  504. begin
  505. inherited init;
  506. typ:=ait_string;
  507. getmem(str,length(_str)+1);
  508. strpcopy(str,_str);
  509. len:=length(_str);
  510. end;
  511. constructor tai_string.init_pchar(_str : pchar);
  512. begin
  513. inherited init;
  514. typ:=ait_string;
  515. str:=_str;
  516. len:=strlen(_str);
  517. end;
  518. constructor tai_string.init_length_pchar(_str : pchar;length : longint);
  519. begin
  520. inherited init;
  521. typ:=ait_string;
  522. str:=_str;
  523. len:=length;
  524. end;
  525. destructor tai_string.done;
  526. begin
  527. { you can have #0 inside the strings so }
  528. if str<>nil then
  529. freemem(str,len+1);
  530. inherited done;
  531. end;
  532. {****************************************************************************
  533. TAI_LABEL
  534. ****************************************************************************}
  535. constructor tai_label.init(_l : pasmlabel);
  536. begin
  537. inherited init;
  538. typ:=ait_label;
  539. l:=_l;
  540. l^.is_set:=true;
  541. is_global:=(l^.typ=AS_GLOBAL);
  542. end;
  543. {****************************************************************************
  544. TAI_DIRECT
  545. ****************************************************************************}
  546. constructor tai_direct.init(_str : pchar);
  547. begin
  548. inherited init;
  549. typ:=ait_direct;
  550. str:=_str;
  551. end;
  552. destructor tai_direct.done;
  553. begin
  554. strdispose(str);
  555. inherited done;
  556. end;
  557. {****************************************************************************
  558. TAI_ASM_COMMENT comment to be inserted in the assembler file
  559. ****************************************************************************}
  560. constructor tai_asm_comment.init(_str : pchar);
  561. begin
  562. inherited init;
  563. typ:=ait_comment;
  564. str:=_str;
  565. end;
  566. destructor tai_asm_comment.done;
  567. begin
  568. strdispose(str);
  569. inherited done;
  570. end;
  571. {****************************************************************************
  572. TAI_ALIGN
  573. ****************************************************************************}
  574. {$ifndef alignreg}
  575. constructor tai_align.init(b: byte);
  576. {$else alignreg}
  577. constructor tai_align_abstract.init(b: byte);
  578. {$endif alignreg}
  579. begin
  580. inherited init;
  581. typ:=ait_align;
  582. if b in [1,2,4,8,16,32] then
  583. aligntype := b
  584. else
  585. aligntype := 1;
  586. fillsize:=0;
  587. fillop:=0;
  588. use_op:=false;
  589. end;
  590. {$ifndef alignreg}
  591. constructor tai_align.init_op(b: byte; _op: byte);
  592. {$else alignreg}
  593. constructor tai_align_abstract.init_op(b: byte; _op: byte);
  594. {$endif alignreg}
  595. begin
  596. inherited init;
  597. typ:=ait_align;
  598. if b in [1,2,4,8,16,32] then
  599. aligntype := b
  600. else
  601. aligntype := 1;
  602. fillsize:=0;
  603. fillop:=_op;
  604. use_op:=true;
  605. end;
  606. {****************************************************************************
  607. TAI_CUT
  608. ****************************************************************************}
  609. constructor tai_cut.init;
  610. begin
  611. inherited init;
  612. typ:=ait_cut;
  613. place:=cut_normal;
  614. end;
  615. constructor tai_cut.init_begin;
  616. begin
  617. inherited init;
  618. typ:=ait_cut;
  619. place:=cut_begin;
  620. end;
  621. constructor tai_cut.init_end;
  622. begin
  623. inherited init;
  624. typ:=ait_cut;
  625. place:=cut_end;
  626. end;
  627. {****************************************************************************
  628. Tai_Marker
  629. ****************************************************************************}
  630. Constructor Tai_Marker.Init(_Kind: TMarker);
  631. Begin
  632. Inherited Init;
  633. typ := ait_marker;
  634. Kind := _Kind;
  635. End;
  636. {*****************************************************************************
  637. TaiTempAlloc
  638. *****************************************************************************}
  639. constructor taitempalloc.alloc(pos,size:longint);
  640. begin
  641. inherited init;
  642. typ:=ait_tempalloc;
  643. allocation:=true;
  644. temppos:=pos;
  645. tempsize:=size;
  646. end;
  647. constructor taitempalloc.dealloc(pos,size:longint);
  648. begin
  649. inherited init;
  650. typ:=ait_tempalloc;
  651. allocation:=false;
  652. temppos:=pos;
  653. tempsize:=size;
  654. end;
  655. {*****************************************************************************
  656. AsmSymbol
  657. *****************************************************************************}
  658. constructor tasmsymbol.init(const s:string;_typ:TAsmsymtype);
  659. begin;
  660. inherited initname(s);
  661. reset;
  662. typ:=_typ;
  663. end;
  664. procedure tasmsymbol.reset;
  665. begin
  666. section:=sec_none;
  667. address:=0;
  668. size:=0;
  669. idx:=-1;
  670. typ:=AS_EXTERNAL;
  671. { mainly used to remove unused labels from the codesegment }
  672. refs:=0;
  673. end;
  674. function tasmsymbol.is_used:boolean;
  675. begin
  676. is_used:=(refs>0);
  677. end;
  678. procedure tasmsymbol.setaddress(sec:tsection;offset,len:longint);
  679. begin
  680. section:=sec;
  681. address:=offset;
  682. size:=len;
  683. end;
  684. {*****************************************************************************
  685. AsmLabel
  686. *****************************************************************************}
  687. constructor tasmlabel.init;
  688. begin;
  689. labelnr:=nextlabelnr;
  690. inc(nextlabelnr);
  691. inherited init(target_asm.labelprefix+tostr(labelnr),AS_LOCAL);
  692. is_set:=false;
  693. end;
  694. constructor tasmlabel.initdata;
  695. begin;
  696. labelnr:=nextlabelnr;
  697. inc(nextlabelnr);
  698. if (cs_create_smart in aktmoduleswitches) then
  699. inherited init('_$'+current_module^.modulename^+'$_L'+tostr(labelnr),AS_GLOBAL)
  700. else
  701. inherited init(target_asm.labelprefix+tostr(labelnr),AS_LOCAL);
  702. is_set:=false;
  703. { write it always }
  704. refs:=1;
  705. end;
  706. function tasmlabel.name:string;
  707. begin
  708. name:=inherited name;
  709. inc(refs);
  710. end;
  711. {*****************************************************************************
  712. AsmSymbolList helpers
  713. *****************************************************************************}
  714. function newasmsymbol(const s : string) : pasmsymbol;
  715. var
  716. hp : pasmsymbol;
  717. begin
  718. hp:=pasmsymbol(asmsymbollist^.search(s));
  719. if assigned(hp) then
  720. begin
  721. newasmsymbol:=hp;
  722. exit;
  723. end;
  724. { Not found, insert it as an External }
  725. hp:=new(pasmsymbol,init(s,AS_EXTERNAL));
  726. asmsymbollist^.insert(hp);
  727. newasmsymbol:=hp;
  728. end;
  729. function newasmsymboltyp(const s : string;_typ:TAsmSymType) : pasmsymbol;
  730. var
  731. hp : pasmsymbol;
  732. begin
  733. hp:=pasmsymbol(asmsymbollist^.search(s));
  734. if assigned(hp) then
  735. begin
  736. hp^.typ:=_typ;
  737. newasmsymboltyp:=hp;
  738. exit;
  739. end;
  740. { Not found, insert it as an External }
  741. hp:=new(pasmsymbol,init(s,_typ));
  742. asmsymbollist^.insert(hp);
  743. newasmsymboltyp:=hp;
  744. end;
  745. function getasmsymbol(const s : string) : pasmsymbol;
  746. begin
  747. getasmsymbol:=pasmsymbol(asmsymbollist^.search(s));
  748. end;
  749. { renames an asmsymbol }
  750. function renameasmsymbol(const sold, snew : string):pasmsymbol;
  751. {$ifdef nodictonaryrename}
  752. var
  753. hpold,hpnew : pasmsymbol;
  754. begin
  755. hpnew:=pasmsymbol(asmsymbollist^.search(snew));
  756. if assigned(hpnew) then
  757. internalerror(405405);
  758. hpold:=pasmsymbol(asmsymbollist^.search(sold));
  759. if not assigned(hpold) then
  760. internalerror(405406);
  761. hpnew:=new(pasmsymbol,init(sold));
  762. { replace the old one }
  763. { WARNING this heavily depends on the
  764. feature that tdictionnary.insert does not delete
  765. the tree element that it replaces !! }
  766. asmsymbollist^.replace_existing:=true;
  767. asmsymbollist^.insert(hpnew);
  768. asmsymbollist^.replace_existing:=false;
  769. { restore the tree }
  770. hpnew^.left:=hpold^.left;
  771. hpnew^.right:=hpold^.right;
  772. stringdispose(hpold^._name);
  773. hpold^._name:=stringdup(snew);
  774. hpold^.speedvalue:=getspeedvalue(snew);
  775. { now reinsert it at right location !! }
  776. asmsymbollist^.insert(hpold);
  777. renameasmsymbol:=hpold;
  778. end;
  779. {$else}
  780. begin
  781. renameasmsymbol:=pasmsymbol(asmsymbollist^.rename(sold,snew));
  782. end;
  783. {$endif}
  784. procedure ResetAsmSym(p:Pnamedindexobject);{$ifndef FPC}far;{$endif}
  785. begin
  786. pasmsymbol(p)^.reset;
  787. end;
  788. procedure ResetAsmsymbolList;
  789. begin
  790. asmsymbollist^.foreach({$ifndef TP}@{$endif}resetasmsym);
  791. end;
  792. {*****************************************************************************
  793. Label Helpers
  794. *****************************************************************************}
  795. procedure getlabel(var l : pasmlabel);
  796. begin
  797. l:=new(pasmlabel,init);
  798. asmsymbollist^.insert(l);
  799. end;
  800. procedure getdatalabel(var l : pasmlabel);
  801. begin
  802. l:=new(pasmlabel,initdata);
  803. asmsymbollist^.insert(l);
  804. end;
  805. procedure freelabel(var l : pasmlabel);
  806. begin
  807. { nothing to do, the dispose of the asmsymbollist will do it }
  808. l:=nil;
  809. end;
  810. procedure getlabelnr(var l : longint);
  811. begin
  812. l:=nextlabelnr;
  813. inc(nextlabelnr);
  814. end;
  815. {*****************************************************************************
  816. TAAsmOutput
  817. *****************************************************************************}
  818. function taasmoutput.getlasttaifilepos : pfileposinfo;
  819. begin
  820. if assigned(last) then
  821. getlasttaifilepos:=@pai(last)^.fileinfo
  822. else
  823. getlasttaifilepos:=nil;
  824. end;
  825. end.
  826. {
  827. $Log$
  828. Revision 1.68 1999-11-06 14:34:16 peter
  829. * truncated log to 20 revs
  830. Revision 1.67 1999/11/05 16:01:45 jonas
  831. + first implementation of choosing least used register for alignment code
  832. (not yet working, between ifdef alignreg)
  833. Revision 1.66 1999/11/02 15:06:56 peter
  834. * import library fixes for win32
  835. * alignment works again
  836. Revision 1.65 1999/10/27 16:11:27 peter
  837. * insns.dat is used to generate all i386*.inc files
  838. Revision 1.64 1999/09/20 16:38:51 peter
  839. * cs_create_smart instead of cs_smartlink
  840. * -CX is create smartlink
  841. * -CD is create dynamic, but does nothing atm.
  842. Revision 1.63 1999/09/16 23:05:51 florian
  843. * m68k compiler is again compilable (only gas writer, no assembler reader)
  844. Revision 1.62 1999/09/15 20:35:37 florian
  845. * small fix to operator overloading when in MMX mode
  846. + the compiler uses now fldz and fld1 if possible
  847. + some fixes to floating point registers
  848. + some math. functions (arctan, ln, sin, cos, sqrt, sqr, pi) are now inlined
  849. * .... ???
  850. Revision 1.61 1999/09/08 15:01:29 jonas
  851. * some small changes so the noew optimizer is again compilable
  852. Revision 1.60 1999/08/06 15:30:17 florian
  853. + cpu flags added, mainly for the new cg
  854. Revision 1.59 1999/08/05 15:51:01 michael
  855. * Added ait_frame, ait_ent
  856. Revision 1.58 1999/08/04 00:39:56 michael
  857. + Added ait_frame
  858. Revision 1.57 1999/08/02 21:01:41 michael
  859. * Moved toperand type back =(
  860. Revision 1.56 1999/08/02 20:45:47 michael
  861. * Moved toperand type to aasm
  862. Revision 1.55 1999/08/01 23:55:55 michael
  863. * Moved taitempalloc
  864. Revision 1.54 1999/07/29 20:53:55 peter
  865. * write .size also
  866. Revision 1.53 1999/07/22 09:37:28 florian
  867. + resourcestring implemented
  868. + start of longstring support
  869. Revision 1.52 1999/07/03 00:26:01 peter
  870. * ag386bin doesn't destroy the aasmoutput lists anymore
  871. Revision 1.51 1999/06/02 22:43:57 pierre
  872. * previous wrong log corrected
  873. Revision 1.50 1999/06/02 22:25:24 pierre
  874. * changed $ifdef FPC @ into $ifndef TP
  875. Revision 1.49 1999/06/01 14:45:41 peter
  876. * @procvar is now always needed for FPC
  877. Revision 1.48 1999/05/28 09:11:39 peter
  878. * also count ref when asmlabel^.name is used
  879. }