ag386att.pas 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943
  1. {
  2. $Id$
  3. Copyright (c) 1996-98 by the FPC development team
  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 RelocSection 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.20 1999-11-06 14:34:16 peter
  806. * truncated log to 20 revs
  807. Revision 1.19 1999/11/02 15:06:56 peter
  808. * import library fixes for win32
  809. * alignment works again
  810. Revision 1.18 1999/10/27 16:11:28 peter
  811. * insns.dat is used to generate all i386*.inc files
  812. Revision 1.17 1999/09/27 23:36:33 peter
  813. * fixed -al with macro's
  814. Revision 1.16 1999/09/21 20:53:21 florian
  815. * fixed 1/s problem from mailing list
  816. Revision 1.15 1999/09/19 20:55:11 florian
  817. * fixed calls to procedures with manglednames=255 chars
  818. (taking the address of such a procedure would still cause a problem!)
  819. Revision 1.14 1999/09/10 18:48:00 florian
  820. * some bug fixes (e.g. must_be_valid and procinfo.funcret_is_valid)
  821. * most things for stored properties fixed
  822. Revision 1.13 1999/09/02 17:07:38 florian
  823. * problems with -Or fixed: tdef.isfpuregable was wrong!
  824. Revision 1.12 1999/08/25 16:03:46 peter
  825. * symbol name is now written using separate asmwrite() calls to overcome
  826. > 255 char strings
  827. Revision 1.11 1999/08/25 11:59:32 jonas
  828. * changed pai386, paippc and paiapha (same for tai*) to paicpu (taicpu)
  829. Revision 1.10 1999/08/13 15:44:57 peter
  830. * first things to include lineinfo in the executable
  831. Revision 1.9 1999/08/10 12:26:20 pierre
  832. * avoid double .edata section if using DLLTOOL
  833. Revision 1.8 1999/08/04 00:22:34 florian
  834. * renamed i386asm and i386base to cpuasm and cpubase
  835. Revision 1.7 1999/07/30 12:26:07 peter
  836. * write .size only for linux
  837. Revision 1.6 1999/07/29 20:53:56 peter
  838. * write .size also
  839. Revision 1.5 1999/07/22 09:37:29 florian
  840. + resourcestring implemented
  841. + start of longstring support
  842. Revision 1.4 1999/07/18 10:19:38 florian
  843. * made it compilable with Dlephi 4 again
  844. + fixed problem with large stack allocations on win32
  845. Revision 1.3 1999/07/03 00:27:04 peter
  846. * better smartlinking support
  847. Revision 1.2 1999/06/22 15:25:14 peter
  848. * merged
  849. Revision 1.1.2.1 1999/06/22 15:23:08 peter
  850. * reinserted
  851. Revision 1.100 1999/06/22 14:41:20 peter
  852. * merged
  853. }