tcadd.pas 38 KB

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