tcadd.pas 52 KB

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