tree.pas 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. This units exports some routines to manage the parse tree
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. {$ifdef tp}
  19. {E+,N+}
  20. {$endif}
  21. unit tree;
  22. interface
  23. uses
  24. globals,scanner,symtable,cobjects,verbose,aasm,files
  25. {$ifdef i386}
  26. ,i386
  27. {$endif}
  28. {$ifdef m68k}
  29. ,m68k
  30. {$endif}
  31. {$ifdef alpha}
  32. ,alpha
  33. {$endif}
  34. ;
  35. type
  36. tconstset = array[0..31] of byte;
  37. pconstset = ^tconstset;
  38. ttreetyp = (addn, {Represents the + operator.}
  39. muln, {Represents the * operator.}
  40. subn, {Represents the - operator.}
  41. divn, {Represents the div operator.}
  42. symdifn, {Represents the >< operator.}
  43. modn, {Represents the mod operator.}
  44. assignn, {Represents an assignment.}
  45. loadn, {Represents the use of a variabele.}
  46. rangen, {Represents a range (i.e. 0..9).}
  47. ltn, {Represents the < operator.}
  48. lten, {Represents the <= operator.}
  49. gtn, {Represents the > operator.}
  50. gten, {Represents the >= operator.}
  51. equaln, {Represents the = operator.}
  52. unequaln, {Represents the <> operator.}
  53. inn, {Represents the in operator.}
  54. orn, {Represents the or operator.}
  55. xorn, {Represents the xor operator.}
  56. shrn, {Represents the shr operator.}
  57. shln, {Represents the shl operator.}
  58. slashn, {Represents the / operator.}
  59. andn, {Represents the and operator.}
  60. subscriptn, {??? Field in a record/object?}
  61. derefn, {Dereferences a pointer.}
  62. addrn, {Represents the @ operator.}
  63. doubleaddrn, {Represents the @@ operator.}
  64. ordconstn, {Represents an ordinal value.}
  65. typeconvn, {Represents type-conversion/typecast.}
  66. calln, {Represents a call node.}
  67. callparan, {Represents a parameter.}
  68. realconstn, {Represents a real value.}
  69. fixconstn, {Represents a fixed value.}
  70. umminusn, {Represents a sign change (i.e. -2).}
  71. asmn, {Represents an assembler node }
  72. vecn, {Represents array indexing.}
  73. stringconstn, {Represents a string constant.}
  74. funcretn, {Represents the function result var.}
  75. selfn, {Represents the self parameter.}
  76. notn, {Represents the not operator.}
  77. inlinen, {Internal procedures (i.e. writeln).}
  78. niln, {Represents the nil pointer.}
  79. errorn, {This part of the tree could not be
  80. parsed because of a compiler error.}
  81. typen, {A type name. Used for i.e. typeof(obj).}
  82. hnewn, {The new operation, constructor call.}
  83. hdisposen, {The dispose operation with destructor call.}
  84. newn, {The new operation, constructor call.}
  85. simpledisposen, {The dispose operation.}
  86. setelen, {A set element (i.e. [a,b]).}
  87. setconstrn, {A set constant (i.e. [1,2]).}
  88. blockn, {A block of statements.}
  89. statementn, {One statement in a block of nodes.}
  90. loopn, { used in genloopnode, must be converted }
  91. ifn, {An if statement.}
  92. breakn, {A break statement.}
  93. continuen, {A continue statement.}
  94. repeatn, {A repeat until block.}
  95. whilen, {A while do statement.}
  96. forn, {A for loop.}
  97. exitn, {An exit statement.}
  98. withn, {A with statement.}
  99. casen, {A case statement.}
  100. labeln, {A label.}
  101. goton, {A goto statement.}
  102. simplenewn, {The new operation.}
  103. tryexceptn, {A try except block.}
  104. raisen, {A raise statement.}
  105. switchesn, {??? Currently unused...}
  106. tryfinallyn, {A try finally statement.}
  107. isn, {Represents the is operator.}
  108. asn, {Represents the as typecast.}
  109. caretn, {Represents the ^ operator.}
  110. failn, {Represents the fail statement.}
  111. starstarn, {Represents the ** operator exponentiation }
  112. procinlinen, {Procedures that can be inlined }
  113. { added for optimizations where we cannot suppress }
  114. nothingn,
  115. loadvmtn); {???.}
  116. tconverttype = (tc_equal,tc_not_possible,tc_u8bit_2_s32bit,
  117. tc_only_rangechecks32bit,tc_s8bit_2_s32bit,
  118. tc_u16bit_2_s32bit,tc_s16bit_2_s32bit,
  119. tc_s32bit_2_s16bit,tc_s32bit_2_u8bit,
  120. tc_s32bit_2_u16bit,tc_string_to_string,
  121. tc_cstring_charpointer,tc_string_chararray,
  122. tc_array_to_pointer,tc_pointer_to_array,
  123. tc_char_to_string,tc_u8bit_2_s16bit,
  124. tc_u8bit_2_u16bit,tc_s8bit_2_s16bit,
  125. tc_s16bit_2_s8bit,tc_s16bit_2_u8bit,
  126. tc_u16bit_2_s8bit,tc_u16bit_2_u8bit,
  127. tc_s8bit_2_u16bit,tc_s32bit_2_s8bit,
  128. tc_s32bit_2_u32bit,tc_s16bit_2_u32bit,
  129. tc_s8bit_2_u32bit,tc_u16bit_2_u32bit,
  130. tc_u8bit_2_u32bit,tc_u32bit_2_s32bit,
  131. tc_u32bit_2_s8bit,tc_u32bit_2_u8bit,
  132. tc_u32bit_2_s16bit,tc_u32bit_2_u16bit,
  133. tc_int_2_real,tc_real_2_fix,
  134. tc_fix_2_real,tc_int_2_fix,tc_real_2_real,
  135. tc_chararray_2_string,tc_bool_2_u8bit,
  136. tc_proc2procvar,
  137. tc_cchar_charpointer);
  138. { allows to determine which elementes are to be replaced }
  139. tdisposetyp = (dt_nothing,dt_leftright,dt_left,
  140. dt_mbleft,dt_string,dt_typeconv,dt_inlinen,
  141. dt_mbleft_and_method,dt_constset,dt_loop,dt_case,
  142. dt_with);
  143. { different assignment types }
  144. tassigntyp = (at_normal,at_plus,at_minus,at_star,at_slash);
  145. pcaserecord = ^tcaserecord;
  146. tcaserecord = record
  147. { range }
  148. _low,_high : longint;
  149. { only used by gentreejmp }
  150. _at : plabel;
  151. { label of instruction }
  152. statement : plabel;
  153. { left and right tree node }
  154. less,greater : pcaserecord;
  155. end;
  156. ptree = ^ttree;
  157. ttree = record
  158. error : boolean;
  159. disposetyp : tdisposetyp;
  160. { is true, if the right and left operand are swaped }
  161. swaped : boolean;
  162. { the location of the result of this node }
  163. location : tlocation;
  164. { the number of registers needed to evalute the node }
  165. registers32,registersfpu : longint; { must be longint !!!! }
  166. {$ifdef SUPPORT_MMX}
  167. registersmmx : longint;
  168. {$endif SUPPORT_MMX}
  169. left,right : ptree;
  170. resulttype : pdef;
  171. { line : longint;
  172. fileindex,colon : word; }
  173. fileinfo : tfileposinfo;
  174. pragmas : Tcswitches;
  175. {$ifdef extdebug}
  176. firstpasscount : longint;
  177. {$endif extdebug}
  178. case treetype : ttreetyp of
  179. addn : (use_strconcat : boolean;string_typ : stringtype);
  180. callparan : (is_colon_para : boolean;exact_match_found : boolean);
  181. assignn : (assigntyp : tassigntyp;concat_string : boolean);
  182. loadn : (symtableentry : psym;symtable : psymtable;
  183. is_absolute,is_first : boolean);
  184. calln : (symtableprocentry : pprocsym;
  185. symtableproc : psymtable;procdefinition : pprocdef;
  186. methodpointer : ptree;
  187. no_check,unit_specific : boolean);
  188. ordconstn : (value : longint);
  189. realconstn : (valued : bestreal;labnumber : longint;realtyp : tait);
  190. fixconstn : (valuef: longint);
  191. {$ifdef TEST_FUNCRET}
  192. funcretn : (funcretprocinfo : pointer;retdef : pdef);
  193. {$endif TEST_FUNCRET}
  194. subscriptn : (vs : pvarsym);
  195. vecn : (memindex,memseg:boolean);
  196. { stringconstn : (length : longint; values : pstring;labstrnumber : longint); }
  197. { string const can be longer then 255 with ansistring !! }
  198. {$ifdef UseAnsiString}
  199. stringconstn : (values : pchar;length : longint; labstrnumber : longint);
  200. {$else UseAnsiString}
  201. stringconstn : (values : pstring; labstrnumber : longint);
  202. {$endif UseAnsiString}
  203. typeconvn : (convtyp : tconverttype;explizit : boolean);
  204. inlinen : (inlinenumber : longint);
  205. procinlinen : (inlineprocdef : pprocdef);
  206. setconstrn : (constset : pconstset);
  207. loopn : (t1,t2 : ptree;backward : boolean);
  208. asmn : (p_asm : paasmoutput);
  209. casen : (nodes : pcaserecord;elseblock : ptree);
  210. labeln,goton : (labelnr : plabel);
  211. withn : (withsymtable : psymtable;tablecount : longint);
  212. end;
  213. procedure init_tree;
  214. function gennode(t : ttreetyp;l,r : ptree) : ptree;
  215. function genlabelnode(t : ttreetyp;nr : plabel) : ptree;
  216. function genloadnode(v : pvarsym;st : psymtable) : ptree;
  217. function gensinglenode(t : ttreetyp;l : ptree) : ptree;
  218. function gensubscriptnode(varsym : pvarsym;l : ptree) : ptree;
  219. function genordinalconstnode(v : longint;def : pdef) : ptree;
  220. function genfixconstnode(v : longint;def : pdef) : ptree;
  221. function gentypeconvnode(node : ptree;t : pdef) : ptree;
  222. function gencallparanode(expr,next : ptree) : ptree;
  223. function genrealconstnode(v : bestreal) : ptree;
  224. function gencallnode(v : pprocsym;st : psymtable) : ptree;
  225. function genmethodcallnode(v : pprocsym;st : psymtable;mp : ptree) : ptree;
  226. { allow pchar or string for defining a pchar node }
  227. function genstringconstnode(const s : string) : ptree;
  228. {$ifdef UseAnsiString}
  229. { length is required for ansistrings }
  230. function genpcharconstnode(s : pchar;length : longint) : ptree;
  231. { helper routine for conststring node }
  232. function getpcharcopy(p : ptree) : pchar;
  233. {$endif UseAnsiString}
  234. function genzeronode(t : ttreetyp) : ptree;
  235. function geninlinenode(number : longint;l : ptree) : ptree;
  236. function genprocinlinenode(callp,code : ptree) : ptree;
  237. function gentypedconstloadnode(sym : ptypedconstsym;st : psymtable) : ptree;
  238. function genenumnode(v : penumsym) : ptree;
  239. function genselfnode(_class : pdef) : ptree;
  240. function gensetconstruktnode(s : pconstset;settype : psetdef) : ptree;
  241. function genloopnode(t : ttreetyp;l,r,n1: ptree;back : boolean) : ptree;
  242. function genasmnode(p_asm : paasmoutput) : ptree;
  243. function gencasenode(l,r : ptree;nodes : pcaserecord) : ptree;
  244. function genwithnode(symtable : psymtable;l,r : ptree;count : longint) : ptree;
  245. function getcopy(p : ptree) : ptree;
  246. function equal_trees(t1,t2 : ptree) : boolean;
  247. procedure disposetree(p : ptree);
  248. procedure putnode(p : ptree);
  249. function getnode : ptree;
  250. procedure clearnodes;
  251. procedure set_location(var destloc,sourceloc : tlocation);
  252. procedure swap_location(var destloc,sourceloc : tlocation);
  253. procedure set_file_line(from,_to : ptree);
  254. procedure set_current_file_line(_to : ptree);
  255. procedure set_tree_filepos(p : ptree;const filepos : tfileposinfo);
  256. {$ifdef extdebug}
  257. const
  258. maxfirstpasscount : longint = 0;
  259. {$endif extdebug}
  260. {$I innr.inc}
  261. implementation
  262. {$ifdef UseTokenInfo}
  263. uses pbase;
  264. {$endif UseTokenInfo}
  265. {****************************************************************************
  266. this is a pool for the tree nodes to get more performance
  267. ****************************************************************************}
  268. var
  269. root : ptree;
  270. procedure init_tree;
  271. begin
  272. root:=nil;
  273. end;
  274. procedure clearnodes;
  275. var
  276. hp : ptree;
  277. begin
  278. hp:=root;
  279. while assigned(hp) do
  280. begin
  281. root:=hp^.left;
  282. dispose(hp);
  283. hp:=root;
  284. end;
  285. end;
  286. function getnode : ptree;
  287. var
  288. hp : ptree;
  289. begin
  290. if root=nil then
  291. new(hp)
  292. else
  293. begin
  294. hp:=root;
  295. root:=root^.left;
  296. end;
  297. { makes error tracking easier }
  298. fillchar(hp^,sizeof(ttree),#0);
  299. hp^.location.loc:=LOC_INVALID;
  300. { new node is error free }
  301. hp^.error:=false;
  302. { we know also the position }
  303. {$ifdef UseTokenInfo}
  304. if assigned(tokeninfo) then
  305. begin
  306. hp^.fileinfo:=tokeninfo^.fi;
  307. end
  308. else
  309. {$endif UseTokenInfo}
  310. get_cur_file_pos(hp^.fileinfo);
  311. hp^.pragmas:=aktswitches;
  312. getnode:=hp;
  313. end;
  314. procedure putnode(p : ptree);
  315. begin
  316. { clean up the contents of a node }
  317. if p^.treetype=asmn then
  318. if assigned(p^.p_asm) then
  319. dispose(p^.p_asm,done);
  320. if p^.treetype=setconstrn then
  321. if assigned(p^.constset) then
  322. dispose(p^.constset);
  323. if (p^.location.loc=LOC_MEM) or (p^.location.loc=LOC_REFERENCE) and
  324. assigned(p^.location.reference.symbol) then
  325. stringdispose(p^.location.reference.symbol);
  326. {$ifndef UseAnsiString}
  327. if p^.disposetyp=dt_string then
  328. stringdispose(p^.values);
  329. {$else UseAnsiString}
  330. if p^.disposetyp=dt_string then
  331. ansistringdispose(p^.values,p^.length);
  332. {$endif UseAnsiString}
  333. {$ifdef extdebug}
  334. if p^.firstpasscount>maxfirstpasscount then
  335. maxfirstpasscount:=p^.firstpasscount;
  336. dispose(p);
  337. {$else extdebug}
  338. p^.left:=root;
  339. root:=p;
  340. {$endif extdebug}
  341. end;
  342. function getcopy(p : ptree) : ptree;
  343. var
  344. hp : ptree;
  345. begin
  346. hp:=getnode;
  347. hp^:=p^;
  348. if assigned(p^.location.reference.symbol) then
  349. hp^.location.reference.symbol:=stringdup(p^.location.reference.symbol^);
  350. case p^.disposetyp of
  351. dt_leftright :
  352. begin
  353. if assigned(p^.left) then
  354. hp^.left:=getcopy(p^.left);
  355. if assigned(p^.right) then
  356. hp^.right:=getcopy(p^.right);
  357. end;
  358. dt_nothing : ;
  359. dt_left :
  360. if assigned(p^.left) then
  361. hp^.left:=getcopy(p^.left);
  362. dt_mbleft :
  363. if assigned(p^.left) then
  364. hp^.left:=getcopy(p^.left);
  365. dt_mbleft_and_method :
  366. begin
  367. if assigned(p^.left) then
  368. hp^.left:=getcopy(p^.left);
  369. hp^.methodpointer:=getcopy(p^.methodpointer);
  370. end;
  371. dt_loop :
  372. begin
  373. if assigned(p^.left) then
  374. hp^.left:=getcopy(p^.left);
  375. if assigned(p^.right) then
  376. hp^.right:=getcopy(p^.right);
  377. if assigned(p^.t1) then
  378. hp^.t1:=getcopy(p^.t1);
  379. if assigned(p^.t2) then
  380. hp^.t2:=getcopy(p^.t2);
  381. end;
  382. {$ifdef UseAnsiString}
  383. dt_string : begin
  384. hp^.values:=getpcharcopy(p);
  385. hp^.length:=p^.length;
  386. end;
  387. {$else UseAnsiString}
  388. dt_string : hp^.values:=stringdup(p^.values^);
  389. {$endif UseAnsiString}
  390. dt_typeconv : hp^.left:=getcopy(p^.left);
  391. dt_inlinen :
  392. if assigned(p^.left) then
  393. hp^.left:=getcopy(p^.left);
  394. else internalerror(11);
  395. end;
  396. getcopy:=hp;
  397. end;
  398. procedure deletecaselabels(p : pcaserecord);
  399. begin
  400. if assigned(p^.greater) then
  401. deletecaselabels(p^.greater);
  402. if assigned(p^.less) then
  403. deletecaselabels(p^.less);
  404. dispose(p);
  405. end;
  406. procedure disposetree(p : ptree);
  407. begin
  408. if not(assigned(p)) then
  409. exit;
  410. case p^.disposetyp of
  411. dt_leftright :
  412. begin
  413. if assigned(p^.left) then
  414. disposetree(p^.left);
  415. if assigned(p^.right) then
  416. disposetree(p^.right);
  417. end;
  418. dt_case :
  419. begin
  420. if assigned(p^.left) then
  421. disposetree(p^.left);
  422. if assigned(p^.right) then
  423. disposetree(p^.right);
  424. if assigned(p^.nodes) then
  425. deletecaselabels(p^.nodes);
  426. if assigned(p^.elseblock) then
  427. disposetree(p^.elseblock);
  428. end;
  429. dt_nothing : ;
  430. dt_left :
  431. if assigned(p^.left) then
  432. disposetree(p^.left);
  433. dt_mbleft :
  434. if assigned(p^.left) then
  435. disposetree(p^.left);
  436. dt_mbleft_and_method :
  437. begin
  438. if assigned(p^.left) then disposetree(p^.left);
  439. disposetree(p^.methodpointer);
  440. end;
  441. {$ifdef UseAnsiString}
  442. dt_string : ansistringdispose(p^.values,p^.length);
  443. {$else UseAnsiString}
  444. dt_string : stringdispose(p^.values);
  445. {$endif UseAnsiString}
  446. dt_constset :
  447. begin
  448. if assigned(p^.constset) then
  449. begin
  450. dispose(p^.constset);
  451. p^.constset:=nil;
  452. end;
  453. if assigned(p^.left) then
  454. disposetree(p^.left);
  455. end;
  456. dt_typeconv : disposetree(p^.left);
  457. dt_inlinen :
  458. if assigned(p^.left) then
  459. disposetree(p^.left);
  460. dt_loop :
  461. begin
  462. if assigned(p^.left) then
  463. disposetree(p^.left);
  464. if assigned(p^.right) then
  465. disposetree(p^.right);
  466. if assigned(p^.t1) then
  467. disposetree(p^.t1);
  468. if assigned(p^.t2) then
  469. disposetree(p^.t2);
  470. end;
  471. dt_with :
  472. begin
  473. if assigned(p^.left) then
  474. disposetree(p^.left);
  475. if assigned(p^.right) then
  476. disposetree(p^.right);
  477. if assigned(p^.withsymtable) then
  478. dispose(p^.withsymtable,done);
  479. end;
  480. else internalerror(12);
  481. end;
  482. putnode(p);
  483. end;
  484. procedure set_file_line(from,_to : ptree);
  485. begin
  486. if assigned(from) then
  487. _to^.fileinfo:=from^.fileinfo;
  488. end;
  489. procedure set_current_file_line(_to : ptree);
  490. begin
  491. current_module^.current_inputfile:=
  492. pinputfile(current_module^.sourcefiles.get_file(_to^.fileinfo.fileindex));
  493. current_module^.current_inputfile^.line_no:=_to^.fileinfo.line;
  494. current_module^.current_index:=_to^.fileinfo.fileindex;
  495. end;
  496. procedure set_tree_filepos(p : ptree;const filepos : tfileposinfo);
  497. begin
  498. p^.fileinfo:=filepos;
  499. end;
  500. function genwithnode(symtable : psymtable;l,r : ptree;count : longint) : ptree;
  501. var
  502. p : ptree;
  503. begin
  504. p:=getnode;
  505. p^.disposetyp:=dt_with;
  506. p^.treetype:=withn;
  507. p^.left:=l;
  508. p^.right:=r;
  509. p^.registers32:=0;
  510. { p^.registers16:=0;
  511. p^.registers8:=0; }
  512. p^.registersfpu:=0;
  513. {$ifdef SUPPORT_MMX}
  514. p^.registersmmx:=0;
  515. {$endif SUPPORT_MMX}
  516. p^.resulttype:=nil;
  517. p^.withsymtable:=symtable;
  518. p^.tablecount:=count;
  519. set_file_line(l,p);
  520. genwithnode:=p;
  521. end;
  522. function genfixconstnode(v : longint;def : pdef) : ptree;
  523. var
  524. p : ptree;
  525. begin
  526. p:=getnode;
  527. p^.disposetyp:=dt_nothing;
  528. p^.treetype:=fixconstn;
  529. p^.registers32:=0;
  530. { p^.registers16:=0;
  531. p^.registers8:=0; }
  532. p^.registersfpu:=0;
  533. {$ifdef SUPPORT_MMX}
  534. p^.registersmmx:=0;
  535. {$endif SUPPORT_MMX}
  536. p^.resulttype:=def;
  537. p^.value:=v;
  538. genfixconstnode:=p;
  539. end;
  540. function gencallparanode(expr,next : ptree) : ptree;
  541. var
  542. p : ptree;
  543. begin
  544. p:=getnode;
  545. p^.disposetyp:=dt_leftright;
  546. p^.treetype:=callparan;
  547. p^.left:=expr;
  548. p^.right:=next;
  549. p^.registers32:=0;
  550. { p^.registers16:=0;
  551. p^.registers8:=0; }
  552. {$ifdef SUPPORT_MMX}
  553. p^.registersmmx:=0;
  554. {$endif SUPPORT_MMX}
  555. p^.registersfpu:=0;
  556. p^.resulttype:=nil;
  557. p^.exact_match_found:=false;
  558. p^.is_colon_para:=false;
  559. set_file_line(expr,p);
  560. gencallparanode:=p;
  561. end;
  562. function gennode(t : ttreetyp;l,r : ptree) : ptree;
  563. var
  564. p : ptree;
  565. begin
  566. p:=getnode;
  567. p^.disposetyp:=dt_leftright;
  568. p^.treetype:=t;
  569. p^.left:=l;
  570. p^.right:=r;
  571. p^.registers32:=0;
  572. { p^.registers16:=0;
  573. p^.registers8:=0; }
  574. p^.registersfpu:=0;
  575. {$ifdef SUPPORT_MMX}
  576. p^.registersmmx:=0;
  577. {$endif SUPPORT_MMX}
  578. p^.resulttype:=nil;
  579. gennode:=p;
  580. end;
  581. function gencasenode(l,r : ptree;nodes : pcaserecord) : ptree;
  582. var
  583. p : ptree;
  584. begin
  585. p:=getnode;
  586. p^.disposetyp:=dt_case;
  587. p^.treetype:=casen;
  588. p^.left:=l;
  589. p^.right:=r;
  590. p^.nodes:=nodes;
  591. p^.registers32:=0;
  592. p^.registersfpu:=0;
  593. {$ifdef SUPPORT_MMX}
  594. p^.registersmmx:=0;
  595. {$endif SUPPORT_MMX}
  596. p^.resulttype:=nil;
  597. set_file_line(l,p);
  598. gencasenode:=p;
  599. end;
  600. function genloopnode(t : ttreetyp;l,r,n1 : ptree;back : boolean) : ptree;
  601. var
  602. p : ptree;
  603. begin
  604. p:=getnode;
  605. p^.disposetyp:=dt_loop;
  606. p^.treetype:=t;
  607. p^.left:=l;
  608. p^.right:=r;
  609. p^.t1:=n1;
  610. p^.t2:=nil;
  611. p^.registers32:=0;
  612. p^.backward:=back;
  613. { p^.registers16:=0;
  614. p^.registers8:=0; }
  615. p^.registersfpu:=0;
  616. {$ifdef SUPPORT_MMX}
  617. p^.registersmmx:=0;
  618. {$endif SUPPORT_MMX}
  619. p^.resulttype:=nil;
  620. set_file_line(l,p);
  621. genloopnode:=p;
  622. end;
  623. function genordinalconstnode(v : longint;def : pdef) : ptree;
  624. var
  625. p : ptree;
  626. begin
  627. p:=getnode;
  628. p^.disposetyp:=dt_nothing;
  629. p^.treetype:=ordconstn;
  630. p^.registers32:=0;
  631. { p^.registers16:=0;
  632. p^.registers8:=0; }
  633. p^.registersfpu:=0;
  634. {$ifdef SUPPORT_MMX}
  635. p^.registersmmx:=0;
  636. {$endif SUPPORT_MMX}
  637. p^.resulttype:=def;
  638. p^.value:=v;
  639. genordinalconstnode:=p;
  640. end;
  641. function genenumnode(v : penumsym) : ptree;
  642. var
  643. p : ptree;
  644. begin
  645. p:=getnode;
  646. p^.disposetyp:=dt_nothing;
  647. p^.treetype:=ordconstn;
  648. p^.registers32:=0;
  649. { p^.registers16:=0;
  650. p^.registers8:=0; }
  651. p^.registersfpu:=0;
  652. {$ifdef SUPPORT_MMX}
  653. p^.registersmmx:=0;
  654. {$endif SUPPORT_MMX}
  655. p^.resulttype:=v^.definition;
  656. p^.value:=v^.value;
  657. genenumnode:=p;
  658. end;
  659. function genrealconstnode(v : bestreal) : ptree;
  660. var
  661. p : ptree;
  662. begin
  663. p:=getnode;
  664. p^.disposetyp:=dt_nothing;
  665. p^.treetype:=realconstn;
  666. p^.registers32:=0;
  667. { p^.registers16:=0;
  668. p^.registers8:=0; }
  669. p^.registersfpu:=0;
  670. {$ifdef SUPPORT_MMX}
  671. p^.registersmmx:=0;
  672. {$endif SUPPORT_MMX}
  673. {$ifdef i386}
  674. p^.resulttype:=c64floatdef;
  675. p^.valued:=v;
  676. { default value is double }
  677. p^.realtyp:=ait_real_64bit;
  678. {$endif}
  679. {$ifdef m68k}
  680. p^.resulttype:=new(pfloatdef,init(s32real));
  681. p^.valued:=v;
  682. { default value is double }
  683. p^.realtyp:=ait_real_32bit;
  684. {$endif}
  685. p^.labnumber:=-1;
  686. genrealconstnode:=p;
  687. end;
  688. function genstringconstnode(const s : string) : ptree;
  689. var
  690. p : ptree;
  691. {$ifdef UseAnsiString}
  692. l : longint;
  693. {$endif UseAnsiString}
  694. begin
  695. p:=getnode;
  696. p^.disposetyp:=dt_string;
  697. p^.treetype:=stringconstn;
  698. p^.registers32:=0;
  699. { p^.registers16:=0;
  700. p^.registers8:=0; }
  701. p^.registersfpu:=0;
  702. {$ifdef SUPPORT_MMX}
  703. p^.registersmmx:=0;
  704. {$endif SUPPORT_MMX}
  705. p^.resulttype:=cstringdef;
  706. {$ifdef UseAnsiString}
  707. l:=length(s);
  708. p^.length:=l;
  709. { stringdup write even past a #0 }
  710. getmem(p^.values,l+1);
  711. move(s[1],p^.values^,l);
  712. p^.values[l]:=#0;
  713. {$else UseAnsiString}
  714. p^.values:=stringdup(s);
  715. {$endif UseAnsiString}
  716. p^.labstrnumber:=-1;
  717. genstringconstnode:=p;
  718. end;
  719. {$ifdef UseAnsiString}
  720. function getpcharcopy(p : ptree) : pchar;
  721. var
  722. pc : pchar;
  723. begin
  724. pc:=nil;
  725. getmem(pc,p^.length+1);
  726. { Peter can you change that ? }
  727. if pc=nil then
  728. comment(V_fatal,'No memory left');
  729. move(p^.values^,pc^,p^.length+1);
  730. getpcharcopy:=pc;
  731. end;
  732. function genpcharconstnode(s : pchar;length : longint) : ptree;
  733. var
  734. p : ptree;
  735. begin
  736. p:=getnode;
  737. p^.disposetyp:=dt_string;
  738. p^.treetype:=stringconstn;
  739. p^.registers32:=0;
  740. { p^.registers16:=0;
  741. p^.registers8:=0; }
  742. p^.registersfpu:=0;
  743. {$ifdef SUPPORT_MMX}
  744. p^.registersmmx:=0;
  745. {$endif SUPPORT_MMX}
  746. p^.resulttype:=cstringdef;
  747. p^.length:=length;
  748. p^.values:=s;
  749. p^.labstrnumber:=-1;
  750. genpcharconstnode:=p;
  751. end;
  752. {$endif UseAnsiString}
  753. function gensinglenode(t : ttreetyp;l : ptree) : ptree;
  754. var
  755. p : ptree;
  756. begin
  757. p:=getnode;
  758. p^.disposetyp:=dt_left;
  759. p^.treetype:=t;
  760. p^.left:=l;
  761. p^.registers32:=0;
  762. { p^.registers16:=0;
  763. p^.registers8:=0; }
  764. p^.registersfpu:=0;
  765. {$ifdef SUPPORT_MMX}
  766. p^.registersmmx:=0;
  767. {$endif SUPPORT_MMX}
  768. p^.resulttype:=nil;
  769. gensinglenode:=p;
  770. end;
  771. function genasmnode(p_asm : paasmoutput) : ptree;
  772. var
  773. p : ptree;
  774. begin
  775. p:=getnode;
  776. p^.disposetyp:=dt_nothing;
  777. p^.treetype:=asmn;
  778. p^.registers32:=4;
  779. p^.p_asm:=p_asm;
  780. { p^.registers16:=0;
  781. p^.registers8:=0; }
  782. p^.registersfpu:=8;
  783. {$ifdef SUPPORT_MMX}
  784. p^.registersmmx:=8;
  785. {$endif SUPPORT_MMX}
  786. p^.resulttype:=nil;
  787. genasmnode:=p;
  788. end;
  789. function genloadnode(v : pvarsym;st : psymtable) : ptree;
  790. var
  791. p : ptree;
  792. begin
  793. p:=getnode;
  794. p^.registers32:=0;
  795. { p^.registers16:=0;
  796. p^.registers8:=0; }
  797. p^.registersfpu:=0;
  798. {$ifdef SUPPORT_MMX}
  799. p^.registersmmx:=0;
  800. {$endif SUPPORT_MMX}
  801. p^.treetype:=loadn;
  802. p^.resulttype:=v^.definition;
  803. p^.symtableentry:=v;
  804. p^.symtable:=st;
  805. p^.is_first := False;
  806. p^.disposetyp:=dt_nothing;
  807. genloadnode:=p;
  808. end;
  809. function gentypedconstloadnode(sym : ptypedconstsym;st : psymtable) : ptree;
  810. var
  811. p : ptree;
  812. begin
  813. p:=getnode;
  814. p^.registers32:=0;
  815. { p^.registers16:=0;
  816. p^.registers8:=0; }
  817. p^.registersfpu:=0;
  818. {$ifdef SUPPORT_MMX}
  819. p^.registersmmx:=0;
  820. {$endif SUPPORT_MMX}
  821. p^.treetype:=loadn;
  822. p^.resulttype:=sym^.definition;
  823. p^.symtableentry:=pvarsym(sym);
  824. p^.symtable:=st;
  825. p^.disposetyp:=dt_nothing;
  826. gentypedconstloadnode:=p;
  827. end;
  828. function gentypeconvnode(node : ptree;t : pdef) : ptree;
  829. var
  830. p : ptree;
  831. begin
  832. p:=getnode;
  833. p^.disposetyp:=dt_typeconv;
  834. p^.treetype:=typeconvn;
  835. p^.left:=node;
  836. p^.registers32:=0;
  837. { p^.registers16:=0;
  838. p^.registers8:=0; }
  839. p^.convtyp:=tc_equal;
  840. p^.registersfpu:=0;
  841. {$ifdef SUPPORT_MMX}
  842. p^.registersmmx:=0;
  843. {$endif SUPPORT_MMX}
  844. p^.resulttype:=t;
  845. p^.convtyp:=tc_equal;
  846. p^.explizit:=false;
  847. set_file_line(node,p);
  848. gentypeconvnode:=p;
  849. end;
  850. function gencallnode(v : pprocsym;st : psymtable) : ptree;
  851. var
  852. p : ptree;
  853. begin
  854. p:=getnode;
  855. p^.registers32:=0;
  856. { p^.registers16:=0;
  857. p^.registers8:=0; }
  858. p^.registersfpu:=0;
  859. {$ifdef SUPPORT_MMX}
  860. p^.registersmmx:=0;
  861. {$endif SUPPORT_MMX}
  862. p^.treetype:=calln;
  863. p^.symtableprocentry:=v;
  864. p^.symtableproc:=st;
  865. p^.unit_specific:=false;
  866. p^.no_check:=false;
  867. p^.disposetyp := dt_leftright;
  868. p^.methodpointer:=nil;
  869. p^.left:=nil;
  870. p^.right:=nil;
  871. p^.procdefinition:=nil;
  872. gencallnode:=p;
  873. end;
  874. function genmethodcallnode(v : pprocsym;st : psymtable;mp : ptree) : ptree;
  875. var
  876. p : ptree;
  877. begin
  878. p:=getnode;
  879. p^.registers32:=0;
  880. { p^.registers16:=0;
  881. p^.registers8:=0; }
  882. p^.registersfpu:=0;
  883. {$ifdef SUPPORT_MMX}
  884. p^.registersmmx:=0;
  885. {$endif SUPPORT_MMX}
  886. p^.treetype:=calln;
  887. p^.symtableprocentry:=v;
  888. p^.symtableproc:=st;
  889. p^.disposetyp:=dt_mbleft_and_method;
  890. p^.left:=nil;
  891. p^.right:=nil;
  892. p^.methodpointer:=mp;
  893. p^.procdefinition:=nil;
  894. genmethodcallnode:=p;
  895. end;
  896. function gensubscriptnode(varsym : pvarsym;l : ptree) : ptree;
  897. var
  898. p : ptree;
  899. begin
  900. p:=getnode;
  901. p^.disposetyp:=dt_left;
  902. p^.treetype:=subscriptn;
  903. p^.left:=l;
  904. p^.registers32:=0;
  905. p^.vs:=varsym;
  906. { p^.registers16:=0;
  907. p^.registers8:=0; }
  908. p^.registersfpu:=0;
  909. {$ifdef SUPPORT_MMX}
  910. p^.registersmmx:=0;
  911. {$endif SUPPORT_MMX}
  912. p^.resulttype:=nil;
  913. gensubscriptnode:=p;
  914. end;
  915. function genzeronode(t : ttreetyp) : ptree;
  916. var
  917. p : ptree;
  918. begin
  919. p:=getnode;
  920. p^.disposetyp:=dt_nothing;
  921. p^.treetype:=t;
  922. p^.registers32:=0;
  923. { p^.registers16:=0;
  924. p^.registers8:=0; }
  925. p^.registersfpu:=0;
  926. {$ifdef SUPPORT_MMX}
  927. p^.registersmmx:=0;
  928. {$endif SUPPORT_MMX}
  929. p^.resulttype:=nil;
  930. genzeronode:=p;
  931. end;
  932. function genlabelnode(t : ttreetyp;nr : plabel) : ptree;
  933. var
  934. p : ptree;
  935. begin
  936. p:=getnode;
  937. p^.disposetyp:=dt_nothing;
  938. p^.treetype:=t;
  939. p^.registers32:=0;
  940. { p^.registers16:=0;
  941. p^.registers8:=0; }
  942. p^.registersfpu:=0;
  943. {$ifdef SUPPORT_MMX}
  944. p^.registersmmx:=0;
  945. {$endif SUPPORT_MMX}
  946. p^.resulttype:=nil;
  947. { for security }
  948. { nr^.is_used:=true;}
  949. p^.labelnr:=nr;
  950. genlabelnode:=p;
  951. end;
  952. function genselfnode(_class : pdef) : ptree;
  953. var
  954. p : ptree;
  955. begin
  956. p:=getnode;
  957. p^.disposetyp:=dt_nothing;
  958. p^.treetype:=selfn;
  959. p^.registers32:=0;
  960. { p^.registers16:=0;
  961. p^.registers8:=0; }
  962. p^.registersfpu:=0;
  963. {$ifdef SUPPORT_MMX}
  964. p^.registersmmx:=0;
  965. {$endif SUPPORT_MMX}
  966. p^.resulttype:=_class;
  967. genselfnode:=p;
  968. end;
  969. function geninlinenode(number : longint;l : ptree) : ptree;
  970. var
  971. p : ptree;
  972. begin
  973. p:=getnode;
  974. p^.disposetyp:=dt_inlinen;
  975. p^.treetype:=inlinen;
  976. p^.left:=l;
  977. p^.inlinenumber:=number;
  978. p^.registers32:=0;
  979. { p^.registers16:=0;
  980. p^.registers8:=0; }
  981. p^.registersfpu:=0;
  982. {$ifdef SUPPORT_MMX}
  983. p^.registersmmx:=0;
  984. {$endif SUPPORT_MMX}
  985. p^.resulttype:=nil;
  986. geninlinenode:=p;
  987. end;
  988. { uses the callnode to create the new procinline node }
  989. function genprocinlinenode(callp,code : ptree) : ptree;
  990. var
  991. p : ptree;
  992. begin
  993. p:=getnode;
  994. p^.disposetyp:=dt_left;
  995. p^.treetype:=procinlinen;
  996. p^.inlineprocdef:=callp^.procdefinition;
  997. { copy args }
  998. p^.left:=getcopy(code);
  999. p^.registers32:=code^.registers32;
  1000. p^.registersfpu:=code^.registersfpu;
  1001. {$ifdef SUPPORT_MMX}
  1002. p^.registersmmx:=0;
  1003. {$endif SUPPORT_MMX}
  1004. p^.resulttype:=p^.inlineprocdef^.retdef;
  1005. genprocinlinenode:=p;
  1006. end;
  1007. function gensetconstruktnode(s : pconstset;settype : psetdef) : ptree;
  1008. var
  1009. p : ptree;
  1010. begin
  1011. p:=getnode;
  1012. p^.disposetyp:=dt_constset;
  1013. p^.treetype:=setconstrn;
  1014. p^.registers32:=0;
  1015. p^.registersfpu:=0;
  1016. {$ifdef SUPPORT_MMX}
  1017. p^.registersmmx:=0;
  1018. {$endif SUPPORT_MMX}
  1019. p^.resulttype:=settype;
  1020. p^.left:=nil;
  1021. new(p^.constset);
  1022. p^.constset^:=s^;
  1023. gensetconstruktnode:=p;
  1024. end;
  1025. function equal_trees(t1,t2 : ptree) : boolean;
  1026. begin
  1027. if t1^.treetype=t2^.treetype then
  1028. begin
  1029. case t1^.treetype of
  1030. addn,
  1031. muln,
  1032. equaln,
  1033. orn,
  1034. xorn,
  1035. andn,
  1036. unequaln:
  1037. begin
  1038. equal_trees:=(equal_trees(t1^.left,t2^.left) and
  1039. equal_trees(t1^.right,t2^.right)) or
  1040. (equal_trees(t1^.right,t2^.left) and
  1041. equal_trees(t1^.left,t2^.right));
  1042. end;
  1043. subn,
  1044. divn,
  1045. modn,
  1046. assignn,
  1047. ltn,
  1048. lten,
  1049. gtn,
  1050. gten,
  1051. inn,
  1052. shrn,
  1053. shln,
  1054. slashn,
  1055. rangen:
  1056. begin
  1057. equal_trees:=(equal_trees(t1^.left,t2^.left) and
  1058. equal_trees(t1^.right,t2^.right));
  1059. end;
  1060. umminusn,
  1061. notn,
  1062. derefn,
  1063. addrn:
  1064. begin
  1065. equal_trees:=(equal_trees(t1^.left,t2^.left));
  1066. end;
  1067. loadn:
  1068. begin
  1069. equal_trees:=(t1^.symtableentry=t2^.symtableentry)
  1070. { not necessary
  1071. and (t1^.symtable=t2^.symtable)};
  1072. end;
  1073. {
  1074. subscriptn,
  1075. ordconstn,typeconvn,calln,callparan,
  1076. realconstn,asmn,vecn,
  1077. stringconstn,funcretn,selfn,
  1078. inlinen,niln,errorn,
  1079. typen,hnewn,hdisposen,newn,
  1080. disposen,setelen,setconstrn
  1081. }
  1082. else equal_trees:=false;
  1083. end;
  1084. end
  1085. else
  1086. equal_trees:=false;
  1087. end;
  1088. {This is needed if you want to be able to delete the string with the nodes !!}
  1089. procedure set_location(var destloc,sourceloc : tlocation);
  1090. begin
  1091. if assigned(destloc.reference.symbol) then
  1092. stringdispose(destloc.reference.symbol);
  1093. destloc:= sourceloc;
  1094. if sourceloc.loc in [LOC_MEM,LOC_REFERENCE] then
  1095. begin
  1096. if assigned(sourceloc.reference.symbol) then
  1097. destloc.reference.symbol:=
  1098. stringdup(sourceloc.reference.symbol^);
  1099. end
  1100. else
  1101. destloc.reference.symbol:=nil;
  1102. end;
  1103. procedure swap_location(var destloc,sourceloc : tlocation);
  1104. var
  1105. swapl : tlocation;
  1106. begin
  1107. swapl := destloc;
  1108. destloc := sourceloc;
  1109. sourceloc := swapl;
  1110. end;
  1111. end.
  1112. {
  1113. $Log$
  1114. Revision 1.5 1998-04-30 15:59:43 pierre
  1115. * GDB works again better :
  1116. correct type info in one pass
  1117. + UseTokenInfo for better source position
  1118. * fixed one remaining bug in scanner for line counts
  1119. * several little fixes
  1120. Revision 1.4 1998/04/29 10:34:08 pierre
  1121. + added some code for ansistring (not complete nor working yet)
  1122. * corrected operator overloading
  1123. * corrected nasm output
  1124. + started inline procedures
  1125. + added starstarn : use ** for exponentiation (^ gave problems)
  1126. + started UseTokenInfo cond to get accurate positions
  1127. Revision 1.3 1998/04/21 10:16:49 peter
  1128. * patches from strasbourg
  1129. * objects is not used anymore in the fpc compiled version
  1130. Revision 1.2 1998/04/07 22:45:05 florian
  1131. * bug0092, bug0115 and bug0121 fixed
  1132. + packed object/class/array
  1133. Revision 1.1.1.1 1998/03/25 11:18:13 root
  1134. * Restored version
  1135. Revision 1.15 1998/03/24 21:48:36 florian
  1136. * just a couple of fixes applied:
  1137. - problem with fixed16 solved
  1138. - internalerror 10005 problem fixed
  1139. - patch for assembler reading
  1140. - small optimizer fix
  1141. - mem is now supported
  1142. Revision 1.14 1998/03/10 16:27:46 pierre
  1143. * better line info in stabs debug
  1144. * symtabletype and lexlevel separated into two fields of tsymtable
  1145. + ifdef MAKELIB for direct library output, not complete
  1146. + ifdef CHAINPROCSYMS for overloaded seach across units, not fully
  1147. working
  1148. + ifdef TESTFUNCRET for setting func result in underfunction, not
  1149. working
  1150. Revision 1.13 1998/03/10 01:17:30 peter
  1151. * all files have the same header
  1152. * messages are fully implemented, EXTDEBUG uses Comment()
  1153. + AG... files for the Assembler generation
  1154. Revision 1.12 1998/03/02 01:49:37 peter
  1155. * renamed target_DOS to target_GO32V1
  1156. + new verbose system, merged old errors and verbose units into one new
  1157. verbose.pas, so errors.pas is obsolete
  1158. Revision 1.11 1998/02/27 09:26:18 daniel
  1159. * Changed symtable handling so no junk symtable is put on the symtablestack.
  1160. Revision 1.10 1998/02/13 10:35:54 daniel
  1161. * Made Motorola version compilable.
  1162. * Fixed optimizer
  1163. Revision 1.9 1998/02/12 11:50:51 daniel
  1164. Yes! Finally! After three retries, my patch!
  1165. Changes:
  1166. Complete rewrite of psub.pas.
  1167. Added support for DLL's.
  1168. Compiler requires less memory.
  1169. Platform units for each platform.
  1170. Revision 1.8 1998/02/04 14:39:31 florian
  1171. * small clean up
  1172. Revision 1.7 1998/01/13 23:11:16 florian
  1173. + class methods
  1174. Revision 1.6 1998/01/11 04:16:36 carl
  1175. + correct floating point support for m68k
  1176. Revision 1.5 1998/01/07 00:17:11 michael
  1177. Restored released version (plus fixes) as current
  1178. Revision 1.3 1997/12/04 12:02:15 pierre
  1179. + added a counter of max firstpass's for a ptree
  1180. for debugging only in ifdef extdebug
  1181. Revision 1.2 1997/11/29 15:43:08 florian
  1182. * some minor changes
  1183. Revision 1.1.1.1 1997/11/27 08:33:03 michael
  1184. FPC Compiler CVS start
  1185. Pre-CVS log:
  1186. CEC Carl-Eric Codere
  1187. FK Florian Klaempfl
  1188. PM Pierre Muller
  1189. + feature added
  1190. - removed
  1191. * bug fixed or changed
  1192. History:
  1193. 19th october 1996:
  1194. + adapted to version 0.9.0
  1195. 6th september 1997:
  1196. + added support for MC68000 (CEC)
  1197. 3rd october 1997:
  1198. + added tc_bool_2_u8bit for in_ord_x (PM)
  1199. 3rd november1997:
  1200. + added symdifn for sets (PM)
  1201. 13th november 1997:
  1202. + added partial code for u32bit support (PM)
  1203. }