pstatmnt.pas 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Does the parsing of the statements
  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. unit pstatmnt;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. tokens,node;
  23. function statement_block(starttoken : ttoken) : tnode;
  24. { reads an assembler block }
  25. function assembler_block : tnode;
  26. implementation
  27. uses
  28. { common }
  29. cutils,
  30. { global }
  31. globtype,globals,verbose,
  32. systems,cpuinfo,
  33. { aasm }
  34. cpubase,aasmbase,aasmtai,aasmcpu,
  35. { symtable }
  36. symconst,symbase,symtype,symdef,symsym,symtable,defutil,defcmp,
  37. paramgr,
  38. { pass 1 }
  39. pass_1,htypechk,
  40. nutils,nbas,nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,
  41. { parser }
  42. scanner,
  43. pbase,pexpr,
  44. { codegen }
  45. tgobj,rgobj,cgbase
  46. ,ncgutil
  47. ,radirect
  48. {$ifdef i386}
  49. {$ifndef NoRa386Int}
  50. ,ra386int
  51. {$endif NoRa386Int}
  52. {$ifndef NoRa386Att}
  53. ,ra386att
  54. {$endif NoRa386Att}
  55. {$else}
  56. ,rasm
  57. {$endif i386}
  58. ;
  59. function statement : tnode;forward;
  60. function if_statement : tnode;
  61. var
  62. ex,if_a,else_a : tnode;
  63. begin
  64. consume(_IF);
  65. ex:=comp_expr(true);
  66. consume(_THEN);
  67. if token<>_ELSE then
  68. if_a:=statement
  69. else
  70. if_a:=nil;
  71. if try_to_consume(_ELSE) then
  72. else_a:=statement
  73. else
  74. else_a:=nil;
  75. if_statement:=genloopnode(ifn,ex,if_a,else_a,false);
  76. end;
  77. { creates a block (list) of statements, til the next END token }
  78. function statements_til_end : tnode;
  79. var
  80. first,last : tstatementnode;
  81. begin
  82. first:=nil;
  83. while token<>_END do
  84. begin
  85. if first=nil then
  86. begin
  87. last:=cstatementnode.create(statement,nil);
  88. first:=last;
  89. end
  90. else
  91. begin
  92. last.right:=cstatementnode.create(statement,nil);
  93. last:=tstatementnode(last.right);
  94. end;
  95. if not try_to_consume(_SEMICOLON) then
  96. break;
  97. consume_emptystats;
  98. end;
  99. consume(_END);
  100. statements_til_end:=cblocknode.create(first,true);
  101. end;
  102. function case_statement : tnode;
  103. var
  104. { contains the label number of currently parsed case block }
  105. aktcaselabel : tasmlabel;
  106. firstlabel : boolean;
  107. root : pcaserecord;
  108. { the typ of the case expression }
  109. casedef : tdef;
  110. procedure newcaselabel(l,h : TConstExprInt;first:boolean);
  111. var
  112. hcaselabel : pcaserecord;
  113. procedure insertlabel(var p : pcaserecord);
  114. begin
  115. if p=nil then p:=hcaselabel
  116. else
  117. if (p^._low>hcaselabel^._low) and
  118. (p^._low>hcaselabel^._high) then
  119. if (hcaselabel^.statement = p^.statement) and
  120. (p^._low = hcaselabel^._high + 1) then
  121. begin
  122. p^._low := hcaselabel^._low;
  123. dispose(hcaselabel);
  124. end
  125. else
  126. insertlabel(p^.less)
  127. else
  128. if (p^._high<hcaselabel^._low) and
  129. (p^._high<hcaselabel^._high) then
  130. if (hcaselabel^.statement = p^.statement) and
  131. (p^._high+1 = hcaselabel^._low) then
  132. begin
  133. p^._high := hcaselabel^._high;
  134. dispose(hcaselabel);
  135. end
  136. else
  137. insertlabel(p^.greater)
  138. else Message(parser_e_double_caselabel);
  139. end;
  140. begin
  141. new(hcaselabel);
  142. hcaselabel^.less:=nil;
  143. hcaselabel^.greater:=nil;
  144. hcaselabel^.statement:=aktcaselabel;
  145. hcaselabel^.firstlabel:=first;
  146. objectlibrary.getlabel(hcaselabel^._at);
  147. hcaselabel^._low:=l;
  148. hcaselabel^._high:=h;
  149. insertlabel(root);
  150. end;
  151. var
  152. code,caseexpr,p,instruc,elseblock : tnode;
  153. hl1,hl2 : TConstExprInt;
  154. casedeferror : boolean;
  155. begin
  156. consume(_CASE);
  157. caseexpr:=comp_expr(true);
  158. { determines result type }
  159. {$ifndef newra}
  160. rg.cleartempgen;
  161. {$endif}
  162. do_resulttypepass(caseexpr);
  163. casedeferror:=false;
  164. casedef:=caseexpr.resulttype.def;
  165. if (not assigned(casedef)) or
  166. not(is_ordinal(casedef)) then
  167. begin
  168. CGMessage(type_e_ordinal_expr_expected);
  169. { create a correct tree }
  170. caseexpr.free;
  171. caseexpr:=cordconstnode.create(0,u32bittype,false);
  172. { set error flag so no rangechecks are done }
  173. casedeferror:=true;
  174. end;
  175. consume(_OF);
  176. root:=nil;
  177. instruc:=nil;
  178. repeat
  179. objectlibrary.getlabel(aktcaselabel);
  180. firstlabel:=true;
  181. { maybe an instruction has more case labels }
  182. repeat
  183. p:=expr;
  184. if is_widechar(casedef) then
  185. begin
  186. if (p.nodetype=rangen) then
  187. begin
  188. trangenode(p).left:=ctypeconvnode.create(trangenode(p).left,cwidechartype);
  189. trangenode(p).right:=ctypeconvnode.create(trangenode(p).right,cwidechartype);
  190. do_resulttypepass(trangenode(p).left);
  191. do_resulttypepass(trangenode(p).right);
  192. end
  193. else
  194. begin
  195. p:=ctypeconvnode.create(p,cwidechartype);
  196. do_resulttypepass(p);
  197. end;
  198. end;
  199. hl1:=0;
  200. hl2:=0;
  201. if (p.nodetype=rangen) then
  202. begin
  203. { type checking for case statements }
  204. if is_subequal(casedef, trangenode(p).left.resulttype.def) and
  205. is_subequal(casedef, trangenode(p).right.resulttype.def) then
  206. begin
  207. hl1:=get_ordinal_value(trangenode(p).left);
  208. hl2:=get_ordinal_value(trangenode(p).right);
  209. if hl1>hl2 then
  210. CGMessage(parser_e_case_lower_less_than_upper_bound);
  211. if not casedeferror then
  212. begin
  213. testrange(casedef,hl1,false);
  214. testrange(casedef,hl2,false);
  215. end;
  216. end
  217. else
  218. CGMessage(parser_e_case_mismatch);
  219. newcaselabel(hl1,hl2,firstlabel);
  220. end
  221. else
  222. begin
  223. { type checking for case statements }
  224. if not is_subequal(casedef, p.resulttype.def) then
  225. CGMessage(parser_e_case_mismatch);
  226. hl1:=get_ordinal_value(p);
  227. if not casedeferror then
  228. testrange(casedef,hl1,false);
  229. newcaselabel(hl1,hl1,firstlabel);
  230. end;
  231. p.free;
  232. if token=_COMMA then
  233. consume(_COMMA)
  234. else
  235. break;
  236. firstlabel:=false;
  237. until false;
  238. consume(_COLON);
  239. { handles instruction block }
  240. p:=clabelnode.createcase(aktcaselabel,statement);
  241. { concats instruction }
  242. instruc:=cstatementnode.create(p,instruc);
  243. if not(token in [_ELSE,_OTHERWISE,_END]) then
  244. consume(_SEMICOLON);
  245. until (token in [_ELSE,_OTHERWISE,_END]);
  246. if (token in [_ELSE,_OTHERWISE]) then
  247. begin
  248. if not try_to_consume(_ELSE) then
  249. consume(_OTHERWISE);
  250. elseblock:=statements_til_end;
  251. end
  252. else
  253. begin
  254. elseblock:=nil;
  255. consume(_END);
  256. end;
  257. code:=ccasenode.create(caseexpr,instruc,root);
  258. tcasenode(code).elseblock:=elseblock;
  259. case_statement:=code;
  260. end;
  261. function repeat_statement : tnode;
  262. var
  263. first,last,p_e : tnode;
  264. begin
  265. consume(_REPEAT);
  266. first:=nil;
  267. while token<>_UNTIL do
  268. begin
  269. if first=nil then
  270. begin
  271. last:=cstatementnode.create(statement,nil);
  272. first:=last;
  273. end
  274. else
  275. begin
  276. tstatementnode(last).right:=cstatementnode.create(statement,nil);
  277. last:=tstatementnode(last).right;
  278. end;
  279. if not try_to_consume(_SEMICOLON) then
  280. break;
  281. consume_emptystats;
  282. end;
  283. consume(_UNTIL);
  284. first:=cblocknode.create(first,true);
  285. p_e:=comp_expr(true);
  286. repeat_statement:=genloopnode(whilerepeatn,p_e,first,nil,true);
  287. end;
  288. function while_statement : tnode;
  289. var
  290. p_e,p_a : tnode;
  291. begin
  292. consume(_WHILE);
  293. p_e:=comp_expr(true);
  294. consume(_DO);
  295. p_a:=statement;
  296. while_statement:=genloopnode(whilerepeatn,p_e,p_a,nil,false);
  297. end;
  298. function for_statement : tnode;
  299. var
  300. p_e,tovalue,p_a : tnode;
  301. backward : boolean;
  302. begin
  303. { parse loop header }
  304. consume(_FOR);
  305. p_e:=expr;
  306. if token=_DOWNTO then
  307. begin
  308. consume(_DOWNTO);
  309. backward:=true;
  310. end
  311. else
  312. begin
  313. consume(_TO);
  314. backward:=false;
  315. end;
  316. tovalue:=comp_expr(true);
  317. consume(_DO);
  318. { ... now the instruction }
  319. p_a:=statement;
  320. for_statement:=genloopnode(forn,p_e,tovalue,p_a,backward);
  321. end;
  322. function _with_statement : tnode;
  323. var
  324. right,p : tnode;
  325. i,levelcount : longint;
  326. withsymtable,symtab : tsymtable;
  327. obj : tobjectdef;
  328. hp : tnode;
  329. newblock : tblocknode;
  330. newstatement : tstatementnode;
  331. calltempp,
  332. loadp : ttempcreatenode;
  333. refp : tnode;
  334. htype : ttype;
  335. hasimplicitderef : boolean;
  336. begin
  337. p:=comp_expr(true);
  338. do_resulttypepass(p);
  339. set_varstate(p,false);
  340. right:=nil;
  341. if (not codegenerror) and
  342. (p.resulttype.def.deftype in [objectdef,recorddef]) then
  343. begin
  344. newblock:=nil;
  345. { ignore nodes that don't add instructions in the tree }
  346. hp:=p;
  347. while { equal type conversions }
  348. (
  349. (hp.nodetype=typeconvn) and
  350. (ttypeconvnode(hp).convtype=tc_equal)
  351. ) or
  352. { constant array index }
  353. (
  354. (hp.nodetype=vecn) and
  355. (tvecnode(hp).right.nodetype=ordconstn)
  356. ) do
  357. hp:=tunarynode(hp).left;
  358. if (hp.nodetype=loadn) and
  359. (
  360. (tloadnode(hp).symtable=current_procinfo.procdef.localst) or
  361. (tloadnode(hp).symtable=current_procinfo.procdef.parast) or
  362. (tloadnode(hp).symtable.symtabletype in [staticsymtable,globalsymtable])
  363. ) then
  364. begin
  365. { simple load, we can reference direct }
  366. loadp:=nil;
  367. refp:=p;
  368. end
  369. else
  370. begin
  371. calltempp:=nil;
  372. { complex load, load in temp first }
  373. newblock:=internalstatements(newstatement,false);
  374. { when right is a call then load it first in a temp }
  375. if p.nodetype=calln then
  376. begin
  377. calltempp:=ctempcreatenode.create(p.resulttype,p.resulttype.def.size,tt_persistent);
  378. addstatement(newstatement,calltempp);
  379. addstatement(newstatement,cassignmentnode.create(
  380. ctemprefnode.create(calltempp),
  381. p));
  382. p:=ctemprefnode.create(calltempp);
  383. resulttypepass(p);
  384. end;
  385. { classes and interfaces have implicit dereferencing }
  386. hasimplicitderef:=is_class_or_interface(p.resulttype.def);
  387. if hasimplicitderef then
  388. htype:=p.resulttype
  389. else
  390. htype.setdef(tpointerdef.create(p.resulttype));
  391. loadp:=ctempcreatenode.create(htype,POINTER_SIZE,tt_persistent);
  392. resulttypepass(loadp);
  393. if hasimplicitderef then
  394. begin
  395. hp:=p;
  396. refp:=ctemprefnode.create(loadp);
  397. end
  398. else
  399. begin
  400. hp:=caddrnode.create(p);
  401. refp:=cderefnode.create(ctemprefnode.create(loadp));
  402. end;
  403. addstatement(newstatement,loadp);
  404. addstatement(newstatement,cassignmentnode.create(
  405. ctemprefnode.create(loadp),
  406. hp));
  407. resulttypepass(refp);
  408. end;
  409. case p.resulttype.def.deftype of
  410. objectdef :
  411. begin
  412. obj:=tobjectdef(p.resulttype.def);
  413. withsymtable:=twithsymtable.Create(obj,obj.symtable.symsearch,refp);
  414. { include also all parent symtables }
  415. levelcount:=1;
  416. obj:=obj.childof;
  417. symtab:=withsymtable;
  418. while assigned(obj) do
  419. begin
  420. symtab.next:=twithsymtable.create(obj,obj.symtable.symsearch,refp);
  421. symtab:=symtab.next;
  422. obj:=obj.childof;
  423. inc(levelcount);
  424. end;
  425. symtab.next:=symtablestack;
  426. symtablestack:=withsymtable;
  427. end;
  428. recorddef :
  429. begin
  430. symtab:=trecorddef(p.resulttype.def).symtable;
  431. levelcount:=1;
  432. withsymtable:=twithsymtable.create(trecorddef(p.resulttype.def),symtab.symsearch,refp);
  433. withsymtable.next:=symtablestack;
  434. symtablestack:=withsymtable;
  435. end;
  436. end;
  437. if try_to_consume(_COMMA) then
  438. right:=_with_statement{$ifdef FPCPROCVAR}(){$endif}
  439. else
  440. begin
  441. consume(_DO);
  442. if token<>_SEMICOLON then
  443. right:=statement
  444. else
  445. right:=cerrornode.create;
  446. end;
  447. { remove symtables from the stack }
  448. for i:=1 to levelcount do
  449. symtablestack:=symtablestack.next;
  450. p:=cwithnode.create(right,twithsymtable(withsymtable),levelcount,refp);
  451. { Finalize complex withnode with destroy of temp }
  452. if assigned(newblock) then
  453. begin
  454. addstatement(newstatement,p);
  455. addstatement(newstatement,ctempdeletenode.create(loadp));
  456. if assigned(calltempp) then
  457. addstatement(newstatement,ctempdeletenode.create(calltempp));
  458. p:=newblock;
  459. end;
  460. _with_statement:=p;
  461. end
  462. else
  463. begin
  464. Message(parser_e_false_with_expr);
  465. { try to recover from error }
  466. if try_to_consume(_COMMA) then
  467. begin
  468. hp:=_with_statement{$ifdef FPCPROCVAR}(){$endif};
  469. if (hp=nil) then; { remove warning about unused }
  470. end
  471. else
  472. begin
  473. consume(_DO);
  474. { ignore all }
  475. if token<>_SEMICOLON then
  476. statement;
  477. end;
  478. _with_statement:=nil;
  479. end;
  480. end;
  481. function with_statement : tnode;
  482. begin
  483. consume(_WITH);
  484. with_statement:=_with_statement;
  485. end;
  486. function raise_statement : tnode;
  487. var
  488. p,pobj,paddr,pframe : tnode;
  489. begin
  490. pobj:=nil;
  491. paddr:=nil;
  492. pframe:=nil;
  493. consume(_RAISE);
  494. if not(token in endtokens) then
  495. begin
  496. { object }
  497. pobj:=comp_expr(true);
  498. if try_to_consume(_AT) then
  499. begin
  500. paddr:=comp_expr(true);
  501. if try_to_consume(_COMMA) then
  502. pframe:=comp_expr(true);
  503. end;
  504. end
  505. else
  506. begin
  507. if (block_type<>bt_except) then
  508. Message(parser_e_no_reraise_possible);
  509. end;
  510. p:=craisenode.create(pobj,paddr,pframe);
  511. raise_statement:=p;
  512. end;
  513. function try_statement : tnode;
  514. var
  515. p_try_block,p_finally_block,first,last,
  516. p_default,p_specific,hp : tnode;
  517. ot : ttype;
  518. sym : tvarsym;
  519. old_block_type : tblock_type;
  520. exceptsymtable : tsymtable;
  521. objname,objrealname : stringid;
  522. srsym : tsym;
  523. srsymtable : tsymtable;
  524. oldaktexceptblock: integer;
  525. begin
  526. include(current_procinfo.flags,pi_uses_exceptions);
  527. p_default:=nil;
  528. p_specific:=nil;
  529. { read statements to try }
  530. consume(_TRY);
  531. first:=nil;
  532. inc(exceptblockcounter);
  533. oldaktexceptblock := aktexceptblock;
  534. aktexceptblock := exceptblockcounter;
  535. while (token<>_FINALLY) and (token<>_EXCEPT) do
  536. begin
  537. if first=nil then
  538. begin
  539. last:=cstatementnode.create(statement,nil);
  540. first:=last;
  541. end
  542. else
  543. begin
  544. tstatementnode(last).right:=cstatementnode.create(statement,nil);
  545. last:=tstatementnode(last).right;
  546. end;
  547. if not try_to_consume(_SEMICOLON) then
  548. break;
  549. consume_emptystats;
  550. end;
  551. p_try_block:=cblocknode.create(first,true);
  552. if try_to_consume(_FINALLY) then
  553. begin
  554. inc(exceptblockcounter);
  555. aktexceptblock := exceptblockcounter;
  556. p_finally_block:=statements_til_end;
  557. try_statement:=ctryfinallynode.create(p_try_block,p_finally_block);
  558. end
  559. else
  560. begin
  561. consume(_EXCEPT);
  562. old_block_type:=block_type;
  563. block_type:=bt_except;
  564. inc(exceptblockcounter);
  565. aktexceptblock := exceptblockcounter;
  566. ot:=generrortype;
  567. p_specific:=nil;
  568. if (idtoken=_ON) then
  569. { catch specific exceptions }
  570. begin
  571. repeat
  572. consume(_ID);
  573. if token=_ID then
  574. begin
  575. objname:=pattern;
  576. objrealname:=orgpattern;
  577. { can't use consume_sym here, because we need already
  578. to check for the colon }
  579. searchsym(objname,srsym,srsymtable);
  580. consume(_ID);
  581. { is a explicit name for the exception given ? }
  582. if try_to_consume(_COLON) then
  583. begin
  584. consume_sym(srsym,srsymtable);
  585. if (srsym.typ=typesym) and
  586. is_class(ttypesym(srsym).restype.def) then
  587. begin
  588. ot:=ttypesym(srsym).restype;
  589. sym:=tvarsym.create(objrealname,vs_value,ot);
  590. end
  591. else
  592. begin
  593. sym:=tvarsym.create(objrealname,vs_value,generrortype);
  594. if (srsym.typ=typesym) then
  595. Message1(type_e_class_type_expected,ttypesym(srsym).restype.def.typename)
  596. else
  597. Message1(type_e_class_type_expected,ot.def.typename);
  598. end;
  599. exceptsymtable:=tstt_exceptsymtable.create;
  600. exceptsymtable.insert(sym);
  601. { insert the exception symtable stack }
  602. exceptsymtable.next:=symtablestack;
  603. symtablestack:=exceptsymtable;
  604. end
  605. else
  606. begin
  607. { check if type is valid, must be done here because
  608. with "e: Exception" the e is not necessary }
  609. if srsym=nil then
  610. begin
  611. identifier_not_found(objrealname);
  612. srsym:=generrorsym;
  613. end;
  614. { support unit.identifier }
  615. if srsym.typ=unitsym then
  616. begin
  617. consume(_POINT);
  618. srsym:=searchsymonlyin(tunitsym(srsym).unitsymtable,pattern);
  619. if srsym=nil then
  620. begin
  621. identifier_not_found(orgpattern);
  622. srsym:=generrorsym;
  623. end;
  624. consume(_ID);
  625. end;
  626. { check if type is valid, must be done here because
  627. with "e: Exception" the e is not necessary }
  628. if (srsym.typ=typesym) and
  629. is_class(ttypesym(srsym).restype.def) then
  630. ot:=ttypesym(srsym).restype
  631. else
  632. begin
  633. ot:=generrortype;
  634. if (srsym.typ=typesym) then
  635. Message1(type_e_class_type_expected,ttypesym(srsym).restype.def.typename)
  636. else
  637. Message1(type_e_class_type_expected,ot.def.typename);
  638. end;
  639. exceptsymtable:=nil;
  640. end;
  641. end
  642. else
  643. consume(_ID);
  644. consume(_DO);
  645. hp:=connode.create(nil,statement);
  646. if ot.def.deftype=errordef then
  647. begin
  648. hp.free;
  649. hp:=cerrornode.create;
  650. end;
  651. if p_specific=nil then
  652. begin
  653. last:=hp;
  654. p_specific:=last;
  655. end
  656. else
  657. begin
  658. tonnode(last).left:=hp;
  659. last:=tonnode(last).left;
  660. end;
  661. { set the informations }
  662. { only if the creation of the onnode was succesful, it's possible }
  663. { that last and hp are errornodes (JM) }
  664. if last.nodetype = onn then
  665. begin
  666. tonnode(last).excepttype:=tobjectdef(ot.def);
  667. tonnode(last).exceptsymtable:=exceptsymtable;
  668. end;
  669. { remove exception symtable }
  670. if assigned(exceptsymtable) then
  671. begin
  672. symtablestack:=symtablestack.next;
  673. if last.nodetype <> onn then
  674. exceptsymtable.free;
  675. end;
  676. if not try_to_consume(_SEMICOLON) then
  677. break;
  678. consume_emptystats;
  679. until (token in [_END,_ELSE]);
  680. if try_to_consume(_ELSE) then
  681. begin
  682. { catch the other exceptions }
  683. p_default:=statements_til_end;
  684. end
  685. else
  686. consume(_END);
  687. end
  688. else
  689. begin
  690. { catch all exceptions }
  691. p_default:=statements_til_end;
  692. end;
  693. block_type:=old_block_type;
  694. try_statement:=ctryexceptnode.create(p_try_block,p_specific,p_default);
  695. end;
  696. aktexceptblock := oldaktexceptblock;
  697. end;
  698. function _asm_statement : tnode;
  699. var
  700. asmstat : tasmnode;
  701. Marker : tai;
  702. reg : tsuperregister;
  703. found : boolean;
  704. hs : string;
  705. begin
  706. Inside_asm_statement:=true;
  707. case aktasmmode of
  708. asmmode_none : ; { just be there to allow to compile a compiler without
  709. any assembler readers }
  710. {$ifdef i386}
  711. {$ifndef NoRA386Att}
  712. asmmode_i386_att:
  713. asmstat:=tasmnode(ra386att.assemble);
  714. {$endif NoRA386Att}
  715. {$ifndef NoRA386Int}
  716. asmmode_i386_intel:
  717. asmstat:=tasmnode(ra386int.assemble);
  718. {$endif NoRA386Int}
  719. {$else not i386}
  720. asmmode_standard:
  721. asmstat:=tasmnode(rasm.assemble);
  722. {$endif i386}
  723. asmmode_direct:
  724. begin
  725. if not target_asm.allowdirect then
  726. Message(parser_f_direct_assembler_not_allowed);
  727. if (current_procinfo.procdef.proccalloption=pocall_inline) then
  728. Begin
  729. Message1(parser_w_not_supported_for_inline,'direct asm');
  730. Message(parser_w_inlining_disabled);
  731. current_procinfo.procdef.proccalloption:=pocall_fpccall;
  732. End;
  733. asmstat:=tasmnode(radirect.assemble);
  734. end;
  735. else
  736. Message(parser_f_assembler_reader_not_supported);
  737. end;
  738. { Read first the _ASM statement }
  739. consume(_ASM);
  740. { END is read, got a list of changed registers? }
  741. if try_to_consume(_LECKKLAMMER) then
  742. begin
  743. rg.used_in_proc_other:=ALL_OTHERREGISTERS;
  744. if token<>_RECKKLAMMER then
  745. begin
  746. repeat
  747. { it's possible to specify the modified registers }
  748. hs:=upper(pattern);
  749. found:=false;
  750. for reg:=first_supreg to last_supreg do
  751. if hs=upper(supreg_name(reg)) then
  752. begin
  753. include(rg.used_in_proc_int,reg);
  754. found:=true;
  755. break;
  756. end;
  757. if not(found) then
  758. Message(asmr_e_invalid_register);
  759. consume(_CSTRING);
  760. if not try_to_consume(_COMMA) then
  761. break;
  762. until false;
  763. end;
  764. consume(_RECKKLAMMER);
  765. end
  766. else
  767. begin
  768. rg.used_in_proc_int:=ALL_INTREGISTERS;
  769. rg.used_in_proc_other:=ALL_OTHERREGISTERS;
  770. end;
  771. { mark the start and the end of the assembler block
  772. this is needed for the optimizer }
  773. If Assigned(AsmStat.p_asm) Then
  774. Begin
  775. Marker := Tai_Marker.Create(AsmBlockStart);
  776. AsmStat.p_asm.Insert(Marker);
  777. Marker := Tai_Marker.Create(AsmBlockEnd);
  778. AsmStat.p_asm.Concat(Marker);
  779. End;
  780. Inside_asm_statement:=false;
  781. _asm_statement:=asmstat;
  782. end;
  783. function statement : tnode;
  784. var
  785. p : tnode;
  786. code : tnode;
  787. filepos : tfileposinfo;
  788. srsym : tsym;
  789. srsymtable : tsymtable;
  790. s : stringid;
  791. begin
  792. filepos:=akttokenpos;
  793. case token of
  794. _GOTO :
  795. begin
  796. if not(cs_support_goto in aktmoduleswitches)then
  797. Message(sym_e_goto_and_label_not_supported);
  798. consume(_GOTO);
  799. if (token<>_INTCONST) and (token<>_ID) then
  800. begin
  801. Message(sym_e_label_not_found);
  802. code:=cerrornode.create;
  803. end
  804. else
  805. begin
  806. if token=_ID then
  807. consume_sym(srsym,srsymtable)
  808. else
  809. begin
  810. searchsym(pattern,srsym,srsymtable);
  811. if srsym=nil then
  812. begin
  813. identifier_not_found(pattern);
  814. srsym:=generrorsym;
  815. srsymtable:=nil;
  816. end;
  817. consume(token);
  818. end;
  819. if srsym.typ<>labelsym then
  820. begin
  821. Message(sym_e_id_is_no_label_id);
  822. code:=cerrornode.create;
  823. end
  824. else
  825. begin
  826. code:=cgotonode.create(tlabelsym(srsym));
  827. tgotonode(code).labsym:=tlabelsym(srsym);
  828. { set flag that this label is used }
  829. tlabelsym(srsym).used:=true;
  830. end;
  831. end;
  832. end;
  833. _BEGIN :
  834. code:=statement_block(_BEGIN);
  835. _IF :
  836. code:=if_statement;
  837. _CASE :
  838. code:=case_statement;
  839. _REPEAT :
  840. code:=repeat_statement;
  841. _WHILE :
  842. code:=while_statement;
  843. _FOR :
  844. code:=for_statement;
  845. _WITH :
  846. code:=with_statement;
  847. _TRY :
  848. code:=try_statement;
  849. _RAISE :
  850. code:=raise_statement;
  851. { semicolons,else until and end are ignored }
  852. _SEMICOLON,
  853. _ELSE,
  854. _UNTIL,
  855. _END:
  856. code:=cnothingnode.create;
  857. _FAIL :
  858. begin
  859. if (current_procinfo.procdef.proctypeoption<>potype_constructor) then
  860. Message(parser_e_fail_only_in_constructor);
  861. consume(_FAIL);
  862. code:=call_fail_node;
  863. end;
  864. _ASM :
  865. code:=_asm_statement;
  866. _EOF :
  867. Message(scan_f_end_of_file);
  868. else
  869. begin
  870. p:=expr;
  871. { When a colon follows a intconst then transform it into a label }
  872. if try_to_consume(_COLON) then
  873. begin
  874. s:=tostr(tordconstnode(p).value);
  875. p.free;
  876. searchsym(s,srsym,srsymtable);
  877. if assigned(srsym) then
  878. begin
  879. if tlabelsym(srsym).defined then
  880. Message(sym_e_label_already_defined);
  881. tlabelsym(srsym).defined:=true;
  882. p:=clabelnode.create(tlabelsym(srsym),nil);
  883. end
  884. else
  885. begin
  886. Message1(sym_e_label_used_and_not_defined,s);
  887. p:=cnothingnode.create;
  888. end;
  889. end;
  890. if p.nodetype=labeln then
  891. begin
  892. { the pointer to the following instruction }
  893. { isn't a very clean way }
  894. tlabelnode(p).left:=statement{$ifdef FPCPROCVAR}(){$endif};
  895. { be sure to have left also resulttypepass }
  896. resulttypepass(tlabelnode(p).left);
  897. end;
  898. { blockn support because a read/write is changed into a blocknode }
  899. { with a separate statement for each read/write operation (JM) }
  900. { the same is true for val() if the third parameter is not 32 bit }
  901. if not(p.nodetype in [nothingn,calln,ifn,assignn,breakn,inlinen,
  902. continuen,labeln,blockn,exitn]) then
  903. Message(cg_e_illegal_expression);
  904. { specify that we don't use the value returned by the call }
  905. { Question : can this be also improtant
  906. for inlinen ??
  907. it is used for :
  908. - dispose of temp stack space
  909. - dispose on FPU stack }
  910. if p.nodetype=calln then
  911. exclude(p.flags,nf_return_value_used);
  912. code:=p;
  913. end;
  914. end;
  915. if assigned(code) then
  916. code.set_tree_filepos(filepos);
  917. statement:=code;
  918. end;
  919. function statement_block(starttoken : ttoken) : tnode;
  920. var
  921. first,last : tnode;
  922. filepos : tfileposinfo;
  923. begin
  924. first:=nil;
  925. filepos:=akttokenpos;
  926. consume(starttoken);
  927. while not(token in [_END,_FINALIZATION]) do
  928. begin
  929. if first=nil then
  930. begin
  931. last:=cstatementnode.create(statement,nil);
  932. first:=last;
  933. end
  934. else
  935. begin
  936. tstatementnode(last).right:=cstatementnode.create(statement,nil);
  937. last:=tstatementnode(last).right;
  938. end;
  939. if (token in [_END,_FINALIZATION]) then
  940. break
  941. else
  942. begin
  943. { if no semicolon, then error and go on }
  944. if token<>_SEMICOLON then
  945. begin
  946. consume(_SEMICOLON);
  947. consume_all_until(_SEMICOLON);
  948. end;
  949. consume(_SEMICOLON);
  950. end;
  951. consume_emptystats;
  952. end;
  953. { don't consume the finalization token, it is consumed when
  954. reading the finalization block, but allow it only after
  955. an initalization ! }
  956. if (starttoken<>_INITIALIZATION) or (token<>_FINALIZATION) then
  957. consume(_END);
  958. last:=cblocknode.create(first,true);
  959. last.set_tree_filepos(filepos);
  960. statement_block:=last;
  961. end;
  962. function assembler_block : tnode;
  963. {# Optimize the assembler block by removing all references
  964. which are via the frame pointer by replacing them with
  965. references via the stack pointer.
  966. This is only available to certain cpu targets where
  967. the frame pointer saving must be done explicitly.
  968. }
  969. procedure OptimizeFramePointer(p:tasmnode);
  970. var
  971. hp : tai;
  972. parafixup,
  973. i : longint;
  974. begin
  975. { replace framepointer with stackpointer }
  976. current_procinfo.framepointer.enum:=R_INTREGISTER;
  977. current_procinfo.framepointer.number:=NR_STACK_POINTER_REG;
  978. { set the right value for parameters }
  979. dec(current_procinfo.procdef.parast.address_fixup,pointer_size);
  980. { replace all references to parameters in the instructions,
  981. the parameters can be identified by the parafixup option
  982. that is set. For normal user coded [ebp+4] this field is not
  983. set }
  984. parafixup:=current_procinfo.procdef.parast.address_fixup;
  985. hp:=tai(p.p_asm.first);
  986. while assigned(hp) do
  987. begin
  988. if hp.typ=ait_instruction then
  989. begin
  990. { fixup the references }
  991. for i:=1 to taicpu(hp).ops do
  992. begin
  993. with taicpu(hp).oper[i-1] do
  994. if typ=top_ref then
  995. begin
  996. case ref^.options of
  997. ref_parafixup :
  998. begin
  999. ref^.offsetfixup:=parafixup;
  1000. ref^.base.enum:=R_INTREGISTER;
  1001. ref^.base.number:=NR_STACK_POINTER_REG;
  1002. end;
  1003. end;
  1004. end;
  1005. end;
  1006. end;
  1007. hp:=tai(hp.next);
  1008. end;
  1009. end;
  1010. {$ifdef CHECKFORPUSH}
  1011. function UsesPush(p:tasmnode):boolean;
  1012. var
  1013. hp : tai;
  1014. begin
  1015. hp:=tai(p.p_asm.first);
  1016. while assigned(hp) do
  1017. begin
  1018. if (hp.typ=ait_instruction) and
  1019. (taicpu(hp).opcode=A_PUSH) then
  1020. begin
  1021. UsesPush:=true;
  1022. exit;
  1023. end;
  1024. hp:=tai(hp.next);
  1025. end;
  1026. UsesPush:=false;
  1027. end;
  1028. {$endif CHECKFORPUSH}
  1029. var
  1030. p : tnode;
  1031. begin
  1032. { Rename the funcret so that recursive calls are possible }
  1033. if not is_void(current_procinfo.procdef.rettype.def) then
  1034. symtablestack.rename(current_procinfo.procdef.resultname,'$hiddenresult');
  1035. { force the asm statement }
  1036. if token<>_ASM then
  1037. consume(_ASM);
  1038. include(current_procinfo.flags,pi_is_assembler);
  1039. p:=_asm_statement;
  1040. { set the framepointer to esp for assembler functions when the
  1041. following conditions are met:
  1042. - if the are no local variables (except the allocated result)
  1043. - if the are no parameters
  1044. - no reference to the result variable (refcount<=1)
  1045. - result is not stored as parameter
  1046. - target processor has optional frame pointer save
  1047. (vm, i386, vm only currently)
  1048. }
  1049. if (po_assembler in current_procinfo.procdef.procoptions) and
  1050. {$ifndef powerpc}
  1051. { is this really necessary??? }
  1052. (current_procinfo.procdef.parast.datasize=0) and
  1053. {$endif powerpc}
  1054. (current_procinfo.procdef.localst.datasize=current_procinfo.procdef.rettype.def.size) and
  1055. (current_procinfo.procdef.owner.symtabletype<>objectsymtable) and
  1056. (not assigned(current_procinfo.procdef.funcretsym) or
  1057. (tvarsym(current_procinfo.procdef.funcretsym).refcount<=1)) and
  1058. not(paramanager.ret_in_param(current_procinfo.procdef.rettype.def,current_procinfo.procdef.proccalloption)) then
  1059. begin
  1060. { we don't need to allocate space for the locals }
  1061. current_procinfo.procdef.localst.datasize:=0;
  1062. current_procinfo.firsttemp_offset:=0;
  1063. { only for cpus with different frame- and stack pointer the code must be changed }
  1064. if (NR_STACK_POINTER_REG<>NR_FRAME_POINTER_REG)
  1065. {$ifdef CHECKFORPUSH}
  1066. and not(UsesPush(tasmnode(p)))
  1067. {$endif CHECKFORPUSH}
  1068. then
  1069. OptimizeFramePointer(tasmnode(p));
  1070. end;
  1071. { Flag the result as assigned when it is returned in a
  1072. register.
  1073. }
  1074. if assigned(current_procinfo.procdef.funcretsym) and
  1075. (not paramanager.ret_in_param(current_procinfo.procdef.rettype.def,current_procinfo.procdef.proccalloption)) then
  1076. tvarsym(current_procinfo.procdef.funcretsym).varstate:=vs_assigned;
  1077. { because the END is already read we need to get the
  1078. last_endtoken_filepos here (PFV) }
  1079. last_endtoken_filepos:=akttokenpos;
  1080. assembler_block:=p;
  1081. end;
  1082. end.
  1083. {
  1084. $Log$
  1085. Revision 1.104 2003-06-13 21:19:31 peter
  1086. * current_procdef removed, use current_procinfo.procdef instead
  1087. Revision 1.103 2003/06/09 18:27:14 peter
  1088. * load calln in temprefn in with statement
  1089. Revision 1.102 2003/05/23 22:33:48 florian
  1090. * fix some small flaws which prevent sparc linux system unit from compiling
  1091. * some reformatting done
  1092. Revision 1.101 2003/05/23 15:15:36 peter
  1093. * better error for undefined ordinal labels
  1094. Revision 1.100 2003/05/17 13:30:08 jonas
  1095. * changed tt_persistant to tt_persistent :)
  1096. * tempcreatenode now doesn't accept a boolean anymore for persistent
  1097. temps, but a ttemptype, so you can also create ansistring temps etc
  1098. Revision 1.99 2003/05/15 18:58:53 peter
  1099. * removed selfpointer_offset, vmtpointer_offset
  1100. * tvarsym.adjusted_address
  1101. * address in localsymtable is now in the real direction
  1102. * removed some obsolete globals
  1103. Revision 1.98 2003/05/13 19:14:41 peter
  1104. * failn removed
  1105. * inherited result code check moven to pexpr
  1106. Revision 1.97 2003/05/11 14:45:12 peter
  1107. * tloadnode does not support objectsymtable,withsymtable anymore
  1108. * withnode cleanup
  1109. * direct with rewritten to use temprefnode
  1110. Revision 1.96 2003/05/09 17:47:03 peter
  1111. * self moved to hidden parameter
  1112. * removed hdisposen,hnewn,selfn
  1113. Revision 1.95 2003/04/30 22:15:59 florian
  1114. * some 64 bit adaptions in ncgadd
  1115. * x86-64 now uses ncgadd
  1116. * tparamanager.ret_in_acc doesn't return true anymore for a void-def
  1117. Revision 1.94 2003/04/27 11:21:34 peter
  1118. * aktprocdef renamed to current_procinfo.procdef
  1119. * procinfo renamed to current_procinfo
  1120. * procinfo will now be stored in current_module so it can be
  1121. cleaned up properly
  1122. * gen_main_procsym changed to create_main_proc and release_main_proc
  1123. to also generate a tprocinfo structure
  1124. * fixed unit implicit initfinal
  1125. Revision 1.93 2003/04/27 07:29:50 peter
  1126. * current_procinfo.procdef cleanup, current_procinfo.procdef is now always nil when parsing
  1127. a new procdef declaration
  1128. * aktprocsym removed
  1129. * lexlevel removed, use symtable.symtablelevel instead
  1130. * implicit init/final code uses the normal genentry/genexit
  1131. * funcret state checking updated for new funcret handling
  1132. Revision 1.92 2003/04/26 11:30:59 florian
  1133. * fixed the powerpc to work with the new function result handling
  1134. Revision 1.91 2003/04/25 20:59:34 peter
  1135. * removed funcretn,funcretsym, function result is now in varsym
  1136. and aliases for result and function name are added using absolutesym
  1137. * vs_hidden parameter for funcret passed in parameter
  1138. * vs_hidden fixes
  1139. * writenode changed to printnode and released from extdebug
  1140. * -vp option added to generate a tree.log with the nodetree
  1141. * nicer printnode for statements, callnode
  1142. Revision 1.90 2002/04/25 20:15:40 florian
  1143. * block nodes within expressions shouldn't release the used registers,
  1144. fixed using a flag till the new rg is ready
  1145. Revision 1.89 2003/04/25 08:25:26 daniel
  1146. * Ifdefs around a lot of calls to cleartempgen
  1147. * Fixed registers that are allocated but not freed in several nodes
  1148. * Tweak to register allocator to cause less spills
  1149. * 8-bit registers now interfere with esi,edi and ebp
  1150. Compiler can now compile rtl successfully when using new register
  1151. allocator
  1152. Revision 1.88 2003/03/28 19:16:57 peter
  1153. * generic constructor working for i386
  1154. * remove fixed self register
  1155. * esi added as address register for i386
  1156. Revision 1.87 2003/03/17 18:55:30 peter
  1157. * allow more tokens instead of only semicolon after inherited
  1158. Revision 1.86 2003/02/19 22:00:14 daniel
  1159. * Code generator converted to new register notation
  1160. - Horribily outdated todo.txt removed
  1161. Revision 1.85 2003/01/08 18:43:56 daniel
  1162. * Tregister changed into a record
  1163. Revision 1.84 2003/01/01 21:05:24 peter
  1164. * fixed assembler methods stackpointer optimization that was
  1165. broken after the previous change
  1166. Revision 1.83 2002/12/29 18:59:34 peter
  1167. * fixed parsing of declarations before asm statement
  1168. Revision 1.82 2002/12/27 18:18:56 peter
  1169. * check for else after empty raise statement
  1170. Revision 1.81 2002/11/27 02:37:14 peter
  1171. * case statement inlining added
  1172. * fixed inlining of write()
  1173. * switched statementnode left and right parts so the statements are
  1174. processed in the correct order when getcopy is used. This is
  1175. required for tempnodes
  1176. Revision 1.80 2002/11/25 17:43:22 peter
  1177. * splitted defbase in defutil,symutil,defcmp
  1178. * merged isconvertable and is_equal into compare_defs(_ext)
  1179. * made operator search faster by walking the list only once
  1180. Revision 1.79 2002/11/18 17:31:58 peter
  1181. * pass proccalloption to ret_in_xxx and push_xxx functions
  1182. Revision 1.78 2002/09/07 19:34:08 florian
  1183. + tcg.direction is used now
  1184. Revision 1.77 2002/09/07 15:25:07 peter
  1185. * old logs removed and tabs fixed
  1186. Revision 1.76 2002/09/07 12:16:03 carl
  1187. * second part bug report 1996 fix, testrange in cordconstnode
  1188. only called if option is set (also make parsing a tiny faster)
  1189. Revision 1.75 2002/09/02 18:40:52 peter
  1190. * fixed parsing of register names with lowercase
  1191. Revision 1.74 2002/09/01 14:43:12 peter
  1192. * fixed direct assembler for i386
  1193. Revision 1.73 2002/08/25 19:25:20 peter
  1194. * sym.insert_in_data removed
  1195. * symtable.insertvardata/insertconstdata added
  1196. * removed insert_in_data call from symtable.insert, it needs to be
  1197. called separatly. This allows to deref the address calculation
  1198. * procedures now calculate the parast addresses after the procedure
  1199. directives are parsed. This fixes the cdecl parast problem
  1200. * push_addr_param has an extra argument that specifies if cdecl is used
  1201. or not
  1202. Revision 1.72 2002/08/17 09:23:40 florian
  1203. * first part of procinfo rewrite
  1204. Revision 1.71 2002/08/16 14:24:58 carl
  1205. * issameref() to test if two references are the same (then emit no opcodes)
  1206. + ret_in_reg to replace ret_in_acc
  1207. (fix some register allocation bugs at the same time)
  1208. + save_std_register now has an extra parameter which is the
  1209. usedinproc registers
  1210. Revision 1.70 2002/08/11 14:32:27 peter
  1211. * renamed current_library to objectlibrary
  1212. Revision 1.69 2002/08/11 13:24:12 peter
  1213. * saving of asmsymbols in ppu supported
  1214. * asmsymbollist global is removed and moved into a new class
  1215. tasmlibrarydata that will hold the info of a .a file which
  1216. corresponds with a single module. Added librarydata to tmodule
  1217. to keep the library info stored for the module. In the future the
  1218. objectfiles will also be stored to the tasmlibrarydata class
  1219. * all getlabel/newasmsymbol and friends are moved to the new class
  1220. Revision 1.68 2002/08/10 14:46:30 carl
  1221. + moved target_cpu_string to cpuinfo
  1222. * renamed asmmode enum.
  1223. * assembler reader has now less ifdef's
  1224. * move from nppcmem.pas -> ncgmem.pas vec. node.
  1225. Revision 1.67 2002/08/09 19:11:44 carl
  1226. + reading of used registers in assembler routines is now
  1227. cpu-independent
  1228. Revision 1.66 2002/08/06 20:55:22 florian
  1229. * first part of ppc calling conventions fix
  1230. Revision 1.65 2002/07/28 20:45:22 florian
  1231. + added direct assembler reader for PowerPC
  1232. Revision 1.64 2002/07/20 11:57:56 florian
  1233. * types.pas renamed to defbase.pas because D6 contains a types
  1234. unit so this would conflicts if D6 programms are compiled
  1235. + Willamette/SSE2 instructions to assembler added
  1236. Revision 1.63 2002/07/19 11:41:36 daniel
  1237. * State tracker work
  1238. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1239. allows the state tracker to change while nodes automatically into
  1240. repeat nodes.
  1241. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1242. 'not(a>b)' is optimized into 'a<=b'.
  1243. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1244. by removing the notn and later switchting the true and falselabels. The
  1245. same is done with 'repeat until not a'.
  1246. Revision 1.62 2002/07/16 15:34:20 florian
  1247. * exit is now a syssym instead of a keyword
  1248. Revision 1.61 2002/07/11 14:41:28 florian
  1249. * start of the new generic parameter handling
  1250. Revision 1.60 2002/07/04 20:43:01 florian
  1251. * first x86-64 patches
  1252. Revision 1.59 2002/07/01 18:46:25 peter
  1253. * internal linker
  1254. * reorganized aasm layer
  1255. Revision 1.58 2002/05/18 13:34:13 peter
  1256. * readded missing revisions
  1257. Revision 1.57 2002/05/16 19:46:44 carl
  1258. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1259. + try to fix temp allocation (still in ifdef)
  1260. + generic constructor calls
  1261. + start of tassembler / tmodulebase class cleanup
  1262. }