ag386att.pas 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303
  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 includecount=0 then
  274. curr_n:=n_sourcefile
  275. else
  276. curr_n:=n_includefile;
  277. if (infile^.path^<>'') then
  278. begin
  279. AsmWriteLn(#9'.stabs "'+lower(BsToSlash(FixPath(infile^.path^,false)))+'",'+
  280. tostr(curr_n)+',0,0,'+'Ltext'+ToStr(IncludeCount));
  281. end;
  282. AsmWriteLn(#9'.stabs "'+lower(FixFileName(infile^.name^))+'",'+
  283. tostr(curr_n)+',0,0,'+'Ltext'+ToStr(IncludeCount));
  284. AsmWriteLn('Ltext'+ToStr(IncludeCount)+':');
  285. inc(includecount);
  286. end;
  287. { line changed ? }
  288. if (stabslastfileinfo.line<>fileinfo.line) and (fileinfo.line<>0) then
  289. begin
  290. if (n_line=n_textline) and assigned(funcname) and
  291. (target_os.use_function_relative_addresses) then
  292. begin
  293. AsmWriteLn(target_asm.labelprefix+'l'+tostr(linecount)+':');
  294. AsmWrite(#9'.stabn '+tostr(n_line)+',0,'+tostr(fileinfo.line)+','+
  295. target_asm.labelprefix+'l'+tostr(linecount)+' - ');
  296. AsmWritePChar(FuncName);
  297. AsmLn;
  298. inc(linecount);
  299. end
  300. else
  301. AsmWriteLn(#9'.stabd'#9+tostr(n_line)+',0,'+tostr(fileinfo.line));
  302. end;
  303. stabslastfileinfo:=fileinfo;
  304. end;
  305. {$endif GDB}
  306. procedure ti386attasmlist.WriteTree(p:paasmoutput);
  307. const
  308. allocstr : array[boolean] of string[10]=(' released',' allocated');
  309. nolinetai =[ait_label,
  310. ait_regalloc,ait_tempalloc,
  311. ait_stabn,ait_stabs,ait_section,
  312. ait_cut,ait_marker,ait_align,ait_stab_function_name];
  313. type
  314. t80bitarray = array[0..9] of byte;
  315. t64bitarray = array[0..7] of byte;
  316. t32bitarray = array[0..3] of byte;
  317. var
  318. ch : char;
  319. hp : pai;
  320. consttyp : tait;
  321. s : string;
  322. found : boolean;
  323. i,pos,l : longint;
  324. co : comp;
  325. sin : single;
  326. d : double;
  327. e : extended;
  328. op : tasmop;
  329. calljmp,
  330. do_line : boolean;
  331. sep : char;
  332. begin
  333. if not assigned(p) then
  334. exit;
  335. { lineinfo is only needed for codesegment (PFV) }
  336. do_line:=(cs_asm_source in aktglobalswitches) or
  337. ((cs_lineinfo in aktmoduleswitches) and (p=codesegment));
  338. hp:=pai(p^.first);
  339. while assigned(hp) do
  340. begin
  341. aktfilepos:=hp^.fileinfo;
  342. if not(hp^.typ in nolinetai) then
  343. begin
  344. {$ifdef GDB}
  345. { write stabs }
  346. if cs_debuginfo in aktmoduleswitches then
  347. WriteFileLineInfo(hp^.fileinfo);
  348. {$endif GDB}
  349. if do_line then
  350. begin
  351. { load infile }
  352. if lastfileinfo.fileindex<>hp^.fileinfo.fileindex then
  353. begin
  354. infile:=current_module^.sourcefiles^.get_file(hp^.fileinfo.fileindex);
  355. { open only if needed !! }
  356. if (cs_asm_source in aktglobalswitches) then
  357. infile^.open;
  358. { avoid unnecessary reopens of the same file !! }
  359. lastfileinfo.fileindex:=hp^.fileinfo.fileindex;
  360. { be sure to change line !! }
  361. lastfileinfo.line:=-1;
  362. end;
  363. { write source }
  364. if (cs_asm_source in aktglobalswitches) then
  365. begin
  366. if (infile<>lastinfile) and assigned(lastinfile) then
  367. begin
  368. AsmWriteLn(target_asm.comment+'['+infile^.name^+']');
  369. lastinfile^.close;
  370. end;
  371. if (hp^.fileinfo.line<>lastfileinfo.line) and
  372. (hp^.fileinfo.line<infile^.maxlinebuf) then
  373. begin
  374. if (hp^.fileinfo.line<>0) and
  375. (infile^.linebuf^[hp^.fileinfo.line]>=0) then
  376. AsmWriteLn(target_asm.comment+'['+tostr(hp^.fileinfo.line)+'] '+
  377. fixline(infile^.GetLineStr(hp^.fileinfo.line)));
  378. { set it to a negative value !
  379. to make that is has been read already !! PM }
  380. infile^.linebuf^[hp^.fileinfo.line]:=-infile^.linebuf^[hp^.fileinfo.line]-1;
  381. end;
  382. end;
  383. {$ifdef LINEINFO}
  384. { lineinfo }
  385. if (cs_lineinfo in aktmoduleswitches) then
  386. begin
  387. if (infile<>lastinfile) then
  388. begin
  389. lineinfolist^.concat(new(pai_const(init_8bit
  390. end
  391. else
  392. begin
  393. end;
  394. end;
  395. {$endif LINEINFO}
  396. lastfileinfo:=hp^.fileinfo;
  397. lastinfile:=infile;
  398. end;
  399. end;
  400. case hp^.typ of
  401. ait_comment :
  402. Begin
  403. AsmWrite(target_asm.comment);
  404. AsmWritePChar(pai_asm_comment(hp)^.str);
  405. AsmLn;
  406. End;
  407. ait_regalloc :
  408. begin
  409. if (cs_asm_regalloc in aktglobalswitches) then
  410. AsmWriteLn(target_asm.comment+'Register '+att_reg2str[pairegalloc(hp)^.reg]+
  411. allocstr[pairegalloc(hp)^.allocation]);
  412. end;
  413. ait_tempalloc :
  414. begin
  415. if (cs_asm_tempalloc in aktglobalswitches) then
  416. AsmWriteLn(target_asm.comment+'Temp '+tostr(paitempalloc(hp)^.temppos)+','+
  417. tostr(paitempalloc(hp)^.tempsize)+allocstr[paitempalloc(hp)^.allocation]);
  418. end;
  419. ait_align :
  420. begin
  421. AsmWrite(#9'.balign '+tostr(pai_align(hp)^.aligntype));
  422. if pai_align(hp)^.use_op then
  423. AsmWrite(','+tostr(pai_align(hp)^.fillop));
  424. AsmLn;
  425. end;
  426. ait_section :
  427. begin
  428. if pai_section(hp)^.sec<>sec_none then
  429. begin
  430. AsmLn;
  431. AsmWriteLn(ait_section2str(pai_section(hp)^.sec));
  432. {$ifdef GDB}
  433. lastfileinfo.line:=-1;
  434. {$endif GDB}
  435. end;
  436. end;
  437. ait_datablock :
  438. begin
  439. if pai_datablock(hp)^.is_global then
  440. AsmWrite(#9'.comm'#9)
  441. else
  442. AsmWrite(#9'.lcomm'#9);
  443. AsmWrite(pai_datablock(hp)^.sym^.name);
  444. AsmWriteLn(','+tostr(pai_datablock(hp)^.size));
  445. end;
  446. ait_const_32bit,
  447. ait_const_16bit,
  448. ait_const_8bit :
  449. begin
  450. AsmWrite(ait_const2str[hp^.typ]+tostr(pai_const(hp)^.value));
  451. consttyp:=hp^.typ;
  452. l:=0;
  453. repeat
  454. found:=(not (Pai(hp^.next)=nil)) and (Pai(hp^.next)^.typ=consttyp);
  455. if found then
  456. begin
  457. hp:=Pai(hp^.next);
  458. s:=','+tostr(pai_const(hp)^.value);
  459. AsmWrite(s);
  460. inc(l,length(s));
  461. end;
  462. until (not found) or (l>line_length);
  463. AsmLn;
  464. end;
  465. ait_const_symbol :
  466. begin
  467. AsmWrite(#9'.long'#9+pai_const_symbol(hp)^.sym^.name);
  468. if pai_const_symbol(hp)^.offset>0 then
  469. AsmWrite('+'+tostr(pai_const_symbol(hp)^.offset))
  470. else if pai_const_symbol(hp)^.offset<0 then
  471. AsmWrite(tostr(pai_const_symbol(hp)^.offset));
  472. AsmLn;
  473. end;
  474. ait_const_rva :
  475. AsmWriteLn(#9'.rva'#9+pai_const_symbol(hp)^.sym^.name);
  476. ait_real_80bit :
  477. begin
  478. if do_line then
  479. AsmWriteLn(target_asm.comment+extended2str(pai_real_80bit(hp)^.value));
  480. { Make sure e is a extended type, bestreal could be
  481. a different type (bestreal) !! (PFV) }
  482. e:=pai_real_80bit(hp)^.value;
  483. AsmWrite(#9'.byte'#9);
  484. for i:=0 to 9 do
  485. begin
  486. if i<>0 then
  487. AsmWrite(',');
  488. AsmWrite(tostr(t80bitarray(e)[i]));
  489. end;
  490. AsmLn;
  491. end;
  492. ait_real_64bit :
  493. begin
  494. if do_line then
  495. AsmWriteLn(target_asm.comment+double2str(pai_real_64bit(hp)^.value));
  496. d:=pai_real_64bit(hp)^.value;
  497. AsmWrite(#9'.byte'#9);
  498. for i:=0 to 7 do
  499. begin
  500. if i<>0 then
  501. AsmWrite(',');
  502. AsmWrite(tostr(t64bitarray(d)[i]));
  503. end;
  504. AsmLn;
  505. end;
  506. ait_real_32bit :
  507. begin
  508. if do_line then
  509. AsmWriteLn(target_asm.comment+single2str(pai_real_32bit(hp)^.value));
  510. sin:=pai_real_32bit(hp)^.value;
  511. AsmWrite(#9'.byte'#9);
  512. for i:=0 to 3 do
  513. begin
  514. if i<>0 then
  515. AsmWrite(',');
  516. AsmWrite(tostr(t32bitarray(sin)[i]));
  517. end;
  518. AsmLn;
  519. end;
  520. ait_comp_64bit :
  521. begin
  522. if do_line then
  523. AsmWriteLn(target_asm.comment+comp2str(pai_comp_64bit(hp)^.value));
  524. AsmWrite(#9'.byte'#9);
  525. {$ifdef FPC}
  526. co:=comp(pai_comp_64bit(hp)^.value);
  527. {$else}
  528. co:=pai_comp_64bit(hp)^.value;
  529. {$endif}
  530. for i:=0 to 7 do
  531. begin
  532. if i<>0 then
  533. AsmWrite(',');
  534. AsmWrite(tostr(t64bitarray(co)[i]));
  535. end;
  536. AsmLn;
  537. end;
  538. ait_direct :
  539. begin
  540. AsmWritePChar(pai_direct(hp)^.str);
  541. AsmLn;
  542. {$IfDef GDB}
  543. if strpos(pai_direct(hp)^.str,'.data')<>nil then
  544. n_line:=n_dataline
  545. else if strpos(pai_direct(hp)^.str,'.text')<>nil then
  546. n_line:=n_textline
  547. else if strpos(pai_direct(hp)^.str,'.bss')<>nil then
  548. n_line:=n_bssline;
  549. {$endif GDB}
  550. end;
  551. ait_string :
  552. begin
  553. pos:=0;
  554. for i:=1 to pai_string(hp)^.len do
  555. begin
  556. if pos=0 then
  557. begin
  558. AsmWrite(#9'.ascii'#9'"');
  559. pos:=20;
  560. end;
  561. ch:=pai_string(hp)^.str[i-1];
  562. case ch of
  563. #0, {This can't be done by range, because a bug in FPC}
  564. #1..#31,
  565. #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  566. '"' : s:='\"';
  567. '\' : s:='\\';
  568. else
  569. s:=ch;
  570. end;
  571. AsmWrite(s);
  572. inc(pos,length(s));
  573. if (pos>line_length) or (i=pai_string(hp)^.len) then
  574. begin
  575. AsmWriteLn('"');
  576. pos:=0;
  577. end;
  578. end;
  579. end;
  580. ait_label :
  581. begin
  582. if (pai_label(hp)^.l^.is_used) then
  583. begin
  584. if pai_label(hp)^.l^.typ=AS_GLOBAL then
  585. begin
  586. AsmWrite('.globl'#9);
  587. AsmWriteLn(pai_label(hp)^.l^.name);
  588. end;
  589. AsmWrite(pai_label(hp)^.l^.name);
  590. AsmWriteLn(':');
  591. end;
  592. end;
  593. ait_symbol :
  594. begin
  595. if pai_symbol(hp)^.is_global then
  596. begin
  597. AsmWrite('.globl'#9);
  598. AsmWriteLn(pai_symbol(hp)^.sym^.name);
  599. end;
  600. if target_info.target=target_i386_linux then
  601. begin
  602. AsmWrite(#9'.type'#9);
  603. AsmWrite(pai_symbol(hp)^.sym^.name);
  604. if assigned(pai(hp^.next)) and
  605. (pai(hp^.next)^.typ in [ait_const_symbol,ait_const_rva,
  606. ait_const_32bit,ait_const_16bit,ait_const_8bit,ait_datablock,
  607. ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit]) then
  608. AsmWriteLn(',@object')
  609. else
  610. AsmWriteLn(',@function');
  611. if pai_symbol(hp)^.sym^.size>0 then
  612. begin
  613. AsmWrite(#9'.size'#9);
  614. AsmWrite(pai_symbol(hp)^.sym^.name);
  615. AsmWrite(', ');
  616. AsmWriteLn(tostr(pai_symbol(hp)^.sym^.size));
  617. end;
  618. end;
  619. AsmWrite(pai_symbol(hp)^.sym^.name);
  620. AsmWriteLn(':');
  621. end;
  622. ait_symbol_end :
  623. begin
  624. if target_info.target=target_i386_linux then
  625. begin
  626. s:=target_asm.labelprefix+'e'+tostr(symendcount);
  627. inc(symendcount);
  628. AsmWriteLn(s+':');
  629. AsmWrite(#9'.size'#9);
  630. AsmWrite(pai_symbol(hp)^.sym^.name);
  631. AsmWrite(', '+s+' - ');
  632. AsmWriteLn(pai_symbol(hp)^.sym^.name);
  633. end;
  634. end;
  635. ait_instruction :
  636. begin
  637. op:=paicpu(hp)^.opcode;
  638. calljmp:=is_calljmp(op);
  639. { call maybe not translated to calll }
  640. s:=#9+att_op2str[op]+cond2str[paicpu(hp)^.condition];
  641. if (not calljmp) and
  642. (not att_nosuffix[op]) and
  643. not(
  644. (paicpu(hp)^.oper[0].typ=top_reg) and
  645. (paicpu(hp)^.oper[0].reg in [R_ST..R_ST7])
  646. ) then
  647. s:=s+att_opsize2str[paicpu(hp)^.opsize];
  648. { process operands }
  649. if paicpu(hp)^.ops<>0 then
  650. begin
  651. { call and jmp need an extra handling }
  652. { this code is only called if jmp isn't a labeled instruction }
  653. if calljmp then
  654. s:=s+#9+getopstr_jmp(paicpu(hp)^.oper[0])
  655. else
  656. begin
  657. for i:=0to paicpu(hp)^.ops-1 do
  658. begin
  659. if i=0 then
  660. sep:=#9
  661. else
  662. sep:=',';
  663. s:=s+sep+getopstr(paicpu(hp)^.oper[i])
  664. end;
  665. end;
  666. end;
  667. AsmWriteLn(s);
  668. end;
  669. {$ifdef GDB}
  670. ait_stabs :
  671. begin
  672. AsmWrite(#9'.stabs ');
  673. AsmWritePChar(pai_stabs(hp)^.str);
  674. AsmLn;
  675. end;
  676. ait_stabn :
  677. begin
  678. AsmWrite(#9'.stabn ');
  679. AsmWritePChar(pai_stabn(hp)^.str);
  680. AsmLn;
  681. end;
  682. ait_force_line :
  683. stabslastfileinfo.line:=0;
  684. ait_stab_function_name:
  685. funcname:=pai_stab_function_name(hp)^.str;
  686. {$endif GDB}
  687. ait_cut :
  688. begin
  689. if SmartAsm then
  690. begin
  691. { only reset buffer if nothing has changed }
  692. if AsmSize=AsmStartSize then
  693. AsmClear
  694. else
  695. begin
  696. AsmClose;
  697. DoAssemble;
  698. if pai_cut(hp)^.EndName then
  699. IsEndFile:=true;
  700. AsmCreate;
  701. end;
  702. { avoid empty files }
  703. while assigned(hp^.next) and (pai(hp^.next)^.typ in [ait_cut,ait_section,ait_comment]) do
  704. begin
  705. if pai(hp^.next)^.typ=ait_section then
  706. lastsec:=pai_section(hp^.next)^.sec;
  707. hp:=pai(hp^.next);
  708. end;
  709. {$ifdef GDB}
  710. { force write of filename }
  711. FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
  712. includecount:=0;
  713. funcname:=nil;
  714. WriteFileLineInfo(hp^.fileinfo);
  715. {$endif GDB}
  716. if lastsec<>sec_none then
  717. AsmWriteLn(ait_section2str(lastsec));
  718. AsmStartSize:=AsmSize;
  719. end;
  720. end;
  721. ait_marker :
  722. ;
  723. else
  724. internalerror(10000);
  725. end;
  726. hp:=pai(hp^.next);
  727. end;
  728. end;
  729. procedure ti386attasmlist.WriteAsmList;
  730. var
  731. p:dirstr;
  732. n:namestr;
  733. e:extstr;
  734. {$ifdef GDB}
  735. fileinfo : tfileposinfo;
  736. {$endif GDB}
  737. begin
  738. {$ifdef EXTDEBUG}
  739. if assigned(current_module^.mainsource) then
  740. Comment(v_info,'Start writing att-styled assembler output for '+current_module^.mainsource^);
  741. {$endif}
  742. LastSec:=sec_none;
  743. {$ifdef GDB}
  744. FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
  745. {$endif GDB}
  746. FillChar(lastfileinfo,sizeof(lastfileinfo),0);
  747. LastInfile:=nil;
  748. if assigned(current_module^.mainsource) then
  749. fsplit(current_module^.mainsource^,p,n,e)
  750. else
  751. begin
  752. p:=inputdir;
  753. n:=inputfile;
  754. e:=inputextension;
  755. end;
  756. { to get symify to work }
  757. AsmWriteLn(#9'.file "'+FixFileName(n+e)+'"');
  758. {$ifdef GDB}
  759. n_line:=n_bssline;
  760. funcname:=nil;
  761. linecount:=1;
  762. includecount:=0;
  763. fileinfo.fileindex:=1;
  764. fileinfo.line:=1;
  765. { Write main file }
  766. WriteFileLineInfo(fileinfo);
  767. {$endif GDB}
  768. AsmStartSize:=AsmSize;
  769. symendcount:=0;
  770. countlabelref:=false;
  771. If (cs_debuginfo in aktmoduleswitches) then
  772. WriteTree(debuglist);
  773. WriteTree(codesegment);
  774. WriteTree(datasegment);
  775. WriteTree(consts);
  776. WriteTree(rttilist);
  777. Writetree(resourcestringlist);
  778. WriteTree(bsssegment);
  779. Writetree(importssection);
  780. { exports are written by DLLTOOL
  781. if we use it so don't insert it twice (PM) }
  782. if not RelocSection then
  783. Writetree(exportssection);
  784. Writetree(resourcesection);
  785. countlabelref:=true;
  786. AsmLn;
  787. {$ifdef EXTDEBUG}
  788. if assigned(current_module^.mainsource) then
  789. comment(v_info,'Done writing att-styled assembler output for '+current_module^.mainsource^);
  790. {$endif EXTDEBUG}
  791. end;
  792. end.
  793. {
  794. $Log$
  795. Revision 1.12 1999-08-25 16:03:46 peter
  796. * symbol name is now written using separate asmwrite() calls to overcome
  797. > 255 char strings
  798. Revision 1.11 1999/08/25 11:59:32 jonas
  799. * changed pai386, paippc and paiapha (same for tai*) to paicpu (taicpu)
  800. Revision 1.10 1999/08/13 15:44:57 peter
  801. * first things to include lineinfo in the executable
  802. Revision 1.9 1999/08/10 12:26:20 pierre
  803. * avoid double .edata section if using DLLTOOL
  804. Revision 1.8 1999/08/04 00:22:34 florian
  805. * renamed i386asm and i386base to cpuasm and cpubase
  806. Revision 1.7 1999/07/30 12:26:07 peter
  807. * write .size only for linux
  808. Revision 1.6 1999/07/29 20:53:56 peter
  809. * write .size also
  810. Revision 1.5 1999/07/22 09:37:29 florian
  811. + resourcestring implemented
  812. + start of longstring support
  813. Revision 1.4 1999/07/18 10:19:38 florian
  814. * made it compilable with Dlephi 4 again
  815. + fixed problem with large stack allocations on win32
  816. Revision 1.3 1999/07/03 00:27:04 peter
  817. * better smartlinking support
  818. Revision 1.2 1999/06/22 15:25:14 peter
  819. * merged
  820. Revision 1.1.2.1 1999/06/22 15:23:08 peter
  821. * reinserted
  822. Revision 1.100 1999/06/22 14:41:20 peter
  823. * merged
  824. Revision 1.99 1999/06/14 17:47:44 peter
  825. * merged
  826. Revision 1.97.2.3 1999/06/22 14:40:27 peter
  827. * small change to fpureg check
  828. Revision 1.97.2.2 1999/06/22 14:20:19 peter
  829. * fixed parsing and writing of fpureg
  830. Revision 1.97.2.1 1999/06/14 17:30:41 peter
  831. * align fixes from pierre
  832. Revision 1.98 1999/06/11 22:54:10 pierre
  833. * .align problem treated :
  834. .align is considered as .p2align on go32v1 and go32v2
  835. and as .balign on other targets
  836. + ra386att supports also .balign and .p2align
  837. * ag386att uses .balign allways
  838. Revision 1.97 1999/06/09 23:00:06 peter
  839. * small ansistring fixes
  840. * val_ansistr_sint destsize changed to longint
  841. * don't write low/hi ascii with -al
  842. Revision 1.96 1999/06/06 15:53:13 peter
  843. * suffix adding can be turned of for some tasmops in att_nosuffix array
  844. Revision 1.95 1999/05/27 19:43:56 peter
  845. * removed oldasm
  846. * plabel -> pasmlabel
  847. * -a switches to source writing automaticly
  848. * assembler readers OOPed
  849. * asmsymbol automaticly external
  850. * jumptables and other label fixes for asm readers
  851. Revision 1.94 1999/05/23 18:41:54 florian
  852. * better error recovering in typed constants
  853. * some problems with arrays of const fixed, some problems
  854. due my previous
  855. - the location type of array constructor is now LOC_MEM
  856. - the pushing of high fixed
  857. - parameter copying fixed
  858. - zero temp. allocation removed
  859. * small problem in the assembler writers fixed:
  860. ref to nil wasn't written correctly
  861. Revision 1.93 1999/05/21 13:54:39 peter
  862. * NEWLAB for label as symbol
  863. Revision 1.92 1999/05/16 17:03:05 peter
  864. * better file position info
  865. Revision 1.91 1999/05/12 00:19:36 peter
  866. * removed R_DEFAULT_SEG
  867. * uniform float names
  868. Revision 1.90 1999/05/08 19:52:31 peter
  869. + MessagePos() which is enhanced Message() function but also gets the
  870. position info
  871. * Removed comp warnings
  872. Revision 1.89 1999/05/07 00:38:22 pierre
  873. * comp fixes 2
  874. Revision 1.88 1999/05/07 00:09:35 pierre
  875. * better comp output
  876. Revision 1.87 1999/05/06 09:05:06 peter
  877. * generic write_float and str_float
  878. * fixed constant float conversions
  879. Revision 1.86 1999/05/04 21:44:29 florian
  880. * changes to compile it with Delphi 4.0
  881. Revision 1.85 1999/05/02 23:29:57 peter
  882. * readded condition, becuase it's needed for set<cond> and cmov<cond> !
  883. Revision 1.84 1999/05/02 22:41:47 peter
  884. * moved section names to systems
  885. * fixed nasm,intel writer
  886. Revision 1.83 1999/05/02 21:33:51 florian
  887. * several bugs regarding -Or fixed
  888. Revision 1.82 1999/05/01 13:47:51 peter
  889. * fix hack for fsub
  890. Revision 1.81 1999/05/01 13:23:56 peter
  891. * merged nasm compiler
  892. * old asm moved to oldasm/
  893. Revision 1.80 1999/04/17 22:17:04 pierre
  894. * ifdef USE_OP3 released (changed into ifndef NO_OP3)
  895. * SHRD and SHLD first operand (ATT syntax) can only be CL reg or immediate const
  896. Revision 1.79 1999/04/16 11:49:37 peter
  897. + tempalloc
  898. + -at to show temp alloc info in .s file
  899. Revision 1.78 1999/04/16 10:00:54 pierre
  900. + ifdef USE_OP3 code :
  901. added all missing op_... constructors for taicpu needed
  902. for SHRD,SHLD and IMUL code in assembler readers
  903. (check in tests/tbs0123.pp)
  904. Revision 1.77 1999/04/14 12:44:46 daniel
  905. * Proper fix for the .bss conflict
  906. Revision 1.76 1999/04/14 11:43:25 michael
  907. + reverted back to .section .bss
  908. Revision 1.75 1999/04/13 08:45:33 daniel
  909. * EMX assembler prefers .bss instead of .section .bss
  910. Revision 1.74 1999/04/10 16:14:59 peter
  911. * fixed browcol
  912. + -ar to show regalloc info in .s file
  913. Revision 1.73 1999/04/09 08:33:45 peter
  914. * write * before register with call for the stricter as versions
  915. Revision 1.72 1999/03/31 13:55:02 peter
  916. * assembler inlining working for ag386bin
  917. Revision 1.71 1999/03/29 16:05:42 peter
  918. * optimizer working for ag386bin
  919. Revision 1.70 1999/03/10 21:48:21 florian
  920. * bug0218 fixed, ag386att writes now all real types as byte
  921. sequences to minimize rouding error, in -al mode the
  922. value is written as comment
  923. Revision 1.69 1999/03/10 13:25:43 pierre
  924. section order changed to get closer output from coff writer
  925. Revision 1.68 1999/03/02 02:56:09 peter
  926. + stabs support for binary writers
  927. * more fixes and missing updates from the previous commit :(
  928. Revision 1.67 1999/03/01 15:46:15 peter
  929. * ag386bin finally make cycles correct
  930. * prefixes are now also normal opcodes
  931. Revision 1.66 1999/02/26 00:48:12 peter
  932. * assembler writers fixed for ag386bin
  933. Revision 1.65 1999/02/25 21:02:17 peter
  934. * ag386bin updates
  935. + coff writer
  936. Revision 1.64 1999/02/22 02:14:57 peter
  937. * updates for ag386bin
  938. Revision 1.63 1999/02/17 10:16:25 peter
  939. * small fixes for the binary writer
  940. Revision 1.62 1999/01/12 14:21:26 peter
  941. * fixed pushw warning
  942. Revision 1.61 1998/12/29 18:50:04 jonas
  943. * don't write debug info if not (cs_debuginfo in aktmoduleswitches)
  944. Revision 1.60 1998/12/23 22:53:43 peter
  945. * don't count ait_marker for lineinfo
  946. Revision 1.58 1998/12/11 00:02:38 peter
  947. + globtype,tokens,version unit splitted from globals
  948. Revision 1.57 1998/12/01 23:36:32 pierre
  949. * zero padded alignment was buggy
  950. Revision 1.56 1998/12/01 11:19:37 peter
  951. * fixed range problem with in [tasmop]
  952. Revision 1.55 1998/11/30 09:42:53 pierre
  953. * some range check bugs fixed (still not working !)
  954. + added DLL writing support for win32 (also accepts variables)
  955. + TempAnsi for code that could be used for Temporary ansi strings
  956. handling
  957. Revision 1.54 1998/11/17 10:04:13 pierre
  958. * zero indexed file not searched
  959. Revision 1.53 1998/11/17 00:26:08 peter
  960. * fixed for $H+
  961. Revision 1.52 1998/11/12 11:19:32 pierre
  962. * fix for first line of function break
  963. Revision 1.51 1998/11/09 09:21:18 pierre
  964. * fix for stabs line infos
  965. Revision 1.50 1998/11/06 09:49:25 pierre
  966. * n_line stuff cleaned
  967. Revision 1.49 1998/10/26 23:07:02 peter
  968. * fixpath fix
  969. Revision 1.48 1998/10/15 15:08:39 pierre
  970. * removed lots of unnecessary inputfile system.open calls
  971. (made a big speed decrease on go32v2 !)
  972. Revision 1.47 1998/10/13 14:01:05 peter
  973. * fixed -al
  974. Revision 1.46 1998/10/13 13:10:07 peter
  975. * new style for m68k/i386 infos and enums
  976. Revision 1.45 1998/10/12 12:20:39 pierre
  977. + added tai_const_symbol_offset
  978. for r : pointer = @var.field;
  979. * better message for different arg names on implementation
  980. of function
  981. Revision 1.44 1998/10/06 17:16:32 pierre
  982. * some memory leaks fixed (thanks to Peter for heaptrc !)
  983. Revision 1.43 1998/10/01 20:19:12 jonas
  984. + ait_marker support
  985. Revision 1.42 1998/09/28 16:57:08 pierre
  986. * changed all length(p^.value_str^) into str_length(p)
  987. to get it work with and without ansistrings
  988. * changed sourcefiles field of tmodule to a pointer
  989. Revision 1.41 1998/09/20 17:11:19 jonas
  990. * released REGALLOC
  991. Revision 1.40 1998/09/16 17:58:34 jonas
  992. * fixed -dRegAlloc and -dDRegalloc problems
  993. Revision 1.39 1998/09/11 11:30:41 pierre
  994. -al -g option bug corrected
  995. Revision 1.38.2.1 1998/09/11 10:49:09 pierre
  996. * bug with -g -al option removed
  997. Revision 1.38 1998/09/07 22:23:35 peter
  998. * fixed for no gdb compiler
  999. Revision 1.37 1998/09/07 18:33:34 peter
  1000. + smartlinking for win95 imports
  1001. Revision 1.36 1998/09/04 17:34:19 pierre
  1002. * bug with datalabel corrected
  1003. + assembler errors better commented
  1004. * one nested record crash removed
  1005. Revision 1.35 1998/09/03 17:08:38 pierre
  1006. * better lines for stabs
  1007. (no scroll back to if before else part
  1008. no return to case line at jump outside case)
  1009. + source lines also if not in order
  1010. Revision 1.34 1998/09/03 11:22:41 peter
  1011. + support for cs_asm_source
  1012. Revision 1.33 1998/08/26 10:06:33 peter
  1013. * reduce amount of asmfiles generated
  1014. * no stabs are written in writefilelineinfo when debuginfo is off
  1015. Revision 1.32 1998/08/20 09:26:35 pierre
  1016. + funcret setting in underproc testing
  1017. compile with _dTEST_FUNCRET
  1018. Revision 1.31 1998/08/11 14:01:16 peter
  1019. * @object type also for extended and comp
  1020. Revision 1.30 1998/08/10 23:56:02 peter
  1021. * fixed extended writing
  1022. Revision 1.29 1998/08/10 14:49:35 peter
  1023. + localswitches, moduleswitches, globalswitches splitting
  1024. Revision 1.27 1998/08/08 12:30:07 florian
  1025. * extended writing improved
  1026. Revision 1.26 1998/08/08 10:19:16 florian
  1027. * small fixes to write the extended type correct
  1028. Revision 1.28 1998/08/10 10:01:33 peter
  1029. * Fixed with GDB undefined
  1030. Revision 1.25 1998/08/06 16:53:25 pierre
  1031. * debugging info corrected
  1032. Revision 1.24 1998/07/14 14:46:37 peter
  1033. * released NEWINPUT
  1034. Revision 1.23 1998/07/07 11:19:51 peter
  1035. + NEWINPUT for a better inputfile and scanner object
  1036. Revision 1.22 1998/06/08 22:59:42 peter
  1037. * smartlinking works for win32
  1038. * some defines to exclude some compiler parts
  1039. Revision 1.21 1998/06/05 17:46:01 peter
  1040. * tp doesn't like comp() typecast
  1041. Revision 1.20 1998/06/04 23:51:27 peter
  1042. * m68k compiles
  1043. + .def file creation moved to gendef.pas so it could also be used
  1044. for win32
  1045. Revision 1.19 1998/05/31 14:13:29 peter
  1046. * fixed call bugs with assembler readers
  1047. + OPR_SYMBOL to hold a symbol in the asm parser
  1048. * fixed staticsymtable vars which were acessed through %ebp instead of
  1049. name
  1050. Revision 1.18 1998/05/28 17:24:25 peter
  1051. - $R- for tp to solve range errors with in[]
  1052. Revision 1.17 1998/05/25 17:11:34 pierre
  1053. * firstpasscount bug fixed
  1054. now all is already set correctly the first time
  1055. under EXTDEBUG try -gp to skip all other firstpasses
  1056. it works !!
  1057. * small bug fixes
  1058. - for smallsets with -dTESTSMALLSET
  1059. - some warnings removed (by correcting code !)
  1060. Revision 1.16 1998/05/23 01:20:54 peter
  1061. + aktasmmode, aktoptprocessor, aktoutputformat
  1062. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  1063. + $LIBNAME to set the library name where the unit will be put in
  1064. * splitted cgi386 a bit (codeseg to large for bp7)
  1065. * nasm, tasm works again. nasm moved to ag386nsm.pas
  1066. Revision 1.15 1998/05/11 13:07:53 peter
  1067. + $ifdef NEWPPU for the new ppuformat
  1068. + $define GDB not longer required
  1069. * removed all warnings and stripped some log comments
  1070. * no findfirst/findnext anymore to remove smartlink *.o files
  1071. Revision 1.14 1998/05/06 18:36:53 peter
  1072. * tai_section extended with code,data,bss sections and enumerated type
  1073. * ident 'compiled by FPC' moved to pmodules
  1074. * small fix for smartlink
  1075. Revision 1.13 1998/05/06 08:38:32 pierre
  1076. * better position info with UseTokenInfo
  1077. UseTokenInfo greatly simplified
  1078. + added check for changed tree after first time firstpass
  1079. (if we could remove all the cases were it happen
  1080. we could skip all firstpass if firstpasscount > 1)
  1081. Only with ExtDebug
  1082. Revision 1.12 1998/05/04 17:54:24 peter
  1083. + smartlinking works (only case jumptable left todo)
  1084. * redesign of systems.pas to support assemblers and linkers
  1085. + Unitname is now also in the PPU-file, increased version to 14
  1086. Revision 1.11 1998/05/01 07:43:52 florian
  1087. + basics for rtti implemented
  1088. + switch $m (generate rtti for published sections)
  1089. Revision 1.10 1998/04/30 15:59:39 pierre
  1090. * GDB works again better :
  1091. correct type info in one pass
  1092. + UseTokenInfo for better source position
  1093. * fixed one remaining bug in scanner for line counts
  1094. * several little fixes
  1095. Revision 1.9 1998/04/29 10:33:41 pierre
  1096. + added some code for ansistring (not complete nor working yet)
  1097. * corrected operator overloading
  1098. * corrected nasm output
  1099. + started inline procedures
  1100. + added starstarn : use ** for exponentiation (^ gave problems)
  1101. + started UseTokenInfo cond to get accurate positions
  1102. Revision 1.8 1998/04/28 08:23:58 pierre
  1103. * bug in stabn generation fixed
  1104. Revision 1.7 1998/04/27 23:10:27 peter
  1105. + new scanner
  1106. * $makelib -> if smartlink
  1107. * small filename fixes pmodule.setfilename
  1108. * moved import from files.pas -> import.pas
  1109. Revision 1.6 1998/04/21 11:30:13 peter
  1110. * fixed $ifdef regalloc
  1111. Revision 1.5 1998/04/16 16:53:24 jonas
  1112. * changed $ifdef regalloc to $ifdef dregalloc (= debugging info)
  1113. Revision 1.4 1998/04/09 15:46:38 florian
  1114. + register allocation tracing stuff added
  1115. Revision 1.3 1998/04/08 16:58:00 pierre
  1116. * several bugfixes
  1117. ADD ADC and AND are also sign extended
  1118. nasm output OK (program still crashes at end
  1119. and creates wrong assembler files !!)
  1120. procsym types sym in tdef removed !!
  1121. }