ag68kgas.pas 28 KB

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