aasm.pas 33 KB

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