ag68kmit.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. {
  2. $Id$
  3. Copyright (c) 1998 by the FPC development team
  4. This unit implements an asmoutput class for MIT syntax with
  5. Motorola 68000 (for MIT syntax TEST WITH GAS v1.34)
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. What's to do:
  19. o Verify if this actually work as indirect mode with name of variables
  20. o write lines numbers and file names to output file
  21. o generate debugging informations
  22. }
  23. unit ag68kmit;
  24. interface
  25. uses aasm,assemble;
  26. type
  27. pm68kmitasmlist=^tm68kmitasmlist;
  28. tm68kmitasmlist = object(tasmlist)
  29. procedure WriteTree(p:paasmoutput);virtual;
  30. procedure WriteAsmList;virtual;
  31. end;
  32. implementation
  33. uses
  34. dos,globals,systems,cobjects,m68k,
  35. strings,files,verbose
  36. {$ifdef GDB}
  37. ,gdb
  38. {$endif GDB}
  39. ;
  40. const
  41. line_length = 70;
  42. var
  43. infile : pextfile;
  44. includecount,lastline : longint;
  45. function double2str(d : double) : string;
  46. var
  47. hs : string;
  48. begin
  49. str(d,hs);
  50. double2str:=hs;
  51. end;
  52. function comp2str(d : bestreal) : string;
  53. type
  54. pdouble = ^double;
  55. var
  56. c : comp;
  57. dd : pdouble;
  58. begin
  59. c:=d;{ this generates a warning but this is not important }
  60. {$ifndef TP}
  61. {$warning The following warning can be ignored}
  62. {$endif TP}
  63. dd:=pdouble(@c); { this makes a bitwise copy of c into a double }
  64. comp2str:=double2str(dd^);
  65. end;
  66. function getreferencestring(const ref : treference) : string;
  67. var
  68. s : string;
  69. begin
  70. s:='';
  71. if ref.isintvalue then
  72. s:='#'+tostr(ref.offset)
  73. else
  74. with ref do
  75. begin
  76. { symbol and offset }
  77. if (assigned(symbol)) and (offset<>0) then
  78. Begin
  79. s:=s+'('+tostr(offset)+symbol^;
  80. end
  81. else
  82. { symbol only }
  83. if (assigned(symbol)) and (offset=0) then
  84. Begin
  85. s:=s+'('+symbol^;
  86. end
  87. else
  88. { offset only }
  89. if (symbol=nil) and (offset<>0) then
  90. Begin
  91. s:=s+'('+tostr(offset);
  92. end
  93. else
  94. { NOTHING - put zero as offset }
  95. if (symbol=nil) and (offset=0) then
  96. Begin
  97. s:=s+'('+'0';
  98. end
  99. else
  100. InternalError(10004);
  101. if (index<>R_NO) and (base=R_NO) and (direction=dir_none) then
  102. InternalError(10004)
  103. else if (index=R_NO) and (base<>R_NO) and (direction=dir_inc) then
  104. begin
  105. if (scalefactor = 1) or (scalefactor = 0) then
  106. Begin
  107. if offset<>0 then
  108. s:=mit_reg2str[base]+'@+'+s+')'
  109. else
  110. s:=mit_reg2str[base]+'@+';
  111. end
  112. else
  113. InternalError(10002);
  114. end
  115. else if (index=R_NO) and (base<>R_NO) and (direction=dir_dec) then
  116. begin
  117. if (scalefactor = 1) or (scalefactor = 0) then
  118. Begin
  119. if offset<>0 then
  120. s:=mit_reg2str[base]+'@-'+s+')'
  121. else
  122. s:=mit_reg2str[base]+'@-';
  123. end
  124. else
  125. InternalError(10003);
  126. end
  127. else if (index=R_NO) and (base<>R_NO) and (direction=dir_none) then
  128. begin
  129. if (offset=0) and (symbol=nil) then
  130. s:=mit_reg2str[base]+'@'
  131. else
  132. s:=mit_reg2str[base]+'@'+s+')';
  133. end
  134. else if (index<>R_NO) and (base<>R_NO) and (direction=dir_none) then
  135. begin
  136. s:=mit_reg2str[base]+'@'+s+','+mit_reg2str[index]+':L';
  137. if (scalefactor = 1) or (scalefactor = 0) then
  138. s:=s+')'
  139. else
  140. s:=s+':'+tostr(scalefactor)+')';
  141. end
  142. else
  143. if assigned(symbol) then
  144. Begin
  145. s:=symbol^;
  146. if offset<>0 then
  147. s:=s+'+'+tostr(offset);
  148. end
  149. { this must be a physical address }
  150. else
  151. s:=s+')';
  152. { else if NOT assigned(symbol) then
  153. InternalError(10004);}
  154. end; { end with }
  155. getreferencestring:=s;
  156. end;
  157. function getopstr(t : byte;o : pointer) : string;
  158. var
  159. hs : string;
  160. i: tregister;
  161. begin
  162. case t of
  163. top_reg : getopstr:=mit_reg2str[tregister(o)];
  164. top_ref : getopstr:=getreferencestring(preference(o)^);
  165. top_reglist: begin
  166. hs:='';
  167. for i:=R_NO to R_FPSR do
  168. begin
  169. if i in tregisterlist(o^) then
  170. hs:=hs+mit_reg2str[i]+'/';
  171. end;
  172. delete(hs,length(hs),1);
  173. getopstr := hs;
  174. end;
  175. top_const : getopstr:='#'+tostr(longint(o));
  176. top_symbol :
  177. { compare with i386, where a symbol is considered }
  178. { a constant. }
  179. begin
  180. hs[0]:=chr(strlen(pchar(pcsymbol(o)^.symbol)));
  181. move(pchar(pcsymbol(o)^.symbol)^,hs[1],byte(hs[0]));
  182. { inc(byte(hs[0]));}
  183. if pcsymbol(o)^.offset>0 then
  184. hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
  185. else if pcsymbol(o)^.offset<0 then
  186. hs:=hs+tostr(pcsymbol(o)^.offset);
  187. getopstr:=hs;
  188. end;
  189. else internalerror(10001);
  190. end;
  191. end;
  192. function getopstr_jmp(t : byte;o : pointer) : string;
  193. var
  194. hs : string;
  195. begin
  196. case t of
  197. top_reg : getopstr_jmp:=mit_reg2str[tregister(o)];
  198. top_ref : getopstr_jmp:=getreferencestring(preference(o)^);
  199. top_const : getopstr_jmp:=tostr(longint(o));
  200. top_symbol : begin
  201. hs[0]:=chr(strlen(pchar(pcsymbol(o)^.symbol)));
  202. move(pchar(pcsymbol(o)^.symbol)^,hs[1],byte(hs[0]));
  203. if pcsymbol(o)^.offset>0 then
  204. hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
  205. else if pcsymbol(o)^.offset<0 then
  206. hs:=hs+tostr(pcsymbol(o)^.offset);
  207. getopstr_jmp:=hs;
  208. end;
  209. else internalerror(10001);
  210. end;
  211. end;
  212. {****************************************************************************
  213. T68kGASASMOUTPUT
  214. ****************************************************************************}
  215. var
  216. { different types of source lines }
  217. n_line : byte;
  218. const
  219. ait_const2str:array[ait_const_32bit..ait_const_8bit] of string[8]=
  220. (#9'.long'#9,'',#9'.short'#9,#9'.byte'#9);
  221. procedure tm68kmitasmlist.WriteTree(p:paasmoutput);
  222. var
  223. hp : pai;
  224. ch : char;
  225. consttyp : tait;
  226. s : string;
  227. pos,l,i : longint;
  228. found : boolean;
  229. {$ifdef GDB}
  230. funcname : pchar;
  231. linecount : longint;
  232. {$endif GDB}
  233. begin
  234. {$ifdef GDB}
  235. funcname:=nil;
  236. linecount:=1;
  237. {$endif GDB}
  238. hp:=pai(p^.first);
  239. while assigned(hp) do
  240. begin
  241. { write debugger informations }
  242. {$ifdef GDB}
  243. if cs_debuginfo in aktswitches then
  244. begin
  245. if not (hp^.typ in [ait_external,ait_stabn,ait_stabs,ait_stab_function_name]) then
  246. begin
  247. if assigned(hp^.infile) and (pextfile(hp^.infile)<>infile) then
  248. begin
  249. infile:=hp^.infile;
  250. inc(includecount);
  251. if (hp^.infile^.path^<>'') then
  252. begin
  253. AsmWriteLn(#9'.stabs "'+FixPath(hp^.infile^.path^)+'",'+tostr(n_includefile)+
  254. ',0,0,Ltext'+ToStr(IncludeCount));
  255. end;
  256. AsmWriteLn(#9'.stabs "'+FixFileName(hp^.infile^.name^+hp^.infile^.ext^)+'",'+tostr(n_includefile)+
  257. ',0,0,Ltext'+ToStr(IncludeCount));
  258. AsmWriteLn('Ltext'+ToStr(IncludeCount)+':');
  259. end;
  260. { file name must be there before line number ! }
  261. if (hp^.line<>lastline) and (hp^.line<>0) then
  262. begin
  263. if (n_line = n_textline) and assigned(funcname) and
  264. (target_info.use_function_relative_addresses) then
  265. begin
  266. AsmWriteLn(target_info.labelprefix+'l'+tostr(linecount)+':');
  267. AsmWriteLn(#9'.stabn '+tostr(n_line)+',0,'+tostr(hp^.line)+','+
  268. target_info.labelprefix+'l'+tostr(linecount)+' - '+StrPas(FuncName));
  269. inc(linecount);
  270. end
  271. else
  272. AsmWriteLn(#9'.stabd'#9+tostr(n_line)+',0,'+tostr(hp^.line));
  273. lastline:=hp^.line;
  274. end;
  275. end;
  276. end;
  277. {$endif GDB}
  278. case hp^.typ of
  279. ait_comment :
  280. Begin
  281. AsmWrite(As_comment);
  282. AsmWritePChar(pai_asm_comment(hp)^.str);
  283. AsmLn;
  284. End;
  285. ait_external : ; { external is ignored }
  286. ait_align : AsmWriteLn(#9'.align '+tostr(pai_align(hp)^.aligntype));
  287. ait_datablock : begin
  288. { ------------------------------------------------------- }
  289. { ----------- ALIGNMENT FOR ANY NON-BYTE VALUE ---------- }
  290. { ------------- REQUIREMENT FOR 680x0 ------------------- }
  291. { ------------------------------------------------------- }
  292. if pai_datablock(hp)^.size <> 1 then
  293. begin
  294. if not(cs_littlesize in aktswitches) then
  295. AsmWriteLn(#9#9'.align 4')
  296. else
  297. AsmWriteLn(#9#9'.align 2');
  298. end;
  299. if pai_datablock(hp)^.is_global then
  300. AsmWrite(#9'.comm'#9)
  301. else
  302. AsmWrite(#9'.lcomm'#9);
  303. AsmWriteLn(StrPas(pai_datablock(hp)^.name)+','+tostr(pai_datablock(hp)^.size));
  304. end;
  305. ait_const_32bit, { alignment is required for 16/32 bit data! }
  306. ait_const_16bit: begin
  307. if not(cs_littlesize in aktswitches) then
  308. AsmWriteLn(#9#9'.align 4')
  309. else
  310. AsmWriteLn(#9#9'.align 2');
  311. AsmWrite(ait_const2str[hp^.typ]+tostr(pai_const(hp)^.value));
  312. consttyp:=hp^.typ;
  313. l:=0;
  314. repeat
  315. found:=(not (Pai(hp^.next)=nil)) and (Pai(hp^.next)^.typ=consttyp);
  316. if found then
  317. begin
  318. hp:=Pai(hp^.next);
  319. s:=','+tostr(pai_const(hp)^.value);
  320. AsmWrite(s);
  321. inc(l,length(s));
  322. end;
  323. until (not found) or (l>line_length);
  324. AsmLn;
  325. end;
  326. ait_const_8bit : begin
  327. AsmWrite(ait_const2str[hp^.typ]+tostr(pai_const(hp)^.value));
  328. consttyp:=hp^.typ;
  329. l:=0;
  330. repeat
  331. found:=(not (Pai(hp^.next)=nil)) and (Pai(hp^.next)^.typ=consttyp);
  332. if found then
  333. begin
  334. hp:=Pai(hp^.next);
  335. s:=','+tostr(pai_const(hp)^.value);
  336. AsmWrite(s);
  337. inc(l,length(s));
  338. end;
  339. until (not found) or (l>line_length);
  340. AsmLn;
  341. end;
  342. ait_const_symbol : Begin
  343. if not(cs_littlesize in aktswitches) then
  344. AsmWriteLn(#9#9'.align 4')
  345. else
  346. AsmWriteLn(#9#9'.align 2');
  347. AsmWriteLn(#9'.long'#9+StrPas(pchar(pai_const(hp)^.value)));
  348. end;
  349. ait_real_64bit : Begin
  350. if not(cs_littlesize in aktswitches) then
  351. AsmWriteLn(#9#9'.align 4')
  352. else
  353. AsmWriteLn(#9#9'.align 2');
  354. AsmWriteLn(#9'.double'#9+double2str(pai_double(hp)^.value));
  355. end;
  356. ait_real_32bit : Begin
  357. if not(cs_littlesize in aktswitches) then
  358. AsmWriteLn(#9#9'.align 4')
  359. else
  360. AsmWriteLn(#9#9'.align 2');
  361. AsmWriteLn(#9'.single'#9+double2str(pai_single(hp)^.value));
  362. end;
  363. ait_real_extended : Begin
  364. if not(cs_littlesize in aktswitches) then
  365. AsmWriteLn(#9#9'.align 4')
  366. else
  367. AsmWriteLn(#9#9'.align 2');
  368. AsmWriteLn(#9'.extend'#9+double2str(pai_extended(hp)^.value));
  369. { comp type is difficult to write so use double }
  370. end;
  371. ait_comp : Begin
  372. if not(cs_littlesize in aktswitches) then
  373. AsmWriteLn(#9#9'.align 4')
  374. else
  375. AsmWriteLn(#9#9'.align 2');
  376. AsmWriteLn(#9'.double'#9+comp2str(pai_extended(hp)^.value));
  377. end;
  378. ait_direct : begin
  379. AsmWritePChar(pai_direct(hp)^.str);
  380. AsmLn;
  381. {$IfDef GDB}
  382. if strpos(pai_direct(hp)^.str,'.data')<>nil then
  383. n_line:=n_dataline
  384. else if strpos(pai_direct(hp)^.str,'.text')<>nil then
  385. n_line:=n_textline
  386. else if strpos(pai_direct(hp)^.str,'.bss')<>nil then
  387. n_line:=n_bssline;
  388. {$endif GDB}
  389. end;
  390. ait_string : begin
  391. pos:=0;
  392. for i:=1 to pai_string(hp)^.len do
  393. begin
  394. if pos=0 then
  395. begin
  396. AsmWrite(#9'.ascii'#9'"');
  397. pos:=20;
  398. end;
  399. ch:=pai_string(hp)^.str[i-1];
  400. case ch of
  401. #0, {This can't be done by range, because a bug in FPC}
  402. #1..#31,
  403. #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  404. '"' : s:='\"';
  405. '\' : s:='\\';
  406. else
  407. s:=ch;
  408. end;
  409. AsmWrite(s);
  410. inc(pos,length(s));
  411. if (pos>line_length) or (i=pai_string(hp)^.len) then
  412. begin
  413. AsmWriteLn('"');
  414. pos:=0;
  415. end;
  416. end;
  417. end;
  418. ait_label : begin
  419. if (pai_label(hp)^.l^.is_used) then
  420. AsmWriteLn(lab2str(pai_label(hp)^.l)+':');
  421. end;
  422. ait_labeled_instruction : begin
  423. { labeled operand }
  424. if pai_labeled(hp)^._op1 = R_NO then
  425. AsmWriteLn(#9+mot_op2str[pai_labeled(hp)^._operator]+#9+lab2str(pai_labeled(hp)^.lab))
  426. else
  427. { labeled operand with register }
  428. AsmWriteLn(#9+mot_op2str[pai_labeled(hp)^._operator]+#9+
  429. reg2str(pai_labeled(hp)^._op1)+','+lab2str(pai_labeled(hp)^.lab))
  430. end;
  431. ait_symbol : begin
  432. { ------------------------------------------------------- }
  433. { ----------- ALIGNMENT FOR ANY NON-BYTE VALUE ---------- }
  434. { ------------- REQUIREMENT FOR 680x0 ------------------- }
  435. { ------------------------------------------------------- }
  436. if assigned(hp^.next) and (pai(hp^.next)^.typ in
  437. [ait_const_32bit,ait_const_16bit,ait_const_symbol,
  438. ait_real_64bit,ait_real_32bit,ait_string]) then
  439. begin
  440. if not(cs_littlesize in aktswitches) then
  441. AsmWriteLn(#9#9'.align 4')
  442. else
  443. AsmWriteLn(#9#9'.align 2');
  444. end;
  445. if pai_symbol(hp)^.is_global then
  446. AsmWriteLn('.globl '+StrPas(pai_symbol(hp)^.name));
  447. AsmWriteLn(StrPas(pai_symbol(hp)^.name)+':');
  448. end;
  449. ait_instruction : begin
  450. { old versions of GAS don't like PEA.L and LEA.L }
  451. if (pai68k(hp)^._operator in [
  452. A_LEA,A_PEA,A_ABCD,A_BCHG,A_BCLR,A_BSET,A_BTST,
  453. A_EXG,A_NBCD,A_SBCD,A_SWAP,A_TAS,A_SCC,A_SCS,
  454. A_SEQ,A_SGE,A_SGT,A_SHI,A_SLE,A_SLS,A_SLT,A_SMI,
  455. A_SNE,A_SPL,A_ST,A_SVC,A_SVS,A_SF]) then
  456. s:=#9+mot_op2str[pai68k(hp)^._operator]
  457. else
  458. s:=#9+mot_op2str[pai68k(hp)^._operator]+mit_opsize2str[pai68k(hp)^.size];
  459. if pai68k(hp)^.op1t<>top_none then
  460. begin
  461. { call and jmp need an extra handling }
  462. { this code is only callded if jmp isn't a labeled instruction }
  463. if pai68k(hp)^._operator in [A_JSR,A_JMP] then
  464. s:=s+#9+getopstr_jmp(pai68k(hp)^.op1t,pai68k(hp)^.op1)
  465. else
  466. if pai68k(hp)^.op1t = top_reglist then
  467. s:=s+#9+getopstr(pai68k(hp)^.op1t,@(pai68k(hp)^.reglist))
  468. else
  469. s:=s+#9+getopstr(pai68k(hp)^.op1t,pai68k(hp)^.op1);
  470. if pai68k(hp)^.op2t<>top_none then
  471. begin
  472. if pai68k(hp)^.op2t = top_reglist then
  473. s:=s+','+getopstr(pai68k(hp)^.op2t,@pai68k(hp)^.reglist)
  474. else
  475. s:=s+','+getopstr(pai68k(hp)^.op2t,pai68k(hp)^.op2);
  476. { three operands }
  477. if pai68k(hp)^.op3t<>top_none then
  478. begin
  479. if (pai68k(hp)^._operator = A_DIVSL) or
  480. (pai68k(hp)^._operator = A_DIVUL) or
  481. (pai68k(hp)^._operator = A_MULU) or
  482. (pai68k(hp)^._operator = A_MULS) or
  483. (pai68k(hp)^._operator = A_DIVS) or
  484. (pai68k(hp)^._operator = A_DIVU) then
  485. s:=s+':'+getopstr(pai68k(hp)^.op3t,pai68k(hp)^.op3)
  486. else
  487. s:=s+','+getopstr(pai68k(hp)^.op3t,pai68k(hp)^.op3);
  488. end;
  489. end;
  490. end;
  491. AsmWriteLn(s);
  492. end;
  493. {$ifdef GDB}
  494. ait_stabs : begin
  495. AsmWrite(#9'.stabs ');
  496. AsmWritePChar(pai_stabs(hp)^.str);
  497. AsmLn;
  498. end;
  499. ait_stabn : begin
  500. AsmWrite(#9'.stabn ');
  501. AsmWritePChar(pai_stabn(hp)^.str);
  502. AsmLn;
  503. end;
  504. ait_stab_function_name : funcname:=pai_stab_function_name(hp)^.str;
  505. {$endif GDB}
  506. else
  507. internalerror(10000);
  508. end;
  509. hp:=pai(hp^.next);
  510. end;
  511. end;
  512. procedure tm68kmitasmlist.WriteAsmList;
  513. {$ifdef GDB}
  514. var
  515. p,n,e : string;
  516. {$endif}
  517. begin
  518. {$ifdef EXTDEBUG}
  519. if assigned(current_module^.mainsource) then
  520. comment(v_info,'Start writing gas-styled assembler output for '+current_module^.mainsource^);
  521. {$endif}
  522. infile:=nil;
  523. includecount:=0;
  524. {$ifdef GDB}
  525. if assigned(current_module^.mainsource) then
  526. fsplit(current_module^.mainsource^,p,n,e)
  527. else
  528. begin
  529. p:=inputdir;
  530. n:=inputfile;
  531. e:=inputextension;
  532. end;
  533. { to get symify to work }
  534. AsmWriteLn(#9'.file "'+FixFileName(n+e)+'"');
  535. { stabs }
  536. n_line:=n_bssline;
  537. if (cs_debuginfo in aktswitches) then
  538. begin
  539. if (p<>'') then
  540. AsmWriteLn(#9'.stabs "'+FixPath(p)+'",'+tostr(n_sourcefile)+',0,0,Ltext0');
  541. AsmWriteLn(#9'.stabs "'+FixFileName(n+e)+'",'+tostr(n_sourcefile)+',0,0,Ltext0');
  542. AsmWriteLn('Ltext0:');
  543. end;
  544. infile:=current_module^.sourcefiles.files;
  545. {$endif GDB}
  546. { main source file is last in list }
  547. while assigned(infile^._next) do
  548. infile:=infile^._next;
  549. lastline:=0;
  550. { there should be nothing but externals so we don't need to process
  551. WriteTree(externals); }
  552. WriteTree(debuglist);
  553. { code segment }
  554. AsmWriteln('.text');
  555. {$ifdef GDB}
  556. n_line:=n_textline;
  557. {$endif GDB}
  558. WriteTree(codesegment);
  559. AsmWriteLn('.data');
  560. {$ifdef EXTDEBUG}
  561. AsmWriteLn(#9'.ascii'#9'"compiled by FPC '+version_string+'\0"');
  562. AsmWriteLn(#9'.ascii'#9'"target: '+target_info.target_name+'\0"');
  563. {$endif EXTDEBUG}
  564. {$ifdef GDB}
  565. n_line:=n_dataline;
  566. {$endif GDB}
  567. DataSegment^.insert(new(pai_align,init(4)));
  568. WriteTree(datasegment);
  569. WriteTree(consts);
  570. { makes problems with old GNU ASes
  571. AsmWriteLn('.bss');
  572. bssSegment^.insert(new(pai_align,init(4))); }
  573. {$ifdef GDB}
  574. n_line:=n_bssline;
  575. {$endif GDB}
  576. WriteTree(bsssegment);
  577. AsmLn;
  578. {$ifdef EXTDEBUG}
  579. if assigned(current_module^.mainsource) then
  580. comment(v_info,'Done writing gas-styled assembler output for '+current_module^.mainsource^);
  581. {$endif EXTDEBUG}
  582. end;
  583. end.
  584. {
  585. $Log$
  586. Revision 1.3 1998-05-23 01:20:57 peter
  587. + aktasmmode, aktoptprocessor, aktoutputformat
  588. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  589. + $LIBNAME to set the library name where the unit will be put in
  590. * splitted cgi386 a bit (codeseg to large for bp7)
  591. * nasm, tasm works again. nasm moved to ag386nsm.pas
  592. Revision 1.2 1998/04/29 10:33:42 pierre
  593. + added some code for ansistring (not complete nor working yet)
  594. * corrected operator overloading
  595. * corrected nasm output
  596. + started inline procedures
  597. + added starstarn : use ** for exponentiation (^ gave problems)
  598. + started UseTokenInfo cond to get accurate positions
  599. Revision 1.1.1.1 1998/03/25 11:18:16 root
  600. * Restored version
  601. Revision 1.3 1998/03/22 12:45:37 florian
  602. * changes of Carl-Eric to m68k target commit:
  603. - wrong nodes because of the new string cg in intel, I had to create
  604. this under m68k also ... had to work it out to fix potential alignment
  605. problems --> this removes the crash of the m68k compiler.
  606. - added absolute addressing in m68k assembler (required for Amiga startup)
  607. - fixed alignment problems (because of byte return values, alignment
  608. would not be always valid) -- is this ok if i change the offset if odd in
  609. setfirsttemp ?? -- it seems ok...
  610. Revision 1.2 1998/03/10 04:22:45 carl
  611. - removed in because can cause range check errors in BP
  612. Revision 1.1 1998/03/10 01:26:10 peter
  613. + new uniform names
  614. Revision 1.8 1998/03/09 12:58:11 peter
  615. * FWait warning is only showed for Go32V2 and $E+
  616. * opcode tables moved to i386.pas/m68k.pas to reduce circular uses (and
  617. for m68k the same tables are removed)
  618. + $E for i386
  619. Revision 1.7 1998/03/06 00:52:25 peter
  620. * replaced all old messages from errore.msg, only ExtDebug and some
  621. Comment() calls are left
  622. * fixed options.pas
  623. Revision 1.6 1998/03/02 01:48:44 peter
  624. * renamed target_DOS to target_GO32V1
  625. + new verbose system, merged old errors and verbose units into one new
  626. verbose.pas, so errors.pas is obsolete
  627. Revision 1.5 1998/02/23 02:53:52 carl
  628. * some bugfix with $extdebug
  629. Revision 1.4 1998/02/22 23:03:19 peter
  630. * renamed msource->mainsource and name->unitname
  631. * optimized filename handling, filename is not seperate anymore with
  632. path+name+ext, this saves stackspace and a lot of fsplit()'s
  633. * recompiling of some units in libraries fixed
  634. * shared libraries are working again
  635. + $LINKLIB <lib> to support automatic linking to libraries
  636. + libraries are saved/read from the ppufile, also allows more libraries
  637. per ppufile
  638. Revision 1.3 1998/02/22 21:56:29 carl
  639. * bugfix of offset with index
  640. Revision 1.2 1998/02/21 20:20:01 carl
  641. * make it work under older versions of GAS
  642. }