ag386nsm.pas 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. This unit implements an asmoutput class for the Nasm assembler with
  5. Intel syntax for the i386+
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. unit ag386nsm;
  20. {$i defines.inc}
  21. interface
  22. uses aasm,assemble;
  23. type
  24. pi386nasmasmlist=^ti386nasmasmlist;
  25. ti386nasmasmlist = object(tasmlist)
  26. procedure WriteTree(p:taasmoutput);virtual;
  27. procedure WriteAsmList;virtual;
  28. procedure WriteExternals;
  29. end;
  30. implementation
  31. uses
  32. {$ifdef delphi}
  33. sysutils,
  34. {$endif}
  35. cutils,globtype,globals,systems,cobjects,
  36. fmodule,finput,verbose,cpubase,cpuasm
  37. ;
  38. const
  39. line_length = 64;
  40. var
  41. lastfileinfo : tfileposinfo;
  42. infile,
  43. lastinfile : tinputfile;
  44. function fixline(s:string):string;
  45. {
  46. return s with all leading and ending spaces and tabs removed
  47. }
  48. var
  49. i,j,k : longint;
  50. begin
  51. i:=length(s);
  52. while (i>0) and (s[i] in [#9,' ']) do
  53. dec(i);
  54. j:=1;
  55. while (j<i) and (s[j] in [#9,' ']) do
  56. inc(j);
  57. for k:=j to i do
  58. if s[k] in [#0..#31,#127..#255] then
  59. s[k]:='.';
  60. fixline:=Copy(s,j,i-j+1);
  61. end;
  62. function single2str(d : single) : string;
  63. var
  64. hs : string;
  65. p : byte;
  66. begin
  67. str(d,hs);
  68. { nasm expects a lowercase e }
  69. p:=pos('E',hs);
  70. if p>0 then
  71. hs[p]:='e';
  72. p:=pos('+',hs);
  73. if p>0 then
  74. delete(hs,p,1);
  75. single2str:=lower(hs);
  76. end;
  77. function double2str(d : double) : string;
  78. var
  79. hs : string;
  80. p : byte;
  81. begin
  82. str(d,hs);
  83. { nasm expects a lowercase e }
  84. p:=pos('E',hs);
  85. if p>0 then
  86. hs[p]:='e';
  87. p:=pos('+',hs);
  88. if p>0 then
  89. delete(hs,p,1);
  90. double2str:=lower(hs);
  91. end;
  92. function extended2str(e : extended) : string;
  93. var
  94. hs : string;
  95. p : byte;
  96. begin
  97. str(e,hs);
  98. { nasm expects a lowercase e }
  99. p:=pos('E',hs);
  100. if p>0 then
  101. hs[p]:='e';
  102. p:=pos('+',hs);
  103. if p>0 then
  104. delete(hs,p,1);
  105. extended2str:=lower(hs);
  106. end;
  107. function comp2str(d : bestreal) : string;
  108. type
  109. pdouble = ^double;
  110. var
  111. c : comp;
  112. dd : pdouble;
  113. begin
  114. {$ifdef FPC}
  115. c:=comp(d);
  116. {$else}
  117. c:=d;
  118. {$endif}
  119. dd:=pdouble(@c); { this makes a bitwise copy of c into a double }
  120. comp2str:=double2str(dd^);
  121. end;
  122. function getreferencestring(var ref : treference) : string;
  123. var
  124. s : string;
  125. first : boolean;
  126. begin
  127. if ref.is_immediate then
  128. begin
  129. getreferencestring:=tostr(ref.offset);
  130. exit;
  131. end
  132. else
  133. with ref do
  134. begin
  135. first:=true;
  136. inc(offset,offsetfixup);
  137. offsetfixup:=0;
  138. if ref.segment<>R_NO then
  139. s:='['+int_reg2str[segment]+':'
  140. else
  141. s:='[';
  142. if assigned(symbol) then
  143. begin
  144. s:=s+symbol^.name;
  145. first:=false;
  146. end;
  147. if (base<>R_NO) then
  148. begin
  149. if not(first) then
  150. s:=s+'+'
  151. else
  152. first:=false;
  153. s:=s+int_reg2str[base];
  154. end;
  155. if (index<>R_NO) then
  156. begin
  157. if not(first) then
  158. s:=s+'+'
  159. else
  160. first:=false;
  161. s:=s+int_reg2str[index];
  162. if scalefactor<>0 then
  163. s:=s+'*'+tostr(scalefactor);
  164. end;
  165. if offset<0 then
  166. s:=s+tostr(offset)
  167. else if (offset>0) then
  168. s:=s+'+'+tostr(offset);
  169. s:=s+']';
  170. end;
  171. getreferencestring:=s;
  172. end;
  173. function sizestr(s:topsize;dest:boolean):string;
  174. begin
  175. case s of
  176. S_B : sizestr:='byte ';
  177. S_W : sizestr:='word ';
  178. S_L : sizestr:='dword ';
  179. S_IS : sizestr:='word ';
  180. S_IL : sizestr:='dword ';
  181. S_IQ : sizestr:='qword ';
  182. S_FS : sizestr:='dword ';
  183. S_FL : sizestr:='qword ';
  184. S_FX : sizestr:='tword ';
  185. S_BW : if dest then
  186. sizestr:='word '
  187. else
  188. sizestr:='byte ';
  189. S_BL : if dest then
  190. sizestr:='dword '
  191. else
  192. sizestr:='byte ';
  193. S_WL : if dest then
  194. sizestr:='dword '
  195. else
  196. sizestr:='word ';
  197. else { S_NO }
  198. sizestr:='';
  199. end;
  200. end;
  201. function getopstr(const o:toper;s : topsize; opcode: tasmop;ops:longint;dest : boolean) : string;
  202. var
  203. hs : string;
  204. begin
  205. case o.typ of
  206. top_reg :
  207. getopstr:=int_nasmreg2str[o.reg];
  208. top_const :
  209. begin
  210. if (ops=1) and (opcode<>A_RET) then
  211. getopstr:=sizestr(s,dest)+tostr(o.val)
  212. else
  213. getopstr:=tostr(o.val);
  214. end;
  215. top_symbol :
  216. begin
  217. if assigned(o.sym) then
  218. hs:='dword '+o.sym^.name
  219. else
  220. hs:='dword ';
  221. if o.symofs>0 then
  222. hs:=hs+'+'+tostr(o.symofs)
  223. else
  224. if o.symofs<0 then
  225. hs:=hs+tostr(o.symofs)
  226. else
  227. if not(assigned(o.sym)) then
  228. hs:=hs+'0';
  229. getopstr:=hs;
  230. end;
  231. top_ref :
  232. begin
  233. hs:=getreferencestring(o.ref^);
  234. if not ((opcode = A_LEA) or (opcode = A_LGS) or
  235. (opcode = A_LSS) or (opcode = A_LFS) or
  236. (opcode = A_LES) or (opcode = A_LDS) or
  237. (opcode = A_SHR) or (opcode = A_SHL) or
  238. (opcode = A_SAR) or (opcode = A_SAL) or
  239. (opcode = A_OUT) or (opcode = A_IN)) then
  240. begin
  241. hs:=sizestr(s,dest)+hs;
  242. end;
  243. getopstr:=hs;
  244. end;
  245. else
  246. internalerror(10001);
  247. end;
  248. end;
  249. function getopstr_jmp(const o:toper; op : tasmop) : string;
  250. var
  251. hs : string;
  252. begin
  253. case o.typ of
  254. top_reg :
  255. getopstr_jmp:=int_nasmreg2str[o.reg];
  256. top_ref :
  257. getopstr_jmp:=getreferencestring(o.ref^);
  258. top_const :
  259. getopstr_jmp:=tostr(o.val);
  260. top_symbol :
  261. begin
  262. hs:=o.sym^.name;
  263. if o.symofs>0 then
  264. hs:=hs+'+'+tostr(o.symofs)
  265. else
  266. if o.symofs<0 then
  267. hs:=hs+tostr(o.symofs);
  268. if (op=A_JCXZ) or (op=A_JECXZ) or
  269. (op=A_LOOP) or (op=A_LOOPE) or
  270. (op=A_LOOPNE) or (op=A_LOOPNZ) or
  271. (op=A_LOOPZ) then
  272. getopstr_jmp:=hs
  273. else
  274. getopstr_jmp:='NEAR '+hs;
  275. end;
  276. else
  277. internalerror(10001);
  278. end;
  279. end;
  280. {****************************************************************************
  281. Ti386nasmasmlist
  282. ****************************************************************************}
  283. var
  284. LastSec : tsection;
  285. const
  286. ait_const2str:array[ait_const_32bit..ait_const_8bit] of string[8]=
  287. (#9'DD'#9,#9'DW'#9,#9'DB'#9);
  288. Function PadTabs(const p:string;addch:char):string;
  289. var
  290. s : string;
  291. i : longint;
  292. begin
  293. i:=length(p);
  294. if addch<>#0 then
  295. begin
  296. inc(i);
  297. s:=p+addch;
  298. end
  299. else
  300. s:=p;
  301. if i<8 then
  302. PadTabs:=s+#9#9
  303. else
  304. PadTabs:=s+#9;
  305. end;
  306. procedure ti386nasmasmlist.WriteTree(p:taasmoutput);
  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. var
  314. s : string;
  315. {prefix,
  316. suffix : string; no need here }
  317. hp : tai;
  318. counter,
  319. lines,
  320. i,j,l : longint;
  321. InlineLevel : longint;
  322. consttyp : tait;
  323. found,
  324. do_line,
  325. quoted : boolean;
  326. sep : char;
  327. begin
  328. if not assigned(p) then
  329. exit;
  330. InlineLevel:=0;
  331. { lineinfo is only needed for codesegment (PFV) }
  332. do_line:=(cs_asm_source in aktglobalswitches) or
  333. ((cs_lineinfo in aktmoduleswitches)
  334. and (p=codesegment));
  335. hp:=tai(p.first);
  336. while assigned(hp) do
  337. begin
  338. aktfilepos:=hp.fileinfo;
  339. if not(hp.typ in nolinetai) then
  340. begin
  341. if do_line then
  342. begin
  343. { load infile }
  344. if lastfileinfo.fileindex<>hp.fileinfo.fileindex then
  345. begin
  346. infile:=current_module.sourcefiles.get_file(hp.fileinfo.fileindex);
  347. if assigned(infile) then
  348. begin
  349. { open only if needed !! }
  350. if (cs_asm_source in aktglobalswitches) then
  351. infile.open;
  352. end;
  353. { avoid unnecessary reopens of the same file !! }
  354. lastfileinfo.fileindex:=hp.fileinfo.fileindex;
  355. { be sure to change line !! }
  356. lastfileinfo.line:=-1;
  357. end;
  358. { write source }
  359. if (cs_asm_source in aktglobalswitches) and
  360. assigned(infile) then
  361. begin
  362. if (infile<>lastinfile) then
  363. begin
  364. AsmWriteLn(target_asm.comment+'['+infile.name^+']');
  365. if assigned(lastinfile) then
  366. lastinfile.close;
  367. end;
  368. if (hp.fileinfo.line<>lastfileinfo.line) and
  369. ((hp.fileinfo.line<infile.maxlinebuf) or (InlineLevel>0)) then
  370. begin
  371. if (hp.fileinfo.line<>0) and
  372. ((infile.linebuf^[hp.fileinfo.line]>=0) or (InlineLevel>0)) then
  373. AsmWriteLn(target_asm.comment+'['+tostr(hp.fileinfo.line)+'] '+
  374. fixline(infile.GetLineStr(hp.fileinfo.line)));
  375. { set it to a negative value !
  376. to make that is has been read already !! PM }
  377. if (infile.linebuf^[hp.fileinfo.line]>=0) then
  378. infile.linebuf^[hp.fileinfo.line]:=-infile.linebuf^[hp.fileinfo.line]-1;
  379. end;
  380. end;
  381. lastfileinfo:=hp.fileinfo;
  382. lastinfile:=infile;
  383. end;
  384. end;
  385. case hp.typ of
  386. ait_comment :
  387. Begin
  388. AsmWrite(target_asm.comment);
  389. AsmWritePChar(tai_asm_comment(hp).str);
  390. AsmLn;
  391. End;
  392. ait_regalloc :
  393. begin
  394. if (cs_asm_regalloc in aktglobalswitches) then
  395. AsmWriteLn(target_asm.comment+'Register '+att_reg2str[tairegalloc(hp).reg]+
  396. allocstr[tairegalloc(hp).allocation]);
  397. end;
  398. ait_tempalloc :
  399. begin
  400. if (cs_asm_tempalloc in aktglobalswitches) then
  401. AsmWriteLn(target_asm.comment+'Temp '+tostr(taitempalloc(hp).temppos)+','+
  402. tostr(taitempalloc(hp).tempsize)+allocstr[taitempalloc(hp).allocation]);
  403. end;
  404. ait_section :
  405. begin
  406. if tai_section(hp).sec<>sec_none then
  407. begin
  408. AsmLn;
  409. AsmWriteLn('SECTION '+target_asm.secnames[tai_section(hp).sec]);
  410. end;
  411. LastSec:=tai_section(hp).sec;
  412. end;
  413. ait_align :
  414. AsmWriteLn(#9'ALIGN '+tostr(tai_align(hp).aligntype));
  415. ait_datablock :
  416. begin
  417. if tai_datablock(hp).is_global then
  418. begin
  419. AsmWrite(#9'GLOBAL ');
  420. AsmWriteLn(tai_datablock(hp).sym^.name);
  421. end;
  422. AsmWrite(PadTabs(tai_datablock(hp).sym^.name,':'));
  423. AsmWriteLn('RESB'#9+tostr(tai_datablock(hp).size));
  424. end;
  425. ait_const_32bit,
  426. ait_const_16bit,
  427. ait_const_8bit :
  428. begin
  429. AsmWrite(ait_const2str[hp.typ]+tostr(tai_const(hp).value));
  430. consttyp:=hp.typ;
  431. l:=0;
  432. repeat
  433. found:=(not (tai(hp.next)=nil)) and (tai(hp.next).typ=consttyp);
  434. if found then
  435. begin
  436. hp:=tai(hp.next);
  437. s:=','+tostr(tai_const(hp).value);
  438. AsmWrite(s);
  439. inc(l,length(s));
  440. end;
  441. until (not found) or (l>line_length);
  442. AsmLn;
  443. end;
  444. ait_const_symbol :
  445. begin
  446. AsmWrite(#9#9'DD'#9);
  447. AsmWrite(tai_const_symbol(hp).sym^.name);
  448. if tai_const_symbol(hp).offset>0 then
  449. AsmWrite('+'+tostr(tai_const_symbol(hp).offset))
  450. else if tai_const_symbol(hp).offset<0 then
  451. AsmWrite(tostr(tai_const_symbol(hp).offset));
  452. AsmLn;
  453. end;
  454. ait_const_rva :
  455. begin
  456. AsmWrite(#9#9'RVA'#9);
  457. AsmWriteLn(tai_const_symbol(hp).sym^.name);
  458. end;
  459. ait_real_32bit :
  460. AsmWriteLn(#9#9'DD'#9+single2str(tai_real_32bit(hp).value));
  461. ait_real_64bit :
  462. AsmWriteLn(#9#9'DQ'#9+double2str(tai_real_64bit(hp).value));
  463. ait_real_80bit :
  464. AsmWriteLn(#9#9'DT'#9+extended2str(tai_real_80bit(hp).value));
  465. ait_comp_64bit :
  466. AsmWriteLn(#9#9'DQ'#9+comp2str(tai_real_80bit(hp).value));
  467. ait_string :
  468. begin
  469. counter := 0;
  470. lines := tai_string(hp).len div line_length;
  471. { separate lines in different parts }
  472. if tai_string(hp).len > 0 then
  473. Begin
  474. for j := 0 to lines-1 do
  475. begin
  476. AsmWrite(#9#9'DB'#9);
  477. quoted:=false;
  478. for i:=counter to counter+line_length-1 do
  479. begin
  480. { it is an ascii character. }
  481. if (ord(tai_string(hp).str[i])>31) and
  482. (ord(tai_string(hp).str[i])<128) and
  483. (tai_string(hp).str[i]<>'"') then
  484. begin
  485. if not(quoted) then
  486. begin
  487. if i>counter then
  488. AsmWrite(',');
  489. AsmWrite('"');
  490. end;
  491. AsmWrite(tai_string(hp).str[i]);
  492. quoted:=true;
  493. end { if > 31 and < 128 and ord('"') }
  494. else
  495. begin
  496. if quoted then
  497. AsmWrite('"');
  498. if i>counter then
  499. AsmWrite(',');
  500. quoted:=false;
  501. AsmWrite(tostr(ord(tai_string(hp).str[i])));
  502. end;
  503. end; { end for i:=0 to... }
  504. if quoted then AsmWrite('"');
  505. AsmWrite(target_os.newline);
  506. inc(counter,line_length);
  507. end; { end for j:=0 ... }
  508. { do last line of lines }
  509. if counter<tai_string(hp).len then
  510. AsmWrite(#9#9'DB'#9);
  511. quoted:=false;
  512. for i:=counter to tai_string(hp).len-1 do
  513. begin
  514. { it is an ascii character. }
  515. if (ord(tai_string(hp).str[i])>31) and
  516. (ord(tai_string(hp).str[i])<128) and
  517. (tai_string(hp).str[i]<>'"') then
  518. begin
  519. if not(quoted) then
  520. begin
  521. if i>counter then
  522. AsmWrite(',');
  523. AsmWrite('"');
  524. end;
  525. AsmWrite(tai_string(hp).str[i]);
  526. quoted:=true;
  527. end { if > 31 and < 128 and " }
  528. else
  529. begin
  530. if quoted then
  531. AsmWrite('"');
  532. if i>counter then
  533. AsmWrite(',');
  534. quoted:=false;
  535. AsmWrite(tostr(ord(tai_string(hp).str[i])));
  536. end;
  537. end; { end for i:=0 to... }
  538. if quoted then
  539. AsmWrite('"');
  540. end;
  541. AsmLn;
  542. end;
  543. ait_label :
  544. begin
  545. if tai_label(hp).l^.is_used then
  546. AsmWriteLn(tai_label(hp).l^.name+':');
  547. end;
  548. ait_direct :
  549. begin
  550. AsmWritePChar(tai_direct(hp).str);
  551. AsmLn;
  552. end;
  553. ait_symbol :
  554. begin
  555. if tai_symbol(hp).is_global then
  556. begin
  557. AsmWrite(#9'GLOBAL ');
  558. AsmWriteLn(tai_symbol(hp).sym^.name);
  559. end;
  560. AsmWrite(tai_symbol(hp).sym^.name);
  561. if assigned(hp.next) and not(tai(hp.next).typ in
  562. [ait_const_32bit,ait_const_16bit,ait_const_8bit,
  563. ait_const_symbol,ait_const_rva,
  564. ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit,ait_string]) then
  565. AsmWriteLn(':')
  566. end;
  567. ait_symbol_end :
  568. begin
  569. end;
  570. ait_instruction :
  571. begin
  572. { Must be done with args in ATT order }
  573. taicpu(hp).CheckNonCommutativeOpcodes;
  574. { We need intel order, no At&t }
  575. taicpu(hp).SwapOperands;
  576. { Reset
  577. suffix:='';
  578. prefix:='';}
  579. s:='';
  580. if (taicpu(hp).opcode=A_FADDP) and (taicpu(hp).ops=0) then
  581. begin
  582. taicpu(hp).ops:=2;
  583. taicpu(hp).oper[0].typ:=top_reg;
  584. taicpu(hp).oper[0].reg:=R_ST1;
  585. taicpu(hp).oper[1].typ:=top_reg;
  586. taicpu(hp).oper[1].reg:=R_ST;
  587. end;
  588. if taicpu(hp).ops<>0 then
  589. begin
  590. if is_calljmp(taicpu(hp).opcode) then
  591. s:=#9+getopstr_jmp(taicpu(hp).oper[0],taicpu(hp).opcode)
  592. else
  593. begin
  594. { We need to explicitely set
  595. word prefix to get selectors
  596. to be pushed in 2 bytes PM }
  597. if (taicpu(hp).opsize=S_W) and
  598. ((taicpu(hp).opcode=A_PUSH) or
  599. (taicpu(hp).opcode=A_POP)) and
  600. (taicpu(hp).oper[0].typ=top_reg) and
  601. ((taicpu(hp).oper[0].reg>=firstsreg) and
  602. (taicpu(hp).oper[0].reg<=lastsreg)) then
  603. AsmWriteln(#9#9'DB'#9'066h');
  604. for i:=0 to taicpu(hp).ops-1 do
  605. begin
  606. if i=0 then
  607. sep:=#9
  608. else
  609. sep:=',';
  610. s:=s+sep+getopstr(taicpu(hp).oper[i],taicpu(hp).opsize,taicpu(hp).opcode,
  611. taicpu(hp).ops,(i=2));
  612. end;
  613. end;
  614. end;
  615. if taicpu(hp).opcode=A_FWAIT then
  616. AsmWriteln(#9#9'DB'#9'09bh')
  617. else
  618. AsmWriteLn(#9#9+{prefix+}int_op2str[taicpu(hp).opcode]+
  619. cond2str[taicpu(hp).condition]+{suffix+}s);
  620. end;
  621. {$ifdef GDB}
  622. ait_stabn,
  623. ait_stabs,
  624. ait_force_line,
  625. ait_stab_function_name : ;
  626. {$endif GDB}
  627. ait_cut :
  628. begin
  629. { only reset buffer if nothing has changed }
  630. if AsmSize=AsmStartSize then
  631. AsmClear
  632. else
  633. begin
  634. AsmClose;
  635. DoAssemble;
  636. AsmCreate(tai_cut(hp).place);
  637. end;
  638. { avoid empty files }
  639. while assigned(hp.next) and (tai(hp.next).typ in [ait_cut,ait_section,ait_comment]) do
  640. begin
  641. if tai(hp.next).typ=ait_section then
  642. lastsec:=tai_section(hp.next).sec;
  643. hp:=tai(hp.next);
  644. end;
  645. if lastsec<>sec_none then
  646. AsmWriteLn('SECTION '+target_asm.secnames[lastsec]);
  647. AsmStartSize:=AsmSize;
  648. end;
  649. ait_marker :
  650. if tai_marker(hp).kind=InlineStart then
  651. inc(InlineLevel)
  652. else if tai_marker(hp).kind=InlineEnd then
  653. dec(InlineLevel);
  654. else
  655. internalerror(10000);
  656. end;
  657. hp:=tai(hp.next);
  658. end;
  659. end;
  660. var
  661. currentasmlist : PAsmList;
  662. procedure writeexternal(p:pnamedindexobject);
  663. begin
  664. if pasmsymbol(p)^.defbind=AB_EXTERNAL then
  665. currentasmlist^.AsmWriteln('EXTERN'#9+p^.name);
  666. end;
  667. procedure ti386nasmasmlist.WriteExternals;
  668. begin
  669. currentasmlist:=@self;
  670. AsmSymbolList^.foreach({$ifdef fpcprocvar}@{$endif}writeexternal);
  671. end;
  672. procedure ti386nasmasmlist.WriteAsmList;
  673. begin
  674. {$ifdef EXTDEBUG}
  675. if assigned(current_module.mainsource) then
  676. comment(v_info,'Start writing nasm-styled assembler output for '+current_module.mainsource^);
  677. {$endif}
  678. LastSec:=sec_none;
  679. AsmWriteLn('BITS 32');
  680. AsmLn;
  681. countlabelref:=false;
  682. lastfileinfo.line:=-1;
  683. lastfileinfo.fileindex:=0;
  684. lastinfile:=nil;
  685. WriteExternals;
  686. { Nasm doesn't support stabs
  687. WriteTree(debuglist);}
  688. WriteTree(codesegment);
  689. WriteTree(datasegment);
  690. WriteTree(consts);
  691. WriteTree(rttilist);
  692. WriteTree(resourcestringlist);
  693. WriteTree(bsssegment);
  694. countlabelref:=true;
  695. AsmLn;
  696. {$ifdef EXTDEBUG}
  697. if assigned(current_module.mainsource) then
  698. comment(v_info,'Done writing nasm-styled assembler output for '+current_module.mainsource^);
  699. {$endif EXTDEBUG}
  700. end;
  701. end.
  702. {
  703. $Log$
  704. Revision 1.3 2000-12-25 00:07:31 peter
  705. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  706. tlinkedlist objects)
  707. Revision 1.2 2000/11/29 00:30:43 florian
  708. * unused units removed from uses clause
  709. * some changes for widestrings
  710. Revision 1.1 2000/10/15 09:47:42 peter
  711. * moved to i386/
  712. Revision 1.6 2000/09/24 15:06:11 peter
  713. * use defines.inc
  714. Revision 1.5 2000/08/27 16:11:49 peter
  715. * moved some util functions from globals,cobjects to cutils
  716. * splitted files into finput,fmodule
  717. Revision 1.4 2000/08/20 17:38:21 peter
  718. * smartlinking fixed for linux (merged)
  719. Revision 1.3 2000/07/13 12:08:24 michael
  720. + patched to 1.1.0 with former 1.09patch from peter
  721. Revision 1.2 2000/07/13 11:32:30 michael
  722. + removed logs
  723. }