pass_2.pas 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. This unit handles the codegeneration pass
  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. {$E+,F+,N+}
  20. {$endif}
  21. unit pass_2;
  22. interface
  23. uses
  24. tree;
  25. { produces assembler for the expression in variable p }
  26. { and produces an assembler node at the end }
  27. procedure generatecode(var p : ptree);
  28. { produces the actual code }
  29. function do_secondpass(var p : ptree) : boolean;
  30. procedure secondpass(var p : ptree);
  31. implementation
  32. uses
  33. globtype,systems,
  34. cobjects,comphook,verbose,globals,files,
  35. symconst,symtable,types,aasm,scanner,
  36. pass_1,hcodegen,temp_gen,cpubase,cpuasm
  37. {$ifdef GDB}
  38. ,gdb
  39. {$endif}
  40. {$ifdef i386}
  41. ,tgeni386,cgai386
  42. ,cg386con,cg386mat,cg386cnv,cg386set,cg386add
  43. ,cg386mem,cg386cal,cg386ld,cg386flw,cg386inl
  44. {$endif}
  45. {$ifdef m68k}
  46. ,tgen68k,cga68k
  47. ,cg68kcon,cg68kmat,cg68kcnv,cg68kset,cg68kadd
  48. ,cg68kmem,cg68kcal,cg68kld,cg68kflw,cg68kinl
  49. {$endif}
  50. ;
  51. {*****************************************************************************
  52. SecondPass
  53. *****************************************************************************}
  54. type
  55. secondpassproc = procedure(var p : ptree);
  56. procedure secondnothing(var p : ptree);
  57. begin
  58. end;
  59. procedure seconderror(var p : ptree);
  60. begin
  61. p^.error:=true;
  62. codegenerror:=true;
  63. end;
  64. procedure secondstatement(var p : ptree);
  65. var
  66. hp : ptree;
  67. begin
  68. hp:=p;
  69. while assigned(hp) do
  70. begin
  71. if assigned(hp^.right) then
  72. begin
  73. cleartempgen;
  74. {!!!!!!
  75. oldrl:=temptoremove;
  76. temptoremove:=new(plinkedlist,init);
  77. }
  78. secondpass(hp^.right);
  79. { !!!!!!!
  80. some temporary data which can't be released elsewhere
  81. removetemps(exprasmlist,temptoremove);
  82. dispose(temptoremove,done);
  83. temptoremove:=oldrl;
  84. }
  85. end;
  86. hp:=hp^.left;
  87. end;
  88. end;
  89. procedure secondblockn(var p : ptree);
  90. begin
  91. { do second pass on left node }
  92. if assigned(p^.left) then
  93. secondpass(p^.left);
  94. end;
  95. procedure secondasm(var p : ptree);
  96. var
  97. hp,hp2 : pai;
  98. localfixup,parafixup,
  99. i : longint;
  100. r : preference;
  101. begin
  102. if (pocall_inline in aktprocsym^.definition^.proccalloptions) then
  103. begin
  104. localfixup:=aktprocsym^.definition^.localst^.address_fixup;
  105. parafixup:=aktprocsym^.definition^.parast^.address_fixup;
  106. hp:=pai(p^.p_asm^.first);
  107. while assigned(hp) do
  108. begin
  109. hp2:=pai(hp^.getcopy);
  110. case hp2^.typ of
  111. ait_instruction :
  112. begin
  113. { fixup the references }
  114. for i:=1 to pai386(hp2)^.ops do
  115. if pai386(hp2)^.oper[i-1].typ=top_ref then
  116. begin
  117. r:=pai386(hp2)^.oper[i-1].ref;
  118. case r^.options of
  119. ref_parafixup :
  120. r^.offsetfixup:=parafixup;
  121. ref_localfixup :
  122. r^.offsetfixup:=localfixup;
  123. end;
  124. end;
  125. exprasmlist^.concat(hp2);
  126. end;
  127. ait_marker :
  128. begin
  129. { it's not an assembler block anymore }
  130. if not(pai_marker(hp2)^.kind in [AsmBlockStart, AsmBlockEnd]) then
  131. exprasmlist^.concat(hp2);
  132. end;
  133. else
  134. exprasmlist^.concat(hp2);
  135. end;
  136. hp:=pai(hp^.next);
  137. end
  138. end
  139. else
  140. exprasmlist^.concatlist(p^.p_asm);
  141. if not p^.object_preserved then
  142. begin
  143. {$ifdef i386}
  144. maybe_loadesi;
  145. {$endif}
  146. {$ifdef m68k}
  147. maybe_loada5;
  148. {$endif}
  149. end;
  150. end;
  151. procedure secondpass(var p : ptree);
  152. const
  153. procedures : array[ttreetyp] of secondpassproc =
  154. (secondadd, {addn}
  155. secondadd, {muln}
  156. secondadd, {subn}
  157. secondmoddiv, {divn}
  158. secondadd, {symdifn}
  159. secondmoddiv, {modn}
  160. secondassignment, {assignn}
  161. secondload, {loadn}
  162. secondnothing, {range}
  163. secondadd, {ltn}
  164. secondadd, {lten}
  165. secondadd, {gtn}
  166. secondadd, {gten}
  167. secondadd, {equaln}
  168. secondadd, {unequaln}
  169. secondin, {inn}
  170. secondadd, {orn}
  171. secondadd, {xorn}
  172. secondshlshr, {shrn}
  173. secondshlshr, {shln}
  174. secondadd, {slashn}
  175. secondadd, {andn}
  176. secondsubscriptn, {subscriptn}
  177. secondderef, {derefn}
  178. secondaddr, {addrn}
  179. seconddoubleaddr, {doubleaddrn}
  180. secondordconst, {ordconstn}
  181. secondtypeconv, {typeconvn}
  182. secondcalln, {calln}
  183. secondnothing, {callparan}
  184. secondrealconst, {realconstn}
  185. secondfixconst, {fixconstn}
  186. secondumminus, {umminusn}
  187. secondasm, {asmn}
  188. secondvecn, {vecn}
  189. secondstringconst, {stringconstn}
  190. secondfuncret, {funcretn}
  191. secondselfn, {selfn}
  192. secondnot, {notn}
  193. secondinline, {inlinen}
  194. secondniln, {niln}
  195. seconderror, {errorn}
  196. secondnothing, {typen}
  197. secondhnewn, {hnewn}
  198. secondhdisposen, {hdisposen}
  199. secondnewn, {newn}
  200. secondsimplenewdispose, {simpledisposen}
  201. secondsetelement, {setelementn}
  202. secondsetconst, {setconstn}
  203. secondblockn, {blockn}
  204. secondstatement, {statementn}
  205. secondnothing, {loopn}
  206. secondifn, {ifn}
  207. secondbreakn, {breakn}
  208. secondcontinuen, {continuen}
  209. second_while_repeatn, {repeatn}
  210. second_while_repeatn, {whilen}
  211. secondfor, {forn}
  212. secondexitn, {exitn}
  213. secondwith, {withn}
  214. secondcase, {casen}
  215. secondlabel, {labeln}
  216. secondgoto, {goton}
  217. secondsimplenewdispose, {simplenewn}
  218. secondtryexcept, {tryexceptn}
  219. secondraise, {raisen}
  220. secondnothing, {switchesn}
  221. secondtryfinally, {tryfinallyn}
  222. secondon, {onn}
  223. secondis, {isn}
  224. secondas, {asn}
  225. seconderror, {caretn}
  226. secondfail, {failn}
  227. secondadd, {starstarn}
  228. secondprocinline, {procinlinen}
  229. secondarrayconstruct, {arrayconstructn}
  230. secondnothing, {arrayconstructrangen}
  231. secondnothing, {nothingn}
  232. secondloadvmt {loadvmtn}
  233. );
  234. var
  235. oldcodegenerror : boolean;
  236. oldlocalswitches : tlocalswitches;
  237. oldpos : tfileposinfo;
  238. begin
  239. if not(p^.error) then
  240. begin
  241. oldcodegenerror:=codegenerror;
  242. oldlocalswitches:=aktlocalswitches;
  243. oldpos:=aktfilepos;
  244. aktfilepos:=p^.fileinfo;
  245. aktlocalswitches:=p^.localswitches;
  246. codegenerror:=false;
  247. procedures[p^.treetype](p);
  248. p^.error:=codegenerror;
  249. codegenerror:=codegenerror or oldcodegenerror;
  250. aktlocalswitches:=oldlocalswitches;
  251. aktfilepos:=oldpos;
  252. end
  253. else
  254. codegenerror:=true;
  255. end;
  256. function do_secondpass(var p : ptree) : boolean;
  257. begin
  258. codegenerror:=false;
  259. if not(p^.error) then
  260. secondpass(p);
  261. do_secondpass:=codegenerror;
  262. end;
  263. var
  264. { the array ranges are oveestimated !!! }
  265. { max(maxvarregs,maxfpuvarregs) would be }
  266. { enough }
  267. regvars : array[1..maxvarregs+maxfpuvarregs] of pvarsym;
  268. regvars_para : array[1..maxvarregs+maxfpuvarregs] of boolean;
  269. regvars_refs : array[1..maxvarregs+maxfpuvarregs] of longint;
  270. parasym : boolean;
  271. procedure searchregvars(p : pnamedindexobject);
  272. var
  273. i,j,k : longint;
  274. begin
  275. if (psym(p)^.typ=varsym) and (vo_regable in pvarsym(p)^.varoptions) then
  276. begin
  277. { walk through all momentary register variables }
  278. for i:=1 to maxvarregs do
  279. begin
  280. { free register ? }
  281. if regvars[i]=nil then
  282. begin
  283. regvars[i]:=pvarsym(p);
  284. regvars_para[i]:=parasym;
  285. break;
  286. end;
  287. { else throw out a variable ? }
  288. j:=pvarsym(p)^.refs;
  289. { parameter get a less value }
  290. if parasym then
  291. begin
  292. if cs_littlesize in aktglobalswitches then
  293. dec(j,1)
  294. else
  295. dec(j,100);
  296. end;
  297. if (j>regvars_refs[i]) and (j>0) then
  298. begin
  299. for k:=maxvarregs-1 downto i do
  300. begin
  301. regvars[k+1]:=regvars[k];
  302. regvars_para[k+1]:=regvars_para[k];
  303. end;
  304. { calc the new refs
  305. pvarsym(p)^.refs:=j; }
  306. regvars[i]:=pvarsym(p);
  307. regvars_para[i]:=parasym;
  308. regvars_refs[i]:=j;
  309. break;
  310. end;
  311. end;
  312. end;
  313. end;
  314. procedure searchfpuregvars(p : pnamedindexobject);
  315. var
  316. i,j,k : longint;
  317. begin
  318. if (psym(p)^.typ=varsym) and (vo_fpuregable in pvarsym(p)^.varoptions) then
  319. begin
  320. { walk through all momentary register variables }
  321. for i:=1 to maxfpuvarregs do
  322. begin
  323. { free register ? }
  324. if regvars[i]=nil then
  325. begin
  326. regvars[i]:=pvarsym(p);
  327. regvars_para[i]:=parasym;
  328. break;
  329. end;
  330. { else throw out a variable ? }
  331. j:=pvarsym(p)^.refs;
  332. { parameter get a less value }
  333. if parasym then
  334. begin
  335. if cs_littlesize in aktglobalswitches then
  336. dec(j,1)
  337. else
  338. dec(j,100);
  339. end;
  340. if (j>regvars_refs[i]) and (j>0) then
  341. begin
  342. for k:=maxfpuvarregs-1 downto i do
  343. begin
  344. regvars[k+1]:=regvars[k];
  345. regvars_para[k+1]:=regvars_para[k];
  346. end;
  347. { calc the new refs
  348. pvarsym(p)^.refs:=j; }
  349. regvars[i]:=pvarsym(p);
  350. regvars_para[i]:=parasym;
  351. regvars_refs[i]:=j;
  352. break;
  353. end;
  354. end;
  355. end;
  356. end;
  357. procedure generatecode(var p : ptree);
  358. var
  359. i : longint;
  360. regsize : topsize;
  361. hr : preference;
  362. label
  363. nextreg;
  364. begin
  365. {!!!!!!!! temptoremove:=nil; }
  366. cleartempgen;
  367. { when size optimization only count occurrence }
  368. if cs_littlesize in aktglobalswitches then
  369. t_times:=1
  370. else
  371. { reference for repetition is 100 }
  372. t_times:=100;
  373. { clear register count }
  374. clearregistercount;
  375. use_esp_stackframe:=false;
  376. if not(do_firstpass(p)) then
  377. begin
  378. { max. optimizations }
  379. { only if no asm is used }
  380. { and no try statement }
  381. if (cs_regalloc in aktglobalswitches) and
  382. ((procinfo.flags and (pi_uses_asm or pi_uses_exceptions))=0) then
  383. begin
  384. { can we omit the stack frame ? }
  385. { conditions:
  386. 1. procedure (not main block)
  387. 2. no constructor or destructor
  388. 3. no call to other procedures
  389. 4. no interrupt handler
  390. }
  391. {!!!!!! this doesn work yet, because of problems with
  392. with linux and windows
  393. }
  394. (*
  395. if assigned(aktprocsym) then
  396. begin
  397. if not(aktprocsym^.definition^.proctypeoption in [potype_constructor,potype_destructor]) and
  398. not(po_interrupt in aktprocsym^.definition^.procoptions) and
  399. ((procinfo.flags and pi_do_call)=0) and
  400. (lexlevel>=normal_function_level) then
  401. begin
  402. { use ESP as frame pointer }
  403. procinfo.framepointer:=stack_pointer;
  404. use_esp_stackframe:=true;
  405. { calc parameter distance new }
  406. dec(procinfo.framepointer_offset,4);
  407. dec(procinfo.ESI_offset,4);
  408. { is this correct ???}
  409. { retoffset can be negativ for results in eax !! }
  410. { the value should be decreased only if positive }
  411. if procinfo.retoffset>=0 then
  412. dec(procinfo.retoffset,4);
  413. dec(procinfo.call_offset,4);
  414. aktprocsym^.definition^.parast^.address_fixup:=procinfo.call_offset;
  415. end;
  416. end;
  417. *)
  418. if (p^.registers32<4) then
  419. begin
  420. for i:=1 to maxvarregs do
  421. regvars[i]:=nil;
  422. parasym:=false;
  423. symtablestack^.foreach({$ifndef TP}@{$endif}searchregvars);
  424. { copy parameter into a register ? }
  425. parasym:=true;
  426. symtablestack^.next^.foreach({$ifndef TP}@{$endif}searchregvars);
  427. { hold needed registers free }
  428. for i:=maxvarregs downto maxvarregs-p^.registers32+1 do
  429. regvars[i]:=nil;
  430. { now assign register }
  431. for i:=1 to maxvarregs-p^.registers32 do
  432. begin
  433. if assigned(regvars[i]) then
  434. begin
  435. { it is nonsens, to copy the variable to }
  436. { a register because we need then much }
  437. { too pushes ? }
  438. if reg_pushes[varregs[i]]>=regvars[i]^.refs then
  439. begin
  440. regvars[i]:=nil;
  441. goto nextreg;
  442. end;
  443. { register is no longer available for }
  444. { expressions }
  445. { search the register which is the most }
  446. { unused }
  447. usableregs:=usableregs-[varregs[i]];
  448. {$ifdef i386}
  449. procinfo.aktentrycode^.concat(new(pairegalloc,alloc(varregs[i])));
  450. {$endif i386}
  451. is_reg_var[varregs[i]]:=true;
  452. dec(c_usableregs);
  453. { possibly no 32 bit register are needed }
  454. { call by reference/const ? }
  455. if (regvars[i]^.varspez=vs_var) or
  456. ((regvars[i]^.varspez=vs_const) and
  457. push_addr_param(regvars[i]^.definition)) then
  458. begin
  459. regvars[i]^.reg:=varregs[i];
  460. regsize:=S_L;
  461. end
  462. else
  463. if (regvars[i]^.definition^.deftype=orddef) and
  464. (porddef(regvars[i]^.definition)^.size=1) then
  465. begin
  466. {$ifdef i386}
  467. regvars[i]^.reg:=reg32toreg8(varregs[i]);
  468. {$endif}
  469. regsize:=S_B;
  470. end
  471. else
  472. if (regvars[i]^.definition^.deftype=orddef) and
  473. (porddef(regvars[i]^.definition)^.size=2) then
  474. begin
  475. {$ifdef i386}
  476. regvars[i]^.reg:=reg32toreg16(varregs[i]);
  477. {$endif}
  478. regsize:=S_W;
  479. end
  480. else
  481. begin
  482. regvars[i]^.reg:=varregs[i];
  483. regsize:=S_L;
  484. end;
  485. { parameter must be load }
  486. if regvars_para[i] then
  487. begin
  488. { procinfo is there actual, }
  489. { because we can't never be in a }
  490. { nested procedure }
  491. { when loading parameter to reg }
  492. new(hr);
  493. reset_reference(hr^);
  494. hr^.offset:=pvarsym(regvars[i])^.address+procinfo.call_offset;
  495. hr^.base:=procinfo.framepointer;
  496. {$ifdef i386}
  497. procinfo.aktentrycode^.concat(new(pai386,op_ref_reg(A_MOV,regsize,
  498. hr,regvars[i]^.reg)));
  499. {$endif i386}
  500. {$ifdef m68k}
  501. procinfo.aktentrycode^.concat(new(pai68k,op_ref_reg(A_MOVE,regsize,
  502. hr,regvars[i]^.reg)));
  503. {$endif m68k}
  504. unused:=unused - [regvars[i]^.reg];
  505. end;
  506. { procedure uses this register }
  507. {$ifdef i386}
  508. usedinproc:=usedinproc or ($80 shr byte(varregs[i]));
  509. {$endif i386}
  510. {$ifdef m68k}
  511. usedinproc:=usedinproc or ($800 shr word(varregs[i]));
  512. {$endif m68k}
  513. end;
  514. nextreg:
  515. { dummy }
  516. regsize:=S_W;
  517. end;
  518. for i:=1 to maxvarregs do
  519. begin
  520. if assigned(regvars[i]) then
  521. begin
  522. if cs_asm_source in aktglobalswitches then
  523. procinfo.aktentrycode^.insert(new(pai_asm_comment,init(strpnew(regvars[i]^.name+
  524. ' with weight '+tostr(regvars[i]^.refs)+' assigned to register '+
  525. reg2str(regvars[i]^.reg)))));
  526. if (status.verbosity and v_debug)=v_debug then
  527. Message3(cg_d_register_weight,reg2str(regvars[i]^.reg),
  528. tostr(regvars[i]^.refs),regvars[i]^.name);
  529. end;
  530. end;
  531. end;
  532. if (p^.registersfpu<maxfpuvarregs-2) then
  533. begin
  534. for i:=1 to maxfpuvarregs do
  535. regvars[i]:=nil;
  536. parasym:=false;
  537. symtablestack^.foreach({$ifndef TP}@{$endif}searchfpuregvars);
  538. {$ifdef dummy}
  539. { copy parameter into a register ? }
  540. parasym:=true;
  541. symtablestack^.next^.foreach({$ifndef TP}@{$endif}searchregvars);
  542. {$endif dummy}
  543. { hold needed registers free }
  544. for i:=maxfpuvarregs downto maxfpuvarregs-p^.registersfpu+1 do
  545. regvars[i]:=nil;
  546. { now assign register }
  547. for i:=1 to maxfpuvarregs-p^.registersfpu do
  548. begin
  549. if assigned(regvars[i]) then
  550. begin
  551. regvars[i]^.reg:=correct_fpuregister(R_ST0,i-1);
  552. {$ifdef dummy}
  553. { parameter must be load }
  554. if regvars_para[i] then
  555. begin
  556. { procinfo is there actual, }
  557. { because we can't never be in a }
  558. { nested procedure }
  559. { when loading parameter to reg }
  560. new(hr);
  561. reset_reference(hr^);
  562. hr^.offset:=pvarsym(regvars[i])^.address+procinfo.call_offset;
  563. hr^.base:=procinfo.framepointer;
  564. {$ifdef i386}
  565. procinfo.aktentrycode^.concat(new(pai386,op_ref_reg(A_MOV,regsize,
  566. hr,regvars[i]^.reg)));
  567. {$endif i386}
  568. {$ifdef m68k}
  569. procinfo.aktentrycode^.concat(new(pai68k,op_ref_reg(A_MOVE,regsize,
  570. hr,regvars[i]^.reg)));
  571. {$endif m68k}
  572. end;
  573. {$endif dummy}
  574. end;
  575. end;
  576. if cs_asm_source in aktglobalswitches then
  577. procinfo.aktentrycode^.insert(new(pai_asm_comment,init(strpnew(tostr(p^.registersfpu)+
  578. ' registers on FPU stack used by temp. expressions'))));
  579. for i:=1 to maxfpuvarregs do
  580. begin
  581. if assigned(regvars[i]) then
  582. begin
  583. if cs_asm_source in aktglobalswitches then
  584. procinfo.aktentrycode^.insert(new(pai_asm_comment,init(strpnew(regvars[i]^.name+
  585. ' with weight '+tostr(regvars[i]^.refs)+' assigned to register '+
  586. reg2str(regvars[i]^.reg)))));
  587. if (status.verbosity and v_debug)=v_debug then
  588. Message3(cg_d_register_weight,reg2str(regvars[i]^.reg),
  589. tostr(regvars[i]^.refs),regvars[i]^.name);
  590. end;
  591. end;
  592. if cs_asm_source in aktglobalswitches then
  593. procinfo.aktentrycode^.insert(new(pai_asm_comment,init(strpnew('Register variable assignment:'))));
  594. end;
  595. end;
  596. if assigned(aktprocsym) and
  597. (pocall_inline in aktprocsym^.definition^.proccalloptions) then
  598. make_const_global:=true;
  599. do_secondpass(p);
  600. if assigned(procinfo.def) then
  601. procinfo.def^.fpu_used:=p^.registersfpu;
  602. { all registers can be used again }
  603. resetusableregisters;
  604. end;
  605. procinfo.aktproccode^.concatlist(exprasmlist);
  606. make_const_global:=false;
  607. end;
  608. end.
  609. {
  610. $Log$
  611. Revision 1.31 1999-08-07 14:20:59 florian
  612. * some small problems fixed
  613. Revision 1.30 1999/08/04 14:21:07 florian
  614. * now every available fpu register is used for
  615. fpu register variables
  616. Revision 1.29 1999/08/04 13:45:28 florian
  617. + floating point register variables !!
  618. * pairegalloc is now generated for register variables
  619. Revision 1.28 1999/08/04 00:23:10 florian
  620. * renamed i386asm and i386base to cpuasm and cpubase
  621. Revision 1.27 1999/08/03 22:02:55 peter
  622. * moved bitmask constants to sets
  623. * some other type/const renamings
  624. Revision 1.26 1999/06/02 22:44:08 pierre
  625. * previous wrong log corrected
  626. Revision 1.25 1999/06/02 22:25:41 pierre
  627. * changed $ifdef FPC @ into $ifndef TP
  628. Revision 1.24 1999/06/01 14:45:50 peter
  629. * @procvar is now always needed for FPC
  630. Revision 1.23 1999/05/27 19:44:43 peter
  631. * removed oldasm
  632. * plabel -> pasmlabel
  633. * -a switches to source writing automaticly
  634. * assembler readers OOPed
  635. * asmsymbol automaticly external
  636. * jumptables and other label fixes for asm readers
  637. Revision 1.22 1999/05/18 14:15:50 peter
  638. * containsself fixes
  639. * checktypes()
  640. Revision 1.21 1999/05/17 21:57:11 florian
  641. * new temporary ansistring handling
  642. Revision 1.20 1999/05/02 21:33:54 florian
  643. * several bugs regarding -Or fixed
  644. Revision 1.19 1999/05/01 13:24:28 peter
  645. * merged nasm compiler
  646. * old asm moved to oldasm/
  647. Revision 1.18 1999/04/28 06:02:04 florian
  648. * changes of Bruessel:
  649. + message handler can now take an explicit self
  650. * typinfo fixed: sometimes the type names weren't written
  651. * the type checking for pointer comparisations and subtraction
  652. and are now more strict (was also buggy)
  653. * small bug fix to link.pas to support compiling on another
  654. drive
  655. * probable bug in popt386 fixed: call/jmp => push/jmp
  656. transformation didn't count correctly the jmp references
  657. + threadvar support
  658. * warning if ln/sqrt gets an invalid constant argument
  659. Revision 1.17 1999/03/31 13:55:11 peter
  660. * assembler inlining working for ag386bin
  661. Revision 1.16 1999/03/24 23:17:11 peter
  662. * fixed bugs 212,222,225,227,229,231,233
  663. Revision 1.15 1999/02/22 02:15:25 peter
  664. * updates for ag386bin
  665. Revision 1.14 1999/01/23 23:29:37 florian
  666. * first running version of the new code generator
  667. * when compiling exceptions under Linux fixed
  668. Revision 1.13 1998/12/30 13:41:09 peter
  669. * released valuepara
  670. Revision 1.12 1998/12/19 00:23:51 florian
  671. * ansistring memory leaks fixed
  672. Revision 1.11 1998/12/11 00:03:28 peter
  673. + globtype,tokens,version unit splitted from globals
  674. Revision 1.10 1998/11/18 15:44:14 peter
  675. * VALUEPARA for tp7 compatible value parameters
  676. Revision 1.9 1998/11/13 15:40:21 pierre
  677. + added -Se in Makefile cvstest target
  678. + lexlevel cleanup
  679. normal_function_level main_program_level and unit_init_level defined
  680. * tins_cache grown to A_EMMS (gave range check error in asm readers)
  681. (test added in code !)
  682. * -Un option was wrong
  683. * _FAIL and _SELF only keyword inside
  684. constructors and methods respectively
  685. Revision 1.8 1998/10/29 15:42:49 florian
  686. + partial disposing of temp. ansistrings
  687. Revision 1.7 1998/10/26 22:58:19 florian
  688. * new introduded problem with classes fix, the parent class wasn't set
  689. correct, if the class was defined forward before
  690. Revision 1.6 1998/09/23 09:58:52 peter
  691. * first working array of const things
  692. Revision 1.5 1998/09/21 10:01:06 peter
  693. * check if procinfo.def is assigned before storing registersfpu
  694. Revision 1.4 1998/09/21 08:45:16 pierre
  695. + added vmt_offset in tobjectdef.write for fututre use
  696. (first steps to have objects without vmt if no virtual !!)
  697. + added fpu_used field for tabstractprocdef :
  698. sets this level to 2 if the functions return with value in FPU
  699. (is then set to correct value at parsing of implementation)
  700. THIS MIGHT refuse some code with FPU expression too complex
  701. that were accepted before and even in some cases
  702. that don't overflow in fact
  703. ( like if f : float; is a forward that finally in implementation
  704. only uses one fpu register !!)
  705. Nevertheless I think that it will improve security on
  706. FPU operations !!
  707. * most other changes only for UseBrowser code
  708. (added symtable references for record and objects)
  709. local switch for refs to args and local of each function
  710. (static symtable still missing)
  711. UseBrowser still not stable and probably broken by
  712. the definition hash array !!
  713. Revision 1.3 1998/09/17 09:42:40 peter
  714. + pass_2 for cg386
  715. * Message() -> CGMessage() for pass_1/pass_2
  716. Revision 1.2 1998/09/07 18:46:07 peter
  717. * update smartlinking, uses getdatalabel
  718. * renamed ptree.value vars to value_str,value_real,value_set
  719. Revision 1.1 1998/09/01 09:07:12 peter
  720. * m68k fixes, splitted cg68k like cgi386
  721. }