pstatmnt.pas 49 KB

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