aggas.pas 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by the Free Pascal team
  4. This unit implements generic GNU assembler (v2.8 or later)
  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. { Base unit for writing GNU assembler output.
  19. }
  20. unit aggas;
  21. {$i fpcdefs.inc}
  22. interface
  23. uses
  24. cclasses,
  25. globals,
  26. aasmbase,aasmtai,aasmcpu,
  27. assemble;
  28. type
  29. {# This is a derived class which is used to write
  30. GAS styled assembler.
  31. The WriteInstruction() method must be overriden
  32. to write a single instruction to the assembler
  33. file.
  34. }
  35. TGNUAssembler=class(texternalassembler)
  36. public
  37. procedure WriteTree(p:TAAsmoutput);override;
  38. procedure WriteAsmList;override;
  39. {$ifdef GDB}
  40. procedure WriteFileLineInfo(var fileinfo : tfileposinfo);
  41. procedure WriteFileEndInfo;
  42. {$endif}
  43. procedure WriteInstruction(hp: tai); virtual; abstract;
  44. end;
  45. implementation
  46. uses
  47. {$ifdef Delphi}
  48. dmisc,
  49. {$else Delphi}
  50. dos,
  51. {$endif Delphi}
  52. cutils,globtype,systems,
  53. fmodule,finput,verbose,cpubase
  54. {$ifdef GDB}
  55. {$ifdef delphi}
  56. ,sysutils
  57. {$else}
  58. ,strings
  59. {$endif}
  60. ,gdb
  61. {$endif GDB}
  62. ;
  63. const
  64. line_length = 70;
  65. var
  66. {$ifdef GDB}
  67. n_line : byte; { different types of source lines }
  68. linecount,
  69. includecount : longint;
  70. funcname : pchar;
  71. stabslastfileinfo : tfileposinfo;
  72. {$endif}
  73. lasTSec : TSection; { last section type written }
  74. lastfileinfo : tfileposinfo;
  75. infile,
  76. lastinfile : tinputfile;
  77. symendcount : longint;
  78. type
  79. t80bitarray = array[0..9] of byte;
  80. t64bitarray = array[0..7] of byte;
  81. t32bitarray = array[0..3] of byte;
  82. {****************************************************************************}
  83. { Support routines }
  84. {****************************************************************************}
  85. function fixline(s:string):string;
  86. {
  87. return s with all leading and ending spaces and tabs removed
  88. }
  89. var
  90. i,j,k : integer;
  91. begin
  92. i:=length(s);
  93. while (i>0) and (s[i] in [#9,' ']) do
  94. dec(i);
  95. j:=1;
  96. while (j<i) and (s[j] in [#9,' ']) do
  97. inc(j);
  98. for k:=j to i do
  99. if s[k] in [#0..#31,#127..#255] then
  100. s[k]:='.';
  101. fixline:=Copy(s,j,i-j+1);
  102. end;
  103. function single2str(d : single) : string;
  104. var
  105. hs : string;
  106. begin
  107. str(d,hs);
  108. { replace space with + }
  109. if hs[1]=' ' then
  110. hs[1]:='+';
  111. single2str:='0d'+hs
  112. end;
  113. function double2str(d : double) : string;
  114. var
  115. hs : string;
  116. begin
  117. str(d,hs);
  118. { replace space with + }
  119. if hs[1]=' ' then
  120. hs[1]:='+';
  121. double2str:='0d'+hs
  122. end;
  123. function extended2str(e : extended) : string;
  124. var
  125. hs : string;
  126. begin
  127. str(e,hs);
  128. { replace space with + }
  129. if hs[1]=' ' then
  130. hs[1]:='+';
  131. extended2str:='0d'+hs
  132. end;
  133. { convert floating point values }
  134. { to correct endian }
  135. procedure swap64bitarray(var t: t64bitarray);
  136. var
  137. b: byte;
  138. begin
  139. b:= t[7];
  140. t[7] := t[0];
  141. t[0] := b;
  142. b := t[6];
  143. t[6] := t[1];
  144. t[1] := b;
  145. b:= t[5];
  146. t[5] := t[2];
  147. t[2] := b;
  148. b:= t[4];
  149. t[4] := t[3];
  150. t[3] := b;
  151. end;
  152. procedure swap32bitarray(var t: t32bitarray);
  153. var
  154. b: byte;
  155. begin
  156. b:= t[1];
  157. t[1]:= t[2];
  158. t[2]:= b;
  159. b:= t[0];
  160. t[0]:= t[3];
  161. t[3]:= b;
  162. end;
  163. procedure swap80bitarray(var t: t80bitarray);
  164. begin
  165. {!!!!!!!!!!!!}
  166. end;
  167. const
  168. ait_const2str : array[ait_const_32bit..ait_const_8bit] of string[8]=
  169. (#9'.long'#9,#9'.short'#9,#9'.byte'#9);
  170. function ait_section2str(s:TSection):string;
  171. begin
  172. ait_section2str:=target_asm.secnames[s];
  173. {$ifdef GDB}
  174. { this is needed for line info in data }
  175. funcname:=nil;
  176. case s of
  177. sec_code : n_line:=n_textline;
  178. sec_data : n_line:=n_dataline;
  179. sec_bss : n_line:=n_bssline;
  180. else n_line:=n_dataline;
  181. end;
  182. {$endif GDB}
  183. LasTSec:=s;
  184. end;
  185. {****************************************************************************}
  186. { GNU Assembler writer }
  187. {****************************************************************************}
  188. {$ifdef GDB}
  189. procedure TGNUAssembler.WriteFileLineInfo(var fileinfo : tfileposinfo);
  190. var
  191. curr_n : byte;
  192. begin
  193. if not ((cs_debuginfo in aktmoduleswitches) or
  194. (cs_gdb_lineinfo in aktglobalswitches)) then
  195. exit;
  196. { file changed ? (must be before line info) }
  197. if (fileinfo.fileindex<>0) and
  198. (stabslastfileinfo.fileindex<>fileinfo.fileindex) then
  199. begin
  200. infile:=current_module.sourcefiles.get_file(fileinfo.fileindex);
  201. if assigned(infile) then
  202. begin
  203. if includecount=0 then
  204. curr_n:=n_sourcefile
  205. else
  206. curr_n:=n_includefile;
  207. if (infile.path^<>'') then
  208. begin
  209. AsmWriteLn(#9'.stabs "'+lower(BsToSlash(FixPath(infile.path^,false)))+'",'+
  210. tostr(curr_n)+',0,0,'+'Ltext'+ToStr(IncludeCount));
  211. end;
  212. AsmWriteLn(#9'.stabs "'+lower(FixFileName(infile.name^))+'",'+
  213. tostr(curr_n)+',0,0,'+'Ltext'+ToStr(IncludeCount));
  214. AsmWriteLn('Ltext'+ToStr(IncludeCount)+':');
  215. inc(includecount);
  216. end;
  217. end;
  218. { line changed ? }
  219. if (stabslastfileinfo.line<>fileinfo.line) and (fileinfo.line<>0) then
  220. begin
  221. if (n_line=n_textline) and assigned(funcname) and
  222. (target_info.use_function_relative_addresses) then
  223. begin
  224. AsmWriteLn(target_asm.labelprefix+'l'+tostr(linecount)+':');
  225. AsmWrite(#9'.stabn '+tostr(n_line)+',0,'+tostr(fileinfo.line)+','+
  226. target_asm.labelprefix+'l'+tostr(linecount)+' - ');
  227. AsmWritePChar(FuncName);
  228. AsmLn;
  229. inc(linecount);
  230. end
  231. else
  232. AsmWriteLn(#9'.stabd'#9+tostr(n_line)+',0,'+tostr(fileinfo.line));
  233. end;
  234. stabslastfileinfo:=fileinfo;
  235. end;
  236. procedure TGNUAssembler.WriteFileEndInfo;
  237. begin
  238. if not ((cs_debuginfo in aktmoduleswitches) or
  239. (cs_gdb_lineinfo in aktglobalswitches)) then
  240. exit;
  241. AsmLn;
  242. AsmWriteLn(ait_section2str(sec_code));
  243. AsmWriteLn(#9'.stabs "",'+tostr(n_sourcefile)+',0,0,Letext');
  244. AsmWriteLn('Letext:');
  245. end;
  246. {$endif GDB}
  247. procedure TGNUAssembler.WriteTree(p:TAAsmoutput);
  248. const
  249. allocstr : array[boolean] of string[10]=(' released',' allocated');
  250. nolinetai =[ait_label,
  251. ait_regalloc,ait_tempalloc,
  252. {$ifdef GDB}
  253. ait_stabn,ait_stabs,ait_stab_function_name,
  254. {$endif GDB}
  255. ait_cut,ait_marker,ait_align,ait_section];
  256. type
  257. t80bitarray = array[0..9] of byte;
  258. t64bitarray = array[0..7] of byte;
  259. t32bitarray = array[0..3] of byte;
  260. var
  261. ch : char;
  262. hp : tai;
  263. consttyp : tait;
  264. s : string;
  265. found : boolean;
  266. i,pos,l : longint;
  267. InlineLevel : longint;
  268. co : comp;
  269. sin : single;
  270. d : double;
  271. e : extended;
  272. do_line : boolean;
  273. sep : char;
  274. begin
  275. if not assigned(p) then
  276. exit;
  277. InlineLevel:=0;
  278. { lineinfo is only needed for codesegment (PFV) }
  279. do_line:=(cs_asm_source in aktglobalswitches) or
  280. ((cs_lineinfo in aktmoduleswitches)
  281. and (p=codesegment));
  282. hp:=tai(p.first);
  283. while assigned(hp) do
  284. begin
  285. aktfilepos:=hp.fileinfo;
  286. if not(hp.typ in nolinetai) then
  287. begin
  288. {$ifdef GDB}
  289. { write stabs }
  290. if (cs_debuginfo in aktmoduleswitches) or
  291. (cs_gdb_lineinfo in aktglobalswitches) then
  292. WriteFileLineInfo(hp.fileinfo);
  293. {$endif GDB}
  294. if do_line then
  295. begin
  296. { load infile }
  297. if lastfileinfo.fileindex<>hp.fileinfo.fileindex then
  298. begin
  299. infile:=current_module.sourcefiles.get_file(hp.fileinfo.fileindex);
  300. if assigned(infile) then
  301. begin
  302. { open only if needed !! }
  303. if (cs_asm_source in aktglobalswitches) then
  304. infile.open;
  305. end;
  306. { avoid unnecessary reopens of the same file !! }
  307. lastfileinfo.fileindex:=hp.fileinfo.fileindex;
  308. { be sure to change line !! }
  309. lastfileinfo.line:=-1;
  310. end;
  311. { write source }
  312. if (cs_asm_source in aktglobalswitches) and
  313. assigned(infile) then
  314. begin
  315. if (infile<>lastinfile) then
  316. begin
  317. AsmWriteLn(target_asm.comment+'['+infile.name^+']');
  318. if assigned(lastinfile) then
  319. lastinfile.close;
  320. end;
  321. if (hp.fileinfo.line<>lastfileinfo.line) and
  322. ((hp.fileinfo.line<infile.maxlinebuf) or (InlineLevel>0)) then
  323. begin
  324. if (hp.fileinfo.line<>0) and
  325. ((infile.linebuf^[hp.fileinfo.line]>=0) or (InlineLevel>0)) then
  326. AsmWriteLn(target_asm.comment+'['+tostr(hp.fileinfo.line)+'] '+
  327. fixline(infile.GetLineStr(hp.fileinfo.line)));
  328. { set it to a negative value !
  329. to make that is has been read already !! PM }
  330. if (infile.linebuf^[hp.fileinfo.line]>=0) then
  331. infile.linebuf^[hp.fileinfo.line]:=-infile.linebuf^[hp.fileinfo.line]-1;
  332. end;
  333. end;
  334. lastfileinfo:=hp.fileinfo;
  335. lastinfile:=infile;
  336. end;
  337. end;
  338. case hp.typ of
  339. ait_comment :
  340. Begin
  341. AsmWrite(target_asm.comment);
  342. AsmWritePChar(tai_asm_comment(hp).str);
  343. AsmLn;
  344. End;
  345. ait_regalloc :
  346. begin
  347. if (cs_asm_regalloc in aktglobalswitches) then
  348. AsmWriteLn(target_asm.comment+'Register '+std_reg2str[tai_regalloc(hp).reg]+
  349. allocstr[tai_regalloc(hp).allocation]);
  350. end;
  351. ait_tempalloc :
  352. begin
  353. if (cs_asm_tempalloc in aktglobalswitches) then
  354. AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
  355. tostr(tai_tempalloc(hp).tempsize)+allocstr[tai_tempalloc(hp).allocation]);
  356. end;
  357. ait_align :
  358. begin
  359. AsmWrite(#9'.balign '+tostr(tai_align(hp).aligntype));
  360. if tai_align(hp).use_op then
  361. AsmWrite(','+tostr(tai_align(hp).fillop));
  362. AsmLn;
  363. end;
  364. ait_section :
  365. begin
  366. if tai_section(hp).sec<>sec_none then
  367. begin
  368. AsmLn;
  369. AsmWriteLn(ait_section2str(tai_section(hp).sec));
  370. {$ifdef GDB}
  371. lastfileinfo.line:=-1;
  372. {$endif GDB}
  373. end;
  374. end;
  375. ait_datablock :
  376. begin
  377. if tai_datablock(hp).is_global then
  378. AsmWrite(#9'.comm'#9)
  379. else
  380. AsmWrite(#9'.lcomm'#9);
  381. AsmWrite(tai_datablock(hp).sym.name);
  382. AsmWriteLn(','+tostr(tai_datablock(hp).size));
  383. end;
  384. ait_const_32bit,
  385. ait_const_16bit,
  386. ait_const_8bit :
  387. begin
  388. AsmWrite(ait_const2str[hp.typ]+tostr(tai_const(hp).value));
  389. consttyp:=hp.typ;
  390. l:=0;
  391. repeat
  392. found:=(not (tai(hp.next)=nil)) and (tai(hp.next).typ=consttyp);
  393. if found then
  394. begin
  395. hp:=tai(hp.next);
  396. s:=','+tostr(tai_const(hp).value);
  397. AsmWrite(s);
  398. inc(l,length(s));
  399. end;
  400. until (not found) or (l>line_length);
  401. AsmLn;
  402. end;
  403. ait_const_symbol :
  404. begin
  405. AsmWrite(#9'.long'#9+tai_const_symbol(hp).sym.name);
  406. if tai_const_symbol(hp).offset>0 then
  407. AsmWrite('+'+tostr(tai_const_symbol(hp).offset))
  408. else if tai_const_symbol(hp).offset<0 then
  409. AsmWrite(tostr(tai_const_symbol(hp).offset));
  410. AsmLn;
  411. end;
  412. ait_const_rva :
  413. AsmWriteLn(#9'.rva'#9+tai_const_symbol(hp).sym.name);
  414. ait_real_80bit :
  415. begin
  416. if do_line then
  417. AsmWriteLn(target_asm.comment+extended2str(tai_real_80bit(hp).value));
  418. { Make sure e is a extended type, bestreal could be
  419. a different type (bestreal) !! (PFV) }
  420. e:=tai_real_80bit(hp).value;
  421. AsmWrite(#9'.byte'#9);
  422. for i:=0 to 9 do
  423. begin
  424. if i<>0 then
  425. AsmWrite(',');
  426. AsmWrite(tostr(t80bitarray(e)[i]));
  427. end;
  428. AsmLn;
  429. end;
  430. ait_real_64bit :
  431. begin
  432. if do_line then
  433. AsmWriteLn(target_asm.comment+double2str(tai_real_64bit(hp).value));
  434. d:=tai_real_64bit(hp).value;
  435. { swap the values to correct endian if required }
  436. if source_info.endian <> target_info.endian then
  437. swap64bitarray(t64bitarray(d));
  438. AsmWrite(#9'.byte'#9);
  439. for i:=0 to 7 do
  440. begin
  441. if i<>0 then
  442. AsmWrite(',');
  443. AsmWrite(tostr(t64bitarray(d)[i]));
  444. end;
  445. AsmLn;
  446. end;
  447. ait_real_32bit :
  448. begin
  449. if do_line then
  450. AsmWriteLn(target_asm.comment+single2str(tai_real_32bit(hp).value));
  451. sin:=tai_real_32bit(hp).value;
  452. { swap the values to correct endian if required }
  453. if source_info.endian <> target_info.endian then
  454. swap32bitarray(t32bitarray(sin));
  455. AsmWrite(#9'.byte'#9);
  456. for i:=0 to 3 do
  457. begin
  458. if i<>0 then
  459. AsmWrite(',');
  460. AsmWrite(tostr(t32bitarray(sin)[i]));
  461. end;
  462. AsmLn;
  463. end;
  464. ait_comp_64bit :
  465. begin
  466. if do_line then
  467. AsmWriteLn(target_asm.comment+extended2str(tai_comp_64bit(hp).value));
  468. AsmWrite(#9'.byte'#9);
  469. {$ifdef FPC}
  470. co:=comp(tai_comp_64bit(hp).value);
  471. {$else}
  472. co:=tai_comp_64bit(hp).value;
  473. {$endif}
  474. { swap the values to correct endian if required }
  475. if source_info.endian <> target_info.endian then
  476. swap64bitarray(t64bitarray(co));
  477. for i:=0 to 7 do
  478. begin
  479. if i<>0 then
  480. AsmWrite(',');
  481. AsmWrite(tostr(t64bitarray(co)[i]));
  482. end;
  483. AsmLn;
  484. end;
  485. ait_direct :
  486. begin
  487. AsmWritePChar(tai_direct(hp).str);
  488. AsmLn;
  489. {$IfDef GDB}
  490. if strpos(tai_direct(hp).str,'.data')<>nil then
  491. n_line:=n_dataline
  492. else if strpos(tai_direct(hp).str,'.text')<>nil then
  493. n_line:=n_textline
  494. else if strpos(tai_direct(hp).str,'.bss')<>nil then
  495. n_line:=n_bssline;
  496. {$endif GDB}
  497. end;
  498. ait_string :
  499. begin
  500. pos:=0;
  501. for i:=1 to tai_string(hp).len do
  502. begin
  503. if pos=0 then
  504. begin
  505. AsmWrite(#9'.ascii'#9'"');
  506. pos:=20;
  507. end;
  508. ch:=tai_string(hp).str[i-1];
  509. case ch of
  510. #0, {This can't be done by range, because a bug in FPC}
  511. #1..#31,
  512. #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  513. '"' : s:='\"';
  514. '\' : s:='\\';
  515. else
  516. s:=ch;
  517. end;
  518. AsmWrite(s);
  519. inc(pos,length(s));
  520. if (pos>line_length) or (i=tai_string(hp).len) then
  521. begin
  522. AsmWriteLn('"');
  523. pos:=0;
  524. end;
  525. end;
  526. end;
  527. ait_label :
  528. begin
  529. if (tai_label(hp).l.is_used) then
  530. begin
  531. if tai_label(hp).l.defbind=AB_GLOBAL then
  532. begin
  533. AsmWrite('.globl'#9);
  534. AsmWriteLn(tai_label(hp).l.name);
  535. end;
  536. AsmWrite(tai_label(hp).l.name);
  537. AsmWriteLn(':');
  538. end;
  539. end;
  540. ait_symbol :
  541. begin
  542. if tai_symbol(hp).is_global then
  543. begin
  544. AsmWrite('.globl'#9);
  545. AsmWriteLn(tai_symbol(hp).sym.name);
  546. end;
  547. if target_info.system in [system_i386_linux,system_i386_beos] then
  548. begin
  549. AsmWrite(#9'.type'#9);
  550. AsmWrite(tai_symbol(hp).sym.name);
  551. if assigned(tai(hp.next)) and
  552. (tai(hp.next).typ in [ait_const_symbol,ait_const_rva,
  553. ait_const_32bit,ait_const_16bit,ait_const_8bit,ait_datablock,
  554. ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit]) then
  555. AsmWriteLn(',@object')
  556. else
  557. AsmWriteLn(',@function');
  558. if tai_symbol(hp).sym.size>0 then
  559. begin
  560. AsmWrite(#9'.size'#9);
  561. AsmWrite(tai_symbol(hp).sym.name);
  562. AsmWrite(', ');
  563. AsmWriteLn(tostr(tai_symbol(hp).sym.size));
  564. end;
  565. end;
  566. AsmWrite(tai_symbol(hp).sym.name);
  567. AsmWriteLn(':');
  568. end;
  569. ait_symbol_end :
  570. begin
  571. if target_info.system in [system_i386_linux,system_i386_beos] then
  572. begin
  573. s:=target_asm.labelprefix+'e'+tostr(symendcount);
  574. inc(symendcount);
  575. AsmWriteLn(s+':');
  576. AsmWrite(#9'.size'#9);
  577. AsmWrite(tai_symbol_end(hp).sym.name);
  578. AsmWrite(', '+s+' - ');
  579. AsmWriteLn(tai_symbol_end(hp).sym.name);
  580. end;
  581. end;
  582. ait_instruction :
  583. begin
  584. WriteInstruction(hp);
  585. end;
  586. {$ifdef GDB}
  587. ait_stabs :
  588. begin
  589. AsmWrite(#9'.stabs ');
  590. AsmWritePChar(tai_stabs(hp).str);
  591. AsmLn;
  592. end;
  593. ait_stabn :
  594. begin
  595. AsmWrite(#9'.stabn ');
  596. AsmWritePChar(tai_stabn(hp).str);
  597. AsmLn;
  598. end;
  599. ait_force_line :
  600. stabslastfileinfo.line:=0;
  601. ait_stab_function_name:
  602. funcname:=tai_stab_function_name(hp).str;
  603. {$endif GDB}
  604. ait_cut :
  605. begin
  606. if SmartAsm then
  607. begin
  608. { only reset buffer if nothing has changed }
  609. if AsmSize=AsmStartSize then
  610. AsmClear
  611. else
  612. begin
  613. AsmClose;
  614. DoAssemble;
  615. AsmCreate(tai_cut(hp).place);
  616. end;
  617. { avoid empty files }
  618. while assigned(hp.next) and (tai(hp.next).typ in [ait_cut,ait_section,ait_comment]) do
  619. begin
  620. if tai(hp.next).typ=ait_section then
  621. lasTSec:=tai_section(hp.next).sec;
  622. hp:=tai(hp.next);
  623. end;
  624. {$ifdef GDB}
  625. { force write of filename }
  626. FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
  627. includecount:=0;
  628. funcname:=nil;
  629. WriteFileLineInfo(hp.fileinfo);
  630. {$endif GDB}
  631. if lasTSec<>sec_none then
  632. AsmWriteLn(ait_section2str(lasTSec));
  633. AsmStartSize:=AsmSize;
  634. end;
  635. end;
  636. ait_marker :
  637. if tai_marker(hp).kind=InlineStart then
  638. inc(InlineLevel)
  639. else if tai_marker(hp).kind=InlineEnd then
  640. dec(InlineLevel);
  641. else
  642. internalerror(10000);
  643. end;
  644. hp:=tai(hp.next);
  645. end;
  646. end;
  647. procedure TGNUAssembler.WriteAsmList;
  648. var
  649. p:dirstr;
  650. n:namestr;
  651. e:extstr;
  652. {$ifdef GDB}
  653. fileinfo : tfileposinfo;
  654. {$endif GDB}
  655. begin
  656. {$ifdef EXTDEBUG}
  657. if assigned(current_module.mainsource) then
  658. Comment(v_info,'Start writing gas-styled assembler output for '+current_module.mainsource^);
  659. {$endif}
  660. LasTSec:=sec_none;
  661. {$ifdef GDB}
  662. FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
  663. {$endif GDB}
  664. FillChar(lastfileinfo,sizeof(lastfileinfo),0);
  665. LastInfile:=nil;
  666. if assigned(current_module.mainsource) then
  667. fsplit(current_module.mainsource^,p,n,e)
  668. else
  669. begin
  670. p:=inputdir;
  671. n:=inputfile;
  672. e:=inputextension;
  673. end;
  674. { to get symify to work }
  675. AsmWriteLn(#9'.file "'+FixFileName(n+e)+'"');
  676. {$ifdef GDB}
  677. n_line:=n_bssline;
  678. funcname:=nil;
  679. linecount:=1;
  680. includecount:=0;
  681. fileinfo.fileindex:=1;
  682. fileinfo.line:=1;
  683. { Write main file }
  684. WriteFileLineInfo(fileinfo);
  685. {$endif GDB}
  686. AsmStartSize:=AsmSize;
  687. symendcount:=0;
  688. If (cs_debuginfo in aktmoduleswitches) then
  689. WriteTree(debuglist);
  690. WriteTree(codesegment);
  691. WriteTree(datasegment);
  692. WriteTree(consts);
  693. WriteTree(rttilist);
  694. Writetree(resourcestringlist);
  695. WriteTree(bsssegment);
  696. Writetree(importssection);
  697. { exports are written by DLLTOOL
  698. if we use it so don't insert it twice (PM) }
  699. if not UseDeffileForExport and assigned(exportssection) then
  700. Writetree(exportssection);
  701. Writetree(resourcesection);
  702. {$ifdef GDB}
  703. WriteFileEndInfo;
  704. {$ENDIF}
  705. AsmLn;
  706. {$ifdef EXTDEBUG}
  707. if assigned(current_module.mainsource) then
  708. comment(v_info,'Done writing gas-styled assembler output for '+current_module.mainsource^);
  709. {$endif EXTDEBUG}
  710. end;
  711. end.
  712. {
  713. $Log$
  714. Revision 1.8 2002-07-26 21:15:37 florian
  715. * rewrote the system handling
  716. Revision 1.7 2002/07/07 09:52:32 florian
  717. * powerpc target fixed, very simple units can be compiled
  718. * some basic stuff for better callparanode handling, far from being finished
  719. Revision 1.6 2002/07/01 18:46:20 peter
  720. * internal linker
  721. * reorganized aasm layer
  722. Revision 1.5 2002/05/18 13:34:05 peter
  723. * readded missing revisions
  724. Revision 1.4 2002/05/16 19:46:34 carl
  725. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  726. + try to fix temp allocation (still in ifdef)
  727. + generic constructor calls
  728. + start of tassembler / tmodulebase class cleanup
  729. Revision 1.2 2002/04/15 18:53:48 carl
  730. + comments in register allocator uses std_Reg2str
  731. Revision 1.1 2002/04/14 16:51:54 carl
  732. + basic GNU assembler writer class
  733. }