pstatmnt.pas 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427
  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:=VOLATILE_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. {$ifndef sparc}
  1041. { set the framepointer to esp for assembler functions when the
  1042. following conditions are met:
  1043. - if the are no local variables (except the allocated result)
  1044. - if the are no parameters
  1045. - no reference to the result variable (refcount<=1)
  1046. - result is not stored as parameter
  1047. - target processor has optional frame pointer save
  1048. (vm, i386, vm only currently)
  1049. }
  1050. if (po_assembler in current_procinfo.procdef.procoptions) and
  1051. {$ifndef powerpc}
  1052. { is this really necessary??? }
  1053. (current_procinfo.procdef.parast.datasize=0) and
  1054. {$endif powerpc}
  1055. (current_procinfo.procdef.localst.datasize=current_procinfo.procdef.rettype.def.size) and
  1056. (current_procinfo.procdef.owner.symtabletype<>objectsymtable) and
  1057. (not assigned(current_procinfo.procdef.funcretsym) or
  1058. (tvarsym(current_procinfo.procdef.funcretsym).refcount<=1)) and
  1059. not(paramanager.ret_in_param(current_procinfo.procdef.rettype.def,current_procinfo.procdef.proccalloption)) then
  1060. begin
  1061. { we don't need to allocate space for the locals }
  1062. current_procinfo.procdef.localst.datasize:=0;
  1063. current_procinfo.firsttemp_offset:=0;
  1064. { only for cpus with different frame- and stack pointer the code must be changed }
  1065. if (NR_STACK_POINTER_REG<>NR_FRAME_POINTER_REG)
  1066. {$ifdef CHECKFORPUSH}
  1067. and not(UsesPush(tasmnode(p)))
  1068. {$endif CHECKFORPUSH}
  1069. then
  1070. OptimizeFramePointer(tasmnode(p));
  1071. end;
  1072. {$endif sparc}
  1073. { Flag the result as assigned when it is returned in a
  1074. register.
  1075. }
  1076. if assigned(current_procinfo.procdef.funcretsym) and
  1077. (not paramanager.ret_in_param(current_procinfo.procdef.rettype.def,current_procinfo.procdef.proccalloption)) then
  1078. tvarsym(current_procinfo.procdef.funcretsym).varstate:=vs_assigned;
  1079. { because the END is already read we need to get the
  1080. last_endtoken_filepos here (PFV) }
  1081. last_endtoken_filepos:=akttokenpos;
  1082. assembler_block:=p;
  1083. end;
  1084. end.
  1085. {
  1086. $Log$
  1087. Revision 1.106 2003-07-08 21:24:59 peter
  1088. * sparc fixes
  1089. Revision 1.105 2003/06/17 16:34:44 jonas
  1090. * lots of newra fixes (need getfuncretparaloc implementation for i386)!
  1091. * renamed all_intregisters to volatile_intregisters and made it
  1092. processor dependent
  1093. Revision 1.104 2003/06/13 21:19:31 peter
  1094. * current_procdef removed, use current_procinfo.procdef instead
  1095. Revision 1.103 2003/06/09 18:27:14 peter
  1096. * load calln in temprefn in with statement
  1097. Revision 1.102 2003/05/23 22:33:48 florian
  1098. * fix some small flaws which prevent sparc linux system unit from compiling
  1099. * some reformatting done
  1100. Revision 1.101 2003/05/23 15:15:36 peter
  1101. * better error for undefined ordinal labels
  1102. Revision 1.100 2003/05/17 13:30:08 jonas
  1103. * changed tt_persistant to tt_persistent :)
  1104. * tempcreatenode now doesn't accept a boolean anymore for persistent
  1105. temps, but a ttemptype, so you can also create ansistring temps etc
  1106. Revision 1.99 2003/05/15 18:58:53 peter
  1107. * removed selfpointer_offset, vmtpointer_offset
  1108. * tvarsym.adjusted_address
  1109. * address in localsymtable is now in the real direction
  1110. * removed some obsolete globals
  1111. Revision 1.98 2003/05/13 19:14:41 peter
  1112. * failn removed
  1113. * inherited result code check moven to pexpr
  1114. Revision 1.97 2003/05/11 14:45:12 peter
  1115. * tloadnode does not support objectsymtable,withsymtable anymore
  1116. * withnode cleanup
  1117. * direct with rewritten to use temprefnode
  1118. Revision 1.96 2003/05/09 17:47:03 peter
  1119. * self moved to hidden parameter
  1120. * removed hdisposen,hnewn,selfn
  1121. Revision 1.95 2003/04/30 22:15:59 florian
  1122. * some 64 bit adaptions in ncgadd
  1123. * x86-64 now uses ncgadd
  1124. * tparamanager.ret_in_acc doesn't return true anymore for a void-def
  1125. Revision 1.94 2003/04/27 11:21:34 peter
  1126. * aktprocdef renamed to current_procinfo.procdef
  1127. * procinfo renamed to current_procinfo
  1128. * procinfo will now be stored in current_module so it can be
  1129. cleaned up properly
  1130. * gen_main_procsym changed to create_main_proc and release_main_proc
  1131. to also generate a tprocinfo structure
  1132. * fixed unit implicit initfinal
  1133. Revision 1.93 2003/04/27 07:29:50 peter
  1134. * current_procinfo.procdef cleanup, current_procinfo.procdef is now always nil when parsing
  1135. a new procdef declaration
  1136. * aktprocsym removed
  1137. * lexlevel removed, use symtable.symtablelevel instead
  1138. * implicit init/final code uses the normal genentry/genexit
  1139. * funcret state checking updated for new funcret handling
  1140. Revision 1.92 2003/04/26 11:30:59 florian
  1141. * fixed the powerpc to work with the new function result handling
  1142. Revision 1.91 2003/04/25 20:59:34 peter
  1143. * removed funcretn,funcretsym, function result is now in varsym
  1144. and aliases for result and function name are added using absolutesym
  1145. * vs_hidden parameter for funcret passed in parameter
  1146. * vs_hidden fixes
  1147. * writenode changed to printnode and released from extdebug
  1148. * -vp option added to generate a tree.log with the nodetree
  1149. * nicer printnode for statements, callnode
  1150. Revision 1.90 2002/04/25 20:15:40 florian
  1151. * block nodes within expressions shouldn't release the used registers,
  1152. fixed using a flag till the new rg is ready
  1153. Revision 1.89 2003/04/25 08:25:26 daniel
  1154. * Ifdefs around a lot of calls to cleartempgen
  1155. * Fixed registers that are allocated but not freed in several nodes
  1156. * Tweak to register allocator to cause less spills
  1157. * 8-bit registers now interfere with esi,edi and ebp
  1158. Compiler can now compile rtl successfully when using new register
  1159. allocator
  1160. Revision 1.88 2003/03/28 19:16:57 peter
  1161. * generic constructor working for i386
  1162. * remove fixed self register
  1163. * esi added as address register for i386
  1164. Revision 1.87 2003/03/17 18:55:30 peter
  1165. * allow more tokens instead of only semicolon after inherited
  1166. Revision 1.86 2003/02/19 22:00:14 daniel
  1167. * Code generator converted to new register notation
  1168. - Horribily outdated todo.txt removed
  1169. Revision 1.85 2003/01/08 18:43:56 daniel
  1170. * Tregister changed into a record
  1171. Revision 1.84 2003/01/01 21:05:24 peter
  1172. * fixed assembler methods stackpointer optimization that was
  1173. broken after the previous change
  1174. Revision 1.83 2002/12/29 18:59:34 peter
  1175. * fixed parsing of declarations before asm statement
  1176. Revision 1.82 2002/12/27 18:18:56 peter
  1177. * check for else after empty raise statement
  1178. Revision 1.81 2002/11/27 02:37:14 peter
  1179. * case statement inlining added
  1180. * fixed inlining of write()
  1181. * switched statementnode left and right parts so the statements are
  1182. processed in the correct order when getcopy is used. This is
  1183. required for tempnodes
  1184. Revision 1.80 2002/11/25 17:43:22 peter
  1185. * splitted defbase in defutil,symutil,defcmp
  1186. * merged isconvertable and is_equal into compare_defs(_ext)
  1187. * made operator search faster by walking the list only once
  1188. Revision 1.79 2002/11/18 17:31:58 peter
  1189. * pass proccalloption to ret_in_xxx and push_xxx functions
  1190. Revision 1.78 2002/09/07 19:34:08 florian
  1191. + tcg.direction is used now
  1192. Revision 1.77 2002/09/07 15:25:07 peter
  1193. * old logs removed and tabs fixed
  1194. Revision 1.76 2002/09/07 12:16:03 carl
  1195. * second part bug report 1996 fix, testrange in cordconstnode
  1196. only called if option is set (also make parsing a tiny faster)
  1197. Revision 1.75 2002/09/02 18:40:52 peter
  1198. * fixed parsing of register names with lowercase
  1199. Revision 1.74 2002/09/01 14:43:12 peter
  1200. * fixed direct assembler for i386
  1201. Revision 1.73 2002/08/25 19:25:20 peter
  1202. * sym.insert_in_data removed
  1203. * symtable.insertvardata/insertconstdata added
  1204. * removed insert_in_data call from symtable.insert, it needs to be
  1205. called separatly. This allows to deref the address calculation
  1206. * procedures now calculate the parast addresses after the procedure
  1207. directives are parsed. This fixes the cdecl parast problem
  1208. * push_addr_param has an extra argument that specifies if cdecl is used
  1209. or not
  1210. Revision 1.72 2002/08/17 09:23:40 florian
  1211. * first part of procinfo rewrite
  1212. Revision 1.71 2002/08/16 14:24:58 carl
  1213. * issameref() to test if two references are the same (then emit no opcodes)
  1214. + ret_in_reg to replace ret_in_acc
  1215. (fix some register allocation bugs at the same time)
  1216. + save_std_register now has an extra parameter which is the
  1217. usedinproc registers
  1218. Revision 1.70 2002/08/11 14:32:27 peter
  1219. * renamed current_library to objectlibrary
  1220. Revision 1.69 2002/08/11 13:24:12 peter
  1221. * saving of asmsymbols in ppu supported
  1222. * asmsymbollist global is removed and moved into a new class
  1223. tasmlibrarydata that will hold the info of a .a file which
  1224. corresponds with a single module. Added librarydata to tmodule
  1225. to keep the library info stored for the module. In the future the
  1226. objectfiles will also be stored to the tasmlibrarydata class
  1227. * all getlabel/newasmsymbol and friends are moved to the new class
  1228. Revision 1.68 2002/08/10 14:46:30 carl
  1229. + moved target_cpu_string to cpuinfo
  1230. * renamed asmmode enum.
  1231. * assembler reader has now less ifdef's
  1232. * move from nppcmem.pas -> ncgmem.pas vec. node.
  1233. Revision 1.67 2002/08/09 19:11:44 carl
  1234. + reading of used registers in assembler routines is now
  1235. cpu-independent
  1236. Revision 1.66 2002/08/06 20:55:22 florian
  1237. * first part of ppc calling conventions fix
  1238. Revision 1.65 2002/07/28 20:45:22 florian
  1239. + added direct assembler reader for PowerPC
  1240. Revision 1.64 2002/07/20 11:57:56 florian
  1241. * types.pas renamed to defbase.pas because D6 contains a types
  1242. unit so this would conflicts if D6 programms are compiled
  1243. + Willamette/SSE2 instructions to assembler added
  1244. Revision 1.63 2002/07/19 11:41:36 daniel
  1245. * State tracker work
  1246. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1247. allows the state tracker to change while nodes automatically into
  1248. repeat nodes.
  1249. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1250. 'not(a>b)' is optimized into 'a<=b'.
  1251. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1252. by removing the notn and later switchting the true and falselabels. The
  1253. same is done with 'repeat until not a'.
  1254. Revision 1.62 2002/07/16 15:34:20 florian
  1255. * exit is now a syssym instead of a keyword
  1256. Revision 1.61 2002/07/11 14:41:28 florian
  1257. * start of the new generic parameter handling
  1258. Revision 1.60 2002/07/04 20:43:01 florian
  1259. * first x86-64 patches
  1260. Revision 1.59 2002/07/01 18:46:25 peter
  1261. * internal linker
  1262. * reorganized aasm layer
  1263. Revision 1.58 2002/05/18 13:34:13 peter
  1264. * readded missing revisions
  1265. Revision 1.57 2002/05/16 19:46:44 carl
  1266. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1267. + try to fix temp allocation (still in ifdef)
  1268. + generic constructor calls
  1269. + start of tassembler / tmodulebase class cleanup
  1270. }