nadd.pas 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Type checking and register allocation for add nodes
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit nadd;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. node;
  23. type
  24. taddnode = class(tbinopnode)
  25. constructor create(tt : tnodetype;l,r : tnode);override;
  26. function pass_1 : tnode;override;
  27. function det_resulttype:tnode;override;
  28. {$ifdef state_tracking}
  29. function track_state_pass(exec_known:boolean):boolean;override;
  30. {$endif}
  31. protected
  32. { override the following if you want to implement }
  33. { parts explicitely in the code generator (JM) }
  34. function first_addstring: tnode; virtual;
  35. function first_addset: tnode; virtual;
  36. { only implements "muln" nodes, the rest always has to be done in }
  37. { the code generator for performance reasons (JM) }
  38. function first_add64bitint: tnode; virtual;
  39. end;
  40. taddnodeclass = class of taddnode;
  41. var
  42. { caddnode is used to create nodes of the add type }
  43. { the virtual constructor allows to assign }
  44. { another class type to caddnode => processor }
  45. { specific node types can be created }
  46. caddnode : taddnodeclass;
  47. implementation
  48. uses
  49. globtype,systems,
  50. cutils,verbose,globals,widestr,
  51. symconst,symtype,symdef,symsym,symtable,defbase,
  52. cgbase,
  53. htypechk,pass_1,
  54. nmat,ncnv,ncon,nset,nopt,ncal,ninl,
  55. {$ifdef state_tracking}
  56. nstate,
  57. {$endif}
  58. cpubase;
  59. {*****************************************************************************
  60. TADDNODE
  61. *****************************************************************************}
  62. {$ifdef fpc}
  63. {$maxfpuregisters 0}
  64. {$endif fpc}
  65. constructor taddnode.create(tt : tnodetype;l,r : tnode);
  66. begin
  67. inherited create(tt,l,r);
  68. end;
  69. function taddnode.det_resulttype:tnode;
  70. var
  71. hp,t : tnode;
  72. lt,rt : tnodetype;
  73. rd,ld : tdef;
  74. htype : ttype;
  75. ot : tnodetype;
  76. concatstrings : boolean;
  77. resultset : Tconstset;
  78. i : longint;
  79. b : boolean;
  80. s1,s2 : pchar;
  81. ws1,ws2 : pcompilerwidestring;
  82. l1,l2 : longint;
  83. rv,lv : tconstexprint;
  84. rvd,lvd : bestreal;
  85. {$ifdef state_tracking}
  86. factval : Tnode;
  87. change : boolean;
  88. {$endif}
  89. begin
  90. result:=nil;
  91. { first do the two subtrees }
  92. resulttypepass(left);
  93. resulttypepass(right);
  94. { both left and right need to be valid }
  95. set_varstate(left,true);
  96. set_varstate(right,true);
  97. if codegenerror then
  98. exit;
  99. { convert array constructors to sets, because there is no other operator
  100. possible for array constructors }
  101. if is_array_constructor(left.resulttype.def) then
  102. begin
  103. arrayconstructor_to_set(left);
  104. resulttypepass(left);
  105. end;
  106. if is_array_constructor(right.resulttype.def) then
  107. begin
  108. arrayconstructor_to_set(right);
  109. resulttypepass(right);
  110. end;
  111. { allow operator overloading }
  112. hp:=self;
  113. if isbinaryoverloaded(hp) then
  114. begin
  115. result:=hp;
  116. exit;
  117. end;
  118. { Kylix allows enum+ordconstn in an enum declaration (blocktype
  119. is bt_type), we need to do the conversion here before the
  120. constant folding }
  121. if (m_delphi in aktmodeswitches) and
  122. (blocktype=bt_type) then
  123. begin
  124. if (left.resulttype.def.deftype=enumdef) and
  125. (right.resulttype.def.deftype=orddef) then
  126. begin
  127. { insert explicit typecast to s32bit }
  128. left:=ctypeconvnode.create(left,s32bittype);
  129. left.toggleflag(nf_explizit);
  130. resulttypepass(left);
  131. end
  132. else
  133. if (left.resulttype.def.deftype=orddef) and
  134. (right.resulttype.def.deftype=enumdef) then
  135. begin
  136. { insert explicit typecast to s32bit }
  137. right:=ctypeconvnode.create(right,s32bittype);
  138. include(right.flags,nf_explizit);
  139. resulttypepass(right);
  140. end;
  141. end;
  142. { is one a real float, then both need to be floats, this
  143. need to be done before the constant folding so constant
  144. operation on a float and int are also handled }
  145. if (right.resulttype.def.deftype=floatdef) or (left.resulttype.def.deftype=floatdef) then
  146. begin
  147. inserttypeconv(right,pbestrealtype^);
  148. inserttypeconv(left,pbestrealtype^);
  149. end;
  150. { if one operand is a widechar or a widestring, both operands }
  151. { are converted to widestring. This must be done before constant }
  152. { folding to allow char+widechar etc. }
  153. if is_widestring(right.resulttype.def) or
  154. is_widestring(left.resulttype.def) or
  155. is_widechar(right.resulttype.def) or
  156. is_widechar(left.resulttype.def) then
  157. begin
  158. inserttypeconv(right,cwidestringtype);
  159. inserttypeconv(left,cwidestringtype);
  160. end;
  161. { load easier access variables }
  162. rd:=right.resulttype.def;
  163. ld:=left.resulttype.def;
  164. rt:=right.nodetype;
  165. lt:=left.nodetype;
  166. { both are int constants }
  167. if (((is_constintnode(left) and is_constintnode(right)) or
  168. (is_constboolnode(left) and is_constboolnode(right) and
  169. (nodetype in [ltn,lten,gtn,gten,equaln,unequaln,andn,xorn,orn])))) or
  170. { support pointer arithmetics on constants (JM) }
  171. ((lt = pointerconstn) and is_constintnode(right) and
  172. (nodetype in [addn,subn])) or
  173. ((lt = pointerconstn) and (rt = pointerconstn) and
  174. (nodetype in [ltn,lten,gtn,gten,equaln,unequaln,subn])) then
  175. begin
  176. { when comparing/substracting pointers, make sure they are }
  177. { of the same type (JM) }
  178. if (lt = pointerconstn) and (rt = pointerconstn) then
  179. begin
  180. if not(cs_extsyntax in aktmoduleswitches) and
  181. not(nodetype in [equaln,unequaln]) then
  182. CGMessage(type_e_mismatch)
  183. else
  184. if (nodetype <> subn) and
  185. is_voidpointer(rd) then
  186. inserttypeconv(right,left.resulttype)
  187. else if (nodetype <> subn) and
  188. is_voidpointer(ld) then
  189. inserttypeconv(left,right.resulttype)
  190. else if not(is_equal(ld,rd)) then
  191. CGMessage(type_e_mismatch);
  192. end
  193. else if (lt=ordconstn) and (rt=ordconstn) then
  194. begin
  195. { make left const type the biggest (u32bit is bigger than
  196. s32bit for or,and,xor) }
  197. if (rd.size>ld.size) or
  198. ((torddef(rd).typ=u32bit) and
  199. (torddef(ld).typ=s32bit) and
  200. (nodetype in [orn,andn,xorn])) then
  201. inserttypeconv(left,right.resulttype);
  202. end;
  203. { load values }
  204. if (lt = ordconstn) then
  205. lv:=tordconstnode(left).value
  206. else
  207. lv:=tpointerconstnode(left).value;
  208. if (rt = ordconstn) then
  209. rv:=tordconstnode(right).value
  210. else
  211. rv:=tpointerconstnode(right).value;
  212. if (lt = pointerconstn) and
  213. (rt <> pointerconstn) then
  214. rv := rv * tpointerdef(left.resulttype.def).pointertype.def.size;
  215. if (rt = pointerconstn) and
  216. (lt <> pointerconstn) then
  217. lv := lv * tpointerdef(right.resulttype.def).pointertype.def.size;
  218. case nodetype of
  219. addn :
  220. if (lt <> pointerconstn) then
  221. t := genintconstnode(lv+rv)
  222. else
  223. t := cpointerconstnode.create(lv+rv,left.resulttype);
  224. subn :
  225. if (lt <> pointerconstn) or (rt = pointerconstn) then
  226. t := genintconstnode(lv-rv)
  227. else
  228. t := cpointerconstnode.create(lv-rv,left.resulttype);
  229. muln :
  230. t:=genintconstnode(lv*rv);
  231. xorn :
  232. t:=cordconstnode.create(lv xor rv,left.resulttype);
  233. orn :
  234. t:=cordconstnode.create(lv or rv,left.resulttype);
  235. andn :
  236. t:=cordconstnode.create(lv and rv,left.resulttype);
  237. ltn :
  238. t:=cordconstnode.create(ord(lv<rv),booltype);
  239. lten :
  240. t:=cordconstnode.create(ord(lv<=rv),booltype);
  241. gtn :
  242. t:=cordconstnode.create(ord(lv>rv),booltype);
  243. gten :
  244. t:=cordconstnode.create(ord(lv>=rv),booltype);
  245. equaln :
  246. t:=cordconstnode.create(ord(lv=rv),booltype);
  247. unequaln :
  248. t:=cordconstnode.create(ord(lv<>rv),booltype);
  249. slashn :
  250. begin
  251. { int/int becomes a real }
  252. rvd:=rv;
  253. lvd:=lv;
  254. if int(rvd)=0 then
  255. begin
  256. Message(parser_e_invalid_float_operation);
  257. t:=crealconstnode.create(0,pbestrealtype^);
  258. end
  259. else
  260. t:=crealconstnode.create(int(lvd)/int(rvd),pbestrealtype^);
  261. end;
  262. else
  263. CGMessage(type_e_mismatch);
  264. end;
  265. result:=t;
  266. exit;
  267. end;
  268. { both real constants ? }
  269. if (lt=realconstn) and (rt=realconstn) then
  270. begin
  271. lvd:=trealconstnode(left).value_real;
  272. rvd:=trealconstnode(right).value_real;
  273. case nodetype of
  274. addn :
  275. t:=crealconstnode.create(lvd+rvd,pbestrealtype^);
  276. subn :
  277. t:=crealconstnode.create(lvd-rvd,pbestrealtype^);
  278. muln :
  279. t:=crealconstnode.create(lvd*rvd,pbestrealtype^);
  280. starstarn,
  281. caretn :
  282. begin
  283. if lvd<0 then
  284. begin
  285. Message(parser_e_invalid_float_operation);
  286. t:=crealconstnode.create(0,pbestrealtype^);
  287. end
  288. else if lvd=0 then
  289. t:=crealconstnode.create(1.0,pbestrealtype^)
  290. else
  291. t:=crealconstnode.create(exp(ln(lvd)*rvd),pbestrealtype^);
  292. end;
  293. slashn :
  294. begin
  295. if rvd=0 then
  296. begin
  297. Message(parser_e_invalid_float_operation);
  298. t:=crealconstnode.create(0,pbestrealtype^);
  299. end
  300. else
  301. t:=crealconstnode.create(lvd/rvd,pbestrealtype^);
  302. end;
  303. ltn :
  304. t:=cordconstnode.create(ord(lvd<rvd),booltype);
  305. lten :
  306. t:=cordconstnode.create(ord(lvd<=rvd),booltype);
  307. gtn :
  308. t:=cordconstnode.create(ord(lvd>rvd),booltype);
  309. gten :
  310. t:=cordconstnode.create(ord(lvd>=rvd),booltype);
  311. equaln :
  312. t:=cordconstnode.create(ord(lvd=rvd),booltype);
  313. unequaln :
  314. t:=cordconstnode.create(ord(lvd<>rvd),booltype);
  315. else
  316. CGMessage(type_e_mismatch);
  317. end;
  318. result:=t;
  319. exit;
  320. end;
  321. { first, we handle widestrings, so we can check later for }
  322. { stringconstn only }
  323. { widechars are converted above to widestrings too }
  324. { this isn't veryy efficient, but I don't think }
  325. { that it does matter that much (FK) }
  326. if (lt=stringconstn) and (rt=stringconstn) and
  327. (tstringconstnode(left).st_type=st_widestring) and
  328. (tstringconstnode(right).st_type=st_widestring) then
  329. begin
  330. initwidestring(ws1);
  331. initwidestring(ws2);
  332. copywidestring(pcompilerwidestring(tstringconstnode(left).value_str),ws1);
  333. copywidestring(pcompilerwidestring(tstringconstnode(right).value_str),ws2);
  334. case nodetype of
  335. addn :
  336. begin
  337. concatwidestrings(ws1,ws2);
  338. t:=cstringconstnode.createwstr(ws1);
  339. end;
  340. ltn :
  341. t:=cordconstnode.create(byte(comparewidestrings(ws1,ws2)<0),booltype);
  342. lten :
  343. t:=cordconstnode.create(byte(comparewidestrings(ws1,ws2)<=0),booltype);
  344. gtn :
  345. t:=cordconstnode.create(byte(comparewidestrings(ws1,ws2)>0),booltype);
  346. gten :
  347. t:=cordconstnode.create(byte(comparewidestrings(ws1,ws2)>=0),booltype);
  348. equaln :
  349. t:=cordconstnode.create(byte(comparewidestrings(ws1,ws2)=0),booltype);
  350. unequaln :
  351. t:=cordconstnode.create(byte(comparewidestrings(ws1,ws2)<>0),booltype);
  352. end;
  353. donewidestring(ws1);
  354. donewidestring(ws2);
  355. result:=t;
  356. exit;
  357. end;
  358. { concating strings ? }
  359. concatstrings:=false;
  360. s1:=nil;
  361. s2:=nil;
  362. if (lt=ordconstn) and (rt=ordconstn) and
  363. is_char(ld) and is_char(rd) then
  364. begin
  365. s1:=strpnew(char(byte(tordconstnode(left).value)));
  366. s2:=strpnew(char(byte(tordconstnode(right).value)));
  367. l1:=1;
  368. l2:=1;
  369. concatstrings:=true;
  370. end
  371. else
  372. if (lt=stringconstn) and (rt=ordconstn) and is_char(rd) then
  373. begin
  374. s1:=tstringconstnode(left).getpcharcopy;
  375. l1:=tstringconstnode(left).len;
  376. s2:=strpnew(char(byte(tordconstnode(right).value)));
  377. l2:=1;
  378. concatstrings:=true;
  379. end
  380. else
  381. if (lt=ordconstn) and (rt=stringconstn) and is_char(ld) then
  382. begin
  383. s1:=strpnew(char(byte(tordconstnode(left).value)));
  384. l1:=1;
  385. s2:=tstringconstnode(right).getpcharcopy;
  386. l2:=tstringconstnode(right).len;
  387. concatstrings:=true;
  388. end
  389. else if (lt=stringconstn) and (rt=stringconstn) then
  390. begin
  391. s1:=tstringconstnode(left).getpcharcopy;
  392. l1:=tstringconstnode(left).len;
  393. s2:=tstringconstnode(right).getpcharcopy;
  394. l2:=tstringconstnode(right).len;
  395. concatstrings:=true;
  396. end;
  397. if concatstrings then
  398. begin
  399. case nodetype of
  400. addn :
  401. t:=cstringconstnode.createpchar(concatansistrings(s1,s2,l1,l2),l1+l2);
  402. ltn :
  403. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)<0),booltype);
  404. lten :
  405. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)<=0),booltype);
  406. gtn :
  407. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)>0),booltype);
  408. gten :
  409. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)>=0),booltype);
  410. equaln :
  411. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)=0),booltype);
  412. unequaln :
  413. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)<>0),booltype);
  414. end;
  415. ansistringdispose(s1,l1);
  416. ansistringdispose(s2,l2);
  417. result:=t;
  418. exit;
  419. end;
  420. { set constant evaluation }
  421. if (right.nodetype=setconstn) and
  422. not assigned(tsetconstnode(right).left) and
  423. (left.nodetype=setconstn) and
  424. not assigned(tsetconstnode(left).left) then
  425. begin
  426. { check if size adjusting is needed, only for left
  427. to right as the other way is checked in the typeconv }
  428. if (tsetdef(right.resulttype.def).settype=smallset) and
  429. (tsetdef(left.resulttype.def).settype<>smallset) then
  430. tsetdef(right.resulttype.def).changesettype(normset);
  431. { check base types }
  432. inserttypeconv(left,right.resulttype);
  433. if codegenerror then
  434. begin
  435. { recover by only returning the left part }
  436. result:=left;
  437. left:=nil;
  438. exit;
  439. end;
  440. {$ifdef oldset}
  441. case nodetype of
  442. addn :
  443. begin
  444. for i:=0 to 31 do
  445. resultset[i]:=tsetconstnode(right).value_set^[i] or tsetconstnode(left).value_set^[i];
  446. t:=csetconstnode.create(@resultset,left.resulttype);
  447. end;
  448. muln :
  449. begin
  450. for i:=0 to 31 do
  451. resultset[i]:=tsetconstnode(right).value_set^[i] and tsetconstnode(left).value_set^[i];
  452. t:=csetconstnode.create(@resultset,left.resulttype);
  453. end;
  454. subn :
  455. begin
  456. for i:=0 to 31 do
  457. resultset[i]:=tsetconstnode(left).value_set^[i] and not(tsetconstnode(right).value_set^[i]);
  458. t:=csetconstnode.create(@resultset,left.resulttype);
  459. end;
  460. symdifn :
  461. begin
  462. for i:=0 to 31 do
  463. resultset[i]:=tsetconstnode(left).value_set^[i] xor tsetconstnode(right).value_set^[i];
  464. t:=csetconstnode.create(@resultset,left.resulttype);
  465. end;
  466. unequaln :
  467. begin
  468. b:=true;
  469. for i:=0 to 31 do
  470. if tsetconstnode(right).value_set^[i]=tsetconstnode(left).value_set^[i] then
  471. begin
  472. b:=false;
  473. break;
  474. end;
  475. t:=cordconstnode.create(ord(b),booltype);
  476. end;
  477. equaln :
  478. begin
  479. b:=true;
  480. for i:=0 to 31 do
  481. if tsetconstnode(right).value_set^[i]<>tsetconstnode(left).value_set^[i] then
  482. begin
  483. b:=false;
  484. break;
  485. end;
  486. t:=cordconstnode.create(ord(b),booltype);
  487. end;
  488. lten :
  489. begin
  490. b := true;
  491. for i := 0 to 31 Do
  492. if (tsetconstnode(right).value_set^[i] And tsetconstnode(left).value_set^[i]) <>
  493. tsetconstnode(left).value_set^[i] Then
  494. begin
  495. b := false;
  496. break
  497. end;
  498. t := cordconstnode.create(ord(b),booltype);
  499. end;
  500. gten :
  501. begin
  502. b := true;
  503. for i := 0 to 31 Do
  504. If (tsetconstnode(left).value_set^[i] And tsetconstnode(right).value_set^[i]) <>
  505. tsetconstnode(right).value_set^[i] Then
  506. begin
  507. b := false;
  508. break
  509. end;
  510. t := cordconstnode.create(ord(b),booltype);
  511. end;
  512. end;
  513. {$else}
  514. case nodetype of
  515. addn :
  516. begin
  517. resultset:=tsetconstnode(right).value_set^ + tsetconstnode(left).value_set^;
  518. t:=csetconstnode.create(@resultset,left.resulttype);
  519. end;
  520. muln :
  521. begin
  522. resultset:=tsetconstnode(right).value_set^ * tsetconstnode(left).value_set^;
  523. t:=csetconstnode.create(@resultset,left.resulttype);
  524. end;
  525. subn :
  526. begin
  527. resultset:=tsetconstnode(left).value_set^ - tsetconstnode(right).value_set^;
  528. t:=csetconstnode.create(@resultset,left.resulttype);
  529. end;
  530. symdifn :
  531. begin
  532. resultset:=tsetconstnode(right).value_set^ >< tsetconstnode(left).value_set^;
  533. t:=csetconstnode.create(@resultset,left.resulttype);
  534. end;
  535. unequaln :
  536. begin
  537. b:=tsetconstnode(right).value_set^ <> tsetconstnode(left).value_set^;
  538. t:=cordconstnode.create(byte(b),booltype);
  539. end;
  540. equaln :
  541. begin
  542. b:=tsetconstnode(right).value_set^ = tsetconstnode(left).value_set^;
  543. t:=cordconstnode.create(byte(b),booltype);
  544. end;
  545. lten :
  546. begin
  547. b:=tsetconstnode(left).value_set^ <= tsetconstnode(right).value_set^;
  548. t:=cordconstnode.create(byte(b),booltype);
  549. end;
  550. gten :
  551. begin
  552. b:=tsetconstnode(left).value_set^ >= tsetconstnode(right).value_set^;
  553. t:=cordconstnode.create(byte(b),booltype);
  554. end;
  555. end;
  556. {$endif}
  557. result:=t;
  558. exit;
  559. end;
  560. { but an int/int gives real/real! }
  561. if nodetype=slashn then
  562. begin
  563. CGMessage(type_h_use_div_for_int);
  564. inserttypeconv(right,pbestrealtype^);
  565. inserttypeconv(left,pbestrealtype^);
  566. end
  567. { if both are orddefs then check sub types }
  568. else if (ld.deftype=orddef) and (rd.deftype=orddef) then
  569. begin
  570. { 2 booleans? Make them equal to the largest boolean }
  571. if is_boolean(ld) and is_boolean(rd) then
  572. begin
  573. if torddef(left.resulttype.def).size>torddef(right.resulttype.def).size then
  574. begin
  575. right:=ctypeconvnode.create(right,left.resulttype);
  576. ttypeconvnode(right).convtype:=tc_bool_2_int;
  577. right.toggleflag(nf_explizit);
  578. resulttypepass(right);
  579. end
  580. else if torddef(left.resulttype.def).size<torddef(right.resulttype.def).size then
  581. begin
  582. left:=ctypeconvnode.create(left,right.resulttype);
  583. ttypeconvnode(left).convtype:=tc_bool_2_int;
  584. left.toggleflag(nf_explizit);
  585. resulttypepass(left);
  586. end;
  587. case nodetype of
  588. xorn,
  589. ltn,
  590. lten,
  591. gtn,
  592. gten,
  593. andn,
  594. orn:
  595. begin
  596. end;
  597. unequaln,
  598. equaln:
  599. begin
  600. if not(cs_full_boolean_eval in aktlocalswitches) then
  601. begin
  602. { Remove any compares with constants }
  603. if (left.nodetype=ordconstn) then
  604. begin
  605. hp:=right;
  606. b:=(tordconstnode(left).value<>0);
  607. ot:=nodetype;
  608. left.free;
  609. left:=nil;
  610. right:=nil;
  611. if (not(b) and (ot=equaln)) or
  612. (b and (ot=unequaln)) then
  613. begin
  614. hp:=cnotnode.create(hp);
  615. end;
  616. result:=hp;
  617. exit;
  618. end;
  619. if (right.nodetype=ordconstn) then
  620. begin
  621. hp:=left;
  622. b:=(tordconstnode(right).value<>0);
  623. ot:=nodetype;
  624. right.free;
  625. right:=nil;
  626. left:=nil;
  627. if (not(b) and (ot=equaln)) or
  628. (b and (ot=unequaln)) then
  629. begin
  630. hp:=cnotnode.create(hp);
  631. end;
  632. result:=hp;
  633. exit;
  634. end;
  635. end;
  636. end;
  637. else
  638. CGMessage(type_e_mismatch);
  639. end;
  640. end
  641. { Both are chars? }
  642. else if is_char(rd) and is_char(ld) then
  643. begin
  644. if nodetype=addn then
  645. begin
  646. resulttype:=cshortstringtype;
  647. if not(is_constcharnode(left) and is_constcharnode(right)) then
  648. begin
  649. inserttypeconv(left,cshortstringtype);
  650. hp := genaddsstringcharoptnode(self);
  651. result := hp;
  652. exit;
  653. end;
  654. end;
  655. end
  656. { is there a signed 64 bit type ? }
  657. else if ((torddef(rd).typ=s64bit) or (torddef(ld).typ=s64bit)) then
  658. begin
  659. if (torddef(ld).typ<>s64bit) then
  660. inserttypeconv(left,cs64bittype);
  661. if (torddef(rd).typ<>s64bit) then
  662. inserttypeconv(right,cs64bittype);
  663. end
  664. { is there a unsigned 64 bit type ? }
  665. else if ((torddef(rd).typ=u64bit) or (torddef(ld).typ=u64bit)) then
  666. begin
  667. if (torddef(ld).typ<>u64bit) then
  668. inserttypeconv(left,cu64bittype);
  669. if (torddef(rd).typ<>u64bit) then
  670. inserttypeconv(right,cu64bittype);
  671. end
  672. { is there a cardinal? }
  673. else if ((torddef(rd).typ=u32bit) or (torddef(ld).typ=u32bit)) then
  674. begin
  675. if is_signed(ld) and
  676. { then rd = u32bit }
  677. { convert positive constants to u32bit }
  678. not(is_constintnode(left) and
  679. (tordconstnode(left).value >= 0)) and
  680. { range/overflow checking on mixed signed/cardinal expressions }
  681. { is only possible if you convert everything to 64bit (JM) }
  682. ((aktlocalswitches * [cs_check_overflow,cs_check_range] <> []) and
  683. (nodetype in [addn,subn,muln])) then
  684. begin
  685. { perform the operation in 64bit }
  686. CGMessage(type_w_mixed_signed_unsigned);
  687. inserttypeconv(left,cs64bittype);
  688. inserttypeconv(right,cs64bittype);
  689. end
  690. else
  691. begin
  692. { and,or,xor work on bit patterns and don't care
  693. about the sign }
  694. if nodetype in [andn,orn,xorn] then
  695. inserttypeconv_explicit(left,u32bittype)
  696. else
  697. begin
  698. if is_signed(ld) and
  699. not(is_constintnode(left) and
  700. (tordconstnode(left).value >= 0)) and
  701. (cs_check_range in aktlocalswitches) then
  702. CGMessage(type_w_mixed_signed_unsigned2);
  703. inserttypeconv(left,u32bittype);
  704. end;
  705. if is_signed(rd) and
  706. { then ld = u32bit }
  707. { convert positive constants to u32bit }
  708. not(is_constintnode(right) and
  709. (tordconstnode(right).value >= 0)) and
  710. ((aktlocalswitches * [cs_check_overflow,cs_check_range] <> []) and
  711. (nodetype in [addn,subn,muln])) then
  712. begin
  713. { perform the operation in 64bit }
  714. CGMessage(type_w_mixed_signed_unsigned);
  715. inserttypeconv(left,cs64bittype);
  716. inserttypeconv(right,cs64bittype);
  717. end
  718. else
  719. begin
  720. { and,or,xor work on bit patterns and don't care
  721. about the sign }
  722. if nodetype in [andn,orn,xorn] then
  723. inserttypeconv_explicit(left,u32bittype)
  724. else
  725. begin
  726. if is_signed(rd) and
  727. not(is_constintnode(right) and
  728. (tordconstnode(right).value >= 0)) and
  729. (cs_check_range in aktlocalswitches) then
  730. CGMessage(type_w_mixed_signed_unsigned2);
  731. inserttypeconv(right,u32bittype);
  732. end;
  733. end;
  734. end;
  735. end
  736. { generic ord conversion is s32bit }
  737. else
  738. begin
  739. inserttypeconv(right,s32bittype);
  740. inserttypeconv(left,s32bittype);
  741. end;
  742. end
  743. { if both are floatdefs, conversion is already done before constant folding }
  744. else if (ld.deftype=floatdef) then
  745. begin
  746. { already converted }
  747. end
  748. { left side a setdef, must be before string processing,
  749. else array constructor can be seen as array of char (PFV) }
  750. else if (ld.deftype=setdef) then
  751. begin
  752. { trying to add a set element? }
  753. if (nodetype=addn) and (rd.deftype<>setdef) then
  754. begin
  755. if (rt=setelementn) then
  756. begin
  757. if not(is_equal(tsetdef(ld).elementtype.def,rd)) then
  758. CGMessage(type_e_set_element_are_not_comp);
  759. end
  760. else
  761. CGMessage(type_e_mismatch)
  762. end
  763. else
  764. begin
  765. if not(nodetype in [addn,subn,symdifn,muln,equaln,unequaln,lten,gten]) then
  766. CGMessage(type_e_set_operation_unknown);
  767. { right def must be a also be set }
  768. if (rd.deftype<>setdef) or not(is_equal(rd,ld)) then
  769. CGMessage(type_e_set_element_are_not_comp);
  770. end;
  771. { ranges require normsets }
  772. if (tsetdef(ld).settype=smallset) and
  773. (rt=setelementn) and
  774. assigned(tsetelementnode(right).right) then
  775. begin
  776. { generate a temporary normset def, it'll be destroyed
  777. when the symtable is unloaded }
  778. htype.setdef(tsetdef.create(tsetdef(ld).elementtype,255));
  779. inserttypeconv(left,htype);
  780. end;
  781. { if the right side is also a setdef then the settype must
  782. be the same as the left setdef }
  783. if (rd.deftype=setdef) and
  784. (tsetdef(ld).settype<>tsetdef(rd).settype) then
  785. inserttypeconv(right,left.resulttype);
  786. end
  787. { compare pchar to char arrays by addresses like BP/Delphi }
  788. else if (is_pchar(ld) and is_chararray(rd)) or
  789. (is_pchar(rd) and is_chararray(ld)) then
  790. begin
  791. if is_chararray(rd) then
  792. inserttypeconv(right,left.resulttype)
  793. else
  794. inserttypeconv(left,right.resulttype);
  795. end
  796. { is one of the operands a string?,
  797. chararrays are also handled as strings (after conversion), also take
  798. care of chararray+chararray and chararray+char }
  799. else if (rd.deftype=stringdef) or (ld.deftype=stringdef) or
  800. ((is_chararray(rd) or is_char(rd)) and
  801. (is_chararray(ld) or is_char(ld))) then
  802. begin
  803. if is_widestring(rd) or is_widestring(ld) then
  804. begin
  805. if not(is_widestring(rd)) then
  806. inserttypeconv(right,cwidestringtype);
  807. if not(is_widestring(ld)) then
  808. inserttypeconv(left,cwidestringtype);
  809. end
  810. else if is_ansistring(rd) or is_ansistring(ld) then
  811. begin
  812. if not(is_ansistring(rd)) then
  813. inserttypeconv(right,cansistringtype);
  814. if not(is_ansistring(ld)) then
  815. inserttypeconv(left,cansistringtype);
  816. end
  817. else if is_longstring(rd) or is_longstring(ld) then
  818. begin
  819. if not(is_longstring(rd)) then
  820. inserttypeconv(right,clongstringtype);
  821. if not(is_longstring(ld)) then
  822. inserttypeconv(left,clongstringtype);
  823. location.loc:=LOC_CREFERENCE;
  824. end
  825. else
  826. begin
  827. if not(is_shortstring(ld)) then
  828. inserttypeconv(left,cshortstringtype);
  829. { don't convert char, that can be handled by the optimized node }
  830. if not(is_shortstring(rd) or is_char(rd)) then
  831. inserttypeconv(right,cshortstringtype);
  832. end;
  833. end
  834. { pointer comparision and subtraction }
  835. else if (rd.deftype=pointerdef) and (ld.deftype=pointerdef) then
  836. begin
  837. case nodetype of
  838. equaln,unequaln :
  839. begin
  840. if is_voidpointer(right.resulttype.def) then
  841. inserttypeconv(right,left.resulttype)
  842. else if is_voidpointer(left.resulttype.def) then
  843. inserttypeconv(left,right.resulttype)
  844. else if not(is_equal(ld,rd)) then
  845. CGMessage(type_e_mismatch);
  846. end;
  847. ltn,lten,gtn,gten:
  848. begin
  849. if (cs_extsyntax in aktmoduleswitches) then
  850. begin
  851. if is_voidpointer(right.resulttype.def) then
  852. inserttypeconv(right,left.resulttype)
  853. else if is_voidpointer(left.resulttype.def) then
  854. inserttypeconv(left,right.resulttype)
  855. else if not(is_equal(ld,rd)) then
  856. CGMessage(type_e_mismatch);
  857. end
  858. else
  859. CGMessage(type_e_mismatch);
  860. end;
  861. subn:
  862. begin
  863. if (cs_extsyntax in aktmoduleswitches) then
  864. begin
  865. if is_voidpointer(right.resulttype.def) then
  866. inserttypeconv(right,left.resulttype)
  867. else if is_voidpointer(left.resulttype.def) then
  868. inserttypeconv(left,right.resulttype)
  869. else if not(is_equal(ld,rd)) then
  870. CGMessage(type_e_mismatch);
  871. end
  872. else
  873. CGMessage(type_e_mismatch);
  874. resulttype:=s32bittype;
  875. exit;
  876. end;
  877. addn:
  878. begin
  879. if (cs_extsyntax in aktmoduleswitches) then
  880. begin
  881. if is_voidpointer(right.resulttype.def) then
  882. inserttypeconv(right,left.resulttype)
  883. else if is_voidpointer(left.resulttype.def) then
  884. inserttypeconv(left,right.resulttype)
  885. else if not(is_equal(ld,rd)) then
  886. CGMessage(type_e_mismatch);
  887. end
  888. else
  889. CGMessage(type_e_mismatch);
  890. resulttype:=s32bittype;
  891. exit;
  892. end;
  893. else
  894. CGMessage(type_e_mismatch);
  895. end;
  896. end
  897. { class or interface equation }
  898. else if is_class_or_interface(rd) or is_class_or_interface(ld) then
  899. begin
  900. if is_class_or_interface(rd) and is_class_or_interface(ld) then
  901. begin
  902. if tobjectdef(rd).is_related(tobjectdef(ld)) then
  903. inserttypeconv(right,left.resulttype)
  904. else
  905. inserttypeconv(left,right.resulttype);
  906. end
  907. else if is_class_or_interface(rd) then
  908. inserttypeconv(left,right.resulttype)
  909. else
  910. inserttypeconv(right,left.resulttype);
  911. if not(nodetype in [equaln,unequaln]) then
  912. CGMessage(type_e_mismatch);
  913. end
  914. else if (rd.deftype=classrefdef) and (ld.deftype=classrefdef) then
  915. begin
  916. if tobjectdef(tclassrefdef(rd).pointertype.def).is_related(
  917. tobjectdef(tclassrefdef(ld).pointertype.def)) then
  918. inserttypeconv(right,left.resulttype)
  919. else
  920. inserttypeconv(left,right.resulttype);
  921. if not(nodetype in [equaln,unequaln]) then
  922. CGMessage(type_e_mismatch);
  923. end
  924. { allows comperasion with nil pointer }
  925. else if is_class_or_interface(rd) or (rd.deftype=classrefdef) then
  926. begin
  927. inserttypeconv(left,right.resulttype);
  928. if not(nodetype in [equaln,unequaln]) then
  929. CGMessage(type_e_mismatch);
  930. end
  931. else if is_class_or_interface(ld) or (ld.deftype=classrefdef) then
  932. begin
  933. inserttypeconv(right,left.resulttype);
  934. if not(nodetype in [equaln,unequaln]) then
  935. CGMessage(type_e_mismatch);
  936. end
  937. { support procvar=nil,procvar<>nil }
  938. else if ((ld.deftype=procvardef) and (rt=niln)) or
  939. ((rd.deftype=procvardef) and (lt=niln)) then
  940. begin
  941. if not(nodetype in [equaln,unequaln]) then
  942. CGMessage(type_e_mismatch);
  943. end
  944. {$ifdef SUPPORT_MMX}
  945. { mmx support, this must be before the zero based array
  946. check }
  947. else if (cs_mmx in aktlocalswitches) and
  948. is_mmx_able_array(ld) and
  949. is_mmx_able_array(rd) and
  950. is_equal(ld,rd) then
  951. begin
  952. case nodetype of
  953. addn,subn,xorn,orn,andn:
  954. ;
  955. { mul is a little bit restricted }
  956. muln:
  957. if not(mmx_type(ld) in [mmxu16bit,mmxs16bit,mmxfixed16]) then
  958. CGMessage(type_e_mismatch);
  959. else
  960. CGMessage(type_e_mismatch);
  961. end;
  962. end
  963. {$endif SUPPORT_MMX}
  964. { this is a little bit dangerous, also the left type }
  965. { pointer to should be checked! This broke the mmx support }
  966. else if (rd.deftype=pointerdef) or is_zero_based_array(rd) then
  967. begin
  968. if is_zero_based_array(rd) then
  969. begin
  970. resulttype.setdef(tpointerdef.create(tarraydef(rd).elementtype));
  971. inserttypeconv(right,resulttype);
  972. end;
  973. inserttypeconv(left,s32bittype);
  974. if nodetype=addn then
  975. begin
  976. if not(cs_extsyntax in aktmoduleswitches) or
  977. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  978. CGMessage(type_e_mismatch);
  979. if (rd.deftype=pointerdef) and
  980. (tpointerdef(rd).pointertype.def.size>1) then
  981. left:=caddnode.create(muln,left,cordconstnode.create(tpointerdef(rd).pointertype.def.size,s32bittype));
  982. end
  983. else
  984. CGMessage(type_e_mismatch);
  985. end
  986. else if (ld.deftype=pointerdef) or is_zero_based_array(ld) then
  987. begin
  988. if is_zero_based_array(ld) then
  989. begin
  990. resulttype.setdef(tpointerdef.create(tarraydef(ld).elementtype));
  991. inserttypeconv(left,resulttype);
  992. end;
  993. inserttypeconv(right,s32bittype);
  994. if nodetype in [addn,subn] then
  995. begin
  996. if not(cs_extsyntax in aktmoduleswitches) or
  997. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  998. CGMessage(type_e_mismatch);
  999. if (ld.deftype=pointerdef) and
  1000. (tpointerdef(ld).pointertype.def.size>1) then
  1001. right:=caddnode.create(muln,right,cordconstnode.create(tpointerdef(ld).pointertype.def.size,s32bittype));
  1002. end
  1003. else
  1004. CGMessage(type_e_mismatch);
  1005. end
  1006. else if (rd.deftype=procvardef) and (ld.deftype=procvardef) and is_equal(rd,ld) then
  1007. begin
  1008. if not (nodetype in [equaln,unequaln]) then
  1009. CGMessage(type_e_mismatch);
  1010. end
  1011. { enums }
  1012. else if (ld.deftype=enumdef) and (rd.deftype=enumdef) then
  1013. begin
  1014. if not(is_equal(ld,rd)) then
  1015. inserttypeconv(right,left.resulttype);
  1016. if not(nodetype in [equaln,unequaln,ltn,lten,gtn,gten]) then
  1017. CGMessage(type_e_mismatch);
  1018. end
  1019. { generic conversion, this is for error recovery }
  1020. else
  1021. begin
  1022. inserttypeconv(left,s32bittype);
  1023. inserttypeconv(right,s32bittype);
  1024. end;
  1025. { set resulttype if not already done }
  1026. if not assigned(resulttype.def) then
  1027. begin
  1028. case nodetype of
  1029. ltn,lten,gtn,gten,equaln,unequaln :
  1030. resulttype:=booltype;
  1031. slashn :
  1032. resulttype:=pbestrealtype^;
  1033. addn:
  1034. begin
  1035. { for strings, return is always a 255 char string }
  1036. if is_shortstring(left.resulttype.def) then
  1037. resulttype:=cshortstringtype
  1038. else
  1039. resulttype:=left.resulttype;
  1040. end;
  1041. else
  1042. resulttype:=left.resulttype;
  1043. end;
  1044. end;
  1045. end;
  1046. function taddnode.first_addstring: tnode;
  1047. var
  1048. p: tnode;
  1049. begin
  1050. { when we get here, we are sure that both the left and the right }
  1051. { node are both strings of the same stringtype (JM) }
  1052. case nodetype of
  1053. addn:
  1054. begin
  1055. { note: if you implemented an fpc_shortstr_concat similar to the }
  1056. { one in i386.inc, you have to override first_addstring like in }
  1057. { ti386addnode.first_string and implement the shortstring concat }
  1058. { manually! The generic routine is different from the i386 one (JM) }
  1059. { create the call to the concat routine both strings as arguments }
  1060. result := ccallnode.createintern('fpc_'+
  1061. tstringdef(resulttype.def).stringtypname+'_concat',
  1062. ccallparanode.create(right,ccallparanode.create(left,nil)));
  1063. { we reused the arguments }
  1064. left := nil;
  1065. right := nil;
  1066. firstpass(result);
  1067. end;
  1068. ltn,lten,gtn,gten,equaln,unequaln :
  1069. begin
  1070. { generate better code for s='' and s<>'' }
  1071. if (nodetype in [equaln,unequaln]) and
  1072. (((left.nodetype=stringconstn) and (str_length(left)=0)) or
  1073. ((right.nodetype=stringconstn) and (str_length(right)=0))) then
  1074. begin
  1075. { switch so that the constant is always on the right }
  1076. if left.nodetype = stringconstn then
  1077. begin
  1078. p := left;
  1079. left := right;
  1080. right := p;
  1081. end;
  1082. if is_shortstring(left.resulttype.def) then
  1083. { compare the length with 0 }
  1084. result := caddnode.create(nodetype,
  1085. cinlinenode.create(in_length_x,false,left),
  1086. cordconstnode.create(0,s32bittype))
  1087. else
  1088. begin
  1089. { compare the pointer with nil (for ansistrings etc), }
  1090. { faster than getting the length (JM) }
  1091. result:= caddnode.create(nodetype,
  1092. ctypeconvnode.create(left,voidpointertype),
  1093. cpointerconstnode.create(0,voidpointertype));
  1094. taddnode(result).left.toggleflag(nf_explizit);
  1095. end;
  1096. { left is reused }
  1097. left := nil;
  1098. { right isn't }
  1099. right.free;
  1100. right := nil;
  1101. firstpass(result);
  1102. exit;
  1103. end;
  1104. { no string constant -> call compare routine }
  1105. result := ccallnode.createintern('fpc_'+
  1106. tstringdef(left.resulttype.def).stringtypname+'_compare',
  1107. ccallparanode.create(right,ccallparanode.create(left,nil)));
  1108. { and compare its result with 0 according to the original operator }
  1109. result := caddnode.create(nodetype,result,
  1110. cordconstnode.create(0,s32bittype));
  1111. left := nil;
  1112. right := nil;
  1113. firstpass(result);
  1114. end;
  1115. end;
  1116. end;
  1117. function taddnode.first_addset: tnode;
  1118. var
  1119. procname: string[31];
  1120. tempn: tnode;
  1121. paras: tcallparanode;
  1122. srsym: ttypesym;
  1123. begin
  1124. { get the sym that represents the fpc_normal_set type }
  1125. if not searchsystype('FPC_NORMAL_SET',srsym) then
  1126. internalerror(200108313);
  1127. case nodetype of
  1128. equaln,unequaln,lten,gten:
  1129. begin
  1130. case nodetype of
  1131. equaln,unequaln:
  1132. procname := 'fpc_set_comp_sets';
  1133. lten,gten:
  1134. begin
  1135. procname := 'fpc_set_contains_sets';
  1136. { (left >= right) = (right <= left) }
  1137. if nodetype = gten then
  1138. begin
  1139. tempn := left;
  1140. left := right;
  1141. right := tempn;
  1142. end;
  1143. end;
  1144. end;
  1145. { convert the arguments (explicitely) to fpc_normal_set's }
  1146. left := ctypeconvnode.create(left,srsym.restype);
  1147. left.toggleflag(nf_explizit);
  1148. right := ctypeconvnode.create(right,srsym.restype);
  1149. right.toggleflag(nf_explizit);
  1150. result := ccallnode.createintern(procname,ccallparanode.create(right,
  1151. ccallparanode.create(left,nil)));
  1152. { left and right are reused as parameters }
  1153. left := nil;
  1154. right := nil;
  1155. { for an unequaln, we have to negate the result of comp_sets }
  1156. if nodetype = unequaln then
  1157. result := cnotnode.create(result);
  1158. end;
  1159. addn:
  1160. begin
  1161. { optimize first loading of a set }
  1162. if (right.nodetype=setelementn) and
  1163. not(assigned(tsetelementnode(right).right)) and
  1164. is_emptyset(left) then
  1165. begin
  1166. { type cast the value to pass as argument to a byte, }
  1167. { since that's what the helper expects }
  1168. tsetelementnode(right).left :=
  1169. ctypeconvnode.create(tsetelementnode(right).left,u8bittype);
  1170. tsetelementnode(right).left.toggleflag(nf_explizit);
  1171. { set the resulttype to the actual one (otherwise it's }
  1172. { "fpc_normal_set") }
  1173. result := ccallnode.createinternres('fpc_set_create_element',
  1174. ccallparanode.create(tsetelementnode(right).left,nil),
  1175. resulttype);
  1176. { reused }
  1177. tsetelementnode(right).left := nil;
  1178. end
  1179. else
  1180. begin
  1181. if right.nodetype=setelementn then
  1182. begin
  1183. { convert the arguments to bytes, since that's what }
  1184. { the helper expects }
  1185. tsetelementnode(right).left :=
  1186. ctypeconvnode.create(tsetelementnode(right).left,
  1187. u8bittype);
  1188. tsetelementnode(right).left.toggleflag(nf_explizit);
  1189. { convert the original set (explicitely) to an }
  1190. { fpc_normal_set so we can pass it to the helper }
  1191. left := ctypeconvnode.create(left,srsym.restype);
  1192. left.toggleflag(nf_explizit);
  1193. { add a range or a single element? }
  1194. if assigned(tsetelementnode(right).right) then
  1195. begin
  1196. tsetelementnode(right).right :=
  1197. ctypeconvnode.create(tsetelementnode(right).right,
  1198. u8bittype);
  1199. tsetelementnode(right).right.toggleflag(nf_explizit);
  1200. { create the call }
  1201. result := ccallnode.createinternres('fpc_set_set_range',
  1202. ccallparanode.create(tsetelementnode(right).right,
  1203. ccallparanode.create(tsetelementnode(right).left,
  1204. ccallparanode.create(left,nil))),resulttype);
  1205. end
  1206. else
  1207. begin
  1208. result := ccallnode.createinternres('fpc_set_set_byte',
  1209. ccallparanode.create(tsetelementnode(right).left,
  1210. ccallparanode.create(left,nil)),resulttype);
  1211. end;
  1212. { remove reused parts from original node }
  1213. tsetelementnode(right).right := nil;
  1214. tsetelementnode(right).left := nil;
  1215. left := nil;
  1216. end
  1217. else
  1218. begin
  1219. { add two sets }
  1220. { convert the sets to fpc_normal_set's }
  1221. left := ctypeconvnode.create(left,srsym.restype);
  1222. left.toggleflag(nf_explizit);
  1223. right := ctypeconvnode.create(right,srsym.restype);
  1224. right.toggleflag(nf_explizit);
  1225. result := ccallnode.createinternres('fpc_set_add_sets',
  1226. ccallparanode.create(right,
  1227. ccallparanode.create(left,nil)),resulttype);
  1228. { remove reused parts from original node }
  1229. left := nil;
  1230. right := nil;
  1231. end;
  1232. end
  1233. end;
  1234. subn,symdifn,muln:
  1235. begin
  1236. { convert the sets to fpc_normal_set's }
  1237. left := ctypeconvnode.create(left,srsym.restype);
  1238. left.toggleflag(nf_explizit);
  1239. right := ctypeconvnode.create(right,srsym.restype);
  1240. right.toggleflag(nf_explizit);
  1241. paras := ccallparanode.create(right,
  1242. ccallparanode.create(left,nil));
  1243. case nodetype of
  1244. subn:
  1245. result := ccallnode.createinternres('fpc_set_sub_sets',
  1246. paras,resulttype);
  1247. symdifn:
  1248. result := ccallnode.createinternres('fpc_set_symdif_sets',
  1249. paras,resulttype);
  1250. muln:
  1251. result := ccallnode.createinternres('fpc_set_mul_sets',
  1252. paras,resulttype);
  1253. end;
  1254. { remove reused parts from original node }
  1255. left := nil;
  1256. right := nil;
  1257. end;
  1258. else
  1259. internalerror(200108311);
  1260. end;
  1261. firstpass(result);
  1262. end;
  1263. function taddnode.first_add64bitint: tnode;
  1264. var
  1265. procname: string[31];
  1266. temp: tnode;
  1267. power: longint;
  1268. begin
  1269. result := nil;
  1270. { create helper calls mul }
  1271. if nodetype <> muln then
  1272. exit;
  1273. { make sure that if there is a constant, that it's on the right }
  1274. if left.nodetype = ordconstn then
  1275. begin
  1276. temp := right;
  1277. right := left;
  1278. left := temp;
  1279. end;
  1280. { can we use a shift instead of a mul? }
  1281. if (right.nodetype = ordconstn) and
  1282. ispowerof2(tordconstnode(right).value,power) then
  1283. begin
  1284. tordconstnode(right).value := power;
  1285. result := cshlshrnode.create(shln,left,right);
  1286. { left and right are reused }
  1287. left := nil;
  1288. right := nil;
  1289. { return firstpassed new node }
  1290. firstpass(result);
  1291. exit;
  1292. end;
  1293. { otherwise, create the parameters for the helper }
  1294. right := ccallparanode.create(
  1295. cordconstnode.create(ord(cs_check_overflow in aktlocalswitches),booltype),
  1296. ccallparanode.create(right,ccallparanode.create(left,nil)));
  1297. left := nil;
  1298. if torddef(resulttype.def).typ = s64bit then
  1299. procname := 'fpc_mul_int64'
  1300. else
  1301. procname := 'fpc_mul_qword';
  1302. result := ccallnode.createintern(procname,right);
  1303. right := nil;
  1304. firstpass(result);
  1305. end;
  1306. function taddnode.pass_1 : tnode;
  1307. var
  1308. hp : tnode;
  1309. lt,rt : tnodetype;
  1310. rd,ld : tdef;
  1311. begin
  1312. result:=nil;
  1313. { first do the two subtrees }
  1314. firstpass(left);
  1315. firstpass(right);
  1316. if codegenerror then
  1317. exit;
  1318. { load easier access variables }
  1319. rd:=right.resulttype.def;
  1320. ld:=left.resulttype.def;
  1321. rt:=right.nodetype;
  1322. lt:=left.nodetype;
  1323. { int/int gives real/real! }
  1324. if nodetype=slashn then
  1325. begin
  1326. location.loc:=LOC_FPUREGISTER;
  1327. { maybe we need an integer register to save }
  1328. { a reference }
  1329. if ((left.location.loc<>LOC_FPUREGISTER) or
  1330. (right.location.loc<>LOC_FPUREGISTER)) and
  1331. (left.registers32=right.registers32) then
  1332. calcregisters(self,1,1,0)
  1333. else
  1334. calcregisters(self,0,1,0);
  1335. { an add node always first loads both the left and the }
  1336. { right in the fpu before doing the calculation. However, }
  1337. { calcregisters(0,2,0) will overestimate the number of }
  1338. { necessary registers (it will make it 3 in case one of }
  1339. { the operands is already in the fpu) (JM) }
  1340. if ((left.location.loc <> LOC_FPUREGISTER) or
  1341. (right.location.loc <> LOC_FPUREGISTER)) and
  1342. (registersfpu < 2) then
  1343. inc(registersfpu);
  1344. end
  1345. { if both are orddefs then check sub types }
  1346. else if (ld.deftype=orddef) and (rd.deftype=orddef) then
  1347. begin
  1348. { 2 booleans ? }
  1349. if is_boolean(ld) and is_boolean(rd) then
  1350. begin
  1351. if not(cs_full_boolean_eval in aktlocalswitches) and
  1352. (nodetype in [andn,orn]) then
  1353. begin
  1354. location.loc:=LOC_JUMP;
  1355. calcregisters(self,0,0,0);
  1356. end
  1357. else
  1358. begin
  1359. location.loc := LOC_FLAGS;
  1360. if (left.location.loc in [LOC_JUMP,LOC_FLAGS]) and
  1361. (left.location.loc in [LOC_JUMP,LOC_FLAGS]) then
  1362. calcregisters(self,2,0,0)
  1363. else
  1364. calcregisters(self,1,0,0);
  1365. end;
  1366. end
  1367. else
  1368. { Both are chars? only convert to shortstrings for addn }
  1369. if is_char(ld) then
  1370. begin
  1371. if nodetype=addn then
  1372. internalerror(200103291);
  1373. location.loc := LOC_FLAGS;
  1374. calcregisters(self,1,0,0);
  1375. end
  1376. { is there a 64 bit type ? }
  1377. else if (torddef(ld).typ in [s64bit,u64bit]) then
  1378. begin
  1379. result := first_add64bitint;
  1380. if assigned(result) then
  1381. exit;
  1382. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1383. location.loc := LOC_REGISTER
  1384. else
  1385. location.loc := LOC_JUMP;
  1386. calcregisters(self,2,0,0)
  1387. end
  1388. { is there a cardinal? }
  1389. else if (torddef(ld).typ=u32bit) then
  1390. begin
  1391. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1392. location.loc := LOC_REGISTER
  1393. else
  1394. location.loc := LOC_FLAGS;
  1395. calcregisters(self,1,0,0);
  1396. { for unsigned mul we need an extra register }
  1397. if nodetype=muln then
  1398. inc(registers32);
  1399. end
  1400. { generic s32bit conversion }
  1401. else
  1402. begin
  1403. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1404. location.loc := LOC_REGISTER
  1405. else
  1406. location.loc := LOC_FLAGS;
  1407. calcregisters(self,1,0,0);
  1408. end;
  1409. end
  1410. { left side a setdef, must be before string processing,
  1411. else array constructor can be seen as array of char (PFV) }
  1412. else if (ld.deftype=setdef) then
  1413. begin
  1414. if tsetdef(ld).settype=smallset then
  1415. begin
  1416. location.loc:=LOC_REGISTER;
  1417. { are we adding set elements ? }
  1418. if right.nodetype=setelementn then
  1419. calcregisters(self,2,0,0)
  1420. else
  1421. calcregisters(self,1,0,0);
  1422. end
  1423. else
  1424. begin
  1425. result := first_addset;
  1426. if assigned(result) then
  1427. exit;
  1428. location.loc:=LOC_CREFERENCE;
  1429. calcregisters(self,0,0,0);
  1430. { here we call SET... }
  1431. if assigned(procinfo) then
  1432. procinfo^.flags:=procinfo^.flags or pi_do_call;
  1433. end;
  1434. end
  1435. { compare pchar by addresses like BP/Delphi }
  1436. else if is_pchar(ld) then
  1437. begin
  1438. location.loc:=LOC_REGISTER;
  1439. calcregisters(self,1,0,0);
  1440. end
  1441. { is one of the operands a string }
  1442. else if (ld.deftype=stringdef) then
  1443. begin
  1444. if is_widestring(ld) then
  1445. begin
  1446. { we use reference counted widestrings so no fast exit here }
  1447. if assigned(procinfo) then
  1448. procinfo^.no_fast_exit:=true;
  1449. { this is only for add, the comparisaion is handled later }
  1450. location.loc:=LOC_REGISTER;
  1451. end
  1452. else if is_ansistring(ld) then
  1453. begin
  1454. { we use ansistrings so no fast exit here }
  1455. if assigned(procinfo) then
  1456. procinfo^.no_fast_exit:=true;
  1457. { this is only for add, the comparisaion is handled later }
  1458. location.loc:=LOC_REGISTER;
  1459. end
  1460. else if is_longstring(ld) then
  1461. begin
  1462. { this is only for add, the comparisaion is handled later }
  1463. location.loc:=LOC_CREFERENCE;
  1464. end
  1465. else
  1466. begin
  1467. if canbeaddsstringcharoptnode(self) then
  1468. begin
  1469. hp := genaddsstringcharoptnode(self);
  1470. firstpass(hp);
  1471. pass_1 := hp;
  1472. exit;
  1473. end
  1474. else
  1475. begin
  1476. { Fix right to be shortstring }
  1477. if is_char(right.resulttype.def) then
  1478. begin
  1479. inserttypeconv(right,cshortstringtype);
  1480. firstpass(right);
  1481. end;
  1482. end;
  1483. if canbeaddsstringcsstringoptnode(self) then
  1484. begin
  1485. hp := genaddsstringcsstringoptnode(self);
  1486. firstpass(hp);
  1487. pass_1 := hp;
  1488. exit;
  1489. end;
  1490. end;
  1491. { otherwise, let addstring convert everything }
  1492. result := first_addstring;
  1493. exit;
  1494. end
  1495. { is one a real float ? }
  1496. else if (rd.deftype=floatdef) or (ld.deftype=floatdef) then
  1497. begin
  1498. location.loc:=LOC_FPUREGISTER;
  1499. calcregisters(self,0,1,0);
  1500. { an add node always first loads both the left and the }
  1501. { right in the fpu before doing the calculation. However, }
  1502. { calcregisters(0,2,0) will overestimate the number of }
  1503. { necessary registers (it will make it 3 in case one of }
  1504. { the operands is already in the fpu) (JM) }
  1505. if ((left.location.loc <> LOC_FPUREGISTER) or
  1506. (right.location.loc <> LOC_FPUREGISTER)) and
  1507. (registersfpu < 2) then
  1508. inc(registersfpu);
  1509. end
  1510. { pointer comperation and subtraction }
  1511. else if (ld.deftype=pointerdef) then
  1512. begin
  1513. location.loc:=LOC_REGISTER;
  1514. calcregisters(self,1,0,0);
  1515. end
  1516. else if is_class_or_interface(ld) then
  1517. begin
  1518. location.loc:=LOC_REGISTER;
  1519. calcregisters(self,1,0,0);
  1520. end
  1521. else if (ld.deftype=classrefdef) then
  1522. begin
  1523. location.loc:=LOC_REGISTER;
  1524. calcregisters(self,1,0,0);
  1525. end
  1526. { support procvar=nil,procvar<>nil }
  1527. else if ((ld.deftype=procvardef) and (rt=niln)) or
  1528. ((rd.deftype=procvardef) and (lt=niln)) then
  1529. begin
  1530. location.loc:=LOC_REGISTER;
  1531. calcregisters(self,1,0,0);
  1532. end
  1533. {$ifdef SUPPORT_MMX}
  1534. { mmx support, this must be before the zero based array
  1535. check }
  1536. else if (cs_mmx in aktlocalswitches) and is_mmx_able_array(ld) and
  1537. is_mmx_able_array(rd) then
  1538. begin
  1539. location.loc:=LOC_MMXREGISTER;
  1540. calcregisters(self,0,0,1);
  1541. end
  1542. {$endif SUPPORT_MMX}
  1543. else if (rd.deftype=pointerdef) or (ld.deftype=pointerdef) then
  1544. begin
  1545. location.loc:=LOC_REGISTER;
  1546. calcregisters(self,1,0,0);
  1547. end
  1548. else if (rd.deftype=procvardef) and (ld.deftype=procvardef) and is_equal(rd,ld) then
  1549. begin
  1550. location.loc:=LOC_REGISTER;
  1551. calcregisters(self,1,0,0);
  1552. end
  1553. else if (ld.deftype=enumdef) then
  1554. begin
  1555. location.loc := LOC_FLAGS;
  1556. calcregisters(self,1,0,0);
  1557. end
  1558. {$ifdef SUPPORT_MMX}
  1559. else if (cs_mmx in aktlocalswitches) and
  1560. is_mmx_able_array(ld) and
  1561. is_mmx_able_array(rd) then
  1562. begin
  1563. location.loc:=LOC_MMXREGISTER;
  1564. calcregisters(self,0,0,1);
  1565. end
  1566. {$endif SUPPORT_MMX}
  1567. { the general solution is to convert to 32 bit int }
  1568. else
  1569. begin
  1570. location.loc:=LOC_REGISTER;
  1571. calcregisters(self,1,0,0);
  1572. end;
  1573. end;
  1574. {$ifdef state_tracking}
  1575. function Taddnode.track_state_pass(exec_known:boolean):boolean;
  1576. var factval:Tnode;
  1577. begin
  1578. track_state_pass:=false;
  1579. if left.track_state_pass(exec_known) then
  1580. begin
  1581. track_state_pass:=true;
  1582. left.resulttype.def:=nil;
  1583. do_resulttypepass(left);
  1584. end;
  1585. factval:=aktstate.find_fact(left);
  1586. if factval<>nil then
  1587. begin
  1588. track_state_pass:=true;
  1589. left.destroy;
  1590. left:=factval.getcopy;
  1591. end;
  1592. if right.track_state_pass(exec_known) then
  1593. begin
  1594. track_state_pass:=true;
  1595. right.resulttype.def:=nil;
  1596. do_resulttypepass(right);
  1597. end;
  1598. factval:=aktstate.find_fact(right);
  1599. if factval<>nil then
  1600. begin
  1601. track_state_pass:=true;
  1602. right.destroy;
  1603. right:=factval.getcopy;
  1604. end;
  1605. end;
  1606. {$endif}
  1607. begin
  1608. caddnode:=taddnode;
  1609. end.
  1610. {
  1611. $Log$
  1612. Revision 1.57 2002-07-23 13:08:16 jonas
  1613. * fixed constant set evaluation of new set handling for non-commutative
  1614. operators
  1615. Revision 1.56 2002/07/23 12:34:29 daniel
  1616. * Readded old set code. To use it define 'oldset'. Activated by default
  1617. for ppc.
  1618. Revision 1.55 2002/07/22 11:48:04 daniel
  1619. * Sets are now internally sets.
  1620. Revision 1.54 2002/07/20 11:57:53 florian
  1621. * types.pas renamed to defbase.pas because D6 contains a types
  1622. unit so this would conflicts if D6 programms are compiled
  1623. + Willamette/SSE2 instructions to assembler added
  1624. Revision 1.53 2002/07/19 11:41:34 daniel
  1625. * State tracker work
  1626. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1627. allows the state tracker to change while nodes automatically into
  1628. repeat nodes.
  1629. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1630. 'not(a>b)' is optimized into 'a<=b'.
  1631. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1632. by removing the notn and later switchting the true and falselabels. The
  1633. same is done with 'repeat until not a'.
  1634. Revision 1.52 2002/07/14 18:00:43 daniel
  1635. + Added the beginning of a state tracker. This will track the values of
  1636. variables through procedures and optimize things away.
  1637. Revision 1.51 2002/05/18 13:34:08 peter
  1638. * readded missing revisions
  1639. Revision 1.50 2002/05/16 19:46:37 carl
  1640. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1641. + try to fix temp allocation (still in ifdef)
  1642. + generic constructor calls
  1643. + start of tassembler / tmodulebase class cleanup
  1644. Revision 1.48 2002/05/13 19:54:36 peter
  1645. * removed n386ld and n386util units
  1646. * maybe_save/maybe_restore added instead of the old maybe_push
  1647. Revision 1.47 2002/05/12 16:53:06 peter
  1648. * moved entry and exitcode to ncgutil and cgobj
  1649. * foreach gets extra argument for passing local data to the
  1650. iterator function
  1651. * -CR checks also class typecasts at runtime by changing them
  1652. into as
  1653. * fixed compiler to cycle with the -CR option
  1654. * fixed stabs with elf writer, finally the global variables can
  1655. be watched
  1656. * removed a lot of routines from cga unit and replaced them by
  1657. calls to cgobj
  1658. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1659. u32bit then the other is typecasted also to u32bit without giving
  1660. a rangecheck warning/error.
  1661. * fixed pascal calling method with reversing also the high tree in
  1662. the parast, detected by tcalcst3 test
  1663. Revision 1.46 2002/04/23 19:16:34 peter
  1664. * add pinline unit that inserts compiler supported functions using
  1665. one or more statements
  1666. * moved finalize and setlength from ninl to pinline
  1667. Revision 1.45 2002/04/04 19:05:56 peter
  1668. * removed unused units
  1669. * use tlocation.size in cg.a_*loc*() routines
  1670. Revision 1.44 2002/04/02 17:11:28 peter
  1671. * tlocation,treference update
  1672. * LOC_CONSTANT added for better constant handling
  1673. * secondadd splitted in multiple routines
  1674. * location_force_reg added for loading a location to a register
  1675. of a specified size
  1676. * secondassignment parses now first the right and then the left node
  1677. (this is compatible with Kylix). This saves a lot of push/pop especially
  1678. with string operations
  1679. * adapted some routines to use the new cg methods
  1680. Revision 1.43 2002/03/30 23:12:09 carl
  1681. * avoid crash with procinfo ('merged')
  1682. }