aasm.pas 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180
  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.1 2000-07-13 06:29:43 michael
  876. + Initial import
  877. Revision 1.82 2000/04/22 14:25:03 jonas
  878. * aasm.pas: pai_align instead of pai_align_abstract if cpu <> i386
  879. + systems.pas: info for macos/ppc
  880. * new/cgobj.pas: compiles again without newst define
  881. * new/powerpc/cgcpu: generate different entry/exit code depending on
  882. whether target_os is MacOs or Linux
  883. Revision 1.81 2000/04/10 12:21:33 jonas
  884. * added ait_symbol_end to SkipInstr
  885. Revision 1.80 2000/02/29 23:55:53 pierre
  886. + InlineStat and InlineEnd amrker added
  887. Revision 1.79 2000/02/28 17:23:56 daniel
  888. * Current work of symtable integration committed. The symtable can be
  889. activated by defining 'newst', but doesn't compile yet. Changes in type
  890. checking and oop are completed. What is left is to write a new
  891. symtablestack and adapt the parser to use it.
  892. Revision 1.78 2000/02/18 20:53:14 pierre
  893. * fixes a stabs problem for functions
  894. + includes a stabs local var for with statements
  895. the name is with in lowercase followed by an index
  896. for nested with.
  897. + Withdebuglist added because the stabs declarations of local
  898. var are postponed to end of function.
  899. Revision 1.77 2000/02/09 13:22:42 peter
  900. * log truncated
  901. Revision 1.76 2000/02/03 23:01:45 peter
  902. * fixed smartlinking
  903. Revision 1.75 2000/01/28 15:15:31 jonas
  904. * moved skipinstr from daopt386 to aasm
  905. * fixed crashing bug with -dreplacereg in csopt386.pas
  906. Revision 1.74 2000/01/23 16:31:38 peter
  907. * fixed uninited asmsymbol.typ var
  908. Revision 1.73 2000/01/19 22:53:57 florian
  909. * empty records/objects would generate static data of size 0 which is optimized away, tai_datablock
  910. checks now the size and sets it to a value > 0
  911. Revision 1.72 2000/01/13 13:07:05 jonas
  912. * released -dalignreg
  913. * some small fixes to -dnewOptimizations helper procedures
  914. Revision 1.71 2000/01/12 10:38:16 peter
  915. * smartlinking fixes for binary writer
  916. * release alignreg code and moved instruction writing align to cpuasm,
  917. but it doesn't use the specified register yet
  918. Revision 1.70 2000/01/07 01:14:18 peter
  919. * updated copyright to 2000
  920. Revision 1.69 1999/12/22 01:01:46 peter
  921. - removed freelabel()
  922. * added undefined label detection in internal assembler, this prevents
  923. a lot of ld crashes and wrong .o files
  924. * .o files aren't written anymore if errors have occured
  925. * inlining of assembler labels is now correct
  926. Revision 1.68 1999/11/06 14:34:16 peter
  927. * truncated log to 20 revs
  928. Revision 1.67 1999/11/05 16:01:45 jonas
  929. + first implementation of choosing least used register for alignment code
  930. (not yet working, between ifdef alignreg)
  931. Revision 1.66 1999/11/02 15:06:56 peter
  932. * import library fixes for win32
  933. * alignment works again
  934. Revision 1.65 1999/10/27 16:11:27 peter
  935. * insns.dat is used to generate all i386*.inc files
  936. Revision 1.64 1999/09/20 16:38:51 peter
  937. * cs_create_smart instead of cs_smartlink
  938. * -CX is create smartlink
  939. * -CD is create dynamic, but does nothing atm.
  940. Revision 1.63 1999/09/16 23:05:51 florian
  941. * m68k compiler is again compilable (only gas writer, no assembler reader)
  942. Revision 1.62 1999/09/15 20:35:37 florian
  943. * small fix to operator overloading when in MMX mode
  944. + the compiler uses now fldz and fld1 if possible
  945. + some fixes to floating point registers
  946. + some math. functions (arctan, ln, sin, cos, sqrt, sqr, pi) are now inlined
  947. * .... ???
  948. Revision 1.61 1999/09/08 15:01:29 jonas
  949. * some small changes so the noew optimizer is again compilable
  950. Revision 1.60 1999/08/06 15:30:17 florian
  951. + cpu flags added, mainly for the new cg
  952. Revision 1.59 1999/08/05 15:51:01 michael
  953. * Added ait_frame, ait_ent
  954. Revision 1.58 1999/08/04 00:39:56 michael
  955. + Added ait_frame
  956. Revision 1.57 1999/08/02 21:01:41 michael
  957. * Moved toperand type back =(
  958. }