nadd.pas 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. Type checking and register allocation for add nodes
  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 nadd;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. node;
  23. type
  24. taddnode = class(tbinopnode)
  25. procedure make_bool_equal_size;
  26. function pass_1 : tnode;override;
  27. end;
  28. var
  29. { caddnode is used to create nodes of the add type }
  30. { the virtual constructor allows to assign }
  31. { another class type to caddnode => processor }
  32. { specific node types can be created }
  33. caddnode : class of taddnode;
  34. implementation
  35. uses
  36. globtype,systems,
  37. cutils,verbose,globals,
  38. symconst,symtype,symdef,types,
  39. cpuinfo,
  40. {$ifdef newcg}
  41. cgbase,
  42. {$else newcg}
  43. hcodegen,
  44. {$endif newcg}
  45. htypechk,pass_1,
  46. nmat,ncnv,nld,ncon,nset,nopt,
  47. cpubase;
  48. {*****************************************************************************
  49. TADDNODE
  50. *****************************************************************************}
  51. {$ifdef fpc}
  52. {$maxfpuregisters 0}
  53. {$endif fpc}
  54. procedure taddnode.make_bool_equal_size;
  55. begin
  56. if porddef(left.resulttype)^.typ>porddef(right.resulttype)^.typ then
  57. begin
  58. right:=gentypeconvnode(right,porddef(left.resulttype));
  59. ttypeconvnode(right).convtype:=tc_bool_2_int;
  60. include(right.flags,nf_explizit);
  61. firstpass(right);
  62. end
  63. else
  64. if porddef(left.resulttype)^.typ<porddef(right.resulttype)^.typ then
  65. begin
  66. left:=gentypeconvnode(left,porddef(right.resulttype));
  67. ttypeconvnode(left).convtype:=tc_bool_2_int;
  68. include(left.flags,nf_explizit);
  69. firstpass(left);
  70. end;
  71. end;
  72. function taddnode.pass_1 : tnode;
  73. var
  74. t,hp : tnode;
  75. ot,
  76. lt,rt : tnodetype;
  77. rv,lv : tconstexprint;
  78. rvd,lvd : bestreal;
  79. rd,ld : pdef;
  80. tempdef : pdef;
  81. concatstrings : boolean;
  82. { to evalute const sets }
  83. resultset : pconstset;
  84. i : longint;
  85. b : boolean;
  86. boolres,
  87. convdone : boolean;
  88. s1,s2 : pchar;
  89. l1,l2 : longint;
  90. begin
  91. pass_1:=nil;
  92. { first do the two subtrees }
  93. firstpass(left);
  94. firstpass(right);
  95. if codegenerror then
  96. exit;
  97. { convert array constructors to sets, because there is no other operator
  98. possible for array constructors }
  99. if is_array_constructor(left.resulttype) then
  100. arrayconstructor_to_set(tarrayconstructornode(left));
  101. if is_array_constructor(right.resulttype) then
  102. arrayconstructor_to_set(tarrayconstructornode(right));
  103. { both left and right need to be valid }
  104. set_varstate(left,true);
  105. set_varstate(right,true);
  106. { load easier access variables }
  107. lt:=left.nodetype;
  108. rt:=right.nodetype;
  109. rd:=right.resulttype;
  110. ld:=left.resulttype;
  111. convdone:=false;
  112. hp:=self;
  113. if isbinaryoverloaded(hp) then
  114. begin
  115. pass_1:=hp;
  116. exit;
  117. end;
  118. { compact consts }
  119. { convert int consts to real consts, if the }
  120. { other operand is a real const }
  121. if (rt=realconstn) and is_constintnode(left) then
  122. begin
  123. t:=genrealconstnode(tordconstnode(left).value,right.resulttype);
  124. left.free;
  125. left:=t;
  126. lt:=realconstn;
  127. end;
  128. if (lt=realconstn) and is_constintnode(right) then
  129. begin
  130. t:=genrealconstnode(tordconstnode(right).value,left.resulttype);
  131. right.free;
  132. right:=t;
  133. rt:=realconstn;
  134. end;
  135. { both are int constants }
  136. if (((is_constintnode(left) and is_constintnode(right)) or
  137. (is_constboolnode(left) and is_constboolnode(right) and
  138. (nodetype in [ltn,lten,gtn,gten,equaln,unequaln,andn,xorn,orn])))) or
  139. { support pointer arithmetics on constants (JM) }
  140. ((lt = pointerconstn) and is_constintnode(right) and
  141. (nodetype in [addn,subn])) or
  142. ((lt = pointerconstn) and (rt = pointerconstn) and
  143. (nodetype in [ltn,lten,gtn,gten,equaln,unequaln,subn])) then
  144. begin
  145. { when comparing/substracting pointers, make sure they are }
  146. { of the same type (JM) }
  147. if (lt = pointerconstn) and (rt = pointerconstn) then
  148. if not(cs_extsyntax in aktmoduleswitches) and
  149. not(nodetype in [equaln,unequaln]) then
  150. CGMessage(type_e_mismatch)
  151. else
  152. if (nodetype <> subn) and
  153. is_equal(right.resulttype,voidpointerdef) then
  154. begin
  155. right:=gentypeconvnode(right,ld);
  156. firstpass(right);
  157. rd := right.resulttype;
  158. end
  159. else if (nodetype <> subn) and
  160. is_equal(left.resulttype,voidpointerdef) then
  161. begin
  162. left:=gentypeconvnode(left,rd);
  163. firstpass(left);
  164. ld := left.resulttype;
  165. end
  166. else if not(is_equal(ld,rd)) then
  167. CGMessage(type_e_mismatch);
  168. { xor, and, or are handled different from arithmetic }
  169. { operations regarding the result type }
  170. { return a boolean for boolean operations (and,xor,or) }
  171. boolres:=is_constboolnode(left);
  172. if (left.nodetype = ordconstn) then
  173. lv:=tordconstnode(left).value
  174. else lv := tpointerconstnode(left).value;
  175. if (right.nodetype = ordconstn) then
  176. rv:=tordconstnode(right).value
  177. else rv := tpointerconstnode(right).value;
  178. if (lt = pointerconstn) and
  179. (rt <> pointerconstn) then
  180. rv := rv * ppointerdef(left.resulttype)^.pointertype.def^.size;
  181. case nodetype of
  182. addn : if (lt <> pointerconstn) then
  183. t:=genintconstnode(lv+rv)
  184. else t := genpointerconstnode(lv+rv,left.resulttype);
  185. subn : if (lt <> pointerconstn) or (rt = pointerconstn) then
  186. t:=genintconstnode(lv-rv)
  187. else t := genpointerconstnode(lv-rv,left.resulttype);
  188. muln : t:=genintconstnode(lv*rv);
  189. xorn : if boolres then
  190. t:=genordinalconstnode(lv xor rv,booldef)
  191. else
  192. t:=genintconstnode(lv xor rv);
  193. orn : if boolres then
  194. t:=genordinalconstnode(lv or rv,booldef)
  195. else
  196. t:=genintconstnode(lv or rv);
  197. andn : if boolres then
  198. t:=genordinalconstnode(lv and rv,booldef)
  199. else
  200. t:=genintconstnode(lv and rv);
  201. ltn : t:=genordinalconstnode(ord(lv<rv),booldef);
  202. lten : t:=genordinalconstnode(ord(lv<=rv),booldef);
  203. gtn : t:=genordinalconstnode(ord(lv>rv),booldef);
  204. gten : t:=genordinalconstnode(ord(lv>=rv),booldef);
  205. equaln : t:=genordinalconstnode(ord(lv=rv),booldef);
  206. unequaln : t:=genordinalconstnode(ord(lv<>rv),booldef);
  207. slashn : begin
  208. { int/int becomes a real }
  209. if int(rv)=0 then
  210. begin
  211. Message(parser_e_invalid_float_operation);
  212. t:=genrealconstnode(0,bestrealdef^);
  213. end
  214. else
  215. t:=genrealconstnode(int(lv)/int(rv),bestrealdef^);
  216. firstpass(t);
  217. end;
  218. else
  219. CGMessage(type_e_mismatch);
  220. end;
  221. pass_1:=t;
  222. exit;
  223. end;
  224. { both real constants ? }
  225. if (lt=realconstn) and (rt=realconstn) then
  226. begin
  227. lvd:=trealconstnode(left).value_real;
  228. rvd:=trealconstnode(right).value_real;
  229. case nodetype of
  230. addn : t:=genrealconstnode(lvd+rvd,bestrealdef^);
  231. subn : t:=genrealconstnode(lvd-rvd,bestrealdef^);
  232. muln : t:=genrealconstnode(lvd*rvd,bestrealdef^);
  233. starstarn,
  234. caretn : begin
  235. if lvd<0 then
  236. begin
  237. Message(parser_e_invalid_float_operation);
  238. t:=genrealconstnode(0,bestrealdef^);
  239. end
  240. else if lvd=0 then
  241. t:=genrealconstnode(1.0,bestrealdef^)
  242. else
  243. t:=genrealconstnode(exp(ln(lvd)*rvd),bestrealdef^);
  244. end;
  245. slashn :
  246. begin
  247. if rvd=0 then
  248. begin
  249. Message(parser_e_invalid_float_operation);
  250. t:=genrealconstnode(0,bestrealdef^);
  251. end
  252. else
  253. t:=genrealconstnode(lvd/rvd,bestrealdef^);
  254. end;
  255. ltn : t:=genordinalconstnode(ord(lvd<rvd),booldef);
  256. lten : t:=genordinalconstnode(ord(lvd<=rvd),booldef);
  257. gtn : t:=genordinalconstnode(ord(lvd>rvd),booldef);
  258. gten : t:=genordinalconstnode(ord(lvd>=rvd),booldef);
  259. equaln : t:=genordinalconstnode(ord(lvd=rvd),booldef);
  260. unequaln : t:=genordinalconstnode(ord(lvd<>rvd),booldef);
  261. else
  262. CGMessage(type_e_mismatch);
  263. end;
  264. pass_1:=t;
  265. exit;
  266. end;
  267. { concating strings ? }
  268. concatstrings:=false;
  269. s1:=nil;
  270. s2:=nil;
  271. if (lt=ordconstn) and (rt=ordconstn) and
  272. is_char(ld) and is_char(rd) then
  273. begin
  274. s1:=strpnew(char(byte(tordconstnode(left).value)));
  275. s2:=strpnew(char(byte(tordconstnode(right).value)));
  276. l1:=1;
  277. l2:=1;
  278. concatstrings:=true;
  279. end
  280. else
  281. if (lt=stringconstn) and (rt=ordconstn) and is_char(rd) then
  282. begin
  283. s1:=tstringconstnode(left).getpcharcopy;
  284. l1:=tstringconstnode(left).len;
  285. s2:=strpnew(char(byte(tordconstnode(right).value)));
  286. l2:=1;
  287. concatstrings:=true;
  288. end
  289. else
  290. if (lt=ordconstn) and (rt=stringconstn) and is_char(ld) then
  291. begin
  292. s1:=strpnew(char(byte(tordconstnode(left).value)));
  293. l1:=1;
  294. s2:=tstringconstnode(right).getpcharcopy;
  295. l2:=tstringconstnode(right).len;
  296. concatstrings:=true;
  297. end
  298. else if (lt=stringconstn) and (rt=stringconstn) then
  299. begin
  300. s1:=tstringconstnode(left).getpcharcopy;
  301. l1:=tstringconstnode(left).len;
  302. s2:=tstringconstnode(right).getpcharcopy;
  303. l2:=tstringconstnode(right).len;
  304. concatstrings:=true;
  305. end;
  306. { I will need to translate all this to ansistrings !!! }
  307. if concatstrings then
  308. begin
  309. case nodetype of
  310. addn :
  311. t:=genpcharconstnode(concatansistrings(s1,s2,l1,l2),l1+l2);
  312. ltn :
  313. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)<0),booldef);
  314. lten :
  315. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)<=0),booldef);
  316. gtn :
  317. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)>0),booldef);
  318. gten :
  319. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)>=0),booldef);
  320. equaln :
  321. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)=0),booldef);
  322. unequaln :
  323. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)<>0),booldef);
  324. end;
  325. ansistringdispose(s1,l1);
  326. ansistringdispose(s2,l2);
  327. pass_1:=t;
  328. exit;
  329. end;
  330. { if both are orddefs then check sub types }
  331. if (ld^.deftype=orddef) and (rd^.deftype=orddef) then
  332. begin
  333. { 2 booleans ? }
  334. if is_boolean(ld) and is_boolean(rd) then
  335. begin
  336. if (cs_full_boolean_eval in aktlocalswitches) or
  337. (nodetype in [xorn,ltn,lten,gtn,gten]) then
  338. begin
  339. make_bool_equal_size;
  340. if (left.location.loc in [LOC_JUMP,LOC_FLAGS]) and
  341. (left.location.loc in [LOC_JUMP,LOC_FLAGS]) then
  342. calcregisters(self,2,0,0)
  343. else
  344. calcregisters(self,1,0,0);
  345. end
  346. else
  347. case nodetype of
  348. andn,
  349. orn:
  350. begin
  351. make_bool_equal_size;
  352. calcregisters(self,0,0,0);
  353. location.loc:=LOC_JUMP;
  354. end;
  355. unequaln,
  356. equaln:
  357. begin
  358. make_bool_equal_size;
  359. { Remove any compares with constants }
  360. if (left.nodetype=ordconstn) then
  361. begin
  362. hp:=right;
  363. b:=(tordconstnode(left).value<>0);
  364. ot:=nodetype;
  365. left.free;
  366. left:=nil;
  367. right:=nil;
  368. if (not(b) and (ot=equaln)) or
  369. (b and (ot=unequaln)) then
  370. begin
  371. hp:=cnotnode.create(hp);
  372. firstpass(hp);
  373. end;
  374. pass_1:=hp;
  375. exit;
  376. end;
  377. if (right.nodetype=ordconstn) then
  378. begin
  379. hp:=left;
  380. b:=(tordconstnode(right).value<>0);
  381. ot:=nodetype;
  382. right.free;
  383. right:=nil;
  384. left:=nil;
  385. if (not(b) and (ot=equaln)) or
  386. (b and (ot=unequaln)) then
  387. begin
  388. hp:=cnotnode.create(hp);
  389. firstpass(hp);
  390. end;
  391. pass_1:=hp;
  392. exit;
  393. end;
  394. if (left.location.loc in [LOC_JUMP,LOC_FLAGS]) and
  395. (left.location.loc in [LOC_JUMP,LOC_FLAGS]) then
  396. calcregisters(self,2,0,0)
  397. else
  398. calcregisters(self,1,0,0);
  399. end;
  400. else
  401. CGMessage(type_e_mismatch);
  402. end;
  403. (*
  404. { these one can't be in flags! }
  405. Yes they can, secondadd converts the loc_flags to a register.
  406. The typeconversions below are simply removed by firsttypeconv()
  407. because the resulttype of left = left.resulttype
  408. (surprise! :) (JM)
  409. if nodetype in [xorn,unequaln,equaln] then
  410. begin
  411. if left.location.loc=LOC_FLAGS then
  412. begin
  413. left:=gentypeconvnode(left,porddef(left.resulttype));
  414. left.convtype:=tc_bool_2_int;
  415. left.explizit:=true;
  416. firstpass(left);
  417. end;
  418. if right.location.loc=LOC_FLAGS then
  419. begin
  420. right:=gentypeconvnode(right,porddef(right.resulttype));
  421. right.convtype:=tc_bool_2_int;
  422. right.explizit:=true;
  423. firstpass(right);
  424. end;
  425. { readjust registers }
  426. calcregisters(p,1,0,0);
  427. end;
  428. *)
  429. convdone:=true;
  430. end
  431. else
  432. { Both are chars? only convert to shortstrings for addn }
  433. if is_char(rd) and is_char(ld) then
  434. begin
  435. if nodetype=addn then
  436. begin
  437. left:=gentypeconvnode(left,cshortstringdef);
  438. firstpass(left);
  439. hp := genaddsstringcharoptnode(self);
  440. firstpass(hp);
  441. pass_1 := hp;
  442. exit;
  443. end
  444. else
  445. calcregisters(self,1,0,0);
  446. convdone:=true;
  447. end
  448. { is there a 64 bit type ? }
  449. else if ((porddef(rd)^.typ=s64bit) or (porddef(ld)^.typ=s64bit)) and
  450. { the / operator is handled later }
  451. (nodetype<>slashn) then
  452. begin
  453. if (porddef(ld)^.typ<>s64bit) then
  454. begin
  455. left:=gentypeconvnode(left,cs64bitdef);
  456. firstpass(left);
  457. end;
  458. if (porddef(rd)^.typ<>s64bit) then
  459. begin
  460. right:=gentypeconvnode(right,cs64bitdef);
  461. firstpass(right);
  462. end;
  463. calcregisters(self,2,0,0);
  464. convdone:=true;
  465. end
  466. else if ((porddef(rd)^.typ=u64bit) or (porddef(ld)^.typ=u64bit)) and
  467. { the / operator is handled later }
  468. (nodetype<>slashn) then
  469. begin
  470. if (porddef(ld)^.typ<>u64bit) then
  471. begin
  472. left:=gentypeconvnode(left,cu64bitdef);
  473. firstpass(left);
  474. end;
  475. if (porddef(rd)^.typ<>u64bit) then
  476. begin
  477. right:=gentypeconvnode(right,cu64bitdef);
  478. firstpass(right);
  479. end;
  480. calcregisters(self,2,0,0);
  481. convdone:=true;
  482. end
  483. else
  484. { is there a cardinal? }
  485. if ((porddef(rd)^.typ=u32bit) or (porddef(ld)^.typ=u32bit)) and
  486. { the / operator is handled later }
  487. (nodetype<>slashn) then
  488. begin
  489. if is_signed(ld) and
  490. { then rd = u32bit }
  491. { convert positive constants to u32bit }
  492. not(is_constintnode(left) and
  493. (tordconstnode(left).value >= 0)) and
  494. { range/overflow checking on mixed signed/cardinal expressions }
  495. { is only possible if you convert everything to 64bit (JM) }
  496. ((aktlocalswitches * [cs_check_overflow,cs_check_range] <> []) and
  497. (nodetype in [addn,subn,muln])) then
  498. begin
  499. { perform the operation in 64bit }
  500. CGMessage(type_w_mixed_signed_unsigned);
  501. left := gentypeconvnode(left,cs64bitdef);
  502. firstpass(left);
  503. right := gentypeconvnode(right,cs64bitdef);
  504. firstpass(right);
  505. end
  506. else
  507. begin
  508. if is_signed(ld) and
  509. not(is_constintnode(left) and
  510. (tordconstnode(left).value >= 0)) and
  511. (cs_check_range in aktlocalswitches) then
  512. CGMessage(type_w_mixed_signed_unsigned2);
  513. left := gentypeconvnode(left,u32bitdef);
  514. firstpass(left);
  515. if is_signed(rd) and
  516. { then ld = u32bit }
  517. { convert positive constants to u32bit }
  518. not(is_constintnode(right) and
  519. (tordconstnode(right).value >= 0)) and
  520. ((aktlocalswitches * [cs_check_overflow,cs_check_range] <> []) and
  521. (nodetype in [addn,subn,muln])) then
  522. begin
  523. { perform the operation in 64bit }
  524. CGMessage(type_w_mixed_signed_unsigned);
  525. left := gentypeconvnode(left,cs64bitdef);
  526. firstpass(left);
  527. right := gentypeconvnode(right,cs64bitdef);
  528. firstpass(right);
  529. end
  530. else
  531. begin
  532. if is_signed(rd) and
  533. not(is_constintnode(right) and
  534. (tordconstnode(right).value >= 0)) and
  535. (cs_check_range in aktlocalswitches) then
  536. CGMessage(type_w_mixed_signed_unsigned2);
  537. right := gentypeconvnode(right,u32bitdef);
  538. firstpass(right);
  539. end;
  540. end;
  541. { did we convert things to 64bit? }
  542. if porddef(left.resulttype)^.typ = s64bit then
  543. calcregisters(self,2,0,0)
  544. else
  545. begin
  546. calcregisters(self,1,0,0);
  547. { for unsigned mul we need an extra register }
  548. if nodetype=muln then
  549. inc(registers32);
  550. end;
  551. convdone:=true;
  552. end;
  553. end
  554. else
  555. { left side a setdef, must be before string processing,
  556. else array constructor can be seen as array of char (PFV) }
  557. if (ld^.deftype=setdef) {or is_array_constructor(ld)} then
  558. begin
  559. { trying to add a set element? }
  560. if (nodetype=addn) and (rd^.deftype<>setdef) then
  561. begin
  562. if (rt=setelementn) then
  563. begin
  564. if not(is_equal(psetdef(ld)^.elementtype.def,rd)) then
  565. CGMessage(type_e_set_element_are_not_comp);
  566. end
  567. else
  568. CGMessage(type_e_mismatch)
  569. end
  570. else
  571. begin
  572. if not(nodetype in [addn,subn,symdifn,muln,equaln,unequaln
  573. {$IfNDef NoSetInclusion}
  574. ,lten,gten
  575. {$EndIf NoSetInclusion}
  576. ]) then
  577. CGMessage(type_e_set_operation_unknown);
  578. { right def must be a also be set }
  579. if (rd^.deftype<>setdef) or not(is_equal(rd,ld)) then
  580. CGMessage(type_e_set_element_are_not_comp);
  581. end;
  582. { ranges require normsets }
  583. if (psetdef(ld)^.settype=smallset) and
  584. (rt=setelementn) and
  585. assigned(tsetelementnode(right).right) then
  586. begin
  587. { generate a temporary normset def, it'll be destroyed
  588. when the symtable is unloaded }
  589. tempdef:=new(psetdef,init(psetdef(ld)^.elementtype.def,255));
  590. left:=gentypeconvnode(left,tempdef);
  591. firstpass(left);
  592. ld:=left.resulttype;
  593. end;
  594. { if the destination is not a smallset then insert a typeconv
  595. which loads a smallset into a normal set }
  596. if (psetdef(ld)^.settype<>smallset) and
  597. (psetdef(rd)^.settype=smallset) then
  598. begin
  599. if (right.nodetype=setconstn) then
  600. begin
  601. t:=gensetconstnode(tsetconstnode(right).value_set,psetdef(left.resulttype));
  602. tsetconstnode(t).left:=tsetconstnode(right).left;
  603. tsetconstnode(right).left:=nil;
  604. right.free;
  605. right:=t;
  606. end
  607. else
  608. right:=gentypeconvnode(right,psetdef(left.resulttype));
  609. firstpass(right);
  610. end;
  611. { do constant evaluation }
  612. if (right.nodetype=setconstn) and
  613. not assigned(tsetconstnode(right).left) and
  614. (left.nodetype=setconstn) and
  615. not assigned(tsetconstnode(left).left) then
  616. begin
  617. new(resultset);
  618. case nodetype of
  619. addn : begin
  620. for i:=0 to 31 do
  621. resultset^[i]:=
  622. tsetconstnode(right).value_set^[i] or tsetconstnode(left).value_set^[i];
  623. t:=gensetconstnode(resultset,psetdef(ld));
  624. end;
  625. muln : begin
  626. for i:=0 to 31 do
  627. resultset^[i]:=
  628. tsetconstnode(right).value_set^[i] and tsetconstnode(left).value_set^[i];
  629. t:=gensetconstnode(resultset,psetdef(ld));
  630. end;
  631. subn : begin
  632. for i:=0 to 31 do
  633. resultset^[i]:=
  634. tsetconstnode(left).value_set^[i] and not(tsetconstnode(right).value_set^[i]);
  635. t:=gensetconstnode(resultset,psetdef(ld));
  636. end;
  637. symdifn : begin
  638. for i:=0 to 31 do
  639. resultset^[i]:=
  640. tsetconstnode(left).value_set^[i] xor tsetconstnode(right).value_set^[i];
  641. t:=gensetconstnode(resultset,psetdef(ld));
  642. end;
  643. unequaln : begin
  644. b:=true;
  645. for i:=0 to 31 do
  646. if tsetconstnode(right).value_set^[i]=tsetconstnode(left).value_set^[i] then
  647. begin
  648. b:=false;
  649. break;
  650. end;
  651. t:=genordinalconstnode(ord(b),booldef);
  652. end;
  653. equaln : begin
  654. b:=true;
  655. for i:=0 to 31 do
  656. if tsetconstnode(right).value_set^[i]<>tsetconstnode(left).value_set^[i] then
  657. begin
  658. b:=false;
  659. break;
  660. end;
  661. t:=genordinalconstnode(ord(b),booldef);
  662. end;
  663. {$IfNDef NoSetInclusion}
  664. lten : Begin
  665. b := true;
  666. For i := 0 to 31 Do
  667. If (tsetconstnode(right).value_set^[i] And tsetconstnode(left).value_set^[i]) <>
  668. tsetconstnode(left).value_set^[i] Then
  669. Begin
  670. b := false;
  671. Break
  672. End;
  673. t := genordinalconstnode(ord(b),booldef);
  674. End;
  675. gten : Begin
  676. b := true;
  677. For i := 0 to 31 Do
  678. If (tsetconstnode(left).value_set^[i] And tsetconstnode(right).value_set^[i]) <>
  679. tsetconstnode(right).value_set^[i] Then
  680. Begin
  681. b := false;
  682. Break
  683. End;
  684. t := genordinalconstnode(ord(b),booldef);
  685. End;
  686. {$EndIf NoSetInclusion}
  687. end;
  688. dispose(resultset);
  689. firstpass(t);
  690. pass_1:=t;
  691. exit;
  692. end
  693. else
  694. if psetdef(ld)^.settype=smallset then
  695. begin
  696. { are we adding set elements ? }
  697. if right.nodetype=setelementn then
  698. calcregisters(self,2,0,0)
  699. else
  700. calcregisters(self,1,0,0);
  701. location.loc:=LOC_REGISTER;
  702. end
  703. else
  704. begin
  705. calcregisters(self,0,0,0);
  706. { here we call SET... }
  707. procinfo^.flags:=procinfo^.flags or pi_do_call;
  708. location.loc:=LOC_MEM;
  709. end;
  710. convdone:=true;
  711. end
  712. else
  713. { compare pchar to char arrays by addresses
  714. like BP/Delphi }
  715. if (is_pchar(ld) and is_chararray(rd)) or
  716. (is_pchar(rd) and is_chararray(ld)) then
  717. begin
  718. if is_chararray(rd) then
  719. begin
  720. right:=gentypeconvnode(right,ld);
  721. firstpass(right);
  722. end
  723. else
  724. begin
  725. left:=gentypeconvnode(left,rd);
  726. firstpass(left);
  727. end;
  728. location.loc:=LOC_REGISTER;
  729. calcregisters(self,1,0,0);
  730. convdone:=true;
  731. end
  732. else
  733. { is one of the operands a string?,
  734. chararrays are also handled as strings (after conversion) }
  735. if (rd^.deftype=stringdef) or (ld^.deftype=stringdef) or
  736. ((is_chararray(rd) or is_char(rd)) and
  737. (is_chararray(ld) or is_char(ld))) then
  738. begin
  739. if is_widestring(rd) or is_widestring(ld) then
  740. begin
  741. if not(is_widestring(rd)) then
  742. right:=gentypeconvnode(right,cwidestringdef);
  743. if not(is_widestring(ld)) then
  744. left:=gentypeconvnode(left,cwidestringdef);
  745. resulttype:=cwidestringdef;
  746. { this is only for add, the comparisaion is handled later }
  747. location.loc:=LOC_REGISTER;
  748. end
  749. else if is_ansistring(rd) or is_ansistring(ld) then
  750. begin
  751. if not(is_ansistring(rd)) then
  752. right:=gentypeconvnode(right,cansistringdef);
  753. if not(is_ansistring(ld)) then
  754. left:=gentypeconvnode(left,cansistringdef);
  755. { we use ansistrings so no fast exit here }
  756. procinfo^.no_fast_exit:=true;
  757. resulttype:=cansistringdef;
  758. { this is only for add, the comparisaion is handled later }
  759. location.loc:=LOC_REGISTER;
  760. end
  761. else if is_longstring(rd) or is_longstring(ld) then
  762. begin
  763. if not(is_longstring(rd)) then
  764. right:=gentypeconvnode(right,clongstringdef);
  765. if not(is_longstring(ld)) then
  766. left:=gentypeconvnode(left,clongstringdef);
  767. resulttype:=clongstringdef;
  768. { this is only for add, the comparisaion is handled later }
  769. location.loc:=LOC_MEM;
  770. end
  771. else
  772. begin
  773. if canbeaddsstringcharoptnode(self) then
  774. begin
  775. hp := genaddsstringcharoptnode(self);
  776. firstpass(hp);
  777. pass_1 := hp;
  778. exit;
  779. end;
  780. if canbeaddsstringcsstringoptnode(self) then
  781. begin
  782. hp := genaddsstringcsstringoptnode(self);
  783. firstpass(hp);
  784. pass_1 := hp;
  785. exit;
  786. end;
  787. if not(is_shortstring(ld)) then
  788. left:=gentypeconvnode(left,cshortstringdef);
  789. if not(is_shortstring(rd)) then
  790. right:=gentypeconvnode(right,cshortstringdef);
  791. resulttype:=left.resulttype;
  792. { this is only for add, the comparisaion is handled later }
  793. location.loc:=LOC_MEM;
  794. end;
  795. { only if there is a type cast we need to do again }
  796. { the first pass }
  797. if left.nodetype=typeconvn then
  798. firstpass(left);
  799. if right.nodetype=typeconvn then
  800. firstpass(right);
  801. { here we call STRCONCAT or STRCMP or STRCOPY }
  802. procinfo^.flags:=procinfo^.flags or pi_do_call;
  803. if location.loc=LOC_MEM then
  804. calcregisters(self,0,0,0)
  805. else
  806. calcregisters(self,1,0,0);
  807. convdone:=true;
  808. end
  809. else
  810. { is one a real float ? }
  811. if (rd^.deftype=floatdef) or (ld^.deftype=floatdef) then
  812. begin
  813. { if one is a fixed, then convert to f32bit }
  814. if ((rd^.deftype=floatdef) and (pfloatdef(rd)^.typ=f32bit)) or
  815. ((ld^.deftype=floatdef) and (pfloatdef(ld)^.typ=f32bit)) then
  816. begin
  817. if not is_integer(rd) or (nodetype<>muln) then
  818. right:=gentypeconvnode(right,s32fixeddef);
  819. if not is_integer(ld) or (nodetype<>muln) then
  820. left:=gentypeconvnode(left,s32fixeddef);
  821. firstpass(left);
  822. firstpass(right);
  823. calcregisters(self,1,0,0);
  824. location.loc:=LOC_REGISTER;
  825. end
  826. else
  827. { convert both to bestreal }
  828. begin
  829. right:=gentypeconvnode(right,bestrealdef^);
  830. left:=gentypeconvnode(left,bestrealdef^);
  831. firstpass(left);
  832. firstpass(right);
  833. calcregisters(self,0,1,0);
  834. location.loc:=LOC_FPU;
  835. end;
  836. convdone:=true;
  837. end
  838. else
  839. { pointer comperation and subtraction }
  840. if (rd^.deftype=pointerdef) and (ld^.deftype=pointerdef) then
  841. begin
  842. location.loc:=LOC_REGISTER;
  843. { right:=gentypeconvnode(right,ld); }
  844. { firstpass(right); }
  845. calcregisters(self,1,0,0);
  846. case nodetype of
  847. equaln,unequaln :
  848. begin
  849. if is_equal(right.resulttype,voidpointerdef) then
  850. begin
  851. right:=gentypeconvnode(right,ld);
  852. firstpass(right);
  853. end
  854. else if is_equal(left.resulttype,voidpointerdef) then
  855. begin
  856. left:=gentypeconvnode(left,rd);
  857. firstpass(left);
  858. end
  859. else if not(is_equal(ld,rd)) then
  860. CGMessage(type_e_mismatch);
  861. end;
  862. ltn,lten,gtn,gten:
  863. begin
  864. if is_equal(right.resulttype,voidpointerdef) then
  865. begin
  866. right:=gentypeconvnode(right,ld);
  867. firstpass(right);
  868. end
  869. else if is_equal(left.resulttype,voidpointerdef) then
  870. begin
  871. left:=gentypeconvnode(left,rd);
  872. firstpass(left);
  873. end
  874. else if not(is_equal(ld,rd)) then
  875. CGMessage(type_e_mismatch);
  876. if not(cs_extsyntax in aktmoduleswitches) then
  877. CGMessage(type_e_mismatch);
  878. end;
  879. subn:
  880. begin
  881. if not(is_equal(ld,rd)) then
  882. CGMessage(type_e_mismatch);
  883. if not(cs_extsyntax in aktmoduleswitches) then
  884. CGMessage(type_e_mismatch);
  885. resulttype:=s32bitdef;
  886. exit;
  887. end;
  888. else CGMessage(type_e_mismatch);
  889. end;
  890. convdone:=true;
  891. end
  892. else
  893. if is_class_or_interface(rd) or is_class_or_interface(ld) then
  894. begin
  895. location.loc:=LOC_REGISTER;
  896. if is_class_or_interface(rd) and is_class_or_interface(ld) then
  897. begin
  898. if pobjectdef(rd)^.is_related(pobjectdef(ld)) then
  899. right:=gentypeconvnode(right,ld)
  900. else
  901. left:=gentypeconvnode(left,rd);
  902. end
  903. else if is_class_or_interface(rd) then
  904. left:=gentypeconvnode(left,rd)
  905. else
  906. right:=gentypeconvnode(right,ld);
  907. firstpass(right);
  908. firstpass(left);
  909. calcregisters(self,1,0,0);
  910. case nodetype of
  911. equaln,unequaln:
  912. ;
  913. else CGMessage(type_e_mismatch);
  914. end;
  915. convdone:=true;
  916. end
  917. else
  918. if (rd^.deftype=classrefdef) and (ld^.deftype=classrefdef) then
  919. begin
  920. location.loc:=LOC_REGISTER;
  921. if pobjectdef(pclassrefdef(rd)^.pointertype.def)^.is_related(pobjectdef(
  922. pclassrefdef(ld)^.pointertype.def)) then
  923. right:=gentypeconvnode(right,ld)
  924. else
  925. left:=gentypeconvnode(left,rd);
  926. firstpass(right);
  927. firstpass(left);
  928. calcregisters(self,1,0,0);
  929. case nodetype of
  930. equaln,unequaln : ;
  931. else CGMessage(type_e_mismatch);
  932. end;
  933. convdone:=true;
  934. end
  935. else
  936. { allows comperasion with nil pointer }
  937. if is_class_or_interface(rd) then
  938. begin
  939. location.loc:=LOC_REGISTER;
  940. left:=gentypeconvnode(left,rd);
  941. firstpass(left);
  942. calcregisters(self,1,0,0);
  943. case nodetype of
  944. equaln,unequaln : ;
  945. else CGMessage(type_e_mismatch);
  946. end;
  947. convdone:=true;
  948. end
  949. else
  950. if is_class_or_interface(ld) then
  951. begin
  952. location.loc:=LOC_REGISTER;
  953. right:=gentypeconvnode(right,ld);
  954. firstpass(right);
  955. calcregisters(self,1,0,0);
  956. case nodetype of
  957. equaln,unequaln : ;
  958. else CGMessage(type_e_mismatch);
  959. end;
  960. convdone:=true;
  961. end
  962. else
  963. if (rd^.deftype=classrefdef) then
  964. begin
  965. left:=gentypeconvnode(left,rd);
  966. firstpass(left);
  967. calcregisters(self,1,0,0);
  968. case nodetype of
  969. equaln,unequaln : ;
  970. else CGMessage(type_e_mismatch);
  971. end;
  972. convdone:=true;
  973. end
  974. else
  975. if (ld^.deftype=classrefdef) then
  976. begin
  977. right:=gentypeconvnode(right,ld);
  978. firstpass(right);
  979. calcregisters(self,1,0,0);
  980. case nodetype of
  981. equaln,unequaln : ;
  982. else
  983. CGMessage(type_e_mismatch);
  984. end;
  985. convdone:=true;
  986. end
  987. else
  988. { support procvar=nil,procvar<>nil }
  989. if ((ld^.deftype=procvardef) and (rt=niln)) or
  990. ((rd^.deftype=procvardef) and (lt=niln)) then
  991. begin
  992. calcregisters(self,1,0,0);
  993. location.loc:=LOC_REGISTER;
  994. case nodetype of
  995. equaln,unequaln : ;
  996. else
  997. CGMessage(type_e_mismatch);
  998. end;
  999. convdone:=true;
  1000. end
  1001. else
  1002. {$ifdef SUPPORT_MMX}
  1003. if (cs_mmx in aktlocalswitches) and is_mmx_able_array(ld) and
  1004. is_mmx_able_array(rd) and is_equal(ld,rd) then
  1005. begin
  1006. firstpass(right);
  1007. firstpass(left);
  1008. case nodetype of
  1009. addn,subn,xorn,orn,andn:
  1010. ;
  1011. { mul is a little bit restricted }
  1012. muln:
  1013. if not(mmx_type(left.resulttype) in
  1014. [mmxu16bit,mmxs16bit,mmxfixed16]) then
  1015. CGMessage(type_e_mismatch);
  1016. else
  1017. CGMessage(type_e_mismatch);
  1018. end;
  1019. location.loc:=LOC_MMXREGISTER;
  1020. calcregisters(self,0,0,1);
  1021. convdone:=true;
  1022. end
  1023. else
  1024. {$endif SUPPORT_MMX}
  1025. { this is a little bit dangerous, also the left type }
  1026. { should be checked! This broke the mmx support }
  1027. if (rd^.deftype=pointerdef) or
  1028. is_zero_based_array(rd) then
  1029. begin
  1030. if is_zero_based_array(rd) then
  1031. begin
  1032. resulttype:=new(ppointerdef,init(parraydef(rd)^.elementtype));
  1033. right:=gentypeconvnode(right,resulttype);
  1034. firstpass(right);
  1035. rd := right.resulttype;
  1036. end;
  1037. location.loc:=LOC_REGISTER;
  1038. left:=gentypeconvnode(left,s32bitdef);
  1039. firstpass(left);
  1040. calcregisters(self,1,0,0);
  1041. if nodetype=addn then
  1042. begin
  1043. if not(cs_extsyntax in aktmoduleswitches) or
  1044. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  1045. CGMessage(type_e_mismatch);
  1046. { Dirty hack, to support multiple firstpasses (PFV) }
  1047. if (resulttype=nil) and
  1048. (rd^.deftype=pointerdef) and
  1049. (ppointerdef(rd)^.pointertype.def^.size>1) then
  1050. begin
  1051. left:=caddnode.create(muln,left,genordinalconstnode(ppointerdef(rd)^.pointertype.def^.size,s32bitdef));
  1052. firstpass(left);
  1053. end;
  1054. end
  1055. else
  1056. CGMessage(type_e_mismatch);
  1057. convdone:=true;
  1058. end
  1059. else
  1060. if (ld^.deftype=pointerdef) or
  1061. is_zero_based_array(ld) then
  1062. begin
  1063. if is_zero_based_array(ld) then
  1064. begin
  1065. resulttype:=new(ppointerdef,init(parraydef(ld)^.elementtype));
  1066. left:=gentypeconvnode(left,resulttype);
  1067. firstpass(left);
  1068. ld := left.resulttype;
  1069. end;
  1070. location.loc:=LOC_REGISTER;
  1071. right:=gentypeconvnode(right,s32bitdef);
  1072. firstpass(right);
  1073. calcregisters(self,1,0,0);
  1074. case nodetype of
  1075. addn,subn : begin
  1076. if not(cs_extsyntax in aktmoduleswitches) or
  1077. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  1078. CGMessage(type_e_mismatch);
  1079. { Dirty hack, to support multiple firstpasses (PFV) }
  1080. if (resulttype=nil) and
  1081. (ld^.deftype=pointerdef) and
  1082. (ppointerdef(ld)^.pointertype.def^.size>1) then
  1083. begin
  1084. right:=caddnode.create(muln,right,
  1085. genordinalconstnode(ppointerdef(ld)^.pointertype.def^.size,s32bitdef));
  1086. firstpass(right);
  1087. end;
  1088. end;
  1089. else
  1090. CGMessage(type_e_mismatch);
  1091. end;
  1092. convdone:=true;
  1093. end
  1094. else
  1095. if (rd^.deftype=procvardef) and (ld^.deftype=procvardef) and is_equal(rd,ld) then
  1096. begin
  1097. calcregisters(self,1,0,0);
  1098. location.loc:=LOC_REGISTER;
  1099. case nodetype of
  1100. equaln,unequaln : ;
  1101. else
  1102. CGMessage(type_e_mismatch);
  1103. end;
  1104. convdone:=true;
  1105. end
  1106. else
  1107. if (ld^.deftype=enumdef) and (rd^.deftype=enumdef) then
  1108. begin
  1109. if not(is_equal(ld,rd)) then
  1110. begin
  1111. right:=gentypeconvnode(right,ld);
  1112. firstpass(right);
  1113. end;
  1114. calcregisters(self,1,0,0);
  1115. case nodetype of
  1116. equaln,unequaln,
  1117. ltn,lten,gtn,gten : ;
  1118. else CGMessage(type_e_mismatch);
  1119. end;
  1120. convdone:=true;
  1121. end;
  1122. { the general solution is to convert to 32 bit int }
  1123. if not convdone then
  1124. begin
  1125. { but an int/int gives real/real! }
  1126. if nodetype=slashn then
  1127. begin
  1128. CGMessage(type_h_use_div_for_int);
  1129. right:=gentypeconvnode(right,bestrealdef^);
  1130. left:=gentypeconvnode(left,bestrealdef^);
  1131. firstpass(left);
  1132. firstpass(right);
  1133. { maybe we need an integer register to save }
  1134. { a reference }
  1135. if ((left.location.loc<>LOC_FPU) or
  1136. (right.location.loc<>LOC_FPU)) and
  1137. (left.registers32=right.registers32) then
  1138. calcregisters(self,1,1,0)
  1139. else
  1140. calcregisters(self,0,1,0);
  1141. location.loc:=LOC_FPU;
  1142. end
  1143. else
  1144. begin
  1145. right:=gentypeconvnode(right,s32bitdef);
  1146. left:=gentypeconvnode(left,s32bitdef);
  1147. firstpass(left);
  1148. firstpass(right);
  1149. calcregisters(self,1,0,0);
  1150. location.loc:=LOC_REGISTER;
  1151. end;
  1152. end;
  1153. if codegenerror then
  1154. exit;
  1155. { determines result type for comparions }
  1156. { here the is a problem with multiple passes }
  1157. { example length(s)+1 gets internal 'longint' type first }
  1158. { if it is a arg it is converted to 'LONGINT' }
  1159. { but a second first pass will reset this to 'longint' }
  1160. case nodetype of
  1161. ltn,lten,gtn,gten,equaln,unequaln:
  1162. begin
  1163. if (not assigned(resulttype)) or
  1164. (resulttype^.deftype=stringdef) then
  1165. resulttype:=booldef;
  1166. if is_64bitint(left.resulttype) then
  1167. location.loc:=LOC_JUMP
  1168. else
  1169. location.loc:=LOC_FLAGS;
  1170. end;
  1171. xorn:
  1172. begin
  1173. if not assigned(resulttype) then
  1174. resulttype:=left.resulttype;
  1175. location.loc:=LOC_REGISTER;
  1176. end;
  1177. addn:
  1178. begin
  1179. if not assigned(resulttype) then
  1180. begin
  1181. { for strings, return is always a 255 char string }
  1182. if is_shortstring(left.resulttype) then
  1183. resulttype:=cshortstringdef
  1184. else
  1185. resulttype:=left.resulttype;
  1186. end;
  1187. end;
  1188. else
  1189. if not assigned(resulttype) then
  1190. resulttype:=left.resulttype;
  1191. end;
  1192. end;
  1193. begin
  1194. caddnode:=taddnode;
  1195. end.
  1196. {
  1197. $Log$
  1198. Revision 1.22 2001-02-04 11:12:17 jonas
  1199. * fixed web bug 1377 & const pointer arithmtic
  1200. Revision 1.21 2001/01/14 22:13:13 peter
  1201. * constant calculation fixed. The type of the new constant is now
  1202. defined after the calculation is done. This should remove a lot
  1203. of wrong warnings (and errors with -Cr).
  1204. Revision 1.20 2000/12/31 11:14:10 jonas
  1205. + implemented/fixed docompare() mathods for all nodes (not tested)
  1206. + nopt.pas, nadd.pas, i386/n386opt.pas: optimized nodes for adding strings
  1207. and constant strings/chars together
  1208. * n386add.pas: don't copy temp strings (of size 256) to another temp string
  1209. when adding
  1210. Revision 1.19 2000/12/16 15:55:32 jonas
  1211. + warning when there is a chance to get a range check error because of
  1212. automatic type conversion to u32bit
  1213. * arithmetic operations with a cardinal and a signed operand are carried
  1214. out in 64bit when range checking is on ("merged" from fixes branch)
  1215. Revision 1.18 2000/11/29 00:30:31 florian
  1216. * unused units removed from uses clause
  1217. * some changes for widestrings
  1218. Revision 1.17 2000/11/20 15:30:42 jonas
  1219. * changed types of values used for constant expression evaluation to
  1220. tconstexprint
  1221. Revision 1.16 2000/11/13 11:30:55 florian
  1222. * some bugs with interfaces and NIL fixed
  1223. Revision 1.15 2000/11/04 14:25:20 florian
  1224. + merged Attila's changes for interfaces, not tested yet
  1225. Revision 1.14 2000/10/31 22:02:47 peter
  1226. * symtable splitted, no real code changes
  1227. Revision 1.13 2000/10/14 10:14:50 peter
  1228. * moehrendorf oct 2000 rewrite
  1229. Revision 1.12 2000/10/01 19:48:23 peter
  1230. * lot of compile updates for cg11
  1231. Revision 1.11 2000/09/30 16:08:45 peter
  1232. * more cg11 updates
  1233. Revision 1.10 2000/09/28 19:49:52 florian
  1234. *** empty log message ***
  1235. Revision 1.9 2000/09/27 21:33:22 florian
  1236. * finally nadd.pas compiles
  1237. Revision 1.8 2000/09/27 20:25:44 florian
  1238. * more stuff fixed
  1239. Revision 1.7 2000/09/27 18:14:31 florian
  1240. * fixed a lot of syntax errors in the n*.pas stuff
  1241. Revision 1.6 2000/09/24 15:06:19 peter
  1242. * use defines.inc
  1243. Revision 1.5 2000/09/22 22:42:52 florian
  1244. * more fixes
  1245. Revision 1.4 2000/09/21 12:22:42 jonas
  1246. * put piece of code between -dnewoptimizations2 since it wasn't
  1247. necessary otherwise
  1248. + support for full boolean evaluation (from tcadd)
  1249. Revision 1.3 2000/09/20 21:50:59 florian
  1250. * updated
  1251. Revision 1.2 2000/08/29 08:24:45 jonas
  1252. * some modifications to -dcardinalmulfix code
  1253. Revision 1.1 2000/08/26 12:24:20 florian
  1254. * initial release
  1255. }