tcadd.pas 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. Type checking and register allocation for add node
  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 tcadd;
  19. interface
  20. uses
  21. tree;
  22. procedure firstadd(var p : ptree);
  23. implementation
  24. uses
  25. globtype,systems,tokens,
  26. cobjects,verbose,globals,
  27. symconst,symtable,aasm,types,
  28. hcodegen,htypechk,pass_1,
  29. cpubase,tccnv
  30. ;
  31. {*****************************************************************************
  32. FirstAdd
  33. *****************************************************************************}
  34. procedure firstadd(var p : ptree);
  35. procedure make_bool_equal_size(var p:ptree);
  36. begin
  37. if porddef(p^.left^.resulttype)^.typ>porddef(p^.right^.resulttype)^.typ then
  38. begin
  39. p^.right:=gentypeconvnode(p^.right,porddef(p^.left^.resulttype));
  40. p^.right^.convtyp:=tc_bool_2_int;
  41. p^.right^.explizit:=true;
  42. firstpass(p^.right);
  43. end
  44. else
  45. if porddef(p^.left^.resulttype)^.typ<porddef(p^.right^.resulttype)^.typ then
  46. begin
  47. p^.left:=gentypeconvnode(p^.left,porddef(p^.right^.resulttype));
  48. p^.left^.convtyp:=tc_bool_2_int;
  49. p^.left^.explizit:=true;
  50. firstpass(p^.left);
  51. end;
  52. end;
  53. var
  54. t,hp : ptree;
  55. ot,
  56. lt,rt : ttreetyp;
  57. rv,lv : longint;
  58. rvd,lvd : bestreal;
  59. resdef,
  60. rd,ld : pdef;
  61. tempdef : pdef;
  62. concatstrings : boolean;
  63. { to evalute const sets }
  64. resultset : pconstset;
  65. i : longint;
  66. b : boolean;
  67. optoken : ttoken;
  68. convdone : boolean;
  69. s1,s2 : pchar;
  70. l1,l2 : longint;
  71. { this totally forgets to set the pi_do_call flag !! }
  72. label
  73. no_overload;
  74. begin
  75. { first do the two subtrees }
  76. firstpass(p^.left);
  77. firstpass(p^.right);
  78. if codegenerror then
  79. exit;
  80. { convert array constructors to sets, because there is no other operator
  81. possible for array constructors }
  82. if is_array_constructor(p^.left^.resulttype) then
  83. arrayconstructor_to_set(p^.left);
  84. if is_array_constructor(p^.right^.resulttype) then
  85. arrayconstructor_to_set(p^.right);
  86. { both left and right need to be valid }
  87. set_varstate(p^.left,true);
  88. set_varstate(p^.right,true);
  89. { load easier access variables }
  90. lt:=p^.left^.treetype;
  91. rt:=p^.right^.treetype;
  92. rd:=p^.right^.resulttype;
  93. ld:=p^.left^.resulttype;
  94. convdone:=false;
  95. { overloaded operator ? }
  96. if (p^.treetype=starstarn) or
  97. (ld^.deftype=recorddef) or
  98. ((ld^.deftype=arraydef) and
  99. not((cs_mmx in aktlocalswitches) and
  100. is_mmx_able_array(ld)) and
  101. (not (rd^.deftype in [orddef])) and
  102. (not is_chararray(ld))
  103. ) or
  104. { <> and = are defined for classes }
  105. ((ld^.deftype=objectdef) and
  106. (not(pobjectdef(ld)^.is_class) or
  107. not(p^.treetype in [equaln,unequaln])
  108. )
  109. ) or
  110. (rd^.deftype=recorddef) or
  111. ((rd^.deftype=arraydef) and
  112. not((cs_mmx in aktlocalswitches) and
  113. is_mmx_able_array(rd)) and
  114. (not (ld^.deftype in [orddef])) and
  115. (not is_chararray(rd))
  116. ) or
  117. { <> and = are defined for classes }
  118. ((rd^.deftype=objectdef) and
  119. (not(pobjectdef(rd)^.is_class) or
  120. not(p^.treetype in [equaln,unequaln])
  121. )
  122. ) then
  123. begin
  124. {!!!!!!!!! handle paras }
  125. case p^.treetype of
  126. { the nil as symtable signs firstcalln that this is
  127. an overloaded operator }
  128. addn:
  129. optoken:=_PLUS;
  130. subn:
  131. optoken:=_MINUS;
  132. muln:
  133. optoken:=_STAR;
  134. starstarn:
  135. optoken:=_STARSTAR;
  136. slashn:
  137. optoken:=_SLASH;
  138. ltn:
  139. optoken:=tokens._lt;
  140. gtn:
  141. optoken:=tokens._gt;
  142. lten:
  143. optoken:=_lte;
  144. gten:
  145. optoken:=_gte;
  146. equaln,unequaln :
  147. optoken:=_EQUAL;
  148. symdifn :
  149. optoken:=_SYMDIF;
  150. modn :
  151. optoken:=_OP_MOD;
  152. orn :
  153. optoken:=_OP_OR;
  154. xorn :
  155. optoken:=_OP_XOR;
  156. andn :
  157. optoken:=_OP_AND;
  158. divn :
  159. optoken:=_OP_DIV;
  160. shln :
  161. optoken:=_OP_SHL;
  162. shrn :
  163. optoken:=_OP_SHR;
  164. else goto no_overload;
  165. end;
  166. t:=gencallnode(overloaded_operators[optoken],nil);
  167. { we have to convert p^.left and p^.right into
  168. callparanodes }
  169. if t^.symtableprocentry=nil then
  170. begin
  171. CGMessage(parser_e_operator_not_overloaded);
  172. putnode(t);
  173. end
  174. else
  175. begin
  176. inc(t^.symtableprocentry^.refs);
  177. t^.left:=gencallparanode(p^.left,nil);
  178. t^.left:=gencallparanode(p^.right,t^.left);
  179. if p^.treetype=unequaln then
  180. t:=gensinglenode(notn,t);
  181. firstpass(t);
  182. putnode(p);
  183. p:=t;
  184. exit;
  185. end;
  186. end;
  187. no_overload:
  188. { compact consts }
  189. { convert int consts to real consts, if the }
  190. { other operand is a real const }
  191. if (rt=realconstn) and is_constintnode(p^.left) then
  192. begin
  193. t:=genrealconstnode(p^.left^.value,p^.right^.resulttype);
  194. disposetree(p^.left);
  195. p^.left:=t;
  196. lt:=realconstn;
  197. end;
  198. if (lt=realconstn) and is_constintnode(p^.right) then
  199. begin
  200. t:=genrealconstnode(p^.right^.value,p^.left^.resulttype);
  201. disposetree(p^.right);
  202. p^.right:=t;
  203. rt:=realconstn;
  204. end;
  205. { both are int constants, also allow operations on two equal enums
  206. in fpc mode (Needed for conversion of C code) }
  207. if ((lt=ordconstn) and (rt=ordconstn)) and
  208. ((is_constintnode(p^.left) and is_constintnode(p^.right)) or
  209. (is_constboolnode(p^.left) and is_constboolnode(p^.right) and
  210. (p^.treetype in [ltn,lten,gtn,gten,equaln,unequaln,andn,xorn,orn]))) then
  211. begin
  212. { return a boolean for boolean operations (and,xor,or) }
  213. if is_constboolnode(p^.left) then
  214. resdef:=booldef
  215. else
  216. resdef:=s32bitdef;
  217. lv:=p^.left^.value;
  218. rv:=p^.right^.value;
  219. case p^.treetype of
  220. addn : t:=genordinalconstnode(lv+rv,resdef);
  221. subn : t:=genordinalconstnode(lv-rv,resdef);
  222. muln : t:=genordinalconstnode(lv*rv,resdef);
  223. xorn : t:=genordinalconstnode(lv xor rv,resdef);
  224. orn : t:=genordinalconstnode(lv or rv,resdef);
  225. andn : t:=genordinalconstnode(lv and rv,resdef);
  226. ltn : t:=genordinalconstnode(ord(lv<rv),booldef);
  227. lten : t:=genordinalconstnode(ord(lv<=rv),booldef);
  228. gtn : t:=genordinalconstnode(ord(lv>rv),booldef);
  229. gten : t:=genordinalconstnode(ord(lv>=rv),booldef);
  230. equaln : t:=genordinalconstnode(ord(lv=rv),booldef);
  231. unequaln : t:=genordinalconstnode(ord(lv<>rv),booldef);
  232. slashn : begin
  233. { int/int becomes a real }
  234. if int(rv)=0 then
  235. begin
  236. Message(parser_e_invalid_float_operation);
  237. t:=genrealconstnode(0,bestrealdef^);
  238. end
  239. else
  240. t:=genrealconstnode(int(lv)/int(rv),bestrealdef^);
  241. firstpass(t);
  242. end;
  243. else
  244. CGMessage(type_e_mismatch);
  245. end;
  246. disposetree(p);
  247. firstpass(t);
  248. p:=t;
  249. exit;
  250. end;
  251. { both real constants ? }
  252. if (lt=realconstn) and (rt=realconstn) then
  253. begin
  254. lvd:=p^.left^.value_real;
  255. rvd:=p^.right^.value_real;
  256. case p^.treetype of
  257. addn : t:=genrealconstnode(lvd+rvd,bestrealdef^);
  258. subn : t:=genrealconstnode(lvd-rvd,bestrealdef^);
  259. muln : t:=genrealconstnode(lvd*rvd,bestrealdef^);
  260. starstarn,
  261. caretn : begin
  262. if lvd<0 then
  263. begin
  264. Message(parser_e_invalid_float_operation);
  265. t:=genrealconstnode(0,bestrealdef^);
  266. end
  267. else if lvd=0 then
  268. t:=genrealconstnode(1.0,bestrealdef^)
  269. else
  270. t:=genrealconstnode(exp(ln(lvd)*rvd),bestrealdef^);
  271. end;
  272. slashn :
  273. begin
  274. if rvd=0 then
  275. begin
  276. Message(parser_e_invalid_float_operation);
  277. t:=genrealconstnode(0,bestrealdef^);
  278. end
  279. else
  280. t:=genrealconstnode(lvd/rvd,bestrealdef^);
  281. end;
  282. ltn : t:=genordinalconstnode(ord(lvd<rvd),booldef);
  283. lten : t:=genordinalconstnode(ord(lvd<=rvd),booldef);
  284. gtn : t:=genordinalconstnode(ord(lvd>rvd),booldef);
  285. gten : t:=genordinalconstnode(ord(lvd>=rvd),booldef);
  286. equaln : t:=genordinalconstnode(ord(lvd=rvd),booldef);
  287. unequaln : t:=genordinalconstnode(ord(lvd<>rvd),booldef);
  288. else
  289. CGMessage(type_e_mismatch);
  290. end;
  291. disposetree(p);
  292. p:=t;
  293. firstpass(p);
  294. exit;
  295. end;
  296. { concating strings ? }
  297. concatstrings:=false;
  298. s1:=nil;
  299. s2:=nil;
  300. if (lt=ordconstn) and (rt=ordconstn) and
  301. is_char(ld) and is_char(rd) then
  302. begin
  303. s1:=strpnew(char(byte(p^.left^.value)));
  304. s2:=strpnew(char(byte(p^.right^.value)));
  305. l1:=1;
  306. l2:=1;
  307. concatstrings:=true;
  308. end
  309. else
  310. if (lt=stringconstn) and (rt=ordconstn) and is_char(rd) then
  311. begin
  312. s1:=getpcharcopy(p^.left);
  313. l1:=p^.left^.length;
  314. s2:=strpnew(char(byte(p^.right^.value)));
  315. l2:=1;
  316. concatstrings:=true;
  317. end
  318. else
  319. if (lt=ordconstn) and (rt=stringconstn) and is_char(ld) then
  320. begin
  321. s1:=strpnew(char(byte(p^.left^.value)));
  322. l1:=1;
  323. s2:=getpcharcopy(p^.right);
  324. l2:=p^.right^.length;
  325. concatstrings:=true;
  326. end
  327. else if (lt=stringconstn) and (rt=stringconstn) then
  328. begin
  329. s1:=getpcharcopy(p^.left);
  330. l1:=p^.left^.length;
  331. s2:=getpcharcopy(p^.right);
  332. l2:=p^.right^.length;
  333. concatstrings:=true;
  334. end;
  335. { I will need to translate all this to ansistrings !!! }
  336. if concatstrings then
  337. begin
  338. case p^.treetype of
  339. addn :
  340. t:=genpcharconstnode(concatansistrings(s1,s2,l1,l2),l1+l2);
  341. ltn :
  342. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)<0),booldef);
  343. lten :
  344. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)<=0),booldef);
  345. gtn :
  346. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)>0),booldef);
  347. gten :
  348. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)>=0),booldef);
  349. equaln :
  350. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)=0),booldef);
  351. unequaln :
  352. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)<>0),booldef);
  353. end;
  354. ansistringdispose(s1,l1);
  355. ansistringdispose(s2,l2);
  356. disposetree(p);
  357. firstpass(t);
  358. p:=t;
  359. exit;
  360. end;
  361. { if both are orddefs then check sub types }
  362. if (ld^.deftype=orddef) and (rd^.deftype=orddef) then
  363. begin
  364. { 2 booleans ? }
  365. if is_boolean(ld) and is_boolean(rd) then
  366. begin
  367. case p^.treetype of
  368. andn,
  369. orn:
  370. begin
  371. calcregisters(p,0,0,0);
  372. make_bool_equal_size(p);
  373. p^.location.loc:=LOC_JUMP;
  374. end;
  375. xorn,ltn,lten,gtn,gten :
  376. begin
  377. make_bool_equal_size(p);
  378. if (p^.left^.location.loc in [LOC_JUMP,LOC_FLAGS]) and
  379. (p^.left^.location.loc in [LOC_JUMP,LOC_FLAGS]) then
  380. calcregisters(p,2,0,0)
  381. else
  382. calcregisters(p,1,0,0);
  383. end;
  384. unequaln,
  385. equaln:
  386. begin
  387. make_bool_equal_size(p);
  388. { Remove any compares with constants }
  389. if (p^.left^.treetype=ordconstn) then
  390. begin
  391. hp:=p^.right;
  392. b:=(p^.left^.value<>0);
  393. ot:=p^.treetype;
  394. disposetree(p^.left);
  395. putnode(p);
  396. p:=hp;
  397. if (not(b) and (ot=equaln)) or
  398. (b and (ot=unequaln)) then
  399. begin
  400. p:=gensinglenode(notn,p);
  401. firstpass(p);
  402. end;
  403. exit;
  404. end;
  405. if (p^.right^.treetype=ordconstn) then
  406. begin
  407. hp:=p^.left;
  408. b:=(p^.right^.value<>0);
  409. ot:=p^.treetype;
  410. disposetree(p^.right);
  411. putnode(p);
  412. p:=hp;
  413. if (not(b) and (ot=equaln)) or
  414. (b and (ot=unequaln)) then
  415. begin
  416. p:=gensinglenode(notn,p);
  417. firstpass(p);
  418. end;
  419. exit;
  420. end;
  421. if (p^.left^.location.loc in [LOC_JUMP,LOC_FLAGS]) and
  422. (p^.left^.location.loc in [LOC_JUMP,LOC_FLAGS]) then
  423. calcregisters(p,2,0,0)
  424. else
  425. calcregisters(p,1,0,0);
  426. end;
  427. else
  428. CGMessage(type_e_mismatch);
  429. end;
  430. { these one can't be in flags! }
  431. if p^.treetype in [xorn,unequaln,equaln] then
  432. begin
  433. if p^.left^.location.loc=LOC_FLAGS then
  434. begin
  435. p^.left:=gentypeconvnode(p^.left,porddef(p^.left^.resulttype));
  436. p^.left^.convtyp:=tc_bool_2_int;
  437. p^.left^.explizit:=true;
  438. firstpass(p^.left);
  439. end;
  440. if p^.right^.location.loc=LOC_FLAGS then
  441. begin
  442. p^.right:=gentypeconvnode(p^.right,porddef(p^.right^.resulttype));
  443. p^.right^.convtyp:=tc_bool_2_int;
  444. p^.right^.explizit:=true;
  445. firstpass(p^.right);
  446. end;
  447. { readjust registers }
  448. calcregisters(p,1,0,0);
  449. end;
  450. convdone:=true;
  451. end
  452. else
  453. { Both are chars? only convert to shortstrings for addn }
  454. if is_char(rd) and is_char(ld) then
  455. begin
  456. if p^.treetype=addn then
  457. begin
  458. p^.left:=gentypeconvnode(p^.left,cshortstringdef);
  459. p^.right:=gentypeconvnode(p^.right,cshortstringdef);
  460. firstpass(p^.left);
  461. firstpass(p^.right);
  462. { here we call STRCOPY }
  463. procinfo^.flags:=procinfo^.flags or pi_do_call;
  464. calcregisters(p,0,0,0);
  465. p^.location.loc:=LOC_MEM;
  466. end
  467. else
  468. calcregisters(p,1,0,0);
  469. convdone:=true;
  470. end
  471. { is there a 64 bit type ? }
  472. else if (porddef(rd)^.typ=s64bit) or (porddef(ld)^.typ=s64bit) then
  473. begin
  474. if (porddef(ld)^.typ<>s64bit) then
  475. begin
  476. p^.left:=gentypeconvnode(p^.left,cs64bitdef);
  477. firstpass(p^.left);
  478. end;
  479. if (porddef(rd)^.typ<>s64bit) then
  480. begin
  481. p^.right:=gentypeconvnode(p^.right,cs64bitdef);
  482. firstpass(p^.right);
  483. end;
  484. calcregisters(p,2,0,0);
  485. convdone:=true;
  486. end
  487. else if (porddef(rd)^.typ=u64bit) or (porddef(ld)^.typ=u64bit) then
  488. begin
  489. if (porddef(ld)^.typ<>u64bit) then
  490. begin
  491. p^.left:=gentypeconvnode(p^.left,cu64bitdef);
  492. firstpass(p^.left);
  493. end;
  494. if (porddef(rd)^.typ<>u64bit) then
  495. begin
  496. p^.right:=gentypeconvnode(p^.right,cu64bitdef);
  497. firstpass(p^.right);
  498. end;
  499. calcregisters(p,2,0,0);
  500. convdone:=true;
  501. end
  502. else
  503. { is there a cardinal? }
  504. if (porddef(rd)^.typ=u32bit) or (porddef(ld)^.typ=u32bit) then
  505. begin
  506. { convert constants to u32bit }
  507. if (porddef(ld)^.typ<>u32bit) then
  508. begin
  509. { s32bit will be used for when the other is also s32bit }
  510. if (porddef(rd)^.typ=s32bit) and (lt<>ordconstn) then
  511. p^.left:=gentypeconvnode(p^.left,s32bitdef)
  512. else
  513. p^.left:=gentypeconvnode(p^.left,u32bitdef);
  514. firstpass(p^.left);
  515. end;
  516. if (porddef(rd)^.typ<>u32bit) then
  517. begin
  518. { s32bit will be used for when the other is also s32bit }
  519. if (porddef(ld)^.typ=s32bit) and (rt<>ordconstn) then
  520. p^.right:=gentypeconvnode(p^.right,s32bitdef)
  521. else
  522. p^.right:=gentypeconvnode(p^.right,u32bitdef);
  523. firstpass(p^.right);
  524. end;
  525. calcregisters(p,1,0,0);
  526. { for unsigned mul we need an extra register }
  527. { p^.registers32:=p^.left^.registers32+p^.right^.registers32; }
  528. if p^.treetype=muln then
  529. inc(p^.registers32);
  530. convdone:=true;
  531. end;
  532. end
  533. else
  534. { left side a setdef, must be before string processing,
  535. else array constructor can be seen as array of char (PFV) }
  536. if (ld^.deftype=setdef) {or is_array_constructor(ld)} then
  537. begin
  538. { trying to add a set element? }
  539. if (p^.treetype=addn) and (rd^.deftype<>setdef) then
  540. begin
  541. if (rt=setelementn) then
  542. begin
  543. if not(is_equal(psetdef(ld)^.setof,rd)) then
  544. CGMessage(type_e_set_element_are_not_comp);
  545. end
  546. else
  547. CGMessage(type_e_mismatch)
  548. end
  549. else
  550. begin
  551. if not(p^.treetype in [addn,subn,symdifn,muln,equaln,unequaln
  552. {$IfNDef NoSetInclusion}
  553. ,lten,gten
  554. {$EndIf NoSetInclusion}
  555. ]) then
  556. CGMessage(type_e_set_operation_unknown);
  557. { right def must be a also be set }
  558. if (rd^.deftype<>setdef) or not(is_equal(rd,ld)) then
  559. CGMessage(type_e_set_element_are_not_comp);
  560. end;
  561. { ranges require normsets }
  562. if (psetdef(ld)^.settype=smallset) and
  563. (rt=setelementn) and
  564. assigned(p^.right^.right) then
  565. begin
  566. { generate a temporary normset def }
  567. tempdef:=new(psetdef,init(psetdef(ld)^.setof,255));
  568. p^.left:=gentypeconvnode(p^.left,tempdef);
  569. firstpass(p^.left);
  570. dispose(tempdef,done);
  571. ld:=p^.left^.resulttype;
  572. end;
  573. { if the destination is not a smallset then insert a typeconv
  574. which loads a smallset into a normal set }
  575. if (psetdef(ld)^.settype<>smallset) and
  576. (psetdef(rd)^.settype=smallset) then
  577. begin
  578. if (p^.right^.treetype=setconstn) then
  579. begin
  580. t:=gensetconstnode(p^.right^.value_set,psetdef(p^.left^.resulttype));
  581. t^.left:=p^.right^.left;
  582. putnode(p^.right);
  583. p^.right:=t;
  584. end
  585. else
  586. p^.right:=gentypeconvnode(p^.right,psetdef(p^.left^.resulttype));
  587. firstpass(p^.right);
  588. end;
  589. { do constant evaluation }
  590. if (p^.right^.treetype=setconstn) and
  591. not assigned(p^.right^.left) and
  592. (p^.left^.treetype=setconstn) and
  593. not assigned(p^.left^.left) then
  594. begin
  595. new(resultset);
  596. case p^.treetype of
  597. addn : begin
  598. for i:=0 to 31 do
  599. resultset^[i]:=
  600. p^.right^.value_set^[i] or p^.left^.value_set^[i];
  601. t:=gensetconstnode(resultset,psetdef(ld));
  602. end;
  603. muln : begin
  604. for i:=0 to 31 do
  605. resultset^[i]:=
  606. p^.right^.value_set^[i] and p^.left^.value_set^[i];
  607. t:=gensetconstnode(resultset,psetdef(ld));
  608. end;
  609. subn : begin
  610. for i:=0 to 31 do
  611. resultset^[i]:=
  612. p^.left^.value_set^[i] and not(p^.right^.value_set^[i]);
  613. t:=gensetconstnode(resultset,psetdef(ld));
  614. end;
  615. symdifn : begin
  616. for i:=0 to 31 do
  617. resultset^[i]:=
  618. p^.left^.value_set^[i] xor p^.right^.value_set^[i];
  619. t:=gensetconstnode(resultset,psetdef(ld));
  620. end;
  621. unequaln : begin
  622. b:=true;
  623. for i:=0 to 31 do
  624. if p^.right^.value_set^[i]=p^.left^.value_set^[i] then
  625. begin
  626. b:=false;
  627. break;
  628. end;
  629. t:=genordinalconstnode(ord(b),booldef);
  630. end;
  631. equaln : begin
  632. b:=true;
  633. for i:=0 to 31 do
  634. if p^.right^.value_set^[i]<>p^.left^.value_set^[i] then
  635. begin
  636. b:=false;
  637. break;
  638. end;
  639. t:=genordinalconstnode(ord(b),booldef);
  640. end;
  641. {$IfNDef NoSetInclusion}
  642. lten : Begin
  643. b := true;
  644. For i := 0 to 31 Do
  645. If (p^.right^.value_set^[i] And p^.left^.value_set^[i]) <>
  646. p^.left^.value_set^[i] Then
  647. Begin
  648. b := false;
  649. Break
  650. End;
  651. t := genordinalconstnode(ord(b),booldef);
  652. End;
  653. gten : Begin
  654. b := true;
  655. For i := 0 to 31 Do
  656. If (p^.left^.value_set^[i] And p^.right^.value_set^[i]) <>
  657. p^.right^.value_set^[i] Then
  658. Begin
  659. b := false;
  660. Break
  661. End;
  662. t := genordinalconstnode(ord(b),booldef);
  663. End;
  664. {$EndIf NoSetInclusion}
  665. end;
  666. dispose(resultset);
  667. disposetree(p);
  668. p:=t;
  669. firstpass(p);
  670. exit;
  671. end
  672. else
  673. if psetdef(ld)^.settype=smallset then
  674. begin
  675. calcregisters(p,1,0,0);
  676. { are we adding set elements ? }
  677. if p^.right^.treetype=setelementn then
  678. begin
  679. { we need at least two registers PM }
  680. if p^.registers32<2 then
  681. p^.registers32:=2;
  682. end;
  683. p^.location.loc:=LOC_REGISTER;
  684. end
  685. else
  686. begin
  687. calcregisters(p,0,0,0);
  688. { here we call SET... }
  689. procinfo^.flags:=procinfo^.flags or pi_do_call;
  690. p^.location.loc:=LOC_MEM;
  691. end;
  692. convdone:=true;
  693. end
  694. else
  695. { is one of the operands a string?,
  696. chararrays are also handled as strings (after conversion) }
  697. if (rd^.deftype=stringdef) or (ld^.deftype=stringdef) or
  698. (is_chararray(rd) and is_chararray(ld)) then
  699. begin
  700. if is_widestring(rd) or is_widestring(ld) then
  701. begin
  702. if not(is_widestring(rd)) then
  703. p^.right:=gentypeconvnode(p^.right,cwidestringdef);
  704. if not(is_widestring(ld)) then
  705. p^.left:=gentypeconvnode(p^.left,cwidestringdef);
  706. p^.resulttype:=cwidestringdef;
  707. { this is only for add, the comparisaion is handled later }
  708. p^.location.loc:=LOC_REGISTER;
  709. end
  710. else if is_ansistring(rd) or is_ansistring(ld) then
  711. begin
  712. if not(is_ansistring(rd)) then
  713. p^.right:=gentypeconvnode(p^.right,cansistringdef);
  714. if not(is_ansistring(ld)) then
  715. p^.left:=gentypeconvnode(p^.left,cansistringdef);
  716. p^.resulttype:=cansistringdef;
  717. { this is only for add, the comparisaion is handled later }
  718. p^.location.loc:=LOC_REGISTER;
  719. end
  720. else if is_longstring(rd) or is_longstring(ld) then
  721. begin
  722. if not(is_longstring(rd)) then
  723. p^.right:=gentypeconvnode(p^.right,clongstringdef);
  724. if not(is_longstring(ld)) then
  725. p^.left:=gentypeconvnode(p^.left,clongstringdef);
  726. p^.resulttype:=clongstringdef;
  727. { this is only for add, the comparisaion is handled later }
  728. p^.location.loc:=LOC_MEM;
  729. end
  730. else
  731. begin
  732. if not(is_shortstring(rd)) then
  733. p^.right:=gentypeconvnode(p^.right,cshortstringdef);
  734. if not(is_shortstring(ld)) then
  735. p^.left:=gentypeconvnode(p^.left,cshortstringdef);
  736. p^.resulttype:=cshortstringdef;
  737. { this is only for add, the comparisaion is handled later }
  738. p^.location.loc:=LOC_MEM;
  739. end;
  740. { only if there is a type cast we need to do again }
  741. { the first pass }
  742. if p^.left^.treetype=typeconvn then
  743. firstpass(p^.left);
  744. if p^.right^.treetype=typeconvn then
  745. firstpass(p^.right);
  746. { here we call STRCONCAT or STRCMP or STRCOPY }
  747. procinfo^.flags:=procinfo^.flags or pi_do_call;
  748. if p^.location.loc=LOC_MEM then
  749. calcregisters(p,0,0,0)
  750. else
  751. calcregisters(p,1,0,0);
  752. convdone:=true;
  753. end
  754. else
  755. { is one a real float ? }
  756. if (rd^.deftype=floatdef) or (ld^.deftype=floatdef) then
  757. begin
  758. { if one is a fixed, then convert to f32bit }
  759. if ((rd^.deftype=floatdef) and (pfloatdef(rd)^.typ=f32bit)) or
  760. ((ld^.deftype=floatdef) and (pfloatdef(ld)^.typ=f32bit)) then
  761. begin
  762. if not is_integer(rd) or (p^.treetype<>muln) then
  763. p^.right:=gentypeconvnode(p^.right,s32fixeddef);
  764. if not is_integer(ld) or (p^.treetype<>muln) then
  765. p^.left:=gentypeconvnode(p^.left,s32fixeddef);
  766. firstpass(p^.left);
  767. firstpass(p^.right);
  768. calcregisters(p,1,0,0);
  769. p^.location.loc:=LOC_REGISTER;
  770. end
  771. else
  772. { convert both to bestreal }
  773. begin
  774. p^.right:=gentypeconvnode(p^.right,bestrealdef^);
  775. p^.left:=gentypeconvnode(p^.left,bestrealdef^);
  776. firstpass(p^.left);
  777. firstpass(p^.right);
  778. calcregisters(p,1,1,0);
  779. p^.location.loc:=LOC_FPU;
  780. end;
  781. convdone:=true;
  782. end
  783. else
  784. { pointer comperation and subtraction }
  785. if (rd^.deftype=pointerdef) and (ld^.deftype=pointerdef) then
  786. begin
  787. p^.location.loc:=LOC_REGISTER;
  788. { p^.right:=gentypeconvnode(p^.right,ld); }
  789. { firstpass(p^.right); }
  790. calcregisters(p,1,0,0);
  791. case p^.treetype of
  792. equaln,unequaln :
  793. begin
  794. if is_equal(p^.right^.resulttype,voidpointerdef) then
  795. begin
  796. p^.right:=gentypeconvnode(p^.right,ld);
  797. firstpass(p^.right);
  798. end
  799. else if is_equal(p^.left^.resulttype,voidpointerdef) then
  800. begin
  801. p^.left:=gentypeconvnode(p^.left,rd);
  802. firstpass(p^.left);
  803. end
  804. else if not(is_equal(ld,rd)) then
  805. CGMessage(type_e_mismatch);
  806. end;
  807. ltn,lten,gtn,gten:
  808. begin
  809. if is_equal(p^.right^.resulttype,voidpointerdef) then
  810. begin
  811. p^.right:=gentypeconvnode(p^.right,ld);
  812. firstpass(p^.right);
  813. end
  814. else if is_equal(p^.left^.resulttype,voidpointerdef) then
  815. begin
  816. p^.left:=gentypeconvnode(p^.left,rd);
  817. firstpass(p^.left);
  818. end
  819. else if not(is_equal(ld,rd)) then
  820. CGMessage(type_e_mismatch);
  821. if not(cs_extsyntax in aktmoduleswitches) then
  822. CGMessage(type_e_mismatch);
  823. end;
  824. subn:
  825. begin
  826. if not(is_equal(ld,rd)) then
  827. CGMessage(type_e_mismatch);
  828. if not(cs_extsyntax in aktmoduleswitches) then
  829. CGMessage(type_e_mismatch);
  830. p^.resulttype:=s32bitdef;
  831. exit;
  832. end;
  833. else CGMessage(type_e_mismatch);
  834. end;
  835. convdone:=true;
  836. end
  837. else
  838. if (rd^.deftype=objectdef) and (ld^.deftype=objectdef) and
  839. pobjectdef(rd)^.is_class and pobjectdef(ld)^.is_class then
  840. begin
  841. p^.location.loc:=LOC_REGISTER;
  842. if pobjectdef(rd)^.is_related(pobjectdef(ld)) then
  843. p^.right:=gentypeconvnode(p^.right,ld)
  844. else
  845. p^.left:=gentypeconvnode(p^.left,rd);
  846. firstpass(p^.right);
  847. firstpass(p^.left);
  848. calcregisters(p,1,0,0);
  849. case p^.treetype of
  850. equaln,unequaln : ;
  851. else CGMessage(type_e_mismatch);
  852. end;
  853. convdone:=true;
  854. end
  855. else
  856. if (rd^.deftype=classrefdef) and (ld^.deftype=classrefdef) then
  857. begin
  858. p^.location.loc:=LOC_REGISTER;
  859. if pobjectdef(pclassrefdef(rd)^.definition)^.is_related(pobjectdef(
  860. pclassrefdef(ld)^.definition)) then
  861. p^.right:=gentypeconvnode(p^.right,ld)
  862. else
  863. p^.left:=gentypeconvnode(p^.left,rd);
  864. firstpass(p^.right);
  865. firstpass(p^.left);
  866. calcregisters(p,1,0,0);
  867. case p^.treetype of
  868. equaln,unequaln : ;
  869. else CGMessage(type_e_mismatch);
  870. end;
  871. convdone:=true;
  872. end
  873. else
  874. { allows comperasion with nil pointer }
  875. if (rd^.deftype=objectdef) and
  876. pobjectdef(rd)^.is_class then
  877. begin
  878. p^.location.loc:=LOC_REGISTER;
  879. p^.left:=gentypeconvnode(p^.left,rd);
  880. firstpass(p^.left);
  881. calcregisters(p,1,0,0);
  882. case p^.treetype of
  883. equaln,unequaln : ;
  884. else CGMessage(type_e_mismatch);
  885. end;
  886. convdone:=true;
  887. end
  888. else
  889. if (ld^.deftype=objectdef) and
  890. pobjectdef(ld)^.is_class then
  891. begin
  892. p^.location.loc:=LOC_REGISTER;
  893. p^.right:=gentypeconvnode(p^.right,ld);
  894. firstpass(p^.right);
  895. calcregisters(p,1,0,0);
  896. case p^.treetype of
  897. equaln,unequaln : ;
  898. else CGMessage(type_e_mismatch);
  899. end;
  900. convdone:=true;
  901. end
  902. else
  903. if (rd^.deftype=classrefdef) then
  904. begin
  905. p^.left:=gentypeconvnode(p^.left,rd);
  906. firstpass(p^.left);
  907. calcregisters(p,1,0,0);
  908. case p^.treetype of
  909. equaln,unequaln : ;
  910. else CGMessage(type_e_mismatch);
  911. end;
  912. convdone:=true;
  913. end
  914. else
  915. if (ld^.deftype=classrefdef) then
  916. begin
  917. p^.right:=gentypeconvnode(p^.right,ld);
  918. firstpass(p^.right);
  919. calcregisters(p,1,0,0);
  920. case p^.treetype of
  921. equaln,unequaln : ;
  922. else
  923. CGMessage(type_e_mismatch);
  924. end;
  925. convdone:=true;
  926. end
  927. else
  928. { support procvar=nil,procvar<>nil }
  929. if ((ld^.deftype=procvardef) and (rt=niln)) or
  930. ((rd^.deftype=procvardef) and (lt=niln)) then
  931. begin
  932. calcregisters(p,1,0,0);
  933. p^.location.loc:=LOC_REGISTER;
  934. case p^.treetype of
  935. equaln,unequaln : ;
  936. else
  937. CGMessage(type_e_mismatch);
  938. end;
  939. convdone:=true;
  940. end
  941. else
  942. if (rd^.deftype=pointerdef) or
  943. is_zero_based_array(rd) then
  944. begin
  945. if is_zero_based_array(rd) then
  946. begin
  947. p^.resulttype:=new(ppointerdef,init(parraydef(rd)^.definition));
  948. p^.right:=gentypeconvnode(p^.right,p^.resulttype);
  949. firstpass(p^.right);
  950. end;
  951. p^.location.loc:=LOC_REGISTER;
  952. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  953. firstpass(p^.left);
  954. calcregisters(p,1,0,0);
  955. if p^.treetype=addn then
  956. begin
  957. if not(cs_extsyntax in aktmoduleswitches) or
  958. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  959. CGMessage(type_e_mismatch);
  960. { Dirty hack, to support multiple firstpasses (PFV) }
  961. if (p^.resulttype=nil) and
  962. (rd^.deftype=pointerdef) and
  963. (ppointerdef(rd)^.definition^.size>1) then
  964. begin
  965. p^.left:=gennode(muln,p^.left,genordinalconstnode(ppointerdef(rd)^.definition^.size,s32bitdef));
  966. firstpass(p^.left);
  967. end;
  968. end
  969. else
  970. CGMessage(type_e_mismatch);
  971. convdone:=true;
  972. end
  973. else
  974. if (ld^.deftype=pointerdef) or
  975. is_zero_based_array(ld) then
  976. begin
  977. if is_zero_based_array(ld) then
  978. begin
  979. p^.resulttype:=new(ppointerdef,init(parraydef(ld)^.definition));
  980. p^.left:=gentypeconvnode(p^.left,p^.resulttype);
  981. firstpass(p^.left);
  982. end;
  983. p^.location.loc:=LOC_REGISTER;
  984. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  985. firstpass(p^.right);
  986. calcregisters(p,1,0,0);
  987. case p^.treetype of
  988. addn,subn : begin
  989. if not(cs_extsyntax in aktmoduleswitches) or
  990. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  991. CGMessage(type_e_mismatch);
  992. { Dirty hack, to support multiple firstpasses (PFV) }
  993. if (p^.resulttype=nil) and
  994. (ld^.deftype=pointerdef) and
  995. (ppointerdef(ld)^.definition^.size>1) then
  996. begin
  997. p^.right:=gennode(muln,p^.right,
  998. genordinalconstnode(ppointerdef(ld)^.definition^.size,s32bitdef));
  999. firstpass(p^.right);
  1000. end;
  1001. end;
  1002. else
  1003. CGMessage(type_e_mismatch);
  1004. end;
  1005. convdone:=true;
  1006. end
  1007. else
  1008. if (rd^.deftype=procvardef) and (ld^.deftype=procvardef) and is_equal(rd,ld) then
  1009. begin
  1010. calcregisters(p,1,0,0);
  1011. p^.location.loc:=LOC_REGISTER;
  1012. case p^.treetype of
  1013. equaln,unequaln : ;
  1014. else
  1015. CGMessage(type_e_mismatch);
  1016. end;
  1017. convdone:=true;
  1018. end
  1019. else
  1020. {$ifdef SUPPORT_MMX}
  1021. if (cs_mmx in aktlocalswitches) and is_mmx_able_array(ld) and
  1022. is_mmx_able_array(rd) and is_equal(ld,rd) then
  1023. begin
  1024. firstpass(p^.right);
  1025. firstpass(p^.left);
  1026. case p^.treetype of
  1027. addn,subn,xorn,orn,andn:
  1028. ;
  1029. { mul is a little bit restricted }
  1030. muln:
  1031. if not(mmx_type(p^.left^.resulttype) in
  1032. [mmxu16bit,mmxs16bit,mmxfixed16]) then
  1033. CGMessage(type_e_mismatch);
  1034. else
  1035. CGMessage(type_e_mismatch);
  1036. end;
  1037. p^.location.loc:=LOC_MMXREGISTER;
  1038. calcregisters(p,0,0,1);
  1039. convdone:=true;
  1040. end
  1041. else
  1042. {$endif SUPPORT_MMX}
  1043. if (ld^.deftype=enumdef) and (rd^.deftype=enumdef) and (is_equal(ld,rd)) then
  1044. begin
  1045. calcregisters(p,1,0,0);
  1046. case p^.treetype of
  1047. equaln,unequaln,
  1048. ltn,lten,gtn,gten : ;
  1049. else CGMessage(type_e_mismatch);
  1050. end;
  1051. convdone:=true;
  1052. end;
  1053. { the general solution is to convert to 32 bit int }
  1054. if not convdone then
  1055. begin
  1056. { but an int/int gives real/real! }
  1057. if p^.treetype=slashn then
  1058. begin
  1059. CGMessage(type_h_use_div_for_int);
  1060. p^.right:=gentypeconvnode(p^.right,bestrealdef^);
  1061. p^.left:=gentypeconvnode(p^.left,bestrealdef^);
  1062. firstpass(p^.left);
  1063. firstpass(p^.right);
  1064. { maybe we need an integer register to save }
  1065. { a reference }
  1066. if ((p^.left^.location.loc<>LOC_FPU) or
  1067. (p^.right^.location.loc<>LOC_FPU)) and
  1068. (p^.left^.registers32=p^.right^.registers32) then
  1069. calcregisters(p,1,1,0)
  1070. else
  1071. calcregisters(p,0,1,0);
  1072. p^.location.loc:=LOC_FPU;
  1073. end
  1074. else
  1075. begin
  1076. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  1077. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  1078. firstpass(p^.left);
  1079. firstpass(p^.right);
  1080. calcregisters(p,1,0,0);
  1081. p^.location.loc:=LOC_REGISTER;
  1082. end;
  1083. end;
  1084. if codegenerror then
  1085. exit;
  1086. { determines result type for comparions }
  1087. { here the is a problem with multiple passes }
  1088. { example length(s)+1 gets internal 'longint' type first }
  1089. { if it is a arg it is converted to 'LONGINT' }
  1090. { but a second first pass will reset this to 'longint' }
  1091. case p^.treetype of
  1092. ltn,lten,gtn,gten,equaln,unequaln:
  1093. begin
  1094. if (not assigned(p^.resulttype)) or
  1095. (p^.resulttype^.deftype=stringdef) then
  1096. p^.resulttype:=booldef;
  1097. if is_64bitint(p^.left^.resulttype) then
  1098. p^.location.loc:=LOC_JUMP
  1099. else
  1100. p^.location.loc:=LOC_FLAGS;
  1101. end;
  1102. xorn:
  1103. begin
  1104. if not assigned(p^.resulttype) then
  1105. p^.resulttype:=p^.left^.resulttype;
  1106. p^.location.loc:=LOC_REGISTER;
  1107. end;
  1108. addn:
  1109. begin
  1110. if not assigned(p^.resulttype) then
  1111. begin
  1112. { for strings, return is always a 255 char string }
  1113. if is_shortstring(p^.left^.resulttype) then
  1114. p^.resulttype:=cshortstringdef
  1115. else
  1116. p^.resulttype:=p^.left^.resulttype;
  1117. end;
  1118. end;
  1119. else
  1120. p^.resulttype:=p^.left^.resulttype;
  1121. end;
  1122. end;
  1123. end.
  1124. {
  1125. $Log$
  1126. Revision 1.56 1999-11-18 15:34:48 pierre
  1127. * Notes/Hints for local syms changed to
  1128. Set_varstate function
  1129. Revision 1.55 1999/11/17 17:05:06 pierre
  1130. * Notes/hints changes
  1131. Revision 1.54 1999/11/16 23:45:28 pierre
  1132. * global var token was changed by overload code (form bug 707)
  1133. Revision 1.53 1999/11/15 21:53:42 peter
  1134. * fixed constant eval for bool xor/or/and bool
  1135. Revision 1.52 1999/11/15 17:53:00 pierre
  1136. + one field added for ttoken record for operator
  1137. linking the id to the corresponding operator token that
  1138. can now now all be overloaded
  1139. * overloaded operators are resetted to nil in InitSymtable
  1140. (bug when trying to compile a uint that overloads operators twice)
  1141. Revision 1.51 1999/11/06 14:34:29 peter
  1142. * truncated log to 20 revs
  1143. Revision 1.50 1999/09/27 23:45:00 peter
  1144. * procinfo is now a pointer
  1145. * support for result setting in sub procedure
  1146. Revision 1.49 1999/09/16 13:39:14 peter
  1147. * arrayconstructor 2 set conversion is now called always in the
  1148. beginning of firstadd
  1149. Revision 1.48 1999/09/15 20:35:45 florian
  1150. * small fix to operator overloading when in MMX mode
  1151. + the compiler uses now fldz and fld1 if possible
  1152. + some fixes to floating point registers
  1153. + some math. functions (arctan, ln, sin, cos, sqrt, sqr, pi) are now inlined
  1154. * .... ???
  1155. Revision 1.47 1999/09/13 16:28:05 peter
  1156. * typo in previous commit open_array -> chararray :(
  1157. Revision 1.46 1999/09/10 15:40:46 peter
  1158. * fixed array check for operators, becuase array can also be a set
  1159. Revision 1.45 1999/09/08 16:05:29 peter
  1160. * pointer add/sub is now as expected and the same results as inc/dec
  1161. Revision 1.44 1999/09/07 07:52:19 peter
  1162. * > < >= <= support for boolean
  1163. * boolean constants are now calculated like integer constants
  1164. Revision 1.43 1999/08/23 23:44:05 pierre
  1165. * setelementn registers32 corrected
  1166. Revision 1.42 1999/08/07 11:29:27 peter
  1167. * better fix for muln register allocation
  1168. Revision 1.41 1999/08/05 21:58:57 peter
  1169. * fixed register count ord*ord
  1170. Revision 1.40 1999/08/04 13:03:13 jonas
  1171. * all tokens now start with an underscore
  1172. * PowerPC compiles!!
  1173. Revision 1.39 1999/08/04 00:23:33 florian
  1174. * renamed i386asm and i386base to cpuasm and cpubase
  1175. Revision 1.38 1999/08/03 22:03:24 peter
  1176. * moved bitmask constants to sets
  1177. * some other type/const renamings
  1178. Revision 1.37 1999/07/16 10:04:37 peter
  1179. * merged
  1180. Revision 1.36 1999/06/17 15:32:48 pierre
  1181. * merged from 0-99-12 branch
  1182. Revision 1.34.2.3 1999/07/16 09:54:58 peter
  1183. * @procvar support in tp7 mode works again
  1184. Revision 1.34.2.2 1999/06/17 15:25:07 pierre
  1185. * for arrays of char operators can not be overloaded
  1186. Revision 1.35 1999/06/17 13:19:57 pierre
  1187. * merged from 0_99_12 branch
  1188. Revision 1.34.2.1 1999/06/17 12:35:23 pierre
  1189. * allow array binary operator overloading if not with orddef
  1190. Revision 1.34 1999/06/02 10:11:52 florian
  1191. * make cycle fixed i.e. compilation with 0.99.10
  1192. * some fixes for qword
  1193. * start of register calling conventions
  1194. }