ag386att.pas 37 KB

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