ag386att.pas 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. This unit implements an asmoutput class for i386 AT&T syntax
  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 ag386att;
  19. {$i defines.inc}
  20. interface
  21. uses cobjects,aasm,assemble;
  22. type
  23. pi386attasmlist=^ti386attasmlist;
  24. ti386attasmlist=object(tasmlist)
  25. procedure WriteTree(p:paasmoutput);virtual;
  26. procedure WriteAsmList;virtual;
  27. {$ifdef GDB}
  28. procedure WriteFileLineInfo(var fileinfo : tfileposinfo);
  29. procedure WriteFileEndInfo;
  30. {$endif}
  31. end;
  32. implementation
  33. uses
  34. {$ifdef Delphi}
  35. sysutils,
  36. dmisc,
  37. {$else Delphi}
  38. strings,
  39. dos,
  40. {$endif Delphi}
  41. cutils,globtype,globals,systems,
  42. fmodule,finput,verbose,cpubase,cpuasm
  43. {$ifdef GDB}
  44. ,gdb
  45. {$endif GDB}
  46. ;
  47. const
  48. line_length = 70;
  49. var
  50. {$ifdef GDB}
  51. n_line : byte; { different types of source lines }
  52. linecount,
  53. includecount : longint;
  54. funcname : pchar;
  55. stabslastfileinfo : tfileposinfo;
  56. {$endif}
  57. lastsec : tsection; { last section type written }
  58. lastfileinfo : tfileposinfo;
  59. infile,
  60. lastinfile : pinputfile;
  61. symendcount : longint;
  62. function fixline(s:string):string;
  63. {
  64. return s with all leading and ending spaces and tabs removed
  65. }
  66. var
  67. i,j,k : longint;
  68. begin
  69. i:=length(s);
  70. while (i>0) and (s[i] in [#9,' ']) do
  71. dec(i);
  72. j:=1;
  73. while (j<i) and (s[j] in [#9,' ']) do
  74. inc(j);
  75. for k:=j to i do
  76. if s[k] in [#0..#31,#127..#255] then
  77. s[k]:='.';
  78. fixline:=Copy(s,j,i-j+1);
  79. end;
  80. function single2str(d : single) : string;
  81. var
  82. hs : string;
  83. begin
  84. str(d,hs);
  85. { replace space with + }
  86. if hs[1]=' ' then
  87. hs[1]:='+';
  88. single2str:='0d'+hs
  89. end;
  90. function double2str(d : double) : string;
  91. var
  92. hs : string;
  93. begin
  94. str(d,hs);
  95. { replace space with + }
  96. if hs[1]=' ' then
  97. hs[1]:='+';
  98. double2str:='0d'+hs
  99. end;
  100. function extended2str(e : extended) : string;
  101. var
  102. hs : string;
  103. begin
  104. str(e,hs);
  105. { replace space with + }
  106. if hs[1]=' ' then
  107. hs[1]:='+';
  108. extended2str:='0d'+hs
  109. end;
  110. type
  111. pdouble = ^double;
  112. function comp2str(d : bestreal) : string;
  113. var
  114. c : comp;
  115. dd : pdouble;
  116. begin
  117. {$ifdef FPC}
  118. c:=comp(d);
  119. {$else}
  120. c:=d;
  121. {$endif}
  122. dd:=pdouble(@c); { this makes a bitwise copy of c into a double }
  123. comp2str:=double2str(dd^);
  124. end;
  125. function getreferencestring(var ref : treference) : string;
  126. var
  127. s : string;
  128. begin
  129. if ref.is_immediate then
  130. begin
  131. internalerror(1000101);
  132. exit;
  133. end
  134. else
  135. begin
  136. with ref do
  137. begin
  138. inc(offset,offsetfixup);
  139. offsetfixup:=0;
  140. { have we a segment prefix ? }
  141. { These are probably not correctly handled under GAS }
  142. { should be replaced by coding the segment override }
  143. { directly! - DJGPP FAQ }
  144. if segment<>R_NO then
  145. s:=att_reg2str[segment]+':'
  146. else
  147. s:='';
  148. if assigned(symbol) then
  149. s:=s+symbol^.name;
  150. if offset<0 then
  151. s:=s+tostr(offset)
  152. else
  153. if (offset>0) then
  154. begin
  155. if assigned(symbol) then
  156. s:=s+'+'+tostr(offset)
  157. else
  158. s:=s+tostr(offset);
  159. end;
  160. if (index<>R_NO) and (base=R_NO) then
  161. Begin
  162. s:=s+'(,'+att_reg2str[index];
  163. if scalefactor<>0 then
  164. s:=s+','+tostr(scalefactor)+')'
  165. else
  166. s:=s+')';
  167. end
  168. else
  169. if (index=R_NO) and (base<>R_NO) then
  170. s:=s+'('+att_reg2str[base]+')'
  171. else
  172. if (index<>R_NO) and (base<>R_NO) then
  173. Begin
  174. s:=s+'('+att_reg2str[base]+','+att_reg2str[index];
  175. if scalefactor<>0 then
  176. s:=s+','+tostr(scalefactor)+')'
  177. else
  178. s := s+')';
  179. end;
  180. end;
  181. end;
  182. getreferencestring:=s;
  183. end;
  184. function getopstr(const o:toper) : string;
  185. var
  186. hs : string;
  187. begin
  188. case o.typ of
  189. top_reg :
  190. getopstr:=att_reg2str[o.reg];
  191. top_ref :
  192. getopstr:=getreferencestring(o.ref^);
  193. top_const :
  194. getopstr:='$'+tostr(o.val);
  195. top_symbol :
  196. begin
  197. if assigned(o.sym) then
  198. hs:='$'+o.sym^.name
  199. else
  200. hs:='$';
  201. if o.symofs>0 then
  202. hs:=hs+'+'+tostr(o.symofs)
  203. else
  204. if o.symofs<0 then
  205. hs:=hs+tostr(o.symofs)
  206. else
  207. if not(assigned(o.sym)) then
  208. hs:=hs+'0';
  209. getopstr:=hs;
  210. end;
  211. else
  212. internalerror(10001);
  213. end;
  214. end;
  215. function getopstr_jmp(const o:toper) : string;
  216. var
  217. hs : string;
  218. begin
  219. case o.typ of
  220. top_reg :
  221. getopstr_jmp:='*'+att_reg2str[o.reg];
  222. top_ref :
  223. getopstr_jmp:='*'+getreferencestring(o.ref^);
  224. top_const :
  225. getopstr_jmp:=tostr(o.val);
  226. top_symbol :
  227. begin
  228. hs:=o.sym^.name;
  229. if o.symofs>0 then
  230. hs:=hs+'+'+tostr(o.symofs)
  231. else
  232. if o.symofs<0 then
  233. hs:=hs+tostr(o.symofs);
  234. getopstr_jmp:=hs;
  235. end;
  236. else
  237. internalerror(10001);
  238. end;
  239. end;
  240. {****************************************************************************
  241. TI386ATTASMOUTPUT
  242. ****************************************************************************}
  243. const
  244. ait_const2str : array[ait_const_32bit..ait_const_8bit] of string[8]=
  245. (#9'.long'#9,#9'.short'#9,#9'.byte'#9);
  246. function ait_section2str(s:tsection):string;
  247. begin
  248. ait_section2str:=target_asm.secnames[s];
  249. {$ifdef GDB}
  250. { this is needed for line info in data }
  251. funcname:=nil;
  252. case s of
  253. sec_code : n_line:=n_textline;
  254. sec_data : n_line:=n_dataline;
  255. sec_bss : n_line:=n_bssline;
  256. else n_line:=n_dataline;
  257. end;
  258. {$endif GDB}
  259. LastSec:=s;
  260. end;
  261. {$ifdef GDB}
  262. procedure ti386attasmlist.WriteFileLineInfo(var fileinfo : tfileposinfo);
  263. var
  264. curr_n : byte;
  265. begin
  266. if not ((cs_debuginfo in aktmoduleswitches) or
  267. (cs_gdb_lineinfo in aktglobalswitches)) then
  268. exit;
  269. { file changed ? (must be before line info) }
  270. if (fileinfo.fileindex<>0) and
  271. (stabslastfileinfo.fileindex<>fileinfo.fileindex) then
  272. begin
  273. infile:=current_module^.sourcefiles^.get_file(fileinfo.fileindex);
  274. if assigned(infile) then
  275. begin
  276. if includecount=0 then
  277. curr_n:=n_sourcefile
  278. else
  279. curr_n:=n_includefile;
  280. if (infile^.path^<>'') then
  281. begin
  282. AsmWriteLn(#9'.stabs "'+lower(BsToSlash(FixPath(infile^.path^,false)))+'",'+
  283. tostr(curr_n)+',0,0,'+'Ltext'+ToStr(IncludeCount));
  284. end;
  285. AsmWriteLn(#9'.stabs "'+lower(FixFileName(infile^.name^))+'",'+
  286. tostr(curr_n)+',0,0,'+'Ltext'+ToStr(IncludeCount));
  287. AsmWriteLn('Ltext'+ToStr(IncludeCount)+':');
  288. inc(includecount);
  289. end;
  290. end;
  291. { line changed ? }
  292. if (stabslastfileinfo.line<>fileinfo.line) and (fileinfo.line<>0) then
  293. begin
  294. if (n_line=n_textline) and assigned(funcname) and
  295. (target_os.use_function_relative_addresses) then
  296. begin
  297. AsmWriteLn(target_asm.labelprefix+'l'+tostr(linecount)+':');
  298. AsmWrite(#9'.stabn '+tostr(n_line)+',0,'+tostr(fileinfo.line)+','+
  299. target_asm.labelprefix+'l'+tostr(linecount)+' - ');
  300. AsmWritePChar(FuncName);
  301. AsmLn;
  302. inc(linecount);
  303. end
  304. else
  305. AsmWriteLn(#9'.stabd'#9+tostr(n_line)+',0,'+tostr(fileinfo.line));
  306. end;
  307. stabslastfileinfo:=fileinfo;
  308. end;
  309. procedure ti386attasmlist.WriteFileEndInfo;
  310. begin
  311. if not ((cs_debuginfo in aktmoduleswitches) or
  312. (cs_gdb_lineinfo in aktglobalswitches)) then
  313. exit;
  314. AsmLn;
  315. AsmWriteLn(ait_section2str(sec_code));
  316. AsmWriteLn(#9'.stabs "",'+tostr(n_sourcefile)+',0,0,Letext');
  317. AsmWriteLn('Letext:');
  318. end;
  319. {$endif GDB}
  320. procedure ti386attasmlist.WriteTree(p:paasmoutput);
  321. const
  322. allocstr : array[boolean] of string[10]=(' released',' allocated');
  323. nolinetai =[ait_label,
  324. ait_regalloc,ait_tempalloc,
  325. ait_stabn,ait_stabs,ait_section,
  326. ait_cut,ait_marker,ait_align,ait_stab_function_name];
  327. type
  328. t80bitarray = array[0..9] of byte;
  329. t64bitarray = array[0..7] of byte;
  330. t32bitarray = array[0..3] of byte;
  331. var
  332. ch : char;
  333. hp : pai;
  334. consttyp : tait;
  335. s : string;
  336. found : boolean;
  337. i,pos,l : longint;
  338. InlineLevel : longint;
  339. co : comp;
  340. sin : single;
  341. d : double;
  342. e : extended;
  343. op : tasmop;
  344. calljmp,
  345. do_line : boolean;
  346. sep : char;
  347. begin
  348. if not assigned(p) then
  349. exit;
  350. InlineLevel:=0;
  351. { lineinfo is only needed for codesegment (PFV) }
  352. do_line:=(cs_asm_source in aktglobalswitches) or
  353. ((cs_lineinfo in aktmoduleswitches)
  354. and (p=codesegment));
  355. hp:=pai(p^.first);
  356. while assigned(hp) do
  357. begin
  358. aktfilepos:=hp^.fileinfo;
  359. if not(hp^.typ in nolinetai) then
  360. begin
  361. {$ifdef GDB}
  362. { write stabs }
  363. if (cs_debuginfo in aktmoduleswitches) or
  364. (cs_gdb_lineinfo in aktglobalswitches) then
  365. WriteFileLineInfo(hp^.fileinfo);
  366. {$endif GDB}
  367. if do_line then
  368. begin
  369. { load infile }
  370. if lastfileinfo.fileindex<>hp^.fileinfo.fileindex then
  371. begin
  372. infile:=current_module^.sourcefiles^.get_file(hp^.fileinfo.fileindex);
  373. if assigned(infile) then
  374. begin
  375. { open only if needed !! }
  376. if (cs_asm_source in aktglobalswitches) then
  377. infile^.open;
  378. end;
  379. { avoid unnecessary reopens of the same file !! }
  380. lastfileinfo.fileindex:=hp^.fileinfo.fileindex;
  381. { be sure to change line !! }
  382. lastfileinfo.line:=-1;
  383. end;
  384. { write source }
  385. if (cs_asm_source in aktglobalswitches) and
  386. assigned(infile) then
  387. begin
  388. if (infile<>lastinfile) then
  389. begin
  390. AsmWriteLn(target_asm.comment+'['+infile^.name^+']');
  391. if assigned(lastinfile) then
  392. lastinfile^.close;
  393. end;
  394. if (hp^.fileinfo.line<>lastfileinfo.line) and
  395. ((hp^.fileinfo.line<infile^.maxlinebuf) or (InlineLevel>0)) then
  396. begin
  397. if (hp^.fileinfo.line<>0) and
  398. ((infile^.linebuf^[hp^.fileinfo.line]>=0) or (InlineLevel>0)) then
  399. AsmWriteLn(target_asm.comment+'['+tostr(hp^.fileinfo.line)+'] '+
  400. fixline(infile^.GetLineStr(hp^.fileinfo.line)));
  401. { set it to a negative value !
  402. to make that is has been read already !! PM }
  403. if (infile^.linebuf^[hp^.fileinfo.line]>=0) then
  404. infile^.linebuf^[hp^.fileinfo.line]:=-infile^.linebuf^[hp^.fileinfo.line]-1;
  405. end;
  406. end;
  407. lastfileinfo:=hp^.fileinfo;
  408. lastinfile:=infile;
  409. end;
  410. end;
  411. case hp^.typ of
  412. ait_comment :
  413. Begin
  414. AsmWrite(target_asm.comment);
  415. AsmWritePChar(pai_asm_comment(hp)^.str);
  416. AsmLn;
  417. End;
  418. ait_regalloc :
  419. begin
  420. if (cs_asm_regalloc in aktglobalswitches) then
  421. AsmWriteLn(target_asm.comment+'Register '+att_reg2str[pairegalloc(hp)^.reg]+
  422. allocstr[pairegalloc(hp)^.allocation]);
  423. end;
  424. ait_tempalloc :
  425. begin
  426. if (cs_asm_tempalloc in aktglobalswitches) then
  427. AsmWriteLn(target_asm.comment+'Temp '+tostr(paitempalloc(hp)^.temppos)+','+
  428. tostr(paitempalloc(hp)^.tempsize)+allocstr[paitempalloc(hp)^.allocation]);
  429. end;
  430. ait_align :
  431. begin
  432. AsmWrite(#9'.balign '+tostr(pai_align(hp)^.aligntype));
  433. if pai_align(hp)^.use_op then
  434. AsmWrite(','+tostr(pai_align(hp)^.fillop));
  435. AsmLn;
  436. end;
  437. ait_section :
  438. begin
  439. if pai_section(hp)^.sec<>sec_none then
  440. begin
  441. AsmLn;
  442. AsmWriteLn(ait_section2str(pai_section(hp)^.sec));
  443. {$ifdef GDB}
  444. lastfileinfo.line:=-1;
  445. {$endif GDB}
  446. end;
  447. end;
  448. ait_datablock :
  449. begin
  450. if pai_datablock(hp)^.is_global then
  451. AsmWrite(#9'.comm'#9)
  452. else
  453. AsmWrite(#9'.lcomm'#9);
  454. AsmWrite(pai_datablock(hp)^.sym^.name);
  455. AsmWriteLn(','+tostr(pai_datablock(hp)^.size));
  456. end;
  457. ait_const_32bit,
  458. ait_const_16bit,
  459. ait_const_8bit :
  460. begin
  461. AsmWrite(ait_const2str[hp^.typ]+tostr(pai_const(hp)^.value));
  462. consttyp:=hp^.typ;
  463. l:=0;
  464. repeat
  465. found:=(not (Pai(hp^.next)=nil)) and (Pai(hp^.next)^.typ=consttyp);
  466. if found then
  467. begin
  468. hp:=Pai(hp^.next);
  469. s:=','+tostr(pai_const(hp)^.value);
  470. AsmWrite(s);
  471. inc(l,length(s));
  472. end;
  473. until (not found) or (l>line_length);
  474. AsmLn;
  475. end;
  476. ait_const_symbol :
  477. begin
  478. AsmWrite(#9'.long'#9+pai_const_symbol(hp)^.sym^.name);
  479. if pai_const_symbol(hp)^.offset>0 then
  480. AsmWrite('+'+tostr(pai_const_symbol(hp)^.offset))
  481. else if pai_const_symbol(hp)^.offset<0 then
  482. AsmWrite(tostr(pai_const_symbol(hp)^.offset));
  483. AsmLn;
  484. end;
  485. ait_const_rva :
  486. AsmWriteLn(#9'.rva'#9+pai_const_symbol(hp)^.sym^.name);
  487. ait_real_80bit :
  488. begin
  489. if do_line then
  490. AsmWriteLn(target_asm.comment+extended2str(pai_real_80bit(hp)^.value));
  491. { Make sure e is a extended type, bestreal could be
  492. a different type (bestreal) !! (PFV) }
  493. e:=pai_real_80bit(hp)^.value;
  494. AsmWrite(#9'.byte'#9);
  495. for i:=0 to 9 do
  496. begin
  497. if i<>0 then
  498. AsmWrite(',');
  499. AsmWrite(tostr(t80bitarray(e)[i]));
  500. end;
  501. AsmLn;
  502. end;
  503. ait_real_64bit :
  504. begin
  505. if do_line then
  506. AsmWriteLn(target_asm.comment+double2str(pai_real_64bit(hp)^.value));
  507. d:=pai_real_64bit(hp)^.value;
  508. AsmWrite(#9'.byte'#9);
  509. for i:=0 to 7 do
  510. begin
  511. if i<>0 then
  512. AsmWrite(',');
  513. AsmWrite(tostr(t64bitarray(d)[i]));
  514. end;
  515. AsmLn;
  516. end;
  517. ait_real_32bit :
  518. begin
  519. if do_line then
  520. AsmWriteLn(target_asm.comment+single2str(pai_real_32bit(hp)^.value));
  521. sin:=pai_real_32bit(hp)^.value;
  522. AsmWrite(#9'.byte'#9);
  523. for i:=0 to 3 do
  524. begin
  525. if i<>0 then
  526. AsmWrite(',');
  527. AsmWrite(tostr(t32bitarray(sin)[i]));
  528. end;
  529. AsmLn;
  530. end;
  531. ait_comp_64bit :
  532. begin
  533. if do_line then
  534. AsmWriteLn(target_asm.comment+comp2str(pai_comp_64bit(hp)^.value));
  535. AsmWrite(#9'.byte'#9);
  536. {$ifdef FPC}
  537. co:=comp(pai_comp_64bit(hp)^.value);
  538. {$else}
  539. co:=pai_comp_64bit(hp)^.value;
  540. {$endif}
  541. for i:=0 to 7 do
  542. begin
  543. if i<>0 then
  544. AsmWrite(',');
  545. AsmWrite(tostr(t64bitarray(co)[i]));
  546. end;
  547. AsmLn;
  548. end;
  549. ait_direct :
  550. begin
  551. AsmWritePChar(pai_direct(hp)^.str);
  552. AsmLn;
  553. {$IfDef GDB}
  554. if strpos(pai_direct(hp)^.str,'.data')<>nil then
  555. n_line:=n_dataline
  556. else if strpos(pai_direct(hp)^.str,'.text')<>nil then
  557. n_line:=n_textline
  558. else if strpos(pai_direct(hp)^.str,'.bss')<>nil then
  559. n_line:=n_bssline;
  560. {$endif GDB}
  561. end;
  562. ait_string :
  563. begin
  564. pos:=0;
  565. for i:=1 to pai_string(hp)^.len do
  566. begin
  567. if pos=0 then
  568. begin
  569. AsmWrite(#9'.ascii'#9'"');
  570. pos:=20;
  571. end;
  572. ch:=pai_string(hp)^.str[i-1];
  573. case ch of
  574. #0, {This can't be done by range, because a bug in FPC}
  575. #1..#31,
  576. #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  577. '"' : s:='\"';
  578. '\' : s:='\\';
  579. else
  580. s:=ch;
  581. end;
  582. AsmWrite(s);
  583. inc(pos,length(s));
  584. if (pos>line_length) or (i=pai_string(hp)^.len) then
  585. begin
  586. AsmWriteLn('"');
  587. pos:=0;
  588. end;
  589. end;
  590. end;
  591. ait_label :
  592. begin
  593. if (pai_label(hp)^.l^.is_used) then
  594. begin
  595. if pai_label(hp)^.l^.defbind=AB_GLOBAL then
  596. begin
  597. AsmWrite('.globl'#9);
  598. AsmWriteLn(pai_label(hp)^.l^.name);
  599. end;
  600. AsmWrite(pai_label(hp)^.l^.name);
  601. AsmWriteLn(':');
  602. end;
  603. end;
  604. ait_symbol :
  605. begin
  606. if pai_symbol(hp)^.is_global then
  607. begin
  608. AsmWrite('.globl'#9);
  609. AsmWriteLn(pai_symbol(hp)^.sym^.name);
  610. end;
  611. if target_info.target=target_i386_linux then
  612. begin
  613. AsmWrite(#9'.type'#9);
  614. AsmWrite(pai_symbol(hp)^.sym^.name);
  615. if assigned(pai(hp^.next)) and
  616. (pai(hp^.next)^.typ in [ait_const_symbol,ait_const_rva,
  617. ait_const_32bit,ait_const_16bit,ait_const_8bit,ait_datablock,
  618. ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit]) then
  619. AsmWriteLn(',@object')
  620. else
  621. AsmWriteLn(',@function');
  622. if pai_symbol(hp)^.sym^.size>0 then
  623. begin
  624. AsmWrite(#9'.size'#9);
  625. AsmWrite(pai_symbol(hp)^.sym^.name);
  626. AsmWrite(', ');
  627. AsmWriteLn(tostr(pai_symbol(hp)^.sym^.size));
  628. end;
  629. end;
  630. AsmWrite(pai_symbol(hp)^.sym^.name);
  631. AsmWriteLn(':');
  632. end;
  633. ait_symbol_end :
  634. begin
  635. if target_info.target=target_i386_linux then
  636. begin
  637. s:=target_asm.labelprefix+'e'+tostr(symendcount);
  638. inc(symendcount);
  639. AsmWriteLn(s+':');
  640. AsmWrite(#9'.size'#9);
  641. AsmWrite(pai_symbol(hp)^.sym^.name);
  642. AsmWrite(', '+s+' - ');
  643. AsmWriteLn(pai_symbol(hp)^.sym^.name);
  644. end;
  645. end;
  646. ait_instruction :
  647. begin
  648. op:=paicpu(hp)^.opcode;
  649. calljmp:=is_calljmp(op);
  650. { call maybe not translated to call }
  651. s:=#9+att_op2str[op]+cond2str[paicpu(hp)^.condition];
  652. { suffix needed ? fnstsw,fldcw don't support suffixes
  653. with binutils 2.9.5 under linux }
  654. if (not calljmp) and
  655. (att_needsuffix[op]<>AttSufNONE) and
  656. (op<>A_FNSTSW) and (op<>A_FSTSW) and
  657. (op<>A_FNSTCW) and (op<>A_FSTCW) and
  658. (op<>A_FLDCW) and
  659. not(
  660. (paicpu(hp)^.oper[0].typ=top_reg) and
  661. (paicpu(hp)^.oper[0].reg in [R_ST..R_ST7])
  662. ) then
  663. s:=s+att_opsize2str[paicpu(hp)^.opsize];
  664. { process operands }
  665. if paicpu(hp)^.ops<>0 then
  666. begin
  667. { call and jmp need an extra handling }
  668. { this code is only called if jmp isn't a labeled instruction }
  669. { quick hack to overcome a problem with manglednames=255 chars }
  670. if calljmp then
  671. begin
  672. AsmWrite(s+#9);
  673. s:=getopstr_jmp(paicpu(hp)^.oper[0]);
  674. end
  675. else
  676. begin
  677. for i:=0 to paicpu(hp)^.ops-1 do
  678. begin
  679. if i=0 then
  680. sep:=#9
  681. else
  682. sep:=',';
  683. s:=s+sep+getopstr(paicpu(hp)^.oper[i])
  684. end;
  685. end;
  686. end;
  687. AsmWriteLn(s);
  688. end;
  689. {$ifdef GDB}
  690. ait_stabs :
  691. begin
  692. AsmWrite(#9'.stabs ');
  693. AsmWritePChar(pai_stabs(hp)^.str);
  694. AsmLn;
  695. end;
  696. ait_stabn :
  697. begin
  698. AsmWrite(#9'.stabn ');
  699. AsmWritePChar(pai_stabn(hp)^.str);
  700. AsmLn;
  701. end;
  702. ait_force_line :
  703. stabslastfileinfo.line:=0;
  704. ait_stab_function_name:
  705. funcname:=pai_stab_function_name(hp)^.str;
  706. {$endif GDB}
  707. ait_cut :
  708. begin
  709. if SmartAsm then
  710. begin
  711. { only reset buffer if nothing has changed }
  712. if AsmSize=AsmStartSize then
  713. AsmClear
  714. else
  715. begin
  716. AsmClose;
  717. DoAssemble;
  718. AsmCreate(pai_cut(hp)^.place);
  719. end;
  720. { avoid empty files }
  721. while assigned(hp^.next) and (pai(hp^.next)^.typ in [ait_cut,ait_section,ait_comment]) do
  722. begin
  723. if pai(hp^.next)^.typ=ait_section then
  724. lastsec:=pai_section(hp^.next)^.sec;
  725. hp:=pai(hp^.next);
  726. end;
  727. {$ifdef GDB}
  728. { force write of filename }
  729. FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
  730. includecount:=0;
  731. funcname:=nil;
  732. WriteFileLineInfo(hp^.fileinfo);
  733. {$endif GDB}
  734. if lastsec<>sec_none then
  735. AsmWriteLn(ait_section2str(lastsec));
  736. AsmStartSize:=AsmSize;
  737. end;
  738. end;
  739. ait_marker :
  740. if pai_marker(hp)^.kind=InlineStart then
  741. inc(InlineLevel)
  742. else if pai_marker(hp)^.kind=InlineEnd then
  743. dec(InlineLevel);
  744. else
  745. internalerror(10000);
  746. end;
  747. hp:=pai(hp^.next);
  748. end;
  749. end;
  750. procedure ti386attasmlist.WriteAsmList;
  751. var
  752. p:dirstr;
  753. n:namestr;
  754. e:extstr;
  755. {$ifdef GDB}
  756. fileinfo : tfileposinfo;
  757. {$endif GDB}
  758. begin
  759. {$ifdef EXTDEBUG}
  760. if assigned(current_module^.mainsource) then
  761. Comment(v_info,'Start writing att-styled assembler output for '+current_module^.mainsource^);
  762. {$endif}
  763. LastSec:=sec_none;
  764. {$ifdef GDB}
  765. FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
  766. {$endif GDB}
  767. FillChar(lastfileinfo,sizeof(lastfileinfo),0);
  768. LastInfile:=nil;
  769. if assigned(current_module^.mainsource) then
  770. fsplit(current_module^.mainsource^,p,n,e)
  771. else
  772. begin
  773. p:=inputdir;
  774. n:=inputfile;
  775. e:=inputextension;
  776. end;
  777. { to get symify to work }
  778. AsmWriteLn(#9'.file "'+FixFileName(n+e)+'"');
  779. {$ifdef GDB}
  780. n_line:=n_bssline;
  781. funcname:=nil;
  782. linecount:=1;
  783. includecount:=0;
  784. fileinfo.fileindex:=1;
  785. fileinfo.line:=1;
  786. { Write main file }
  787. WriteFileLineInfo(fileinfo);
  788. {$endif GDB}
  789. AsmStartSize:=AsmSize;
  790. symendcount:=0;
  791. countlabelref:=false;
  792. If (cs_debuginfo in aktmoduleswitches) then
  793. WriteTree(debuglist);
  794. WriteTree(codesegment);
  795. WriteTree(datasegment);
  796. WriteTree(consts);
  797. WriteTree(rttilist);
  798. Writetree(resourcestringlist);
  799. WriteTree(bsssegment);
  800. Writetree(importssection);
  801. { exports are written by DLLTOOL
  802. if we use it so don't insert it twice (PM) }
  803. if not UseDeffileForExport and assigned(exportssection) then
  804. Writetree(exportssection);
  805. Writetree(resourcesection);
  806. {$ifdef GDB}
  807. WriteFileEndInfo;
  808. {$ENDIF}
  809. countlabelref:=true;
  810. AsmLn;
  811. {$ifdef EXTDEBUG}
  812. if assigned(current_module^.mainsource) then
  813. comment(v_info,'Done writing att-styled assembler output for '+current_module^.mainsource^);
  814. {$endif EXTDEBUG}
  815. end;
  816. end.
  817. {
  818. $Log$
  819. Revision 1.6 2000-09-24 15:06:10 peter
  820. * use defines.inc
  821. Revision 1.5 2000/08/27 16:11:49 peter
  822. * moved some util functions from globals,cobjects to cutils
  823. * splitted files into finput,fmodule
  824. Revision 1.4 2000/08/20 17:38:21 peter
  825. * smartlinking fixed for linux (merged)
  826. Revision 1.3 2000/07/13 12:08:24 michael
  827. + patched to 1.1.0 with former 1.09patch from peter
  828. Revision 1.2 2000/07/13 11:32:28 michael
  829. + removed logs
  830. }