ag386att.pas 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226
  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. if SmartAsm then
  651. begin
  652. { only reset buffer if nothing has changed }
  653. if AsmSize=AsmStartSize then
  654. AsmClear
  655. else
  656. begin
  657. AsmClose;
  658. DoAssemble;
  659. if pai_cut(hp)^.EndName then
  660. IsEndFile:=true;
  661. AsmCreate;
  662. end;
  663. { avoid empty files }
  664. while assigned(hp^.next) and (pai(hp^.next)^.typ in [ait_cut,ait_section,ait_comment]) do
  665. begin
  666. if pai(hp^.next)^.typ=ait_section then
  667. lastsec:=pai_section(hp^.next)^.sec;
  668. hp:=pai(hp^.next);
  669. end;
  670. {$ifdef GDB}
  671. { force write of filename }
  672. FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
  673. includecount:=0;
  674. funcname:=nil;
  675. WriteFileLineInfo(hp^.fileinfo);
  676. {$endif GDB}
  677. if lastsec<>sec_none then
  678. AsmWriteLn(ait_section2str(lastsec));
  679. AsmStartSize:=AsmSize;
  680. end;
  681. end;
  682. ait_marker :
  683. ;
  684. else
  685. internalerror(10000);
  686. end;
  687. hp:=pai(hp^.next);
  688. end;
  689. end;
  690. procedure ti386attasmlist.WriteAsmList;
  691. var
  692. p:dirstr;
  693. n:namestr;
  694. e:extstr;
  695. {$ifdef GDB}
  696. fileinfo : tfileposinfo;
  697. {$endif GDB}
  698. begin
  699. {$ifdef EXTDEBUG}
  700. if assigned(current_module^.mainsource) then
  701. Comment(v_info,'Start writing att-styled assembler output for '+current_module^.mainsource^);
  702. {$endif}
  703. LastSec:=sec_none;
  704. {$ifdef GDB}
  705. FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
  706. {$endif GDB}
  707. FillChar(lastfileinfo,sizeof(lastfileinfo),0);
  708. LastInfile:=nil;
  709. if assigned(current_module^.mainsource) then
  710. fsplit(current_module^.mainsource^,p,n,e)
  711. else
  712. begin
  713. p:=inputdir;
  714. n:=inputfile;
  715. e:=inputextension;
  716. end;
  717. { to get symify to work }
  718. AsmWriteLn(#9'.file "'+FixFileName(n+e)+'"');
  719. {$ifdef GDB}
  720. n_line:=n_bssline;
  721. funcname:=nil;
  722. linecount:=1;
  723. includecount:=0;
  724. fileinfo.fileindex:=1;
  725. fileinfo.line:=1;
  726. { Write main file }
  727. WriteFileLineInfo(fileinfo);
  728. {$endif GDB}
  729. AsmStartSize:=AsmSize;
  730. countlabelref:=false;
  731. If (cs_debuginfo in aktmoduleswitches) then
  732. WriteTree(debuglist);
  733. WriteTree(codesegment);
  734. WriteTree(datasegment);
  735. WriteTree(consts);
  736. WriteTree(rttilist);
  737. WriteTree(bsssegment);
  738. Writetree(importssection);
  739. Writetree(exportssection);
  740. Writetree(resourcesection);
  741. countlabelref:=true;
  742. AsmLn;
  743. {$ifdef EXTDEBUG}
  744. if assigned(current_module^.mainsource) then
  745. comment(v_info,'Done writing att-styled assembler output for '+current_module^.mainsource^);
  746. {$endif EXTDEBUG}
  747. end;
  748. end.
  749. {
  750. $Log$
  751. Revision 1.3 1999-07-03 00:27:04 peter
  752. * better smartlinking support
  753. Revision 1.2 1999/06/22 15:25:14 peter
  754. * merged
  755. Revision 1.1.2.1 1999/06/22 15:23:08 peter
  756. * reinserted
  757. Revision 1.100 1999/06/22 14:41:20 peter
  758. * merged
  759. Revision 1.99 1999/06/14 17:47:44 peter
  760. * merged
  761. Revision 1.97.2.3 1999/06/22 14:40:27 peter
  762. * small change to fpureg check
  763. Revision 1.97.2.2 1999/06/22 14:20:19 peter
  764. * fixed parsing and writing of fpureg
  765. Revision 1.97.2.1 1999/06/14 17:30:41 peter
  766. * align fixes from pierre
  767. Revision 1.98 1999/06/11 22:54:10 pierre
  768. * .align problem treated :
  769. .align is considered as .p2align on go32v1 and go32v2
  770. and as .balign on other targets
  771. + ra386att supports also .balign and .p2align
  772. * ag386att uses .balign allways
  773. Revision 1.97 1999/06/09 23:00:06 peter
  774. * small ansistring fixes
  775. * val_ansistr_sint destsize changed to longint
  776. * don't write low/hi ascii with -al
  777. Revision 1.96 1999/06/06 15:53:13 peter
  778. * suffix adding can be turned of for some tasmops in att_nosuffix array
  779. Revision 1.95 1999/05/27 19:43:56 peter
  780. * removed oldasm
  781. * plabel -> pasmlabel
  782. * -a switches to source writing automaticly
  783. * assembler readers OOPed
  784. * asmsymbol automaticly external
  785. * jumptables and other label fixes for asm readers
  786. Revision 1.94 1999/05/23 18:41:54 florian
  787. * better error recovering in typed constants
  788. * some problems with arrays of const fixed, some problems
  789. due my previous
  790. - the location type of array constructor is now LOC_MEM
  791. - the pushing of high fixed
  792. - parameter copying fixed
  793. - zero temp. allocation removed
  794. * small problem in the assembler writers fixed:
  795. ref to nil wasn't written correctly
  796. Revision 1.93 1999/05/21 13:54:39 peter
  797. * NEWLAB for label as symbol
  798. Revision 1.92 1999/05/16 17:03:05 peter
  799. * better file position info
  800. Revision 1.91 1999/05/12 00:19:36 peter
  801. * removed R_DEFAULT_SEG
  802. * uniform float names
  803. Revision 1.90 1999/05/08 19:52:31 peter
  804. + MessagePos() which is enhanced Message() function but also gets the
  805. position info
  806. * Removed comp warnings
  807. Revision 1.89 1999/05/07 00:38:22 pierre
  808. * comp fixes 2
  809. Revision 1.88 1999/05/07 00:09:35 pierre
  810. * better comp output
  811. Revision 1.87 1999/05/06 09:05:06 peter
  812. * generic write_float and str_float
  813. * fixed constant float conversions
  814. Revision 1.86 1999/05/04 21:44:29 florian
  815. * changes to compile it with Delphi 4.0
  816. Revision 1.85 1999/05/02 23:29:57 peter
  817. * readded condition, becuase it's needed for set<cond> and cmov<cond> !
  818. Revision 1.84 1999/05/02 22:41:47 peter
  819. * moved section names to systems
  820. * fixed nasm,intel writer
  821. Revision 1.83 1999/05/02 21:33:51 florian
  822. * several bugs regarding -Or fixed
  823. Revision 1.82 1999/05/01 13:47:51 peter
  824. * fix hack for fsub
  825. Revision 1.81 1999/05/01 13:23:56 peter
  826. * merged nasm compiler
  827. * old asm moved to oldasm/
  828. Revision 1.80 1999/04/17 22:17:04 pierre
  829. * ifdef USE_OP3 released (changed into ifndef NO_OP3)
  830. * SHRD and SHLD first operand (ATT syntax) can only be CL reg or immediate const
  831. Revision 1.79 1999/04/16 11:49:37 peter
  832. + tempalloc
  833. + -at to show temp alloc info in .s file
  834. Revision 1.78 1999/04/16 10:00:54 pierre
  835. + ifdef USE_OP3 code :
  836. added all missing op_... constructors for tai386 needed
  837. for SHRD,SHLD and IMUL code in assembler readers
  838. (check in tests/tbs0123.pp)
  839. Revision 1.77 1999/04/14 12:44:46 daniel
  840. * Proper fix for the .bss conflict
  841. Revision 1.76 1999/04/14 11:43:25 michael
  842. + reverted back to .section .bss
  843. Revision 1.75 1999/04/13 08:45:33 daniel
  844. * EMX assembler prefers .bss instead of .section .bss
  845. Revision 1.74 1999/04/10 16:14:59 peter
  846. * fixed browcol
  847. + -ar to show regalloc info in .s file
  848. Revision 1.73 1999/04/09 08:33:45 peter
  849. * write * before register with call for the stricter as versions
  850. Revision 1.72 1999/03/31 13:55:02 peter
  851. * assembler inlining working for ag386bin
  852. Revision 1.71 1999/03/29 16:05:42 peter
  853. * optimizer working for ag386bin
  854. Revision 1.70 1999/03/10 21:48:21 florian
  855. * bug0218 fixed, ag386att writes now all real types as byte
  856. sequences to minimize rouding error, in -al mode the
  857. value is written as comment
  858. Revision 1.69 1999/03/10 13:25:43 pierre
  859. section order changed to get closer output from coff writer
  860. Revision 1.68 1999/03/02 02:56:09 peter
  861. + stabs support for binary writers
  862. * more fixes and missing updates from the previous commit :(
  863. Revision 1.67 1999/03/01 15:46:15 peter
  864. * ag386bin finally make cycles correct
  865. * prefixes are now also normal opcodes
  866. Revision 1.66 1999/02/26 00:48:12 peter
  867. * assembler writers fixed for ag386bin
  868. Revision 1.65 1999/02/25 21:02:17 peter
  869. * ag386bin updates
  870. + coff writer
  871. Revision 1.64 1999/02/22 02:14:57 peter
  872. * updates for ag386bin
  873. Revision 1.63 1999/02/17 10:16:25 peter
  874. * small fixes for the binary writer
  875. Revision 1.62 1999/01/12 14:21:26 peter
  876. * fixed pushw warning
  877. Revision 1.61 1998/12/29 18:50:04 jonas
  878. * don't write debug info if not (cs_debuginfo in aktmoduleswitches)
  879. Revision 1.60 1998/12/23 22:53:43 peter
  880. * don't count ait_marker for lineinfo
  881. Revision 1.58 1998/12/11 00:02:38 peter
  882. + globtype,tokens,version unit splitted from globals
  883. Revision 1.57 1998/12/01 23:36:32 pierre
  884. * zero padded alignment was buggy
  885. Revision 1.56 1998/12/01 11:19:37 peter
  886. * fixed range problem with in [tasmop]
  887. Revision 1.55 1998/11/30 09:42:53 pierre
  888. * some range check bugs fixed (still not working !)
  889. + added DLL writing support for win32 (also accepts variables)
  890. + TempAnsi for code that could be used for Temporary ansi strings
  891. handling
  892. Revision 1.54 1998/11/17 10:04:13 pierre
  893. * zero indexed file not searched
  894. Revision 1.53 1998/11/17 00:26:08 peter
  895. * fixed for $H+
  896. Revision 1.52 1998/11/12 11:19:32 pierre
  897. * fix for first line of function break
  898. Revision 1.51 1998/11/09 09:21:18 pierre
  899. * fix for stabs line infos
  900. Revision 1.50 1998/11/06 09:49:25 pierre
  901. * n_line stuff cleaned
  902. Revision 1.49 1998/10/26 23:07:02 peter
  903. * fixpath fix
  904. Revision 1.48 1998/10/15 15:08:39 pierre
  905. * removed lots of unnecessary inputfile system.open calls
  906. (made a big speed decrease on go32v2 !)
  907. Revision 1.47 1998/10/13 14:01:05 peter
  908. * fixed -al
  909. Revision 1.46 1998/10/13 13:10:07 peter
  910. * new style for m68k/i386 infos and enums
  911. Revision 1.45 1998/10/12 12:20:39 pierre
  912. + added tai_const_symbol_offset
  913. for r : pointer = @var.field;
  914. * better message for different arg names on implementation
  915. of function
  916. Revision 1.44 1998/10/06 17:16:32 pierre
  917. * some memory leaks fixed (thanks to Peter for heaptrc !)
  918. Revision 1.43 1998/10/01 20:19:12 jonas
  919. + ait_marker support
  920. Revision 1.42 1998/09/28 16:57:08 pierre
  921. * changed all length(p^.value_str^) into str_length(p)
  922. to get it work with and without ansistrings
  923. * changed sourcefiles field of tmodule to a pointer
  924. Revision 1.41 1998/09/20 17:11:19 jonas
  925. * released REGALLOC
  926. Revision 1.40 1998/09/16 17:58:34 jonas
  927. * fixed -dRegAlloc and -dDRegalloc problems
  928. Revision 1.39 1998/09/11 11:30:41 pierre
  929. -al -g option bug corrected
  930. Revision 1.38.2.1 1998/09/11 10:49:09 pierre
  931. * bug with -g -al option removed
  932. Revision 1.38 1998/09/07 22:23:35 peter
  933. * fixed for no gdb compiler
  934. Revision 1.37 1998/09/07 18:33:34 peter
  935. + smartlinking for win95 imports
  936. Revision 1.36 1998/09/04 17:34:19 pierre
  937. * bug with datalabel corrected
  938. + assembler errors better commented
  939. * one nested record crash removed
  940. Revision 1.35 1998/09/03 17:08:38 pierre
  941. * better lines for stabs
  942. (no scroll back to if before else part
  943. no return to case line at jump outside case)
  944. + source lines also if not in order
  945. Revision 1.34 1998/09/03 11:22:41 peter
  946. + support for cs_asm_source
  947. Revision 1.33 1998/08/26 10:06:33 peter
  948. * reduce amount of asmfiles generated
  949. * no stabs are written in writefilelineinfo when debuginfo is off
  950. Revision 1.32 1998/08/20 09:26:35 pierre
  951. + funcret setting in underproc testing
  952. compile with _dTEST_FUNCRET
  953. Revision 1.31 1998/08/11 14:01:16 peter
  954. * @object type also for extended and comp
  955. Revision 1.30 1998/08/10 23:56:02 peter
  956. * fixed extended writing
  957. Revision 1.29 1998/08/10 14:49:35 peter
  958. + localswitches, moduleswitches, globalswitches splitting
  959. Revision 1.27 1998/08/08 12:30:07 florian
  960. * extended writing improved
  961. Revision 1.26 1998/08/08 10:19:16 florian
  962. * small fixes to write the extended type correct
  963. Revision 1.28 1998/08/10 10:01:33 peter
  964. * Fixed with GDB undefined
  965. Revision 1.25 1998/08/06 16:53:25 pierre
  966. * debugging info corrected
  967. Revision 1.24 1998/07/14 14:46:37 peter
  968. * released NEWINPUT
  969. Revision 1.23 1998/07/07 11:19:51 peter
  970. + NEWINPUT for a better inputfile and scanner object
  971. Revision 1.22 1998/06/08 22:59:42 peter
  972. * smartlinking works for win32
  973. * some defines to exclude some compiler parts
  974. Revision 1.21 1998/06/05 17:46:01 peter
  975. * tp doesn't like comp() typecast
  976. Revision 1.20 1998/06/04 23:51:27 peter
  977. * m68k compiles
  978. + .def file creation moved to gendef.pas so it could also be used
  979. for win32
  980. Revision 1.19 1998/05/31 14:13:29 peter
  981. * fixed call bugs with assembler readers
  982. + OPR_SYMBOL to hold a symbol in the asm parser
  983. * fixed staticsymtable vars which were acessed through %ebp instead of
  984. name
  985. Revision 1.18 1998/05/28 17:24:25 peter
  986. - $R- for tp to solve range errors with in[]
  987. Revision 1.17 1998/05/25 17:11:34 pierre
  988. * firstpasscount bug fixed
  989. now all is already set correctly the first time
  990. under EXTDEBUG try -gp to skip all other firstpasses
  991. it works !!
  992. * small bug fixes
  993. - for smallsets with -dTESTSMALLSET
  994. - some warnings removed (by correcting code !)
  995. Revision 1.16 1998/05/23 01:20:54 peter
  996. + aktasmmode, aktoptprocessor, aktoutputformat
  997. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  998. + $LIBNAME to set the library name where the unit will be put in
  999. * splitted cgi386 a bit (codeseg to large for bp7)
  1000. * nasm, tasm works again. nasm moved to ag386nsm.pas
  1001. Revision 1.15 1998/05/11 13:07:53 peter
  1002. + $ifdef NEWPPU for the new ppuformat
  1003. + $define GDB not longer required
  1004. * removed all warnings and stripped some log comments
  1005. * no findfirst/findnext anymore to remove smartlink *.o files
  1006. Revision 1.14 1998/05/06 18:36:53 peter
  1007. * tai_section extended with code,data,bss sections and enumerated type
  1008. * ident 'compiled by FPC' moved to pmodules
  1009. * small fix for smartlink
  1010. Revision 1.13 1998/05/06 08:38:32 pierre
  1011. * better position info with UseTokenInfo
  1012. UseTokenInfo greatly simplified
  1013. + added check for changed tree after first time firstpass
  1014. (if we could remove all the cases were it happen
  1015. we could skip all firstpass if firstpasscount > 1)
  1016. Only with ExtDebug
  1017. Revision 1.12 1998/05/04 17:54:24 peter
  1018. + smartlinking works (only case jumptable left todo)
  1019. * redesign of systems.pas to support assemblers and linkers
  1020. + Unitname is now also in the PPU-file, increased version to 14
  1021. Revision 1.11 1998/05/01 07:43:52 florian
  1022. + basics for rtti implemented
  1023. + switch $m (generate rtti for published sections)
  1024. Revision 1.10 1998/04/30 15:59:39 pierre
  1025. * GDB works again better :
  1026. correct type info in one pass
  1027. + UseTokenInfo for better source position
  1028. * fixed one remaining bug in scanner for line counts
  1029. * several little fixes
  1030. Revision 1.9 1998/04/29 10:33:41 pierre
  1031. + added some code for ansistring (not complete nor working yet)
  1032. * corrected operator overloading
  1033. * corrected nasm output
  1034. + started inline procedures
  1035. + added starstarn : use ** for exponentiation (^ gave problems)
  1036. + started UseTokenInfo cond to get accurate positions
  1037. Revision 1.8 1998/04/28 08:23:58 pierre
  1038. * bug in stabn generation fixed
  1039. Revision 1.7 1998/04/27 23:10:27 peter
  1040. + new scanner
  1041. * $makelib -> if smartlink
  1042. * small filename fixes pmodule.setfilename
  1043. * moved import from files.pas -> import.pas
  1044. Revision 1.6 1998/04/21 11:30:13 peter
  1045. * fixed $ifdef regalloc
  1046. Revision 1.5 1998/04/16 16:53:24 jonas
  1047. * changed $ifdef regalloc to $ifdef dregalloc (= debugging info)
  1048. Revision 1.4 1998/04/09 15:46:38 florian
  1049. + register allocation tracing stuff added
  1050. Revision 1.3 1998/04/08 16:58:00 pierre
  1051. * several bugfixes
  1052. ADD ADC and AND are also sign extended
  1053. nasm output OK (program still crashes at end
  1054. and creates wrong assembler files !!)
  1055. procsym types sym in tdef removed !!
  1056. }