ag68kgas.pas 24 KB

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