ag386int.pas 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. {
  2. $Id$
  3. Copyright (c) 1996,97 by Florian Klaempfl
  4. This unit implements an asmoutput class for Intel syntax with Intel i386+
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. {$ifdef TP}
  19. {$N+,E+}
  20. {$endif}
  21. unit ag386int;
  22. interface
  23. uses aasm,assemble;
  24. type
  25. pi386intasmlist=^ti386intasmlist;
  26. ti386intasmlist = object(tasmlist)
  27. procedure WriteTree(p:paasmoutput);virtual;
  28. procedure WriteAsmList;virtual;
  29. end;
  30. implementation
  31. uses
  32. dos,globals,systems,cobjects,i386,
  33. strings,files,verbose
  34. {$ifdef GDB}
  35. ,gdb
  36. {$endif GDB}
  37. ;
  38. const
  39. line_length = 70;
  40. extstr : array[EXT_NEAR..EXT_ABS] of String[8] =
  41. ('NEAR','FAR','PROC','BYTE','WORD','DWORD',
  42. 'CODEPTR','DATAPTR','FWORD','PWORD','QWORD','TBYTE','ABS');
  43. function double2str(d : double) : string;
  44. var
  45. hs : string;
  46. p : byte;
  47. begin
  48. str(d,hs);
  49. { nasm expects a lowercase e }
  50. p:=pos('E',hs);
  51. if p>0 then
  52. hs[p]:='e';
  53. p:=pos('+',hs);
  54. if p>0 then
  55. delete(hs,p,1);
  56. double2str:=lower(hs);
  57. end;
  58. function extended2str(e : extended) : string;
  59. var
  60. hs : string;
  61. p : byte;
  62. begin
  63. str(e,hs);
  64. { nasm expects a lowercase e }
  65. p:=pos('E',hs);
  66. if p>0 then
  67. hs[p]:='e';
  68. p:=pos('+',hs);
  69. if p>0 then
  70. delete(hs,p,1);
  71. extended2str:=lower(hs);
  72. end;
  73. function comp2str(d : bestreal) : string;
  74. type
  75. pdouble = ^double;
  76. var
  77. c : comp;
  78. dd : pdouble;
  79. begin
  80. {$ifdef TP}
  81. c:=d;
  82. {$else}
  83. c:=comp(d);
  84. {$endif}
  85. dd:=pdouble(@c); { this makes a bitwise copy of c into a double }
  86. comp2str:=double2str(dd^);
  87. end;
  88. function getreferencestring(const ref : treference) : string;
  89. var
  90. s : string;
  91. first : boolean;
  92. begin
  93. if ref.isintvalue then
  94. s:= tostr(ref.offset)
  95. else
  96. with ref do
  97. begin
  98. first:=true;
  99. if ref.segment<>R_DEFAULT_SEG then
  100. s:=int_reg2str[segment]+':['
  101. else
  102. s:='[';
  103. if assigned(symbol) then
  104. begin
  105. s:=s+symbol^;
  106. first:=false;
  107. end;
  108. if (base<>R_NO) then
  109. begin
  110. if not(first) then
  111. s:=s+'+'
  112. else
  113. first:=false;
  114. s:=s+int_reg2str[base];
  115. end;
  116. if (index<>R_NO) then
  117. begin
  118. if not(first) then
  119. s:=s+'+'
  120. else
  121. first:=false;
  122. s:=s+int_reg2str[index];
  123. if scalefactor<>0 then
  124. s:=s+'*'+tostr(scalefactor);
  125. end;
  126. if offset<0 then
  127. s:=s+tostr(offset)
  128. else if (offset>0) then
  129. s:=s+'+'+tostr(offset);
  130. s:=s+']';
  131. end;
  132. getreferencestring:=s;
  133. end;
  134. function getopstr(t : byte;o : pointer;s : topsize; _operator: tasmop;dest : boolean) : string;
  135. var
  136. hs : string;
  137. begin
  138. case t of
  139. top_reg : getopstr:=int_reg2str[tregister(o)];
  140. top_const,
  141. top_ref : begin
  142. if t=top_const then
  143. hs := tostr(longint(o))
  144. else
  145. hs:=getreferencestring(preference(o)^);
  146. { can possibly give a range check error under tp }
  147. { if using in... }
  148. if ((_operator <> A_LGS) and (_operator <> A_LSS) and
  149. (_operator <> A_LFS) and (_operator <> A_LDS) and
  150. (_operator <> A_LES)) then
  151. Begin
  152. case s of
  153. S_B : hs:='byte ptr '+hs;
  154. S_W : hs:='word ptr '+hs;
  155. S_L : hs:='dword ptr '+hs;
  156. S_IS : hs:='word ptr '+hs;
  157. S_IL : hs:='dword ptr '+hs;
  158. S_IQ : hs:='qword ptr '+hs;
  159. S_FS : hs:='dword ptr '+hs;
  160. S_FL : hs:='qword ptr '+hs;
  161. S_FX : hs:='tbyte ptr '+hs;
  162. S_BW : if dest then
  163. hs:='word ptr '+hs
  164. else
  165. hs:='byte ptr '+hs;
  166. S_BL : if dest then
  167. hs:='dword ptr '+hs
  168. else
  169. hs:='byte ptr '+hs;
  170. S_WL : if dest then
  171. hs:='dword ptr '+hs
  172. else
  173. hs:='word ptr '+hs;
  174. end;
  175. end;
  176. getopstr:=hs;
  177. end;
  178. top_symbol : begin
  179. hs:='offset '+strpas(pchar(pcsymbol(o)^.symbol));
  180. if pcsymbol(o)^.offset>0 then
  181. hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
  182. else
  183. if pcsymbol(o)^.offset<0 then
  184. hs:=hs+tostr(pcsymbol(o)^.offset);
  185. getopstr:=hs;
  186. end;
  187. else
  188. internalerror(10001);
  189. end;
  190. end;
  191. function getopstr_jmp(t : byte;o : pointer) : string;
  192. var
  193. hs : string;
  194. begin
  195. case t of
  196. top_reg : getopstr_jmp:=int_reg2str[tregister(o)];
  197. top_ref : getopstr_jmp:=getreferencestring(preference(o)^);
  198. top_const : getopstr_jmp:=tostr(longint(o));
  199. top_symbol : begin
  200. hs:=strpas(pchar(pcsymbol(o)^.symbol));
  201. if pcsymbol(o)^.offset>0 then
  202. hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
  203. else
  204. if pcsymbol(o)^.offset<0 then
  205. hs:=hs+tostr(pcsymbol(o)^.offset);
  206. getopstr_jmp:=hs;
  207. end;
  208. else
  209. internalerror(10001);
  210. end;
  211. end;
  212. {****************************************************************************
  213. TI386INTASMLIST
  214. ****************************************************************************}
  215. var
  216. LastSec : tsection;
  217. const
  218. ait_const2str:array[ait_const_32bit..ait_const_8bit] of string[8]=
  219. (#9'DD'#9,#9'DW'#9,#9'DB'#9);
  220. ait_section2masmstr : array[tsection] of string[6]=
  221. ('','CODE','DATA','BSS','','');
  222. Function PadTabs(p:pchar;addch:char):string;
  223. var
  224. s : string;
  225. i : longint;
  226. begin
  227. i:=strlen(p);
  228. if addch<>#0 then
  229. begin
  230. inc(i);
  231. s:=StrPas(p)+addch;
  232. end
  233. else
  234. s:=StrPas(p);
  235. if i<8 then
  236. PadTabs:=s+#9#9
  237. else
  238. PadTabs:=s+#9;
  239. end;
  240. procedure ti386intasmlist.WriteTree(p:paasmoutput);
  241. type
  242. twowords=record
  243. word1,word2:word;
  244. end;
  245. var
  246. s,
  247. prefix,
  248. suffix : string;
  249. hp : pai;
  250. counter,
  251. lines,
  252. i,j,l : longint;
  253. consttyp : tait;
  254. found,
  255. quoted : boolean;
  256. begin
  257. if not assigned(p) then
  258. exit;
  259. hp:=pai(p^.first);
  260. while assigned(hp) do
  261. begin
  262. case hp^.typ of
  263. ait_comment : Begin
  264. AsmWrite(target_asm.comment);
  265. AsmWritePChar(pai_asm_comment(hp)^.str);
  266. AsmLn;
  267. End;
  268. ait_regalloc,
  269. ait_regdealloc :;
  270. ait_section : begin
  271. if LastSec<>sec_none then
  272. AsmWriteLn('_'+ait_section2masmstr[LastSec]+#9#9'ENDS');
  273. if pai_section(hp)^.sec<>sec_none then
  274. begin
  275. AsmLn;
  276. AsmWriteLn('_'+ait_section2masmstr[pai_section(hp)^.sec]+#9#9+
  277. 'SEGMENT'#9'PARA PUBLIC USE32 '''+
  278. ait_section2masmstr[pai_section(hp)^.sec]+'''');
  279. end;
  280. LastSec:=pai_section(hp)^.sec;
  281. end;
  282. ait_align : begin
  283. { CAUSES PROBLEMS WITH THE SEGMENT DEFINITION }
  284. { SEGMENT DEFINITION SHOULD MATCH TYPE OF ALIGN }
  285. { HERE UNDER TASM! }
  286. AsmWriteLn(#9'ALIGN '+tostr(pai_align(hp)^.aligntype));
  287. end;
  288. ait_external : AsmWriteLn(#9'EXTRN'#9+StrPas(pai_external(hp)^.name)+
  289. ' :'+extstr[pai_external(hp)^.exttyp]);
  290. ait_datablock : begin
  291. if pai_datablock(hp)^.is_global then
  292. AsmWriteLn(#9'PUBLIC'#9+StrPas(pai_datablock(hp)^.name));
  293. AsmWriteLn(PadTabs(pai_datablock(hp)^.name,#0)+'DB'#9+tostr(pai_datablock(hp)^.size)+' DUP(?)');
  294. end;
  295. ait_const_32bit,
  296. ait_const_8bit,
  297. ait_const_16bit : begin
  298. AsmWrite(ait_const2str[hp^.typ]+tostr(pai_const(hp)^.value));
  299. consttyp:=hp^.typ;
  300. l:=0;
  301. repeat
  302. found:=(not (Pai(hp^.next)=nil)) and (Pai(hp^.next)^.typ=consttyp);
  303. if found then
  304. begin
  305. hp:=Pai(hp^.next);
  306. s:=','+tostr(pai_const(hp)^.value);
  307. AsmWrite(s);
  308. inc(l,length(s));
  309. end;
  310. until (not found) or (l>line_length);
  311. AsmLn;
  312. end;
  313. ait_const_symbol : begin
  314. AsmWrite(#9#9+'DD '#9'offset ');
  315. AsmWritePChar(pchar(pai_const(hp)^.value));
  316. AsmLn;
  317. end;
  318. ait_const_symbol_offset : begin
  319. AsmWrite(#9#9+'DD '#9'offset ');
  320. AsmWritePChar(pai_const_symbol_offset(hp)^.name);
  321. if pai_const_symbol_offset(hp)^.offset>0 then
  322. AsmWrite('+'+tostr(pai_const_symbol_offset(hp)^.offset))
  323. else if pai_const_symbol_offset(hp)^.offset<0 then
  324. AsmWrite(tostr(pai_const_symbol_offset(hp)^.offset));
  325. AsmLn;
  326. end;
  327. ait_real_32bit : AsmWriteLn(#9#9'DD'#9+double2str(pai_single(hp)^.value));
  328. ait_real_64bit : AsmWriteLn(#9#9'DQ'#9+double2str(pai_double(hp)^.value));
  329. ait_real_extended : AsmWriteLn(#9#9'DT'#9+extended2str(pai_extended(hp)^.value));
  330. ait_comp : AsmWriteLn(#9#9'DQ'#9+comp2str(pai_extended(hp)^.value));
  331. ait_string : begin
  332. counter := 0;
  333. lines := pai_string(hp)^.len div line_length;
  334. { separate lines in different parts }
  335. if pai_string(hp)^.len > 0 then
  336. Begin
  337. for j := 0 to lines-1 do
  338. begin
  339. AsmWrite(#9#9'DB'#9);
  340. quoted:=false;
  341. for i:=counter to counter+line_length do
  342. begin
  343. { it is an ascii character. }
  344. if (ord(pai_string(hp)^.str[i])>31) and
  345. (ord(pai_string(hp)^.str[i])<128) and
  346. (pai_string(hp)^.str[i]<>'"') then
  347. begin
  348. if not(quoted) then
  349. begin
  350. if i>counter then
  351. AsmWrite(',');
  352. AsmWrite('"');
  353. end;
  354. AsmWrite(pai_string(hp)^.str[i]);
  355. quoted:=true;
  356. end { if > 31 and < 128 and ord('"') }
  357. else
  358. begin
  359. if quoted then
  360. AsmWrite('"');
  361. if i>counter then
  362. AsmWrite(',');
  363. quoted:=false;
  364. AsmWrite(tostr(ord(pai_string(hp)^.str[i])));
  365. end;
  366. end; { end for i:=0 to... }
  367. if quoted then AsmWrite('"');
  368. AsmWrite(target_os.newline);
  369. counter := counter+line_length;
  370. end; { end for j:=0 ... }
  371. { do last line of lines }
  372. AsmWrite(#9#9'DB'#9);
  373. quoted:=false;
  374. for i:=counter to pai_string(hp)^.len-1 do
  375. begin
  376. { it is an ascii character. }
  377. if (ord(pai_string(hp)^.str[i])>31) and
  378. (ord(pai_string(hp)^.str[i])<128) and
  379. (pai_string(hp)^.str[i]<>'"') then
  380. begin
  381. if not(quoted) then
  382. begin
  383. if i>counter then
  384. AsmWrite(',');
  385. AsmWrite('"');
  386. end;
  387. AsmWrite(pai_string(hp)^.str[i]);
  388. quoted:=true;
  389. end { if > 31 and < 128 and " }
  390. else
  391. begin
  392. if quoted then
  393. AsmWrite('"');
  394. if i>counter then
  395. AsmWrite(',');
  396. quoted:=false;
  397. AsmWrite(tostr(ord(pai_string(hp)^.str[i])));
  398. end;
  399. end; { end for i:=0 to... }
  400. if quoted then
  401. AsmWrite('"');
  402. end;
  403. AsmLn;
  404. end;
  405. ait_label : begin
  406. if pai_label(hp)^.l^.is_used then
  407. begin
  408. AsmWrite(lab2str(pai_label(hp)^.l));
  409. if (assigned(hp^.next) and not(pai(hp^.next)^.typ in
  410. [ait_const_32bit,ait_const_16bit,ait_const_8bit,
  411. ait_const_symbol,ait_const_symbol_offset,
  412. ait_real_32bit,ait_real_64bit,ait_real_extended,ait_string])) then
  413. AsmWriteLn(':');
  414. end;
  415. end;
  416. ait_direct : begin
  417. AsmWritePChar(pai_direct(hp)^.str);
  418. AsmLn;
  419. end;
  420. ait_labeled_instruction : AsmWriteLn(#9#9+int_op2str[pai386_labeled(hp)^._operator]+#9+lab2str(pai386_labeled(hp)^.lab));
  421. ait_symbol : begin
  422. if pai_symbol(hp)^.is_global then
  423. AsmWriteLn(#9'PUBLIC'#9+StrPas(pai_symbol(hp)^.name));
  424. AsmWritePChar(pai_symbol(hp)^.name);
  425. if assigned(hp^.next) and not(pai(hp^.next)^.typ in
  426. [ait_const_32bit,ait_const_16bit,ait_const_8bit,
  427. ait_const_symbol,ait_const_symbol_offset,
  428. ait_real_64bit,ait_real_extended,ait_string]) then
  429. AsmWriteLn(':')
  430. end;
  431. ait_instruction : begin
  432. suffix:='';
  433. prefix:= '';
  434. { added prefix instructions, must be on same line as opcode }
  435. if (pai386(hp)^.op1t = top_none) and
  436. ((pai386(hp)^._operator = A_REP) or
  437. (pai386(hp)^._operator = A_LOCK) or
  438. (pai386(hp)^._operator = A_REPE) or
  439. (pai386(hp)^._operator = A_REPNE)) then
  440. Begin
  441. prefix:=int_op2str[pai386(hp)^._operator]+#9;
  442. hp:=Pai(hp^.next);
  443. { this is theorically impossible... }
  444. if hp=nil then
  445. begin
  446. s:=#9#9+prefix;
  447. AsmWriteLn(s);
  448. break;
  449. end;
  450. end
  451. else
  452. prefix:= '';
  453. if pai386(hp)^.op1t<>top_none then
  454. begin
  455. if pai386(hp)^._operator=A_CALL then
  456. begin
  457. { with tasm call near ptr [edi+12] does not
  458. work but call near [edi+12] works ?? (PM)
  459. It works with call dword ptr [], but you
  460. need /m2 (2 passes) with tasm (PFV)
  461. }
  462. { if pai386(hp)^.op1t=top_ref then
  463. s:='near '+getopstr_jmp(pai386(hp)^.op1t,pai386(hp)^.op1)
  464. else
  465. s:='near ptr '+getopstr_jmp(pai386(hp)^.op1t,pai386(hp)^.op1);}
  466. s:='dword ptr '+getopstr_jmp(pai386(hp)^.op1t,pai386(hp)^.op1);
  467. end
  468. else
  469. begin
  470. s:=getopstr(pai386(hp)^.op1t,pai386(hp)^.op1,pai386(hp)^.size,pai386(hp)^._operator,false);
  471. if pai386(hp)^.op3t<>top_none then
  472. begin
  473. if pai386(hp)^.op2t<>top_none then
  474. s:=getopstr(pai386(hp)^.op2t,pointer(longint(twowords(pai386(hp)^.op2).word1)),
  475. pai386(hp)^.size,pai386(hp)^._operator,true)+','+s;
  476. s:=getopstr(pai386(hp)^.op3t,pointer(longint(twowords(pai386(hp)^.op2).word2)),
  477. pai386(hp)^.size,pai386(hp)^._operator,false)+','+s;
  478. end
  479. else
  480. if pai386(hp)^.op2t<>top_none then
  481. s:=getopstr(pai386(hp)^.op2t,pai386(hp)^.op2,pai386(hp)^.size,
  482. pai386(hp)^._operator,true)+','+s;
  483. end;
  484. s:=#9+s;
  485. end
  486. else
  487. begin
  488. { check if string instruction }
  489. { long form, otherwise may give range check errors }
  490. { in turbo pascal... }
  491. if ((pai386(hp)^._operator = A_CMPS) or
  492. (pai386(hp)^._operator = A_INS) or
  493. (pai386(hp)^._operator = A_OUTS) or
  494. (pai386(hp)^._operator = A_SCAS) or
  495. (pai386(hp)^._operator = A_STOS) or
  496. (pai386(hp)^._operator = A_MOVS) or
  497. (pai386(hp)^._operator = A_LODS) or
  498. (pai386(hp)^._operator = A_XLAT)) then
  499. Begin
  500. case pai386(hp)^.size of
  501. S_B: suffix:='b';
  502. S_W: suffix:='w';
  503. S_L: suffix:='d';
  504. else
  505. Message(assem_f_invalid_suffix_intel);
  506. end;
  507. end;
  508. s:='';
  509. end;
  510. AsmWriteLn(#9#9+prefix+int_op2str[pai386(hp)^._operator]+suffix+s);
  511. end;
  512. {$ifdef GDB}
  513. ait_stabn,
  514. ait_stabs,
  515. ait_force_line,
  516. ait_stab_function_name : ;
  517. {$endif GDB}
  518. ait_cut : begin
  519. { only reset buffer if nothing has changed }
  520. if AsmSize=AsmStartSize then
  521. AsmClear
  522. else
  523. begin
  524. if LastSec<>sec_none then
  525. AsmWriteLn('_'+ait_section2masmstr[LastSec]+#9#9'ENDS');
  526. AsmLn;
  527. AsmWriteLn(#9'END');
  528. AsmClose;
  529. DoAssemble;
  530. if pai_cut(hp)^.EndName then
  531. IsEndFile:=true;
  532. AsmCreate;
  533. end;
  534. { avoid empty files }
  535. while assigned(hp^.next) and (pai(hp^.next)^.typ in [ait_cut,ait_section,ait_comment]) do
  536. begin
  537. if pai(hp^.next)^.typ=ait_section then
  538. begin
  539. lastsec:=pai_section(hp^.next)^.sec;
  540. end;
  541. hp:=pai(hp^.next);
  542. end;
  543. AsmWriteLn(#9'.386p');
  544. AsmWriteLn(#9'LOCALS '+target_asm.labelprefix);
  545. if lastsec<>sec_none then
  546. AsmWriteLn('_'+ait_section2masmstr[lastsec]+#9#9+
  547. 'SEGMENT'#9'PARA PUBLIC USE32 '''+
  548. ait_section2masmstr[lastsec]+'''');
  549. AsmStartSize:=AsmSize;
  550. end;
  551. ait_marker: ;
  552. else
  553. internalerror(10000);
  554. end;
  555. hp:=pai(hp^.next);
  556. end;
  557. end;
  558. procedure ti386intasmlist.WriteAsmList;
  559. begin
  560. {$ifdef EXTDEBUG}
  561. if assigned(current_module^.mainsource) then
  562. comment(v_info,'Start writing intel-styled assembler output for '+current_module^.mainsource^);
  563. {$endif}
  564. LastSec:=sec_none;
  565. AsmWriteLn(#9'.386p');
  566. AsmWriteLn(#9'LOCALS '+target_asm.labelprefix);
  567. AsmWriteLn('DGROUP'#9'GROUP'#9'_BSS,_DATA');
  568. AsmWriteLn(#9'ASSUME'#9'CS:_CODE,ES:DGROUP,DS:DGROUP,SS:DGROUP');
  569. AsmLn;
  570. countlabelref:=false;
  571. WriteTree(externals);
  572. { INTEL ASM doesn't support stabs
  573. WriteTree(debuglist);}
  574. WriteTree(codesegment);
  575. WriteTree(datasegment);
  576. WriteTree(consts);
  577. WriteTree(rttilist);
  578. WriteTree(bsssegment);
  579. countlabelref:=true;
  580. AsmWriteLn(#9'END');
  581. AsmLn;
  582. {$ifdef EXTDEBUG}
  583. if assigned(current_module^.mainsource) then
  584. comment(v_info,'Done writing intel-styled assembler output for '+current_module^.mainsource^);
  585. {$endif EXTDEBUG}
  586. end;
  587. end.
  588. {
  589. $Log$
  590. Revision 1.25 1999-02-22 02:14:59 peter
  591. * updates for ag386bin
  592. Revision 1.24 1998/12/20 16:21:22 peter
  593. * smartlinking doesn't crash anymore
  594. Revision 1.23 1998/12/16 00:27:17 peter
  595. * removed some obsolete version checks
  596. Revision 1.22 1998/12/01 11:19:38 peter
  597. * fixed range problem with in [tasmop]
  598. Revision 1.21 1998/11/30 09:42:55 pierre
  599. * some range check bugs fixed (still not working !)
  600. + added DLL writing support for win32 (also accepts variables)
  601. + TempAnsi for code that could be used for Temporary ansi strings
  602. handling
  603. Revision 1.20 1998/11/17 00:26:09 peter
  604. * fixed for $H+
  605. Revision 1.19 1998/11/16 12:38:05 jonas
  606. + readded ait_marker support
  607. Revision 1.18 1998/11/12 11:19:33 pierre
  608. * fix for first line of function break
  609. Revision 1.17 1998/10/12 12:20:40 pierre
  610. + added tai_const_symbol_offset
  611. for r : pointer = @var.field;
  612. * better message for different arg names on implementation
  613. of function
  614. Revision 1.16 1998/10/06 17:16:33 pierre
  615. * some memory leaks fixed (thanks to Peter for heaptrc !)
  616. Revision 1.15 1998/10/01 20:19:06 jonas
  617. + ait_marker support
  618. Revision 1.14 1998/09/20 17:11:21 jonas
  619. * released REGALLOC
  620. Revision 1.13 1998/08/10 15:49:38 peter
  621. * small fixes for 0.99.5
  622. Revision 1.12 1998/08/08 10:19:17 florian
  623. * small fixes to write the extended type correct
  624. Revision 1.11 1998/06/05 17:46:02 peter
  625. * tp doesn't like comp() typecast
  626. Revision 1.10 1998/05/25 17:11:36 pierre
  627. * firstpasscount bug fixed
  628. now all is already set correctly the first time
  629. under EXTDEBUG try -gp to skip all other firstpasses
  630. it works !!
  631. * small bug fixes
  632. - for smallsets with -dTESTSMALLSET
  633. - some warnings removed (by correcting code !)
  634. Revision 1.9 1998/05/23 01:20:55 peter
  635. + aktasmmode, aktoptprocessor, aktoutputformat
  636. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  637. + $LIBNAME to set the library name where the unit will be put in
  638. * splitted cgi386 a bit (codeseg to large for bp7)
  639. * nasm, tasm works again. nasm moved to ag386nsm.pas
  640. Revision 1.8 1998/05/06 18:36:53 peter
  641. * tai_section extended with code,data,bss sections and enumerated type
  642. * ident 'compiled by FPC' moved to pmodules
  643. * small fix for smartlink
  644. Revision 1.7 1998/05/06 08:38:32 pierre
  645. * better position info with UseTokenInfo
  646. UseTokenInfo greatly simplified
  647. + added check for changed tree after first time firstpass
  648. (if we could remove all the cases were it happen
  649. we could skip all firstpass if firstpasscount > 1)
  650. Only with ExtDebug
  651. Revision 1.6 1998/05/04 17:54:24 peter
  652. + smartlinking works (only case jumptable left todo)
  653. * redesign of systems.pas to support assemblers and linkers
  654. + Unitname is now also in the PPU-file, increased version to 14
  655. Revision 1.5 1998/05/01 07:43:52 florian
  656. + basics for rtti implemented
  657. + switch $m (generate rtti for published sections)
  658. Revision 1.4 1998/04/29 10:33:41 pierre
  659. + added some code for ansistring (not complete nor working yet)
  660. * corrected operator overloading
  661. * corrected nasm output
  662. + started inline procedures
  663. + added starstarn : use ** for exponentiation (^ gave problems)
  664. + started UseTokenInfo cond to get accurate positions
  665. Revision 1.3 1998/04/08 16:58:01 pierre
  666. * several bugfixes
  667. ADD ADC and AND are also sign extended
  668. nasm output OK (program still crashes at end
  669. and creates wrong assembler files !!)
  670. procsym types sym in tdef removed !!
  671. Revision 1.2 1998/04/08 11:34:17 peter
  672. * nasm works (linux only tested)
  673. }