ag68kgas.pas 29 KB

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