nadd.pas 48 KB

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