ag386att.pas 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957
  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. {$ifdef TP}
  19. {$N+,E+}
  20. {$endif}
  21. unit ag386att;
  22. interface
  23. uses cobjects,aasm,assemble;
  24. type
  25. pi386attasmlist=^ti386attasmlist;
  26. ti386attasmlist=object(tasmlist)
  27. procedure WriteTree(p:paasmoutput);virtual;
  28. procedure WriteAsmList;virtual;
  29. {$ifdef GDB}
  30. procedure WriteFileLineInfo(var fileinfo : tfileposinfo);
  31. {$endif}
  32. end;
  33. implementation
  34. uses
  35. {$ifdef Delphi}
  36. dmisc,
  37. {$else Delphi}
  38. dos,
  39. {$endif Delphi}
  40. strings,
  41. globtype,globals,systems,
  42. files,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) then
  267. exit;
  268. { file changed ? (must be before line info) }
  269. if (fileinfo.fileindex<>0) and
  270. (stabslastfileinfo.fileindex<>fileinfo.fileindex) then
  271. begin
  272. infile:=current_module^.sourcefiles^.get_file(fileinfo.fileindex);
  273. if assigned(infile) then
  274. begin
  275. if includecount=0 then
  276. curr_n:=n_sourcefile
  277. else
  278. curr_n:=n_includefile;
  279. if (infile^.path^<>'') then
  280. begin
  281. AsmWriteLn(#9'.stabs "'+lower(BsToSlash(FixPath(infile^.path^,false)))+'",'+
  282. tostr(curr_n)+',0,0,'+'Ltext'+ToStr(IncludeCount));
  283. end;
  284. AsmWriteLn(#9'.stabs "'+lower(FixFileName(infile^.name^))+'",'+
  285. tostr(curr_n)+',0,0,'+'Ltext'+ToStr(IncludeCount));
  286. AsmWriteLn('Ltext'+ToStr(IncludeCount)+':');
  287. inc(includecount);
  288. end;
  289. end;
  290. { line changed ? }
  291. if (stabslastfileinfo.line<>fileinfo.line) and (fileinfo.line<>0) then
  292. begin
  293. if (n_line=n_textline) and assigned(funcname) and
  294. (target_os.use_function_relative_addresses) then
  295. begin
  296. AsmWriteLn(target_asm.labelprefix+'l'+tostr(linecount)+':');
  297. AsmWrite(#9'.stabn '+tostr(n_line)+',0,'+tostr(fileinfo.line)+','+
  298. target_asm.labelprefix+'l'+tostr(linecount)+' - ');
  299. AsmWritePChar(FuncName);
  300. AsmLn;
  301. inc(linecount);
  302. end
  303. else
  304. AsmWriteLn(#9'.stabd'#9+tostr(n_line)+',0,'+tostr(fileinfo.line));
  305. end;
  306. stabslastfileinfo:=fileinfo;
  307. end;
  308. {$endif GDB}
  309. procedure ti386attasmlist.WriteTree(p:paasmoutput);
  310. const
  311. allocstr : array[boolean] of string[10]=(' released',' allocated');
  312. nolinetai =[ait_label,
  313. ait_regalloc,ait_tempalloc,
  314. ait_stabn,ait_stabs,ait_section,
  315. ait_cut,ait_marker,ait_align,ait_stab_function_name];
  316. type
  317. t80bitarray = array[0..9] of byte;
  318. t64bitarray = array[0..7] of byte;
  319. t32bitarray = array[0..3] of byte;
  320. var
  321. ch : char;
  322. hp : pai;
  323. consttyp : tait;
  324. s : string;
  325. found : boolean;
  326. i,pos,l : longint;
  327. co : comp;
  328. sin : single;
  329. d : double;
  330. e : extended;
  331. op : tasmop;
  332. calljmp,
  333. do_line : boolean;
  334. sep : char;
  335. begin
  336. if not assigned(p) then
  337. exit;
  338. { lineinfo is only needed for codesegment (PFV) }
  339. do_line:=(cs_asm_source in aktglobalswitches) or
  340. ((cs_lineinfo in aktmoduleswitches) and (p=codesegment));
  341. hp:=pai(p^.first);
  342. while assigned(hp) do
  343. begin
  344. aktfilepos:=hp^.fileinfo;
  345. if not(hp^.typ in nolinetai) then
  346. begin
  347. {$ifdef GDB}
  348. { write stabs }
  349. if cs_debuginfo in aktmoduleswitches then
  350. WriteFileLineInfo(hp^.fileinfo);
  351. {$endif GDB}
  352. if do_line then
  353. begin
  354. { load infile }
  355. if lastfileinfo.fileindex<>hp^.fileinfo.fileindex then
  356. begin
  357. infile:=current_module^.sourcefiles^.get_file(hp^.fileinfo.fileindex);
  358. if assigned(infile) then
  359. begin
  360. { open only if needed !! }
  361. if (cs_asm_source in aktglobalswitches) then
  362. infile^.open;
  363. end;
  364. { avoid unnecessary reopens of the same file !! }
  365. lastfileinfo.fileindex:=hp^.fileinfo.fileindex;
  366. { be sure to change line !! }
  367. lastfileinfo.line:=-1;
  368. end;
  369. { write source }
  370. if (cs_asm_source in aktglobalswitches) and
  371. assigned(infile) then
  372. begin
  373. if (infile<>lastinfile) then
  374. begin
  375. AsmWriteLn(target_asm.comment+'['+infile^.name^+']');
  376. if assigned(lastinfile) then
  377. lastinfile^.close;
  378. end;
  379. if (hp^.fileinfo.line<>lastfileinfo.line) and
  380. (hp^.fileinfo.line<infile^.maxlinebuf) then
  381. begin
  382. if (hp^.fileinfo.line<>0) and
  383. (infile^.linebuf^[hp^.fileinfo.line]>=0) then
  384. AsmWriteLn(target_asm.comment+'['+tostr(hp^.fileinfo.line)+'] '+
  385. fixline(infile^.GetLineStr(hp^.fileinfo.line)));
  386. { set it to a negative value !
  387. to make that is has been read already !! PM }
  388. infile^.linebuf^[hp^.fileinfo.line]:=-infile^.linebuf^[hp^.fileinfo.line]-1;
  389. end;
  390. end;
  391. {$ifdef LINEINFO}
  392. { lineinfo }
  393. if (cs_lineinfo in aktmoduleswitches) then
  394. begin
  395. if (infile<>lastinfile) then
  396. begin
  397. lineinfolist^.concat(new(pai_const(init_8bit
  398. end
  399. else
  400. begin
  401. end;
  402. end;
  403. {$endif LINEINFO}
  404. lastfileinfo:=hp^.fileinfo;
  405. lastinfile:=infile;
  406. end;
  407. end;
  408. case hp^.typ of
  409. ait_comment :
  410. Begin
  411. AsmWrite(target_asm.comment);
  412. AsmWritePChar(pai_asm_comment(hp)^.str);
  413. AsmLn;
  414. End;
  415. ait_regalloc :
  416. begin
  417. if (cs_asm_regalloc in aktglobalswitches) then
  418. AsmWriteLn(target_asm.comment+'Register '+att_reg2str[pairegalloc(hp)^.reg]+
  419. allocstr[pairegalloc(hp)^.allocation]);
  420. end;
  421. ait_tempalloc :
  422. begin
  423. if (cs_asm_tempalloc in aktglobalswitches) then
  424. AsmWriteLn(target_asm.comment+'Temp '+tostr(paitempalloc(hp)^.temppos)+','+
  425. tostr(paitempalloc(hp)^.tempsize)+allocstr[paitempalloc(hp)^.allocation]);
  426. end;
  427. ait_align :
  428. begin
  429. AsmWrite(#9'.balign '+tostr(pai_align(hp)^.aligntype));
  430. if pai_align(hp)^.use_op then
  431. AsmWrite(','+tostr(pai_align(hp)^.fillop));
  432. AsmLn;
  433. end;
  434. ait_section :
  435. begin
  436. if pai_section(hp)^.sec<>sec_none then
  437. begin
  438. AsmLn;
  439. AsmWriteLn(ait_section2str(pai_section(hp)^.sec));
  440. {$ifdef GDB}
  441. lastfileinfo.line:=-1;
  442. {$endif GDB}
  443. end;
  444. end;
  445. ait_datablock :
  446. begin
  447. if pai_datablock(hp)^.is_global then
  448. AsmWrite(#9'.comm'#9)
  449. else
  450. AsmWrite(#9'.lcomm'#9);
  451. AsmWrite(pai_datablock(hp)^.sym^.name);
  452. AsmWriteLn(','+tostr(pai_datablock(hp)^.size));
  453. end;
  454. ait_const_32bit,
  455. ait_const_16bit,
  456. ait_const_8bit :
  457. begin
  458. AsmWrite(ait_const2str[hp^.typ]+tostr(pai_const(hp)^.value));
  459. consttyp:=hp^.typ;
  460. l:=0;
  461. repeat
  462. found:=(not (Pai(hp^.next)=nil)) and (Pai(hp^.next)^.typ=consttyp);
  463. if found then
  464. begin
  465. hp:=Pai(hp^.next);
  466. s:=','+tostr(pai_const(hp)^.value);
  467. AsmWrite(s);
  468. inc(l,length(s));
  469. end;
  470. until (not found) or (l>line_length);
  471. AsmLn;
  472. end;
  473. ait_const_symbol :
  474. begin
  475. AsmWrite(#9'.long'#9+pai_const_symbol(hp)^.sym^.name);
  476. if pai_const_symbol(hp)^.offset>0 then
  477. AsmWrite('+'+tostr(pai_const_symbol(hp)^.offset))
  478. else if pai_const_symbol(hp)^.offset<0 then
  479. AsmWrite(tostr(pai_const_symbol(hp)^.offset));
  480. AsmLn;
  481. end;
  482. ait_const_rva :
  483. AsmWriteLn(#9'.rva'#9+pai_const_symbol(hp)^.sym^.name);
  484. ait_real_80bit :
  485. begin
  486. if do_line then
  487. AsmWriteLn(target_asm.comment+extended2str(pai_real_80bit(hp)^.value));
  488. { Make sure e is a extended type, bestreal could be
  489. a different type (bestreal) !! (PFV) }
  490. e:=pai_real_80bit(hp)^.value;
  491. AsmWrite(#9'.byte'#9);
  492. for i:=0 to 9 do
  493. begin
  494. if i<>0 then
  495. AsmWrite(',');
  496. AsmWrite(tostr(t80bitarray(e)[i]));
  497. end;
  498. AsmLn;
  499. end;
  500. ait_real_64bit :
  501. begin
  502. if do_line then
  503. AsmWriteLn(target_asm.comment+double2str(pai_real_64bit(hp)^.value));
  504. d:=pai_real_64bit(hp)^.value;
  505. AsmWrite(#9'.byte'#9);
  506. for i:=0 to 7 do
  507. begin
  508. if i<>0 then
  509. AsmWrite(',');
  510. AsmWrite(tostr(t64bitarray(d)[i]));
  511. end;
  512. AsmLn;
  513. end;
  514. ait_real_32bit :
  515. begin
  516. if do_line then
  517. AsmWriteLn(target_asm.comment+single2str(pai_real_32bit(hp)^.value));
  518. sin:=pai_real_32bit(hp)^.value;
  519. AsmWrite(#9'.byte'#9);
  520. for i:=0 to 3 do
  521. begin
  522. if i<>0 then
  523. AsmWrite(',');
  524. AsmWrite(tostr(t32bitarray(sin)[i]));
  525. end;
  526. AsmLn;
  527. end;
  528. ait_comp_64bit :
  529. begin
  530. if do_line then
  531. AsmWriteLn(target_asm.comment+comp2str(pai_comp_64bit(hp)^.value));
  532. AsmWrite(#9'.byte'#9);
  533. {$ifdef FPC}
  534. co:=comp(pai_comp_64bit(hp)^.value);
  535. {$else}
  536. co:=pai_comp_64bit(hp)^.value;
  537. {$endif}
  538. for i:=0 to 7 do
  539. begin
  540. if i<>0 then
  541. AsmWrite(',');
  542. AsmWrite(tostr(t64bitarray(co)[i]));
  543. end;
  544. AsmLn;
  545. end;
  546. ait_direct :
  547. begin
  548. AsmWritePChar(pai_direct(hp)^.str);
  549. AsmLn;
  550. {$IfDef GDB}
  551. if strpos(pai_direct(hp)^.str,'.data')<>nil then
  552. n_line:=n_dataline
  553. else if strpos(pai_direct(hp)^.str,'.text')<>nil then
  554. n_line:=n_textline
  555. else if strpos(pai_direct(hp)^.str,'.bss')<>nil then
  556. n_line:=n_bssline;
  557. {$endif GDB}
  558. end;
  559. ait_string :
  560. begin
  561. pos:=0;
  562. for i:=1 to pai_string(hp)^.len do
  563. begin
  564. if pos=0 then
  565. begin
  566. AsmWrite(#9'.ascii'#9'"');
  567. pos:=20;
  568. end;
  569. ch:=pai_string(hp)^.str[i-1];
  570. case ch of
  571. #0, {This can't be done by range, because a bug in FPC}
  572. #1..#31,
  573. #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  574. '"' : s:='\"';
  575. '\' : s:='\\';
  576. else
  577. s:=ch;
  578. end;
  579. AsmWrite(s);
  580. inc(pos,length(s));
  581. if (pos>line_length) or (i=pai_string(hp)^.len) then
  582. begin
  583. AsmWriteLn('"');
  584. pos:=0;
  585. end;
  586. end;
  587. end;
  588. ait_label :
  589. begin
  590. if (pai_label(hp)^.l^.is_used) then
  591. begin
  592. if pai_label(hp)^.l^.typ=AS_GLOBAL then
  593. begin
  594. AsmWrite('.globl'#9);
  595. AsmWriteLn(pai_label(hp)^.l^.name);
  596. end;
  597. AsmWrite(pai_label(hp)^.l^.name);
  598. AsmWriteLn(':');
  599. end;
  600. end;
  601. ait_symbol :
  602. begin
  603. if pai_symbol(hp)^.is_global then
  604. begin
  605. AsmWrite('.globl'#9);
  606. AsmWriteLn(pai_symbol(hp)^.sym^.name);
  607. end;
  608. if target_info.target=target_i386_linux then
  609. begin
  610. AsmWrite(#9'.type'#9);
  611. AsmWrite(pai_symbol(hp)^.sym^.name);
  612. if assigned(pai(hp^.next)) and
  613. (pai(hp^.next)^.typ in [ait_const_symbol,ait_const_rva,
  614. ait_const_32bit,ait_const_16bit,ait_const_8bit,ait_datablock,
  615. ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit]) then
  616. AsmWriteLn(',@object')
  617. else
  618. AsmWriteLn(',@function');
  619. if pai_symbol(hp)^.sym^.size>0 then
  620. begin
  621. AsmWrite(#9'.size'#9);
  622. AsmWrite(pai_symbol(hp)^.sym^.name);
  623. AsmWrite(', ');
  624. AsmWriteLn(tostr(pai_symbol(hp)^.sym^.size));
  625. end;
  626. end;
  627. AsmWrite(pai_symbol(hp)^.sym^.name);
  628. AsmWriteLn(':');
  629. end;
  630. ait_symbol_end :
  631. begin
  632. if target_info.target=target_i386_linux then
  633. begin
  634. s:=target_asm.labelprefix+'e'+tostr(symendcount);
  635. inc(symendcount);
  636. AsmWriteLn(s+':');
  637. AsmWrite(#9'.size'#9);
  638. AsmWrite(pai_symbol(hp)^.sym^.name);
  639. AsmWrite(', '+s+' - ');
  640. AsmWriteLn(pai_symbol(hp)^.sym^.name);
  641. end;
  642. end;
  643. ait_instruction :
  644. begin
  645. op:=paicpu(hp)^.opcode;
  646. calljmp:=is_calljmp(op);
  647. { call maybe not translated to call }
  648. s:=#9+att_op2str[op]+cond2str[paicpu(hp)^.condition];
  649. if (not calljmp) and
  650. (att_needsuffix[op]) and
  651. not(
  652. (paicpu(hp)^.oper[0].typ=top_reg) and
  653. (paicpu(hp)^.oper[0].reg in [R_ST..R_ST7])
  654. ) then
  655. s:=s+att_opsize2str[paicpu(hp)^.opsize];
  656. { process operands }
  657. if paicpu(hp)^.ops<>0 then
  658. begin
  659. { call and jmp need an extra handling }
  660. { this code is only called if jmp isn't a labeled instruction }
  661. { quick hack to overcome a problem with manglednames=255 chars }
  662. if calljmp then
  663. begin
  664. AsmWrite(s+#9);
  665. s:=+getopstr_jmp(paicpu(hp)^.oper[0]);
  666. end
  667. else
  668. begin
  669. for i:=0 to paicpu(hp)^.ops-1 do
  670. begin
  671. if i=0 then
  672. sep:=#9
  673. else
  674. sep:=',';
  675. s:=s+sep+getopstr(paicpu(hp)^.oper[i])
  676. end;
  677. end;
  678. end;
  679. AsmWriteLn(s);
  680. end;
  681. {$ifdef GDB}
  682. ait_stabs :
  683. begin
  684. AsmWrite(#9'.stabs ');
  685. AsmWritePChar(pai_stabs(hp)^.str);
  686. AsmLn;
  687. end;
  688. ait_stabn :
  689. begin
  690. AsmWrite(#9'.stabn ');
  691. AsmWritePChar(pai_stabn(hp)^.str);
  692. AsmLn;
  693. end;
  694. ait_force_line :
  695. stabslastfileinfo.line:=0;
  696. ait_stab_function_name:
  697. funcname:=pai_stab_function_name(hp)^.str;
  698. {$endif GDB}
  699. ait_cut :
  700. begin
  701. if SmartAsm then
  702. begin
  703. { only reset buffer if nothing has changed }
  704. if AsmSize=AsmStartSize then
  705. AsmClear
  706. else
  707. begin
  708. AsmClose;
  709. DoAssemble;
  710. AsmCreate(pai_cut(hp)^.place);
  711. end;
  712. { avoid empty files }
  713. while assigned(hp^.next) and (pai(hp^.next)^.typ in [ait_cut,ait_section,ait_comment]) do
  714. begin
  715. if pai(hp^.next)^.typ=ait_section then
  716. lastsec:=pai_section(hp^.next)^.sec;
  717. hp:=pai(hp^.next);
  718. end;
  719. {$ifdef GDB}
  720. { force write of filename }
  721. FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
  722. includecount:=0;
  723. funcname:=nil;
  724. WriteFileLineInfo(hp^.fileinfo);
  725. {$endif GDB}
  726. if lastsec<>sec_none then
  727. AsmWriteLn(ait_section2str(lastsec));
  728. AsmStartSize:=AsmSize;
  729. end;
  730. end;
  731. ait_marker :
  732. ;
  733. else
  734. internalerror(10000);
  735. end;
  736. hp:=pai(hp^.next);
  737. end;
  738. end;
  739. procedure ti386attasmlist.WriteAsmList;
  740. var
  741. p:dirstr;
  742. n:namestr;
  743. e:extstr;
  744. {$ifdef GDB}
  745. fileinfo : tfileposinfo;
  746. {$endif GDB}
  747. begin
  748. {$ifdef EXTDEBUG}
  749. if assigned(current_module^.mainsource) then
  750. Comment(v_info,'Start writing att-styled assembler output for '+current_module^.mainsource^);
  751. {$endif}
  752. LastSec:=sec_none;
  753. {$ifdef GDB}
  754. FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
  755. {$endif GDB}
  756. FillChar(lastfileinfo,sizeof(lastfileinfo),0);
  757. LastInfile:=nil;
  758. if assigned(current_module^.mainsource) then
  759. fsplit(current_module^.mainsource^,p,n,e)
  760. else
  761. begin
  762. p:=inputdir;
  763. n:=inputfile;
  764. e:=inputextension;
  765. end;
  766. { to get symify to work }
  767. AsmWriteLn(#9'.file "'+FixFileName(n+e)+'"');
  768. {$ifdef GDB}
  769. n_line:=n_bssline;
  770. funcname:=nil;
  771. linecount:=1;
  772. includecount:=0;
  773. fileinfo.fileindex:=1;
  774. fileinfo.line:=1;
  775. { Write main file }
  776. WriteFileLineInfo(fileinfo);
  777. {$endif GDB}
  778. AsmStartSize:=AsmSize;
  779. symendcount:=0;
  780. countlabelref:=false;
  781. If (cs_debuginfo in aktmoduleswitches) then
  782. WriteTree(debuglist);
  783. WriteTree(codesegment);
  784. WriteTree(datasegment);
  785. WriteTree(consts);
  786. WriteTree(rttilist);
  787. Writetree(resourcestringlist);
  788. WriteTree(bsssegment);
  789. Writetree(importssection);
  790. { exports are written by DLLTOOL
  791. if we use it so don't insert it twice (PM) }
  792. if not UseDeffileForExport and assigned(exportssection) then
  793. Writetree(exportssection);
  794. Writetree(resourcesection);
  795. countlabelref:=true;
  796. AsmLn;
  797. {$ifdef EXTDEBUG}
  798. if assigned(current_module^.mainsource) then
  799. comment(v_info,'Done writing att-styled assembler output for '+current_module^.mainsource^);
  800. {$endif EXTDEBUG}
  801. end;
  802. end.
  803. {
  804. $Log$
  805. Revision 1.23 2000-01-07 01:14:18 peter
  806. * updated copyright to 2000
  807. Revision 1.22 1999/12/18 20:00:33 florian
  808. * Bug reported by Marco fixed: Intel assembler reader: fld qword ptr x
  809. was read as fldq x but it must be fldl x
  810. Revision 1.21 1999/12/08 10:39:59 pierre
  811. + allow use of unit var in exports of DLL for win32
  812. by using direct export writing by default instead of use of DEFFILE
  813. that does not allow assembler labels that do not
  814. start with an underscore.
  815. Use -WD to force use of Deffile for Win32 DLL
  816. Revision 1.20 1999/11/06 14:34:16 peter
  817. * truncated log to 20 revs
  818. Revision 1.19 1999/11/02 15:06:56 peter
  819. * import library fixes for win32
  820. * alignment works again
  821. Revision 1.18 1999/10/27 16:11:28 peter
  822. * insns.dat is used to generate all i386*.inc files
  823. Revision 1.17 1999/09/27 23:36:33 peter
  824. * fixed -al with macro's
  825. Revision 1.16 1999/09/21 20:53:21 florian
  826. * fixed 1/s problem from mailing list
  827. Revision 1.15 1999/09/19 20:55:11 florian
  828. * fixed calls to procedures with manglednames=255 chars
  829. (taking the address of such a procedure would still cause a problem!)
  830. Revision 1.14 1999/09/10 18:48:00 florian
  831. * some bug fixes (e.g. must_be_valid and procinfo.funcret_is_valid)
  832. * most things for stored properties fixed
  833. Revision 1.13 1999/09/02 17:07:38 florian
  834. * problems with -Or fixed: tdef.isfpuregable was wrong!
  835. Revision 1.12 1999/08/25 16:03:46 peter
  836. * symbol name is now written using separate asmwrite() calls to overcome
  837. > 255 char strings
  838. Revision 1.11 1999/08/25 11:59:32 jonas
  839. * changed pai386, paippc and paiapha (same for tai*) to paicpu (taicpu)
  840. Revision 1.10 1999/08/13 15:44:57 peter
  841. * first things to include lineinfo in the executable
  842. Revision 1.9 1999/08/10 12:26:20 pierre
  843. * avoid double .edata section if using DLLTOOL
  844. Revision 1.8 1999/08/04 00:22:34 florian
  845. * renamed i386asm and i386base to cpuasm and cpubase
  846. Revision 1.7 1999/07/30 12:26:07 peter
  847. * write .size only for linux
  848. Revision 1.6 1999/07/29 20:53:56 peter
  849. * write .size also
  850. Revision 1.5 1999/07/22 09:37:29 florian
  851. + resourcestring implemented
  852. + start of longstring support
  853. Revision 1.4 1999/07/18 10:19:38 florian
  854. * made it compilable with Dlephi 4 again
  855. + fixed problem with large stack allocations on win32
  856. Revision 1.3 1999/07/03 00:27:04 peter
  857. * better smartlinking support
  858. Revision 1.2 1999/06/22 15:25:14 peter
  859. * merged
  860. Revision 1.1.2.1 1999/06/22 15:23:08 peter
  861. * reinserted
  862. Revision 1.100 1999/06/22 14:41:20 peter
  863. * merged
  864. }