ag68kgas.pas 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  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. 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.23 1999-09-16 23:05:51 florian
  666. * m68k compiler is again compilable (only gas writer, no assembler reader)
  667. Revision 1.22 1998/12/23 22:53:44 peter
  668. * don't count ait_marker for lineinfo
  669. Revision 1.21 1998/12/11 00:02:39 peter
  670. + globtype,tokens,version unit splitted from globals
  671. Revision 1.20 1998/11/12 11:19:35 pierre
  672. * fix for first line of function break
  673. Revision 1.19 1998/10/29 11:35:36 florian
  674. * some dll support for win32
  675. * fixed assembler writing for PalmOS
  676. Revision 1.18 1998/10/14 15:56:39 pierre
  677. * all references to comp suppressed for m68k
  678. Revision 1.17 1998/10/13 13:10:08 peter
  679. * new style for m68k/i386 infos and enums
  680. Revision 1.16 1998/10/12 12:27:44 pierre
  681. * typo error for tai_const_symbol_offset corrected
  682. Revision 1.15 1998/10/12 12:20:43 pierre
  683. + added tai_const_symbol_offset
  684. for r : pointer = @var.field;
  685. * better message for different arg names on implementation
  686. of function
  687. Revision 1.14 1998/10/06 17:16:36 pierre
  688. * some memory leaks fixed (thanks to Peter for heaptrc !)
  689. Revision 1.13 1998/10/01 20:19:08 jonas
  690. + ait_marker support
  691. Revision 1.12 1998/09/28 16:57:09 pierre
  692. * changed all length(p^.value_str^) into str_length(p)
  693. to get it work with and without ansistrings
  694. * changed sourcefiles field of tmodule to a pointer
  695. Revision 1.11 1998/09/16 01:07:13 carl
  696. * alignment fix for bytes
  697. Revision 1.10 1998/09/01 09:07:08 peter
  698. * m68k fixes, splitted cg68k like cgi386
  699. Revision 1.9 1998/08/31 12:26:20 peter
  700. * m68k and palmos updates from surebugfixes
  701. Revision 1.8 1998/08/10 14:49:36 peter
  702. + localswitches, moduleswitches, globalswitches splitting
  703. Revision 1.7 1998/07/14 14:46:38 peter
  704. * released NEWINPUT
  705. Revision 1.6 1998/07/10 10:50:54 peter
  706. * m68k updates
  707. Revision 1.5 1998/06/05 17:46:04 peter
  708. * tp doesn't like comp() typecast
  709. Revision 1.4 1998/06/04 23:51:28 peter
  710. * m68k compiles
  711. + .def file creation moved to gendef.pas so it could also be used
  712. for win32
  713. }