ag68kgas.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  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. }
  19. { R- Necessary for the in [] }
  20. {$ifdef TP}
  21. {$N+,E+,R-}
  22. {$endif}
  23. unit ag68kgas;
  24. interface
  25. uses cobjects,aasm,assemble;
  26. type
  27. pm68kgasasmlist=^tm68kgasasmlist;
  28. tm68kgasasmlist = object(tasmlist)
  29. procedure WriteTree(p:paasmoutput);virtual;
  30. procedure WriteAsmList;virtual;
  31. {$ifdef GDB}
  32. procedure WriteFileLineInfo(var fileinfo : tfileposinfo);
  33. {$endif}
  34. end;
  35. implementation
  36. uses
  37. globtype,systems,
  38. dos,globals,cpubase,
  39. strings,files,verbose
  40. {$ifdef GDB}
  41. ,gdb
  42. {$endif GDB}
  43. ;
  44. const
  45. line_length = 70;
  46. var
  47. {$ifdef GDB}
  48. n_line : byte; { different types of source lines }
  49. linecount,
  50. includecount : longint;
  51. funcname : pchar;
  52. stabslastfileinfo : tfileposinfo;
  53. {$endif}
  54. lastsec : tsection; { last section type written }
  55. lastsecidx,
  56. lastfileindex,
  57. lastline : longint;
  58. function double2str(d : double) : string;
  59. var
  60. hs : string;
  61. begin
  62. str(d,hs);
  63. { replace space with + }
  64. if hs[1]=' ' then
  65. hs[1]:='+';
  66. double2str:='0d'+hs
  67. end;
  68. (* TO SUPPORT SOONER OR LATER!!!
  69. function comp2str(d : bestreal) : string;
  70. type
  71. pdouble = ^double;
  72. var
  73. c : comp;
  74. dd : pdouble;
  75. begin
  76. {$ifdef TP}
  77. c:=d;
  78. {$else}
  79. c:=comp(d);
  80. {$endif}
  81. dd:=pdouble(@c); { this makes a bitwise copy of c into a double }
  82. comp2str:=double2str(dd^);
  83. end; *)
  84. function getreferencestring(const ref : treference) : string;
  85. var
  86. s,basestr,indexstr : string;
  87. begin
  88. s:='';
  89. if ref.isintvalue then
  90. s:='#'+tostr(ref.offset)
  91. else
  92. with ref do
  93. begin
  94. if target_info.target=target_m68k_PalmOS then
  95. begin
  96. basestr:=gasPalmOS_reg2str[base];
  97. indexstr:=gasPalmOS_reg2str[index];
  98. end
  99. else
  100. begin
  101. basestr:=gas_reg2str[base];
  102. indexstr:=gas_reg2str[index];
  103. end;
  104. if assigned(symbol) then
  105. s:=s+symbol^;
  106. if offset<0 then s:=s+tostr(offset)
  107. else if (offset>0) then
  108. begin
  109. if (symbol=nil) then s:=tostr(offset)
  110. else s:=s+'+'+tostr(offset);
  111. end;
  112. if (index<>R_NO) and (base=R_NO) and (direction=dir_none) then
  113. begin
  114. if (scalefactor = 1) or (scalefactor = 0) then
  115. s:=s+'(,'+indexstr+'.l)'
  116. else
  117. s:=s+'(,'+indexstr+'.l*'+tostr(scalefactor)+')'
  118. end
  119. else if (index=R_NO) and (base<>R_NO) and (direction=dir_inc) then
  120. begin
  121. if (scalefactor = 1) or (scalefactor = 0) then
  122. s:=s+'('+basestr+')+'
  123. else
  124. InternalError(10002);
  125. end
  126. else if (index=R_NO) and (base<>R_NO) and (direction=dir_dec) then
  127. begin
  128. if (scalefactor = 1) or (scalefactor = 0) then
  129. s:=s+'-('+basestr+')'
  130. else
  131. InternalError(10003);
  132. end
  133. else if (index=R_NO) and (base<>R_NO) and (direction=dir_none) then
  134. begin
  135. s:=s+'('+basestr+')'
  136. end
  137. else if (index<>R_NO) and (base<>R_NO) and (direction=dir_none) then
  138. begin
  139. if (scalefactor = 1) or (scalefactor = 0) then
  140. s:=s+'('+basestr+','+indexstr+'.l)'
  141. else
  142. s:=s+'('+basestr+','+indexstr+'.l*'+tostr(scalefactor)+')';
  143. end;
  144. end; { end with }
  145. getreferencestring:=s;
  146. end;
  147. function getopstr(t : byte;o : pointer) : string;
  148. var
  149. hs : string;
  150. i: tregister;
  151. begin
  152. case t of
  153. top_reg : if target_info.target=target_m68k_PalmOS then
  154. getopstr:=gasPalmOS_reg2str[tregister(o)]
  155. else
  156. getopstr:=gas_reg2str[tregister(o)];
  157. top_ref : getopstr:=getreferencestring(preference(o)^);
  158. top_reglist : begin
  159. hs:='';
  160. for i:=R_NO to R_FPSR do
  161. begin
  162. if i in tregisterlist(o^) then
  163. hs:=hs+gas_reg2str[i]+'/';
  164. end;
  165. delete(hs,length(hs),1);
  166. getopstr := hs;
  167. end;
  168. top_const : getopstr:='#'+tostr(longint(o));
  169. top_symbol :
  170. { compare with i386, where a symbol is considered }
  171. { a constant. }
  172. begin
  173. hs[0]:=chr(strlen(pchar(pcsymbol(o)^.symbol)));
  174. move(pchar(pcsymbol(o)^.symbol)^,hs[1],byte(hs[0]));
  175. { inc(byte(hs[0]));}
  176. if pcsymbol(o)^.offset>0 then
  177. hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
  178. else if pcsymbol(o)^.offset<0 then
  179. hs:=hs+tostr(pcsymbol(o)^.offset);
  180. getopstr:=hs;
  181. end;
  182. else internalerror(10001);
  183. end;
  184. end;
  185. function getopstr_jmp(t : byte;o : pointer) : string;
  186. var
  187. hs : string;
  188. begin
  189. case t of
  190. top_reg : getopstr_jmp:=gas_reg2str[tregister(o)];
  191. top_ref : getopstr_jmp:=getreferencestring(preference(o)^);
  192. top_const : getopstr_jmp:=tostr(longint(o));
  193. top_symbol : begin
  194. hs[0]:=chr(strlen(pchar(pcsymbol(o)^.symbol)));
  195. move(pchar(pcsymbol(o)^.symbol)^,hs[1],byte(hs[0]));
  196. if pcsymbol(o)^.offset>0 then
  197. hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
  198. else if pcsymbol(o)^.offset<0 then
  199. hs:=hs+tostr(pcsymbol(o)^.offset);
  200. getopstr_jmp:=hs;
  201. end;
  202. else internalerror(10001);
  203. end;
  204. end;
  205. {****************************************************************************
  206. T68kGASASMOUTPUT
  207. ****************************************************************************}
  208. const
  209. ait_const2str:array[ait_const_32bit..ait_const_8bit] of string[8]=
  210. (#9'.long'#9,#9'.short'#9,#9'.byte'#9);
  211. function ait_section2str(s:tsection):string;
  212. begin
  213. case s of
  214. sec_code : ait_section2str:='.text';
  215. sec_data : ait_section2str:='.data';
  216. sec_bss : ait_section2str:='.bss';
  217. else
  218. ait_section2str:='';
  219. end;
  220. LastSec:=s;
  221. end;
  222. {$ifdef GDB}
  223. var
  224. curr_n : byte;
  225. infile : pinputfile;
  226. procedure tm68kgasasmlist.WriteFileLineInfo(var fileinfo : tfileposinfo);
  227. begin
  228. if not (cs_debuginfo in aktmoduleswitches) then
  229. exit;
  230. { file changed ? (must be before line info) }
  231. if lastfileindex<>fileinfo.fileindex then
  232. begin
  233. infile:=current_module^.sourcefiles^.get_file(fileinfo.fileindex);
  234. if includecount=0 then
  235. curr_n:=n_sourcefile
  236. else
  237. curr_n:=n_includefile;
  238. if (infile^.path^<>'') then
  239. begin
  240. AsmWriteLn(#9'.stabs "'+lower(BsToSlash(FixPath(infile^.path^,false)))+'",'+
  241. tostr(curr_n)+',0,0,'+'Ltext'+ToStr(IncludeCount));
  242. end;
  243. AsmWriteLn(#9'.stabs "'+lower(FixFileName(infile^.name^))+'",'+
  244. tostr(curr_n)+',0,0,'+'Ltext'+ToStr(IncludeCount));
  245. AsmWriteLn('Ltext'+ToStr(IncludeCount)+':');
  246. inc(includecount);
  247. lastfileindex:=fileinfo.fileindex;
  248. end;
  249. { line changed ? }
  250. if (fileinfo.line<>lastline) and (fileinfo.line<>0) then
  251. begin
  252. if (n_line=n_textline) and assigned(funcname) and
  253. (target_os.use_function_relative_addresses) then
  254. begin
  255. AsmWriteLn(target_asm.labelprefix+'l'+tostr(linecount)+':');
  256. AsmWrite(#9'.stabn '+tostr(n_line)+',0,'+tostr(fileinfo.line)+','+
  257. target_asm.labelprefix+'l'+tostr(linecount)+' - ');
  258. AsmWritePChar(FuncName);
  259. AsmLn;
  260. inc(linecount);
  261. end
  262. else
  263. AsmWriteLn(#9'.stabd'#9+tostr(n_line)+',0,'+tostr(fileinfo.line));
  264. lastline:=fileinfo.line;
  265. end;
  266. end;
  267. {$endif GDB}
  268. procedure tm68kgasasmlist.WriteTree(p:paasmoutput);
  269. type
  270. twowords=record
  271. word1,word2:word;
  272. end;
  273. textendedarray = array[0..9] of byte; { last longint will be and $ffff }
  274. var
  275. hp : pai;
  276. ch : char;
  277. consttyp : tait;
  278. s : string;
  279. pos,l,i : longint;
  280. found : boolean;
  281. begin
  282. if not assigned(p) then
  283. exit;
  284. hp:=pai(p^.first);
  285. while assigned(hp) do
  286. begin
  287. { write debugger informations }
  288. {$ifdef GDB}
  289. if cs_debuginfo in aktmoduleswitches then
  290. begin
  291. if not (hp^.typ in [ait_external,ait_regalloc, ait_regdealloc,ait_stabn,ait_stabs,
  292. ait_label,ait_cut,ait_marker,ait_align,ait_stab_function_name]) then
  293. WriteFileLineInfo(hp^.fileinfo);
  294. end;
  295. {$endif GDB}
  296. case hp^.typ of
  297. ait_comment : Begin
  298. AsmWrite(target_asm.comment);
  299. AsmWritePChar(pai_asm_comment(hp)^.str);
  300. AsmLn;
  301. End;
  302. {$ifdef DREGALLOC}
  303. ait_regalloc : AsmWriteLn(target_asm.comment+'Register '+att_reg2str[pairegalloc(hp)^.reg]+' allocated');
  304. ait_regdealloc : AsmWriteLn(target_asm.comment+'Register '+att_reg2str[pairegalloc(hp)^.reg]+' released');
  305. {$endif DREGALLOC}
  306. ait_align : AsmWriteLn(#9'.align '+tostr(pai_align(hp)^.aligntype));
  307. ait_section : begin
  308. if pai_section(hp)^.sec<>sec_none then
  309. begin
  310. AsmLn;
  311. AsmWrite(ait_section2str(pai_section(hp)^.sec));
  312. {!!!!
  313. if pai_section(hp)^.idataidx>0 then
  314. AsmWrite('$'+tostr(pai_section(hp)^.idataidx));
  315. }
  316. AsmLn;
  317. {$ifdef GDB}
  318. case pai_section(hp)^.sec of
  319. sec_code : n_line:=n_textline;
  320. sec_data : n_line:=n_dataline;
  321. sec_bss : n_line:=n_bssline;
  322. end;
  323. {$endif GDB}
  324. end;
  325. LastSec:=pai_section(hp)^.sec;
  326. end;
  327. ait_datablock : begin
  328. { ------------------------------------------------------- }
  329. { ----------- ALIGNMENT FOR ANY NON-BYTE VALUE ---------- }
  330. { ------------- REQUIREMENT FOR 680x0 ------------------- }
  331. { ------------------------------------------------------- }
  332. if pai_datablock(hp)^.size <> 1 then
  333. begin
  334. if not(cs_littlesize in aktglobalswitches) then
  335. AsmWriteLn(#9#9'.align 4')
  336. else
  337. AsmWriteLn(#9#9'.align 2');
  338. end;
  339. if pai_datablock(hp)^.is_global then
  340. AsmWrite(#9'.comm'#9)
  341. else
  342. AsmWrite(#9'.lcomm'#9);
  343. AsmWriteLn(pai_datablock(hp)^.sym^.name+','+tostr(pai_datablock(hp)^.size));
  344. end;
  345. ait_const_32bit, { alignment is required for 16/32 bit data! }
  346. ait_const_16bit: begin
  347. AsmWrite(ait_const2str[hp^.typ]+tostr(pai_const(hp)^.value));
  348. consttyp:=hp^.typ;
  349. l:=0;
  350. repeat
  351. found:=(not (Pai(hp^.next)=nil)) and (Pai(hp^.next)^.typ=consttyp);
  352. if found then
  353. begin
  354. hp:=Pai(hp^.next);
  355. s:=','+tostr(pai_const(hp)^.value);
  356. AsmWrite(s);
  357. inc(l,length(s));
  358. end;
  359. until (not found) or (l>line_length);
  360. AsmLn;
  361. end;
  362. ait_const_8bit : begin
  363. AsmWrite(ait_const2str[hp^.typ]+tostr(pai_const(hp)^.value));
  364. consttyp:=hp^.typ;
  365. l:=0;
  366. repeat
  367. found:=(not (Pai(hp^.next)=nil)) and (Pai(hp^.next)^.typ=consttyp);
  368. if found then
  369. begin
  370. hp:=Pai(hp^.next);
  371. s:=','+tostr(pai_const(hp)^.value);
  372. AsmWrite(s);
  373. inc(l,length(s));
  374. end;
  375. until (not found) or (l>line_length);
  376. AsmLn;
  377. end;
  378. ait_const_symbol : Begin
  379. AsmWriteLn(#9'.long'#9+StrPas(pchar(pai_const(hp)^.value)));
  380. end;
  381. {
  382. ait_const_symbol_offset :
  383. Begin
  384. AsmWrite(#9'.long'#9);
  385. AsmWritePChar(pai_const_symbol_offset(hp)^.name);
  386. if pai_const_symbol_offset(hp)^.offset>0 then
  387. AsmWrite('+'+tostr(pai_const_symbol_offset(hp)^.offset))
  388. else if pai_const_symbol_offset(hp)^.offset<0 then
  389. AsmWrite(tostr(pai_const_symbol_offset(hp)^.offset));
  390. AsmLn;
  391. end;
  392. }
  393. ait_real_64bit : Begin
  394. AsmWriteLn(#9'.double'#9+double2str(pai_real_64bit(hp)^.value));
  395. end;
  396. ait_real_32bit : Begin
  397. AsmWriteLn(#9'.single'#9+double2str(pai_real_32bit(hp)^.value));
  398. end;
  399. ait_real_80bit : Begin
  400. AsmWriteLn(#9'.extend'#9+double2str(pai_real_80bit(hp)^.value));
  401. { comp type is difficult to write so use double }
  402. end;
  403. { TO SUPPORT SOONER OR LATER!!!
  404. ait_comp : Begin
  405. AsmWriteLn(#9'.double'#9+comp2str(pai_extended(hp)^.value));
  406. end; }
  407. ait_direct : begin
  408. AsmWritePChar(pai_direct(hp)^.str);
  409. AsmLn;
  410. {$IfDef GDB}
  411. if strpos(pai_direct(hp)^.str,'.data')<>nil then
  412. n_line:=n_dataline
  413. else if strpos(pai_direct(hp)^.str,'.text')<>nil then
  414. n_line:=n_textline
  415. else if strpos(pai_direct(hp)^.str,'.bss')<>nil then
  416. n_line:=n_bssline;
  417. {$endif GDB}
  418. end;
  419. ait_string : begin
  420. pos:=0;
  421. for i:=1 to pai_string(hp)^.len do
  422. begin
  423. if pos=0 then
  424. begin
  425. AsmWrite(#9'.ascii'#9'"');
  426. pos:=20;
  427. end;
  428. ch:=pai_string(hp)^.str[i-1];
  429. case ch of
  430. #0, {This can't be done by range, because a bug in FPC}
  431. #1..#31,
  432. #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  433. '"' : s:='\"';
  434. '\' : s:='\\';
  435. else
  436. s:=ch;
  437. end;
  438. AsmWrite(s);
  439. inc(pos,length(s));
  440. if (pos>line_length) or (i=pai_string(hp)^.len) then
  441. begin
  442. AsmWriteLn('"');
  443. pos:=0;
  444. end;
  445. end;
  446. end;
  447. ait_label : begin
  448. if assigned(hp^.next) and (pai(hp^.next)^.typ in
  449. [ait_const_32bit,ait_const_16bit,ait_const_8bit,
  450. ait_const_symbol,{ ait_const_symbol_offset, }
  451. ait_real_64bit,ait_real_32bit,ait_string]) then
  452. begin
  453. if not(cs_littlesize in aktglobalswitches) then
  454. AsmWriteLn(#9#9'.align 4')
  455. else
  456. AsmWriteLn(#9#9'.align 2');
  457. end;
  458. if (pai_label(hp)^.l^.is_used) then
  459. AsmWriteLn(pai_label(hp)^.l^.name+':');
  460. end;
  461. ait_labeled_instruction : begin
  462. { labeled operand }
  463. if pai_labeled(hp)^._op1 = R_NO then
  464. AsmWriteLn(#9+mot_op2str[pai_labeled(hp)^._operator]+#9+pai_labeled(hp)^.lab^.name)
  465. else
  466. { labeled operand with register }
  467. begin
  468. if target_info.target=target_m68k_PalmOS then
  469. AsmWriteLn(#9+mot_op2str[pai_labeled(hp)^._operator]+#9+
  470. gasPalmOS_reg2str[pai_labeled(hp)^._op1]+','+pai_labeled(hp)^.lab^.name)
  471. else
  472. AsmWriteLn(#9+mot_op2str[pai_labeled(hp)^._operator]+#9+
  473. gas_reg2str[pai_labeled(hp)^._op1]+','+pai_labeled(hp)^.lab^.name)
  474. end;
  475. end;
  476. ait_symbol : begin
  477. { ------------------------------------------------------- }
  478. { ----------- ALIGNMENT FOR ANY NON-BYTE VALUE ---------- }
  479. { ------------- REQUIREMENT FOR 680x0 ------------------- }
  480. { ------------------------------------------------------- }
  481. if assigned(hp^.next) and (pai(hp^.next)^.typ in
  482. [ait_const_32bit,ait_const_16bit,ait_const_8bit,
  483. ait_const_symbol,{!!! ait_const_symbol_offset, }
  484. ait_real_64bit,ait_real_32bit,ait_string]) then
  485. begin
  486. if not(cs_littlesize in aktglobalswitches) then
  487. AsmWriteLn(#9#9'.align 4')
  488. else
  489. AsmWriteLn(#9#9'.align 2');
  490. end;
  491. if pai_symbol(hp)^.is_global then
  492. AsmWriteLn('.globl '+pai_symbol(hp)^.sym^.name);
  493. AsmWriteLn(pai_symbol(hp)^.sym^.name+':');
  494. end;
  495. ait_instruction : begin
  496. { old versions of GAS don't like PEA.L and LEA.L }
  497. if (paicpu(hp)^._operator in [
  498. A_LEA,A_PEA,A_ABCD,A_BCHG,A_BCLR,A_BSET,A_BTST,
  499. A_EXG,A_NBCD,A_SBCD,A_SWAP,A_TAS,A_SCC,A_SCS,
  500. A_SEQ,A_SGE,A_SGT,A_SHI,A_SLE,A_SLS,A_SLT,A_SMI,
  501. A_SNE,A_SPL,A_ST,A_SVC,A_SVS,A_SF]) then
  502. s:=#9+mot_op2str[paicpu(hp)^._operator]
  503. else
  504. if target_info.target=target_m68k_PalmOS then
  505. s:=#9+mot_op2str[paicpu(hp)^._operator]+gas_opsize2str[paicpu(hp)^.size]
  506. else
  507. s:=#9+mot_op2str[paicpu(hp)^._operator]+mit_opsize2str[paicpu(hp)^.size];
  508. if paicpu(hp)^.op1t<>top_none then
  509. begin
  510. { call and jmp need an extra handling }
  511. { this code is only callded if jmp isn't a labeled instruction }
  512. if paicpu(hp)^._operator in [A_JSR,A_JMP] then
  513. s:=s+#9+getopstr_jmp(paicpu(hp)^.op1t,paicpu(hp)^.op1)
  514. else
  515. if paicpu(hp)^.op1t = top_reglist then
  516. s:=s+#9+getopstr(paicpu(hp)^.op1t,@(paicpu(hp)^.reglist))
  517. else
  518. s:=s+#9+getopstr(paicpu(hp)^.op1t,paicpu(hp)^.op1);
  519. if paicpu(hp)^.op2t<>top_none then
  520. begin
  521. if paicpu(hp)^.op2t = top_reglist then
  522. s:=s+','+getopstr(paicpu(hp)^.op2t,@paicpu(hp)^.reglist)
  523. else
  524. s:=s+','+getopstr(paicpu(hp)^.op2t,paicpu(hp)^.op2);
  525. { three operands }
  526. if paicpu(hp)^.op3t<>top_none then
  527. begin
  528. if (paicpu(hp)^._operator = A_DIVSL) or
  529. (paicpu(hp)^._operator = A_DIVUL) or
  530. (paicpu(hp)^._operator = A_MULU) or
  531. (paicpu(hp)^._operator = A_MULS) or
  532. (paicpu(hp)^._operator = A_DIVS) or
  533. (paicpu(hp)^._operator = A_DIVU) then
  534. s:=s+':'+getopstr(paicpu(hp)^.op3t,paicpu(hp)^.op3)
  535. else
  536. s:=s+','+getopstr(paicpu(hp)^.op3t,paicpu(hp)^.op3);
  537. end;
  538. end;
  539. end;
  540. AsmWriteLn(s);
  541. end;
  542. {$ifdef GDB}
  543. ait_stabs : begin
  544. AsmWrite(#9'.stabs ');
  545. AsmWritePChar(pai_stabs(hp)^.str);
  546. AsmLn;
  547. end;
  548. ait_stabn : begin
  549. AsmWrite(#9'.stabn ');
  550. AsmWritePChar(pai_stabn(hp)^.str);
  551. AsmLn;
  552. end;
  553. ait_force_line : begin
  554. stabslastfileinfo.line:=0;
  555. end;
  556. ait_stab_function_name : funcname:=pai_stab_function_name(hp)^.str;
  557. {$endif GDB}
  558. ait_cut : begin
  559. { only reset buffer if nothing has changed }
  560. if AsmSize=AsmStartSize then
  561. AsmClear
  562. else
  563. begin
  564. AsmClose;
  565. DoAssemble;
  566. AsmCreate;
  567. end;
  568. { avoid empty files }
  569. while assigned(hp^.next) and (pai(hp^.next)^.typ in [ait_cut,ait_section,ait_comment]) do
  570. begin
  571. if pai(hp^.next)^.typ=ait_section then
  572. begin
  573. lastsec:=pai_section(hp^.next)^.sec;
  574. {!!!!!
  575. lastsecidx:=pai_section(hp^.next)^.idataidx;
  576. }
  577. {$ifdef GDB}
  578. { this is needed for line info in data }
  579. case pai_section(hp^.next)^.sec of
  580. sec_code : n_line:=n_textline;
  581. sec_data : n_line:=n_dataline;
  582. sec_bss : n_line:=n_bssline;
  583. end;
  584. {$endif GDB}
  585. end;
  586. hp:=pai(hp^.next);
  587. end;
  588. {$ifdef GDB}
  589. { force write of filename }
  590. lastfileindex:=0;
  591. includecount:=0;
  592. funcname:=nil;
  593. WriteFileLineInfo(hp^.fileinfo);
  594. {$endif GDB}
  595. if lastsec<>sec_none then
  596. AsmWriteLn(ait_section2str(lastsec));
  597. AsmStartSize:=AsmSize;
  598. end;
  599. ait_marker : ;
  600. else
  601. internalerror(10000);
  602. end;
  603. hp:=pai(hp^.next);
  604. end;
  605. end;
  606. procedure tm68kgasasmlist.WriteAsmList;
  607. var
  608. p:dirstr;
  609. n:namestr;
  610. e:extstr;
  611. {$ifdef GDB}
  612. fileinfo : tfileposinfo;
  613. {$endif GDB}
  614. begin
  615. {$ifdef EXTDEBUG}
  616. if assigned(current_module^.mainsource) then
  617. comment(v_info,'Start writing gas-styled assembler output for '+current_module^.mainsource^);
  618. {$endif}
  619. LastSec:=sec_none;
  620. if assigned(current_module^.mainsource) then
  621. fsplit(current_module^.mainsource^,p,n,e)
  622. else
  623. begin
  624. p:=inputdir;
  625. n:=inputfile;
  626. e:=inputextension;
  627. end;
  628. { to get symify to work }
  629. AsmWriteLn(#9'.file "'+FixFileName(n+e)+'"');
  630. {$ifdef GDB}
  631. includecount:=0;
  632. n_line:=n_bssline;
  633. lastline:=0;
  634. lastfileindex:=0;
  635. funcname:=nil;
  636. linecount:=1;
  637. fileinfo.fileindex:=1;
  638. fileinfo.line:=1;
  639. { Write main file }
  640. WriteFileLineInfo(fileinfo);
  641. {$endif GDB}
  642. AsmStartSize:=AsmSize;
  643. countlabelref:=false;
  644. { there should be nothing but externals so we don't need to process
  645. WriteTree(externals); }
  646. WriteTree(debuglist);
  647. WriteTree(codesegment);
  648. WriteTree(datasegment);
  649. WriteTree(consts);
  650. WriteTree(rttilist);
  651. WriteTree(bsssegment);
  652. Writetree(importssection);
  653. Writetree(exportssection);
  654. Writetree(resourcesection);
  655. countlabelref:=true;
  656. AsmLn;
  657. {$ifdef EXTDEBUG}
  658. if assigned(current_module^.mainsource) then
  659. comment(v_info,'Done writing gas-styled assembler output for '+current_module^.mainsource^);
  660. {$endif EXTDEBUG}
  661. end;
  662. end.
  663. {
  664. $Log$
  665. Revision 1.25 2000-02-09 13:22:44 peter
  666. * log truncated
  667. Revision 1.24 2000/01/07 01:14:18 peter
  668. * updated copyright to 2000
  669. Revision 1.23 1999/09/16 23:05:51 florian
  670. * m68k compiler is again compilable (only gas writer, no assembler reader)
  671. }