ag386int.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  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[pai_labeled(hp)^._operator]+#9+lab2str(pai_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.24 1998-12-20 16:21:22 peter
  591. * smartlinking doesn't crash anymore
  592. Revision 1.23 1998/12/16 00:27:17 peter
  593. * removed some obsolete version checks
  594. Revision 1.22 1998/12/01 11:19:38 peter
  595. * fixed range problem with in [tasmop]
  596. Revision 1.21 1998/11/30 09:42:55 pierre
  597. * some range check bugs fixed (still not working !)
  598. + added DLL writing support for win32 (also accepts variables)
  599. + TempAnsi for code that could be used for Temporary ansi strings
  600. handling
  601. Revision 1.20 1998/11/17 00:26:09 peter
  602. * fixed for $H+
  603. Revision 1.19 1998/11/16 12:38:05 jonas
  604. + readded ait_marker support
  605. Revision 1.18 1998/11/12 11:19:33 pierre
  606. * fix for first line of function break
  607. Revision 1.17 1998/10/12 12:20:40 pierre
  608. + added tai_const_symbol_offset
  609. for r : pointer = @var.field;
  610. * better message for different arg names on implementation
  611. of function
  612. Revision 1.16 1998/10/06 17:16:33 pierre
  613. * some memory leaks fixed (thanks to Peter for heaptrc !)
  614. Revision 1.15 1998/10/01 20:19:06 jonas
  615. + ait_marker support
  616. Revision 1.14 1998/09/20 17:11:21 jonas
  617. * released REGALLOC
  618. Revision 1.13 1998/08/10 15:49:38 peter
  619. * small fixes for 0.99.5
  620. Revision 1.12 1998/08/08 10:19:17 florian
  621. * small fixes to write the extended type correct
  622. Revision 1.11 1998/06/05 17:46:02 peter
  623. * tp doesn't like comp() typecast
  624. Revision 1.10 1998/05/25 17:11:36 pierre
  625. * firstpasscount bug fixed
  626. now all is already set correctly the first time
  627. under EXTDEBUG try -gp to skip all other firstpasses
  628. it works !!
  629. * small bug fixes
  630. - for smallsets with -dTESTSMALLSET
  631. - some warnings removed (by correcting code !)
  632. Revision 1.9 1998/05/23 01:20:55 peter
  633. + aktasmmode, aktoptprocessor, aktoutputformat
  634. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  635. + $LIBNAME to set the library name where the unit will be put in
  636. * splitted cgi386 a bit (codeseg to large for bp7)
  637. * nasm, tasm works again. nasm moved to ag386nsm.pas
  638. Revision 1.8 1998/05/06 18:36:53 peter
  639. * tai_section extended with code,data,bss sections and enumerated type
  640. * ident 'compiled by FPC' moved to pmodules
  641. * small fix for smartlink
  642. Revision 1.7 1998/05/06 08:38:32 pierre
  643. * better position info with UseTokenInfo
  644. UseTokenInfo greatly simplified
  645. + added check for changed tree after first time firstpass
  646. (if we could remove all the cases were it happen
  647. we could skip all firstpass if firstpasscount > 1)
  648. Only with ExtDebug
  649. Revision 1.6 1998/05/04 17:54:24 peter
  650. + smartlinking works (only case jumptable left todo)
  651. * redesign of systems.pas to support assemblers and linkers
  652. + Unitname is now also in the PPU-file, increased version to 14
  653. Revision 1.5 1998/05/01 07:43:52 florian
  654. + basics for rtti implemented
  655. + switch $m (generate rtti for published sections)
  656. Revision 1.4 1998/04/29 10:33:41 pierre
  657. + added some code for ansistring (not complete nor working yet)
  658. * corrected operator overloading
  659. * corrected nasm output
  660. + started inline procedures
  661. + added starstarn : use ** for exponentiation (^ gave problems)
  662. + started UseTokenInfo cond to get accurate positions
  663. Revision 1.3 1998/04/08 16:58:01 pierre
  664. * several bugfixes
  665. ADD ADC and AND are also sign extended
  666. nasm output OK (program still crashes at end
  667. and creates wrong assembler files !!)
  668. procsym types sym in tdef removed !!
  669. Revision 1.2 1998/04/08 11:34:17 peter
  670. * nasm works (linux only tested)
  671. }