tcadd.pas 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048
  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. symtable,aasm,types,
  28. hcodegen,htypechk,pass_1
  29. {$ifdef i386}
  30. ,i386
  31. {$endif}
  32. {$ifdef m68k}
  33. ,m68k
  34. {$endif}
  35. ;
  36. {*****************************************************************************
  37. FirstAdd
  38. *****************************************************************************}
  39. procedure firstadd(var p : ptree);
  40. procedure make_bool_equal_size(var p:ptree);
  41. begin
  42. if porddef(p^.left^.resulttype)^.typ>porddef(p^.right^.resulttype)^.typ then
  43. begin
  44. p^.right:=gentypeconvnode(p^.right,porddef(p^.left^.resulttype));
  45. p^.right^.convtyp:=tc_bool_2_int;
  46. p^.right^.explizit:=true;
  47. firstpass(p^.right);
  48. end
  49. else
  50. if porddef(p^.left^.resulttype)^.typ<porddef(p^.right^.resulttype)^.typ then
  51. begin
  52. p^.left:=gentypeconvnode(p^.left,porddef(p^.right^.resulttype));
  53. p^.left^.convtyp:=tc_bool_2_int;
  54. p^.left^.explizit:=true;
  55. firstpass(p^.left);
  56. end;
  57. end;
  58. var
  59. t,hp : ptree;
  60. ot,
  61. lt,rt : ttreetyp;
  62. rv,lv : longint;
  63. rvd,lvd : bestreal;
  64. rd,ld : pdef;
  65. tempdef : pdef;
  66. concatstrings : boolean;
  67. { to evalute const sets }
  68. resultset : pconstset;
  69. i : longint;
  70. b : boolean;
  71. convdone : boolean;
  72. s1,s2 : pchar;
  73. l1,l2 : longint;
  74. { this totally forgets to set the pi_do_call flag !! }
  75. label
  76. no_overload;
  77. begin
  78. { first do the two subtrees }
  79. firstpass(p^.left);
  80. firstpass(p^.right);
  81. lt:=p^.left^.treetype;
  82. rt:=p^.right^.treetype;
  83. rd:=p^.right^.resulttype;
  84. ld:=p^.left^.resulttype;
  85. convdone:=false;
  86. if codegenerror then
  87. exit;
  88. { overloaded operator ? }
  89. if (p^.treetype=starstarn) or
  90. (ld^.deftype=recorddef) or
  91. { <> and = are defined for classes }
  92. ((ld^.deftype=objectdef) and
  93. (not(pobjectdef(ld)^.isclass) or
  94. not(p^.treetype in [equaln,unequaln])
  95. )
  96. ) or
  97. (rd^.deftype=recorddef) or
  98. { <> and = are defined for classes }
  99. ((rd^.deftype=objectdef) and
  100. (not(pobjectdef(rd)^.isclass) or
  101. not(p^.treetype in [equaln,unequaln])
  102. )
  103. ) then
  104. begin
  105. {!!!!!!!!! handle paras }
  106. case p^.treetype of
  107. { the nil as symtable signs firstcalln that this is
  108. an overloaded operator }
  109. addn:
  110. t:=gencallnode(overloaded_operators[plus],nil);
  111. subn:
  112. t:=gencallnode(overloaded_operators[minus],nil);
  113. muln:
  114. t:=gencallnode(overloaded_operators[star],nil);
  115. starstarn:
  116. t:=gencallnode(overloaded_operators[starstar],nil);
  117. slashn:
  118. t:=gencallnode(overloaded_operators[slash],nil);
  119. ltn:
  120. t:=gencallnode(overloaded_operators[tokens.lt],nil);
  121. gtn:
  122. t:=gencallnode(overloaded_operators[gt],nil);
  123. lten:
  124. t:=gencallnode(overloaded_operators[lte],nil);
  125. gten:
  126. t:=gencallnode(overloaded_operators[gte],nil);
  127. equaln,unequaln :
  128. t:=gencallnode(overloaded_operators[equal],nil);
  129. else goto no_overload;
  130. end;
  131. { we have to convert p^.left and p^.right into
  132. callparanodes }
  133. if t^.symtableprocentry=nil then
  134. begin
  135. CGMessage(parser_e_operator_not_overloaded);
  136. putnode(t);
  137. end
  138. else
  139. begin
  140. t^.left:=gencallparanode(p^.left,nil);
  141. t^.left:=gencallparanode(p^.right,t^.left);
  142. if p^.treetype=unequaln then
  143. t:=gensinglenode(notn,t);
  144. firstpass(t);
  145. putnode(p);
  146. p:=t;
  147. exit;
  148. end;
  149. end;
  150. no_overload:
  151. { compact consts }
  152. { convert int consts to real consts, if the }
  153. { other operand is a real const }
  154. if (rt=realconstn) and is_constintnode(p^.left) then
  155. begin
  156. t:=genrealconstnode(p^.left^.value);
  157. disposetree(p^.left);
  158. p^.left:=t;
  159. lt:=realconstn;
  160. end;
  161. if (lt=realconstn) and is_constintnode(p^.right) then
  162. begin
  163. t:=genrealconstnode(p^.right^.value);
  164. disposetree(p^.right);
  165. p^.right:=t;
  166. rt:=realconstn;
  167. end;
  168. { both are int constants ? }
  169. if is_constintnode(p^.left) and is_constintnode(p^.right) then
  170. begin
  171. lv:=p^.left^.value;
  172. rv:=p^.right^.value;
  173. case p^.treetype of
  174. addn : t:=genordinalconstnode(lv+rv,s32bitdef);
  175. subn : t:=genordinalconstnode(lv-rv,s32bitdef);
  176. muln : t:=genordinalconstnode(lv*rv,s32bitdef);
  177. xorn : t:=genordinalconstnode(lv xor rv,s32bitdef);
  178. orn : t:=genordinalconstnode(lv or rv,s32bitdef);
  179. andn : t:=genordinalconstnode(lv and rv,s32bitdef);
  180. ltn : t:=genordinalconstnode(ord(lv<rv),booldef);
  181. lten : t:=genordinalconstnode(ord(lv<=rv),booldef);
  182. gtn : t:=genordinalconstnode(ord(lv>rv),booldef);
  183. gten : t:=genordinalconstnode(ord(lv>=rv),booldef);
  184. equaln : t:=genordinalconstnode(ord(lv=rv),booldef);
  185. unequaln : t:=genordinalconstnode(ord(lv<>rv),booldef);
  186. slashn : begin
  187. { int/int becomes a real }
  188. if int(rv)=0 then
  189. begin
  190. Message(parser_e_invalid_float_operation);
  191. t:=genrealconstnode(0);
  192. end
  193. else
  194. t:=genrealconstnode(int(lv)/int(rv));
  195. firstpass(t);
  196. end;
  197. else
  198. CGMessage(type_e_mismatch);
  199. end;
  200. disposetree(p);
  201. firstpass(t);
  202. p:=t;
  203. exit;
  204. end;
  205. { both real constants ? }
  206. if (lt=realconstn) and (rt=realconstn) then
  207. begin
  208. lvd:=p^.left^.value_real;
  209. rvd:=p^.right^.value_real;
  210. case p^.treetype of
  211. addn : t:=genrealconstnode(lvd+rvd);
  212. subn : t:=genrealconstnode(lvd-rvd);
  213. muln : t:=genrealconstnode(lvd*rvd);
  214. caretn : t:=genrealconstnode(exp(ln(lvd)*rvd));
  215. slashn : begin
  216. if rvd=0 then
  217. begin
  218. Message(parser_e_invalid_float_operation);
  219. t:=genrealconstnode(0);
  220. end
  221. else
  222. t:=genrealconstnode(lvd/rvd);
  223. end;
  224. ltn : t:=genordinalconstnode(ord(lvd<rvd),booldef);
  225. lten : t:=genordinalconstnode(ord(lvd<=rvd),booldef);
  226. gtn : t:=genordinalconstnode(ord(lvd>rvd),booldef);
  227. gten : t:=genordinalconstnode(ord(lvd>=rvd),booldef);
  228. equaln : t:=genordinalconstnode(ord(lvd=rvd),booldef);
  229. unequaln : t:=genordinalconstnode(ord(lvd<>rvd),booldef);
  230. else
  231. CGMessage(type_e_mismatch);
  232. end;
  233. disposetree(p);
  234. p:=t;
  235. firstpass(p);
  236. exit;
  237. end;
  238. { concating strings ? }
  239. concatstrings:=false;
  240. s1:=nil;
  241. s2:=nil;
  242. if (lt=ordconstn) and (rt=ordconstn) and
  243. is_char(ld) and is_char(rd) then
  244. begin
  245. s1:=strpnew(char(byte(p^.left^.value)));
  246. s2:=strpnew(char(byte(p^.right^.value)));
  247. l1:=1;
  248. l2:=1;
  249. concatstrings:=true;
  250. end
  251. else
  252. if (lt=stringconstn) and (rt=ordconstn) and is_char(rd) then
  253. begin
  254. s1:=getpcharcopy(p^.left);
  255. l1:=p^.left^.length;
  256. s2:=strpnew(char(byte(p^.right^.value)));
  257. l2:=1;
  258. concatstrings:=true;
  259. end
  260. else
  261. if (lt=ordconstn) and (rt=stringconstn) and is_char(ld) then
  262. begin
  263. s1:=strpnew(char(byte(p^.left^.value)));
  264. l1:=1;
  265. s2:=getpcharcopy(p^.right);
  266. l2:=p^.right^.length;
  267. concatstrings:=true;
  268. end
  269. else if (lt=stringconstn) and (rt=stringconstn) then
  270. begin
  271. s1:=getpcharcopy(p^.left);
  272. l1:=p^.left^.length;
  273. s2:=getpcharcopy(p^.right);
  274. l2:=p^.right^.length;
  275. concatstrings:=true;
  276. end;
  277. { I will need to translate all this to ansistrings !!! }
  278. if concatstrings then
  279. begin
  280. case p^.treetype of
  281. addn :
  282. t:=genpcharconstnode(concatansistrings(s1,s2,l1,l2),l1+l2);
  283. ltn :
  284. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)<0),booldef);
  285. lten :
  286. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)<=0),booldef);
  287. gtn :
  288. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)>0),booldef);
  289. gten :
  290. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)>=0),booldef);
  291. equaln :
  292. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)=0),booldef);
  293. unequaln :
  294. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)<>0),booldef);
  295. end;
  296. ansistringdispose(s1,l1);
  297. ansistringdispose(s2,l2);
  298. disposetree(p);
  299. firstpass(t);
  300. p:=t;
  301. exit;
  302. end;
  303. { if both are orddefs then check sub types }
  304. if (ld^.deftype=orddef) and (rd^.deftype=orddef) then
  305. begin
  306. { 2 booleans ? }
  307. if is_boolean(ld) and is_boolean(rd) then
  308. begin
  309. case p^.treetype of
  310. andn,
  311. orn:
  312. begin
  313. calcregisters(p,0,0,0);
  314. make_bool_equal_size(p);
  315. p^.location.loc:=LOC_JUMP;
  316. end;
  317. xorn:
  318. begin
  319. make_bool_equal_size(p);
  320. calcregisters(p,1,0,0);
  321. end;
  322. unequaln,
  323. equaln:
  324. begin
  325. make_bool_equal_size(p);
  326. { Remove any compares with constants, becuase then
  327. we get a compare with Flags in the codegen which
  328. is not supported (PFV) }
  329. if (p^.left^.treetype=ordconstn) then
  330. begin
  331. hp:=p^.right;
  332. b:=(p^.left^.value<>0);
  333. ot:=p^.treetype;
  334. disposetree(p^.left);
  335. putnode(p);
  336. p:=hp;
  337. if (not(b) and (ot=equaln)) or
  338. (b and (ot=unequaln)) then
  339. begin
  340. p:=gensinglenode(notn,p);
  341. firstpass(p);
  342. end;
  343. exit;
  344. end;
  345. if (p^.right^.treetype=ordconstn) then
  346. begin
  347. hp:=p^.left;
  348. b:=(p^.right^.value<>0);
  349. ot:=p^.treetype;
  350. disposetree(p^.right);
  351. putnode(p);
  352. p:=hp;
  353. if (not(b) and (ot=equaln)) or
  354. (b and (ot=unequaln)) then
  355. begin
  356. p:=gensinglenode(notn,p);
  357. firstpass(p);
  358. end;
  359. exit;
  360. end;
  361. calcregisters(p,1,0,0);
  362. end;
  363. else
  364. CGMessage(type_e_mismatch);
  365. end;
  366. convdone:=true;
  367. end
  368. else
  369. { Both are chars? only convert to shortstrings for addn }
  370. if is_char(rd) and is_char(ld) then
  371. begin
  372. if p^.treetype=addn then
  373. begin
  374. p^.left:=gentypeconvnode(p^.left,cshortstringdef);
  375. p^.right:=gentypeconvnode(p^.right,cshortstringdef);
  376. firstpass(p^.left);
  377. firstpass(p^.right);
  378. { here we call STRCOPY }
  379. procinfo.flags:=procinfo.flags or pi_do_call;
  380. calcregisters(p,0,0,0);
  381. p^.location.loc:=LOC_MEM;
  382. end
  383. else
  384. calcregisters(p,1,0,0);
  385. convdone:=true;
  386. end
  387. else
  388. { is there a cardinal? }
  389. if (porddef(rd)^.typ=u32bit) or (porddef(ld)^.typ=u32bit) then
  390. begin
  391. { convert constants to u32bit }
  392. if (porddef(ld)^.typ<>u32bit) then
  393. begin
  394. { s32bit will be used for when the other is also s32bit }
  395. if (porddef(rd)^.typ=s32bit) and (lt<>ordconstn) then
  396. p^.left:=gentypeconvnode(p^.left,s32bitdef)
  397. else
  398. p^.left:=gentypeconvnode(p^.left,u32bitdef);
  399. firstpass(p^.left);
  400. end;
  401. if (porddef(rd)^.typ<>u32bit) then
  402. begin
  403. { s32bit will be used for when the other is also s32bit }
  404. if (porddef(ld)^.typ=s32bit) and (rt<>ordconstn) then
  405. p^.right:=gentypeconvnode(p^.right,s32bitdef)
  406. else
  407. p^.right:=gentypeconvnode(p^.right,u32bitdef);
  408. firstpass(p^.right);
  409. end;
  410. calcregisters(p,1,0,0);
  411. convdone:=true;
  412. end
  413. else if (porddef(rd)^.typ=s64bitint) or (porddef(ld)^.typ=s64bitint) then
  414. begin
  415. if (porddef(ld)^.typ<>s64bitint) then
  416. begin
  417. p^.left:=gentypeconvnode(p^.left,cs64bitintdef);
  418. firstpass(p^.left);
  419. end;
  420. if (porddef(rd)^.typ<>s64bitint) then
  421. begin
  422. p^.right:=gentypeconvnode(p^.right,cs64bitintdef);
  423. firstpass(p^.right);
  424. end;
  425. calcregisters(p,2,0,0);
  426. convdone:=true;
  427. end
  428. else if (porddef(rd)^.typ=u64bit) or (porddef(ld)^.typ=u64bit) then
  429. begin
  430. if (porddef(ld)^.typ<>u64bit) then
  431. begin
  432. p^.left:=gentypeconvnode(p^.left,cu64bitdef);
  433. firstpass(p^.left);
  434. end;
  435. if (porddef(rd)^.typ<>u64bit) then
  436. begin
  437. p^.right:=gentypeconvnode(p^.right,cu64bitdef);
  438. firstpass(p^.right);
  439. end;
  440. calcregisters(p,2,0,0);
  441. convdone:=true;
  442. end;
  443. end
  444. else
  445. { is one of the operands a string?,
  446. chararrays are also handled as strings (after conversion) }
  447. if (rd^.deftype=stringdef) or (ld^.deftype=stringdef) or
  448. is_chararray(rd) or is_chararray(ld) then
  449. begin
  450. if is_widestring(rd) or is_widestring(ld) then
  451. begin
  452. if not(is_widestring(rd)) then
  453. p^.right:=gentypeconvnode(p^.right,cwidestringdef);
  454. if not(is_widestring(ld)) then
  455. p^.left:=gentypeconvnode(p^.left,cwidestringdef);
  456. p^.resulttype:=cwidestringdef;
  457. { this is only for add, the comparisaion is handled later }
  458. p^.location.loc:=LOC_REGISTER;
  459. end
  460. else if is_ansistring(rd) or is_ansistring(ld) then
  461. begin
  462. if not(is_ansistring(rd)) then
  463. p^.right:=gentypeconvnode(p^.right,cansistringdef);
  464. if not(is_ansistring(ld)) then
  465. p^.left:=gentypeconvnode(p^.left,cansistringdef);
  466. p^.resulttype:=cansistringdef;
  467. { this is only for add, the comparisaion is handled later }
  468. p^.location.loc:=LOC_REGISTER;
  469. end
  470. else if is_longstring(rd) or is_longstring(ld) then
  471. begin
  472. if not(is_longstring(rd)) then
  473. p^.right:=gentypeconvnode(p^.right,clongstringdef);
  474. if not(is_longstring(ld)) then
  475. p^.left:=gentypeconvnode(p^.left,clongstringdef);
  476. p^.resulttype:=clongstringdef;
  477. { this is only for add, the comparisaion is handled later }
  478. p^.location.loc:=LOC_MEM;
  479. end
  480. else
  481. begin
  482. if not(is_shortstring(rd)) then
  483. p^.right:=gentypeconvnode(p^.right,cshortstringdef);
  484. if not(is_shortstring(ld)) then
  485. p^.left:=gentypeconvnode(p^.left,cshortstringdef);
  486. p^.resulttype:=cshortstringdef;
  487. { this is only for add, the comparisaion is handled later }
  488. p^.location.loc:=LOC_MEM;
  489. end;
  490. { only if there is a type cast we need to do again }
  491. { the first pass }
  492. if p^.left^.treetype=typeconvn then
  493. firstpass(p^.left);
  494. if p^.right^.treetype=typeconvn then
  495. firstpass(p^.right);
  496. { here we call STRCONCAT or STRCMP or STRCOPY }
  497. procinfo.flags:=procinfo.flags or pi_do_call;
  498. if p^.location.loc=LOC_MEM then
  499. calcregisters(p,0,0,0)
  500. else
  501. calcregisters(p,1,0,0);
  502. convdone:=true;
  503. end
  504. else
  505. { left side a setdef ? }
  506. if (ld^.deftype=setdef) then
  507. begin
  508. { trying to add a set element? }
  509. if (p^.treetype=addn) and (rd^.deftype<>setdef) then
  510. begin
  511. if (rt=setelementn) then
  512. begin
  513. if not(is_equal(psetdef(ld)^.setof,rd)) then
  514. CGMessage(type_e_set_element_are_not_comp);
  515. end
  516. else
  517. CGMessage(type_e_mismatch)
  518. end
  519. else
  520. begin
  521. if not(p^.treetype in [addn,subn,symdifn,muln,equaln,unequaln]) then
  522. CGMessage(type_e_set_operation_unknown);
  523. { right def must be a also be set }
  524. if (rd^.deftype<>setdef) or not(is_equal(rd,ld)) then
  525. CGMessage(type_e_set_element_are_not_comp);
  526. end;
  527. { ranges require normsets }
  528. if (psetdef(ld)^.settype=smallset) and
  529. (rt=setelementn) and
  530. assigned(p^.right^.right) then
  531. begin
  532. { generate a temporary normset def }
  533. tempdef:=new(psetdef,init(psetdef(ld)^.setof,255));
  534. p^.left:=gentypeconvnode(p^.left,tempdef);
  535. firstpass(p^.left);
  536. dispose(tempdef,done);
  537. ld:=p^.left^.resulttype;
  538. end;
  539. { if the destination is not a smallset then insert a typeconv
  540. which loads a smallset into a normal set }
  541. if (psetdef(ld)^.settype<>smallset) and
  542. (psetdef(rd)^.settype=smallset) then
  543. begin
  544. if (p^.right^.treetype=setconstn) then
  545. begin
  546. t:=gensetconstnode(p^.right^.value_set,psetdef(p^.left^.resulttype));
  547. t^.left:=p^.right^.left;
  548. putnode(p^.right);
  549. p^.right:=t;
  550. end
  551. else
  552. p^.right:=gentypeconvnode(p^.right,psetdef(p^.left^.resulttype));
  553. firstpass(p^.right);
  554. end;
  555. { do constant evaluation }
  556. if (p^.right^.treetype=setconstn) and
  557. not assigned(p^.right^.left) and
  558. (p^.left^.treetype=setconstn) and
  559. not assigned(p^.left^.left) then
  560. begin
  561. new(resultset);
  562. case p^.treetype of
  563. addn : begin
  564. for i:=0 to 31 do
  565. resultset^[i]:=
  566. p^.right^.value_set^[i] or p^.left^.value_set^[i];
  567. t:=gensetconstnode(resultset,psetdef(ld));
  568. end;
  569. muln : begin
  570. for i:=0 to 31 do
  571. resultset^[i]:=
  572. p^.right^.value_set^[i] and p^.left^.value_set^[i];
  573. t:=gensetconstnode(resultset,psetdef(ld));
  574. end;
  575. subn : begin
  576. for i:=0 to 31 do
  577. resultset^[i]:=
  578. p^.left^.value_set^[i] and not(p^.right^.value_set^[i]);
  579. t:=gensetconstnode(resultset,psetdef(ld));
  580. end;
  581. symdifn : begin
  582. for i:=0 to 31 do
  583. resultset^[i]:=
  584. p^.left^.value_set^[i] xor p^.right^.value_set^[i];
  585. t:=gensetconstnode(resultset,psetdef(ld));
  586. end;
  587. unequaln : begin
  588. b:=true;
  589. for i:=0 to 31 do
  590. if p^.right^.value_set^[i]=p^.left^.value_set^[i] then
  591. begin
  592. b:=false;
  593. break;
  594. end;
  595. t:=genordinalconstnode(ord(b),booldef);
  596. end;
  597. equaln : begin
  598. b:=true;
  599. for i:=0 to 31 do
  600. if p^.right^.value_set^[i]<>p^.left^.value_set^[i] then
  601. begin
  602. b:=false;
  603. break;
  604. end;
  605. t:=genordinalconstnode(ord(b),booldef);
  606. end;
  607. end;
  608. dispose(resultset);
  609. disposetree(p);
  610. p:=t;
  611. firstpass(p);
  612. exit;
  613. end
  614. else
  615. if psetdef(ld)^.settype=smallset then
  616. begin
  617. calcregisters(p,1,0,0);
  618. p^.location.loc:=LOC_REGISTER;
  619. end
  620. else
  621. begin
  622. calcregisters(p,0,0,0);
  623. { here we call SET... }
  624. procinfo.flags:=procinfo.flags or pi_do_call;
  625. p^.location.loc:=LOC_MEM;
  626. end;
  627. convdone:=true;
  628. end
  629. else
  630. { is one a real float ? }
  631. if (rd^.deftype=floatdef) or (ld^.deftype=floatdef) then
  632. begin
  633. { if one is a fixed, then convert to f32bit }
  634. if ((rd^.deftype=floatdef) and (pfloatdef(rd)^.typ=f32bit)) or
  635. ((ld^.deftype=floatdef) and (pfloatdef(ld)^.typ=f32bit)) then
  636. begin
  637. if not is_integer(rd) or (p^.treetype<>muln) then
  638. p^.right:=gentypeconvnode(p^.right,s32fixeddef);
  639. if not is_integer(ld) or (p^.treetype<>muln) then
  640. p^.left:=gentypeconvnode(p^.left,s32fixeddef);
  641. firstpass(p^.left);
  642. firstpass(p^.right);
  643. calcregisters(p,1,0,0);
  644. p^.location.loc:=LOC_REGISTER;
  645. end
  646. else
  647. { convert both to c64float }
  648. begin
  649. p^.right:=gentypeconvnode(p^.right,c64floatdef);
  650. p^.left:=gentypeconvnode(p^.left,c64floatdef);
  651. firstpass(p^.left);
  652. firstpass(p^.right);
  653. calcregisters(p,1,1,0);
  654. p^.location.loc:=LOC_FPU;
  655. end;
  656. convdone:=true;
  657. end
  658. else
  659. { pointer comperation and subtraction }
  660. if (rd^.deftype=pointerdef) and (ld^.deftype=pointerdef) then
  661. begin
  662. p^.location.loc:=LOC_REGISTER;
  663. p^.right:=gentypeconvnode(p^.right,ld);
  664. firstpass(p^.right);
  665. calcregisters(p,1,0,0);
  666. case p^.treetype of
  667. equaln,unequaln : ;
  668. ltn,lten,gtn,gten:
  669. begin
  670. if not(cs_extsyntax in aktmoduleswitches) then
  671. CGMessage(type_e_mismatch);
  672. end;
  673. subn:
  674. begin
  675. if not(cs_extsyntax in aktmoduleswitches) then
  676. CGMessage(type_e_mismatch);
  677. p^.resulttype:=s32bitdef;
  678. exit;
  679. end;
  680. else CGMessage(type_e_mismatch);
  681. end;
  682. convdone:=true;
  683. end
  684. else
  685. if (rd^.deftype=objectdef) and (ld^.deftype=objectdef) and
  686. pobjectdef(rd)^.isclass and pobjectdef(ld)^.isclass then
  687. begin
  688. p^.location.loc:=LOC_REGISTER;
  689. if pobjectdef(rd)^.isrelated(pobjectdef(ld)) then
  690. p^.right:=gentypeconvnode(p^.right,ld)
  691. else
  692. p^.left:=gentypeconvnode(p^.left,rd);
  693. firstpass(p^.right);
  694. firstpass(p^.left);
  695. calcregisters(p,1,0,0);
  696. case p^.treetype of
  697. equaln,unequaln : ;
  698. else CGMessage(type_e_mismatch);
  699. end;
  700. convdone:=true;
  701. end
  702. else
  703. if (rd^.deftype=classrefdef) and (ld^.deftype=classrefdef) then
  704. begin
  705. p^.location.loc:=LOC_REGISTER;
  706. if pobjectdef(pclassrefdef(rd)^.definition)^.isrelated(pobjectdef(
  707. pclassrefdef(ld)^.definition)) then
  708. p^.right:=gentypeconvnode(p^.right,ld)
  709. else
  710. p^.left:=gentypeconvnode(p^.left,rd);
  711. firstpass(p^.right);
  712. firstpass(p^.left);
  713. calcregisters(p,1,0,0);
  714. case p^.treetype of
  715. equaln,unequaln : ;
  716. else CGMessage(type_e_mismatch);
  717. end;
  718. convdone:=true;
  719. end
  720. else
  721. { allows comperasion with nil pointer }
  722. if (rd^.deftype=objectdef) and
  723. pobjectdef(rd)^.isclass then
  724. begin
  725. p^.location.loc:=LOC_REGISTER;
  726. p^.left:=gentypeconvnode(p^.left,rd);
  727. firstpass(p^.left);
  728. calcregisters(p,1,0,0);
  729. case p^.treetype of
  730. equaln,unequaln : ;
  731. else CGMessage(type_e_mismatch);
  732. end;
  733. convdone:=true;
  734. end
  735. else
  736. if (ld^.deftype=objectdef) and
  737. pobjectdef(ld)^.isclass then
  738. begin
  739. p^.location.loc:=LOC_REGISTER;
  740. p^.right:=gentypeconvnode(p^.right,ld);
  741. firstpass(p^.right);
  742. calcregisters(p,1,0,0);
  743. case p^.treetype of
  744. equaln,unequaln : ;
  745. else CGMessage(type_e_mismatch);
  746. end;
  747. convdone:=true;
  748. end
  749. else
  750. if (rd^.deftype=classrefdef) then
  751. begin
  752. p^.left:=gentypeconvnode(p^.left,rd);
  753. firstpass(p^.left);
  754. calcregisters(p,1,0,0);
  755. case p^.treetype of
  756. equaln,unequaln : ;
  757. else CGMessage(type_e_mismatch);
  758. end;
  759. convdone:=true;
  760. end
  761. else
  762. if (ld^.deftype=classrefdef) then
  763. begin
  764. p^.right:=gentypeconvnode(p^.right,ld);
  765. firstpass(p^.right);
  766. calcregisters(p,1,0,0);
  767. case p^.treetype of
  768. equaln,unequaln : ;
  769. else
  770. CGMessage(type_e_mismatch);
  771. end;
  772. convdone:=true;
  773. end
  774. else
  775. if (rd^.deftype=pointerdef) then
  776. begin
  777. p^.location.loc:=LOC_REGISTER;
  778. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  779. firstpass(p^.left);
  780. calcregisters(p,1,0,0);
  781. if p^.treetype=addn then
  782. begin
  783. if not(cs_extsyntax in aktmoduleswitches) then
  784. CGMessage(type_e_mismatch);
  785. end
  786. else
  787. CGMessage(type_e_mismatch);
  788. convdone:=true;
  789. end
  790. else
  791. if (ld^.deftype=pointerdef) then
  792. begin
  793. p^.location.loc:=LOC_REGISTER;
  794. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  795. firstpass(p^.right);
  796. calcregisters(p,1,0,0);
  797. case p^.treetype of
  798. addn,subn : begin
  799. if not(cs_extsyntax in aktmoduleswitches) or
  800. (not(is_pchar(ld)) and (m_tp in aktmodeswitches)) then
  801. CGMessage(type_e_mismatch);
  802. end;
  803. else
  804. CGMessage(type_e_mismatch);
  805. end;
  806. convdone:=true;
  807. end
  808. else
  809. if (rd^.deftype=procvardef) and (ld^.deftype=procvardef) and is_equal(rd,ld) then
  810. begin
  811. calcregisters(p,1,0,0);
  812. p^.location.loc:=LOC_REGISTER;
  813. case p^.treetype of
  814. equaln,unequaln : ;
  815. else
  816. CGMessage(type_e_mismatch);
  817. end;
  818. convdone:=true;
  819. end
  820. else
  821. {$ifdef SUPPORT_MMX}
  822. if (cs_mmx in aktlocalswitches) and is_mmx_able_array(ld) and
  823. is_mmx_able_array(rd) and is_equal(ld,rd) then
  824. begin
  825. firstpass(p^.right);
  826. firstpass(p^.left);
  827. case p^.treetype of
  828. addn,subn,xorn,orn,andn:
  829. ;
  830. { mul is a little bit restricted }
  831. muln:
  832. if not(mmx_type(p^.left^.resulttype) in
  833. [mmxu16bit,mmxs16bit,mmxfixed16]) then
  834. CGMessage(type_e_mismatch);
  835. else
  836. CGMessage(type_e_mismatch);
  837. end;
  838. p^.location.loc:=LOC_MMXREGISTER;
  839. calcregisters(p,0,0,1);
  840. convdone:=true;
  841. end
  842. else
  843. {$endif SUPPORT_MMX}
  844. if (ld^.deftype=enumdef) and (rd^.deftype=enumdef) and (is_equal(ld,rd)) then
  845. begin
  846. calcregisters(p,1,0,0);
  847. case p^.treetype of
  848. equaln,unequaln,
  849. ltn,lten,gtn,gten : ;
  850. else CGMessage(type_e_mismatch);
  851. end;
  852. convdone:=true;
  853. end;
  854. { the general solution is to convert to 32 bit int }
  855. if not convdone then
  856. begin
  857. { but an int/int gives real/real! }
  858. if p^.treetype=slashn then
  859. begin
  860. CGMessage(type_w_int_slash_int);
  861. CGMessage(type_h_use_div_for_int);
  862. p^.right:=gentypeconvnode(p^.right,c64floatdef);
  863. p^.left:=gentypeconvnode(p^.left,c64floatdef);
  864. firstpass(p^.left);
  865. firstpass(p^.right);
  866. { maybe we need an integer register to save }
  867. { a reference }
  868. if ((p^.left^.location.loc<>LOC_FPU) or
  869. (p^.right^.location.loc<>LOC_FPU)) and
  870. (p^.left^.registers32=p^.right^.registers32) then
  871. calcregisters(p,1,1,0)
  872. else
  873. calcregisters(p,0,1,0);
  874. p^.location.loc:=LOC_FPU;
  875. end
  876. else
  877. begin
  878. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  879. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  880. firstpass(p^.left);
  881. firstpass(p^.right);
  882. calcregisters(p,1,0,0);
  883. p^.location.loc:=LOC_REGISTER;
  884. end;
  885. end;
  886. if codegenerror then
  887. exit;
  888. { determines result type for comparions }
  889. { here the is a problem with multiple passes }
  890. { example length(s)+1 gets internal 'longint' type first }
  891. { if it is a arg it is converted to 'LONGINT' }
  892. { but a second first pass will reset this to 'longint' }
  893. case p^.treetype of
  894. ltn,lten,gtn,gten,equaln,unequaln:
  895. begin
  896. if (not assigned(p^.resulttype)) or
  897. (p^.resulttype^.deftype=stringdef) then
  898. p^.resulttype:=booldef;
  899. if is_64bitint(p^.left^.resulttype) then
  900. p^.location.loc:=LOC_JUMP
  901. else
  902. p^.location.loc:=LOC_FLAGS;
  903. end;
  904. xorn:
  905. begin
  906. if not assigned(p^.resulttype) then
  907. p^.resulttype:=p^.left^.resulttype;
  908. p^.location.loc:=LOC_REGISTER;
  909. end;
  910. addn:
  911. begin
  912. if not assigned(p^.resulttype) then
  913. begin
  914. { for strings, return is always a 255 char string }
  915. if is_shortstring(p^.left^.resulttype) then
  916. p^.resulttype:=cshortstringdef
  917. else
  918. p^.resulttype:=p^.left^.resulttype;
  919. end;
  920. end;
  921. else
  922. p^.resulttype:=p^.left^.resulttype;
  923. end;
  924. end;
  925. end.
  926. {
  927. $Log$
  928. Revision 1.19 1998-12-30 13:35:35 peter
  929. * fix for boolean=true compares
  930. Revision 1.18 1998/12/15 17:12:35 peter
  931. * pointer+ord not allowed in tp mode
  932. Revision 1.17 1998/12/11 00:03:51 peter
  933. + globtype,tokens,version unit splitted from globals
  934. Revision 1.16 1998/12/10 09:47:31 florian
  935. + basic operations with int64/qord (compiler with -dint64)
  936. + rtti of enumerations extended: names are now written
  937. Revision 1.15 1998/11/24 22:59:05 peter
  938. * handle array of char the same as strings
  939. Revision 1.14 1998/11/17 00:36:47 peter
  940. * more ansistring fixes
  941. Revision 1.13 1998/11/16 15:33:05 peter
  942. * fixed return for ansistrings
  943. Revision 1.12 1998/11/05 14:28:16 peter
  944. * fixed unknown set operation msg
  945. Revision 1.11 1998/11/05 12:03:02 peter
  946. * released useansistring
  947. * removed -Sv, its now available in fpc modes
  948. Revision 1.10 1998/11/04 10:11:46 peter
  949. * ansistring fixes
  950. Revision 1.9 1998/10/25 23:32:04 peter
  951. * fixed u32bit - s32bit conversion problems
  952. Revision 1.8 1998/10/22 12:12:28 pierre
  953. + better error info on unimplemented set operators
  954. Revision 1.7 1998/10/21 15:12:57 pierre
  955. * bug fix for IOCHECK inside a procedure with iocheck modifier
  956. * removed the GPF for unexistant overloading
  957. (firstcall was called with procedinition=nil !)
  958. * changed typen to what Florian proposed
  959. gentypenode(p : pdef) sets the typenodetype field
  960. and resulttype is only set if inside bt_type block !
  961. Revision 1.6 1998/10/20 15:09:24 florian
  962. + binary operators for ansi strings
  963. Revision 1.5 1998/10/20 08:07:05 pierre
  964. * several memory corruptions due to double freemem solved
  965. => never use p^.loc.location:=p^.left^.loc.location;
  966. + finally I added now by default
  967. that ra386dir translates global and unit symbols
  968. + added a first field in tsymtable and
  969. a nextsym field in tsym
  970. (this allows to obtain ordered type info for
  971. records and objects in gdb !)
  972. Revision 1.4 1998/10/14 12:53:39 peter
  973. * fixed small tp7 things
  974. * boolean:=longbool and longbool fixed
  975. Revision 1.3 1998/10/11 14:31:19 peter
  976. + checks for division by zero
  977. Revision 1.2 1998/10/05 21:33:31 peter
  978. * fixed 161,165,166,167,168
  979. Revision 1.1 1998/09/23 20:42:24 peter
  980. * splitted pass_1
  981. }