ag68kgas.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. {
  2. $Id$
  3. Copyright (c) 1998 by the FPC development team
  4. This unit implements an asmoutput class for MOTOROLA syntax with
  5. Motorola 68000 (for GAS v2.52 AND HIGER)
  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. What's to do:
  19. o Verify if this actually work as indirect mode with name of variables
  20. o write lines numbers and file names to output file
  21. o generate debugging informations
  22. }
  23. unit ag68kgas;
  24. interface
  25. uses aasm,assemble;
  26. type
  27. pm68kgasasmlist=^tm68kgasasmlist;
  28. tm68kgasasmlist = object(tasmlist)
  29. procedure WriteTree(p:paasmoutput);virtual;
  30. procedure WriteAsmList;virtual;
  31. end;
  32. implementation
  33. uses
  34. dos,globals,systems,cobjects,m68k,
  35. strings,files,verbose
  36. {$ifdef GDB}
  37. ,gdb
  38. {$endif GDB}
  39. ;
  40. const
  41. line_length = 70;
  42. var
  43. infile : pextfile;
  44. includecount,lastline : longint;
  45. function double2str(d : double) : string;
  46. var
  47. hs : string;
  48. begin
  49. str(d,hs);
  50. { replace space with + }
  51. if hs[1]=' ' then
  52. hs[1]:='+';
  53. double2str:='0d'+hs
  54. end;
  55. function comp2str(d : bestreal) : string;
  56. type
  57. pdouble = ^double;
  58. var
  59. c : comp;
  60. dd : pdouble;
  61. begin
  62. c:=comp(d);
  63. dd:=pdouble(@c); { this makes a bitwise copy of c into a double }
  64. comp2str:=double2str(dd^);
  65. end;
  66. function getreferencestring(const ref : treference) : string;
  67. var
  68. s : string;
  69. begin
  70. s:='';
  71. if ref.isintvalue then
  72. s:='#'+tostr(ref.offset)
  73. else
  74. with ref do
  75. begin
  76. if assigned(symbol) then
  77. s:=s+symbol^;
  78. if offset<0 then s:=s+tostr(offset)
  79. else if (offset>0) then
  80. begin
  81. if (symbol=nil) then s:=tostr(offset)
  82. else s:=s+'+'+tostr(offset);
  83. end;
  84. if (index<>R_NO) and (base=R_NO) and (direction=dir_none) then
  85. begin
  86. if (scalefactor = 1) or (scalefactor = 0) then
  87. s:=s+'(,'+gas_reg2str[index]+'.l)'
  88. else
  89. s:=s+'(,'+gas_reg2str[index]+'.l*'+tostr(scalefactor)+')'
  90. end
  91. else if (index=R_NO) and (base<>R_NO) and (direction=dir_inc) then
  92. begin
  93. if (scalefactor = 1) or (scalefactor = 0) then
  94. s:=s+'('+gas_reg2str[base]+')+'
  95. else
  96. InternalError(10002);
  97. end
  98. else if (index=R_NO) and (base<>R_NO) and (direction=dir_dec) then
  99. begin
  100. if (scalefactor = 1) or (scalefactor = 0) then
  101. s:=s+'-('+gas_reg2str[base]+')'
  102. else
  103. InternalError(10003);
  104. end
  105. else if (index=R_NO) and (base<>R_NO) and (direction=dir_none) then
  106. begin
  107. s:=s+'('+gas_reg2str[base]+')'
  108. end
  109. else if (index<>R_NO) and (base<>R_NO) and (direction=dir_none) then
  110. begin
  111. if (scalefactor = 1) or (scalefactor = 0) then
  112. s:=s+'('+gas_reg2str[base]+','+gas_reg2str[index]+'.l)'
  113. else
  114. s:=s+'('+gas_reg2str[base]+','+gas_reg2str[index]+'.l*'+tostr(scalefactor)+')';
  115. end;
  116. end; { end with }
  117. getreferencestring:=s;
  118. end;
  119. function getopstr(t : byte;o : pointer) : string;
  120. var
  121. hs : string;
  122. i: tregister;
  123. begin
  124. case t of
  125. top_reg : getopstr:=gas_reg2str[tregister(o)];
  126. top_ref : getopstr:=getreferencestring(preference(o)^);
  127. top_reglist: begin
  128. hs:='';
  129. for i:=R_NO to R_FPSR do
  130. begin
  131. if i in tregisterlist(o^) then
  132. hs:=hs+gas_reg2str[i]+'/';
  133. end;
  134. delete(hs,length(hs),1);
  135. getopstr := hs;
  136. end;
  137. top_const : getopstr:='#'+tostr(longint(o));
  138. top_symbol :
  139. { compare with i386, where a symbol is considered }
  140. { a constant. }
  141. begin
  142. hs[0]:=chr(strlen(pchar(pcsymbol(o)^.symbol)));
  143. move(pchar(pcsymbol(o)^.symbol)^,hs[1],byte(hs[0]));
  144. { inc(byte(hs[0]));}
  145. if pcsymbol(o)^.offset>0 then
  146. hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
  147. else if pcsymbol(o)^.offset<0 then
  148. hs:=hs+tostr(pcsymbol(o)^.offset);
  149. getopstr:=hs;
  150. end;
  151. else internalerror(10001);
  152. end;
  153. end;
  154. function getopstr_jmp(t : byte;o : pointer) : string;
  155. var
  156. hs : string;
  157. begin
  158. case t of
  159. top_reg : getopstr_jmp:=gas_reg2str[tregister(o)];
  160. top_ref : getopstr_jmp:=getreferencestring(preference(o)^);
  161. top_const : getopstr_jmp:=tostr(longint(o));
  162. top_symbol : begin
  163. hs[0]:=chr(strlen(pchar(pcsymbol(o)^.symbol)));
  164. move(pchar(pcsymbol(o)^.symbol)^,hs[1],byte(hs[0]));
  165. if pcsymbol(o)^.offset>0 then
  166. hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
  167. else if pcsymbol(o)^.offset<0 then
  168. hs:=hs+tostr(pcsymbol(o)^.offset);
  169. getopstr_jmp:=hs;
  170. end;
  171. else internalerror(10001);
  172. end;
  173. end;
  174. {****************************************************************************
  175. T68kGASASMOUTPUT
  176. ****************************************************************************}
  177. var
  178. {$ifdef GDB}
  179. n_line : byte;
  180. {$endif}
  181. lastsec : tsection;
  182. const
  183. ait_const2str:array[ait_const_32bit..ait_const_8bit] of string[8]=
  184. (#9'.long'#9,'',#9'.short'#9,#9'.byte'#9);
  185. ait_section2str : array[tsection] of string[6]=
  186. ('','.text','.data','.bss','.idata');
  187. procedure tm68kgasasmlist.WriteTree(p:paasmoutput);
  188. var
  189. hp : pai;
  190. ch : char;
  191. consttyp : tait;
  192. s : string;
  193. pos,l,i : longint;
  194. found : boolean;
  195. {$ifdef GDB}
  196. funcname : pchar;
  197. linecount : longint;
  198. {$endif GDB}
  199. begin
  200. if not assigned(p) then
  201. exit;
  202. {$ifdef GDB}
  203. funcname:=nil;
  204. linecount:=1;
  205. {$endif GDB}
  206. hp:=pai(p^.first);
  207. while assigned(hp) do
  208. begin
  209. { write debugger informations }
  210. {$ifdef GDB}
  211. if cs_debuginfo in aktswitches then
  212. begin
  213. if not (hp^.typ in [ait_external,ait_stabn,ait_stabs,ait_stab_function_name]) then
  214. begin
  215. if assigned(hp^.infile) and (pextfile(hp^.infile)<>infile) then
  216. begin
  217. infile:=hp^.infile;
  218. inc(includecount);
  219. if (hp^.infile^.path^<>'') then
  220. begin
  221. AsmWriteLn(#9'.stabs "'+FixPath(hp^.infile^.path^)+'",'+tostr(n_includefile)+
  222. ',0,0,Ltext'+ToStr(IncludeCount));
  223. end;
  224. AsmWriteLn(#9'.stabs "'+FixFileName(hp^.infile^.name^+hp^.infile^.ext^)+'",'+tostr(n_includefile)+
  225. ',0,0,Ltext'+ToStr(IncludeCount));
  226. AsmWriteLn('Ltext'+ToStr(IncludeCount)+':');
  227. end;
  228. { file name must be there before line number ! }
  229. if (hp^.line<>lastline) and (hp^.line<>0) then
  230. begin
  231. if (n_line = n_textline) and assigned(funcname) and
  232. (target_os.use_function_relative_addresses) then
  233. begin
  234. AsmWriteLn(target_asm.labelprefix+'l'+tostr(linecount)+':');
  235. AsmWriteLn(#9'.stabn '+tostr(n_line)+',0,'+tostr(hp^.line)+','+
  236. target_asm.labelprefix+'l'+tostr(linecount)+' - '+StrPas(FuncName));
  237. inc(linecount);
  238. end
  239. else
  240. AsmWriteLn(#9'.stabd'#9+tostr(n_line)+',0,'+tostr(hp^.line));
  241. lastline:=hp^.line;
  242. end;
  243. end;
  244. end;
  245. {$endif GDB}
  246. case hp^.typ of
  247. ait_external : ; { external is ignored }
  248. ait_comment : Begin
  249. AsmWrite(target_asm.comment);
  250. AsmWritePChar(pai_asm_comment(hp)^.str);
  251. AsmLn;
  252. End;
  253. {$ifdef DREGALLOC}
  254. ait_regalloc : AsmWriteLn(target_asm.comment+'Register '+att_reg2str[pairegalloc(hp)^.reg]+' allocated');
  255. ait_regdealloc : AsmWriteLn(target_asm.comment+'Register '+att_reg2str[pairegalloc(hp)^.reg]+' released');
  256. {$endif DREGALLOC}
  257. ait_align : AsmWriteLn(#9'.align '+tostr(pai_align(hp)^.aligntype));
  258. ait_section : begin
  259. if pai_section(hp)^.sec<>sec_none then
  260. begin
  261. AsmLn;
  262. AsmWrite(ait_section2str[pai_section(hp)^.sec]);
  263. if pai_section(hp)^.idataidx>0 then
  264. AsmWrite('$'+tostr(pai_section(hp)^.idataidx));
  265. AsmLn;
  266. {$ifdef GDB}
  267. case pai_section(hp)^.sec of
  268. sec_code : n_line:=n_textline;
  269. sec_data : n_line:=n_dataline;
  270. sec_bss : n_line:=n_bssline;
  271. end;
  272. {$endif GDB}
  273. end;
  274. LastSec:=pai_section(hp)^.sec;
  275. end;
  276. ait_datablock : begin
  277. { ------------------------------------------------------- }
  278. { ----------- ALIGNMENT FOR ANY NON-BYTE VALUE ---------- }
  279. { ------------- REQUIREMENT FOR 680x0 ------------------- }
  280. { ------------------------------------------------------- }
  281. if pai_datablock(hp)^.size <> 1 then
  282. begin
  283. if not(cs_littlesize in aktswitches) then
  284. AsmWriteLn(#9#9'.align 4')
  285. else
  286. AsmWriteLn(#9#9'.align 2');
  287. end;
  288. if pai_datablock(hp)^.is_global then
  289. AsmWrite(#9'.comm'#9)
  290. else
  291. AsmWrite(#9'.lcomm'#9);
  292. AsmWriteLn(StrPas(pai_datablock(hp)^.name)+','+tostr(pai_datablock(hp)^.size));
  293. end;
  294. ait_const_32bit, { alignment is required for 16/32 bit data! }
  295. ait_const_16bit: begin
  296. if not(cs_littlesize in aktswitches) then
  297. AsmWriteLn(#9#9'.align 4')
  298. else
  299. AsmWriteLn(#9#9'.align 2');
  300. AsmWrite(ait_const2str[hp^.typ]+tostr(pai_const(hp)^.value));
  301. consttyp:=hp^.typ;
  302. l:=0;
  303. repeat
  304. found:=(not (Pai(hp^.next)=nil)) and (Pai(hp^.next)^.typ=consttyp);
  305. if found then
  306. begin
  307. hp:=Pai(hp^.next);
  308. s:=','+tostr(pai_const(hp)^.value);
  309. AsmWrite(s);
  310. inc(l,length(s));
  311. end;
  312. until (not found) or (l>line_length);
  313. AsmLn;
  314. end;
  315. ait_const_8bit : begin
  316. AsmWrite(ait_const2str[hp^.typ]+tostr(pai_const(hp)^.value));
  317. consttyp:=hp^.typ;
  318. l:=0;
  319. repeat
  320. found:=(not (Pai(hp^.next)=nil)) and (Pai(hp^.next)^.typ=consttyp);
  321. if found then
  322. begin
  323. hp:=Pai(hp^.next);
  324. s:=','+tostr(pai_const(hp)^.value);
  325. AsmWrite(s);
  326. inc(l,length(s));
  327. end;
  328. until (not found) or (l>line_length);
  329. AsmLn;
  330. end;
  331. ait_const_symbol : Begin
  332. if not(cs_littlesize in aktswitches) then
  333. AsmWriteLn(#9#9'.align 4')
  334. else
  335. AsmWriteLn(#9#9'.align 2');
  336. AsmWriteLn(#9'.long'#9+StrPas(pchar(pai_const(hp)^.value)));
  337. end;
  338. ait_real_64bit : Begin
  339. if not(cs_littlesize in aktswitches) then
  340. AsmWriteLn(#9#9'.align 4')
  341. else
  342. AsmWriteLn(#9#9'.align 2');
  343. AsmWriteLn(#9'.double'#9+double2str(pai_double(hp)^.value));
  344. end;
  345. ait_real_32bit : Begin
  346. if not(cs_littlesize in aktswitches) then
  347. AsmWriteLn(#9#9'.align 4')
  348. else
  349. AsmWriteLn(#9#9'.align 2');
  350. AsmWriteLn(#9'.single'#9+double2str(pai_single(hp)^.value));
  351. end;
  352. ait_real_extended : Begin
  353. if not(cs_littlesize in aktswitches) then
  354. AsmWriteLn(#9#9'.align 4')
  355. else
  356. AsmWriteLn(#9#9'.align 2');
  357. AsmWriteLn(#9'.extend'#9+double2str(pai_extended(hp)^.value));
  358. { comp type is difficult to write so use double }
  359. end;
  360. ait_comp : Begin
  361. if not(cs_littlesize in aktswitches) then
  362. AsmWriteLn(#9#9'.align 4')
  363. else
  364. AsmWriteLn(#9#9'.align 2');
  365. AsmWriteLn(#9'.double'#9+comp2str(pai_extended(hp)^.value));
  366. end;
  367. ait_direct : begin
  368. AsmWritePChar(pai_direct(hp)^.str);
  369. AsmLn;
  370. {$IfDef GDB}
  371. if strpos(pai_direct(hp)^.str,'.data')<>nil then
  372. n_line:=n_dataline
  373. else if strpos(pai_direct(hp)^.str,'.text')<>nil then
  374. n_line:=n_textline
  375. else if strpos(pai_direct(hp)^.str,'.bss')<>nil then
  376. n_line:=n_bssline;
  377. {$endif GDB}
  378. end;
  379. ait_string : begin
  380. pos:=0;
  381. for i:=1 to pai_string(hp)^.len do
  382. begin
  383. if pos=0 then
  384. begin
  385. AsmWrite(#9'.ascii'#9'"');
  386. pos:=20;
  387. end;
  388. ch:=pai_string(hp)^.str[i-1];
  389. case ch of
  390. #0, {This can't be done by range, because a bug in FPC}
  391. #1..#31,
  392. #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  393. '"' : s:='\"';
  394. '\' : s:='\\';
  395. else
  396. s:=ch;
  397. end;
  398. AsmWrite(s);
  399. inc(pos,length(s));
  400. if (pos>line_length) or (i=pai_string(hp)^.len) then
  401. begin
  402. AsmWriteLn('"');
  403. pos:=0;
  404. end;
  405. end;
  406. end;
  407. ait_label : begin
  408. if (pai_label(hp)^.l^.is_used) then
  409. AsmWriteLn(lab2str(pai_label(hp)^.l)+':');
  410. end;
  411. ait_labeled_instruction : begin
  412. { labeled operand }
  413. if pai_labeled(hp)^._op1 = R_NO then
  414. AsmWriteLn(#9+mot_op2str[pai_labeled(hp)^._operator]+#9+lab2str(pai_labeled(hp)^.lab))
  415. else
  416. { labeled operand with register }
  417. AsmWriteLn(#9+mot_op2str[pai_labeled(hp)^._operator]+#9+
  418. reg2str(pai_labeled(hp)^._op1)+','+lab2str(pai_labeled(hp)^.lab))
  419. end;
  420. ait_symbol : begin
  421. { ------------------------------------------------------- }
  422. { ----------- ALIGNMENT FOR ANY NON-BYTE VALUE ---------- }
  423. { ------------- REQUIREMENT FOR 680x0 ------------------- }
  424. { ------------------------------------------------------- }
  425. if assigned(hp^.next) and (pai(hp^.next)^.typ in
  426. [ait_const_32bit,ait_const_16bit,ait_const_symbol,
  427. ait_real_64bit,ait_real_32bit,ait_string]) then
  428. begin
  429. if not(cs_littlesize in aktswitches) then
  430. AsmWriteLn(#9#9'.align 4')
  431. else
  432. AsmWriteLn(#9#9'.align 2');
  433. end;
  434. if pai_symbol(hp)^.is_global then
  435. AsmWriteLn('.globl '+StrPas(pai_symbol(hp)^.name));
  436. AsmWriteLn(StrPas(pai_symbol(hp)^.name)+':');
  437. end;
  438. ait_instruction : begin
  439. { old versions of GAS don't like PEA.L and LEA.L }
  440. if (pai68k(hp)^._operator <> A_LEA) and (pai68k(hp)^._operator<> A_PEA) then
  441. s:=#9+mot_op2str[pai68k(hp)^._operator]+gas_opsize2str[pai68k(hp)^.size]
  442. else
  443. s:=#9+mot_op2str[pai68k(hp)^._operator];
  444. if pai68k(hp)^.op1t<>top_none then
  445. begin
  446. { call and jmp need an extra handling }
  447. { this code is only callded if jmp isn't a labeled instruction }
  448. if pai68k(hp)^._operator in [A_JSR,A_JMP] then
  449. s:=s+#9+getopstr_jmp(pai68k(hp)^.op1t,pai68k(hp)^.op1)
  450. else
  451. if pai68k(hp)^.op1t = top_reglist then
  452. s:=s+#9+getopstr(pai68k(hp)^.op1t,@(pai68k(hp)^.reglist))
  453. else
  454. s:=s+#9+getopstr(pai68k(hp)^.op1t,pai68k(hp)^.op1);
  455. if pai68k(hp)^.op2t<>top_none then
  456. begin
  457. if pai68k(hp)^.op2t = top_reglist then
  458. s:=s+','+getopstr(pai68k(hp)^.op2t,@pai68k(hp)^.reglist)
  459. else
  460. s:=s+','+getopstr(pai68k(hp)^.op2t,pai68k(hp)^.op2);
  461. { three operands }
  462. if pai68k(hp)^.op3t<>top_none then
  463. begin
  464. if (pai68k(hp)^._operator = A_DIVSL) or
  465. (pai68k(hp)^._operator = A_DIVUL) or
  466. (pai68k(hp)^._operator = A_MULU) or
  467. (pai68k(hp)^._operator = A_MULS) or
  468. (pai68k(hp)^._operator = A_DIVS) or
  469. (pai68k(hp)^._operator = A_DIVU) then
  470. s:=s+':'+getopstr(pai68k(hp)^.op3t,pai68k(hp)^.op3)
  471. else
  472. s:=s+','+getopstr(pai68k(hp)^.op3t,pai68k(hp)^.op3);
  473. end;
  474. end;
  475. end;
  476. AsmWriteLn(s);
  477. end;
  478. {$ifdef GDB}
  479. ait_stabs : begin
  480. AsmWrite(#9'.stabs ');
  481. AsmWritePChar(pai_stabs(hp)^.str);
  482. AsmLn;
  483. end;
  484. ait_stabn : begin
  485. AsmWrite(#9'.stabn ');
  486. AsmWritePChar(pai_stabn(hp)^.str);
  487. AsmLn;
  488. end;
  489. ait_stab_function_name : funcname:=pai_stab_function_name(hp)^.str;
  490. {$endif GDB}
  491. {$ifdef SMARTLINK}
  492. ait_cut : begin { used to split into tiny assembler files }
  493. if (cs_smartlink in aktswitches) then
  494. begin
  495. AsmClose;
  496. DoAssemble;
  497. AsmCreate;
  498. AsmWriteLn(ait_section2str[lastsec]);
  499. { avoid empty files }
  500. while assigned(hp^.next) and (pai(hp^.next)^.typ=ait_cut) do
  501. hp:=pai(hp^.next);
  502. end;
  503. end;
  504. {$endif SMARTLINK}
  505. else
  506. internalerror(10000);
  507. end;
  508. hp:=pai(hp^.next);
  509. end;
  510. end;
  511. procedure tm68kgasasmlist.WriteAsmList;
  512. {$ifdef GDB}
  513. var
  514. p:dirstr;
  515. n:namestr;
  516. e:extstr;
  517. {$endif}
  518. begin
  519. {$ifdef EXTDEBUG}
  520. if assigned(current_module^.mainsource) then
  521. comment(v_info,'Start writing gas-styled assembler output for '+current_module^.mainsource^);
  522. {$endif}
  523. infile:=nil;
  524. includecount:=0;
  525. {$ifdef GDB}
  526. if assigned(current_module^.mainsource) then
  527. fsplit(current_module^.mainsource^,p,n,e)
  528. else
  529. begin
  530. p:=inputdir;
  531. n:=inputfile;
  532. e:=inputextension;
  533. end;
  534. { to get symify to work }
  535. AsmWriteLn(#9'.file "'+FixFileName(n+e)+'"');
  536. { stabs }
  537. n_line:=n_bssline;
  538. if (cs_debuginfo in aktswitches) then
  539. begin
  540. if (p<>'') then
  541. AsmWriteLn(#9'.stabs "'+FixPath(p)+'",'+tostr(n_sourcefile)+',0,0,Ltext0');
  542. AsmWriteLn(#9'.stabs "'+FixFileName(n+e)+'",'+tostr(n_sourcefile)+',0,0,Ltext0');
  543. AsmWriteLn('Ltext0:');
  544. end;
  545. infile:=current_module^.sourcefiles.files;
  546. { main source file is last in list }
  547. while assigned(infile^._next) do
  548. infile:=infile^._next;
  549. lastline:=0;
  550. {$endif GDB}
  551. { there should be nothing but externals so we don't need to process
  552. WriteTree(externals); }
  553. WriteTree(debuglist);
  554. WriteTree(codesegment);
  555. WriteTree(datasegment);
  556. WriteTree(consts);
  557. WriteTree(rttilist);
  558. WriteTree(bsssegment);
  559. Writetree(importssection);
  560. Writetree(exportssection);
  561. Writetree(resourcesection);
  562. AsmLn;
  563. {$ifdef EXTDEBUG}
  564. if assigned(current_module^.mainsource) then
  565. comment(v_info,'Done writing gas-styled assembler output for '+current_module^.mainsource^);
  566. {$endif EXTDEBUG}
  567. end;
  568. end.
  569. {
  570. $Log$
  571. Revision 1.4 1998-06-04 23:51:28 peter
  572. * m68k compiles
  573. + .def file creation moved to gendef.pas so it could also be used
  574. for win32
  575. }