nadd.pas 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711
  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. case nodetype of
  441. addn :
  442. begin
  443. resultset:=tsetconstnode(right).value_set^ + tsetconstnode(left).value_set^;
  444. t:=csetconstnode.create(@resultset,left.resulttype);
  445. end;
  446. muln :
  447. begin
  448. resultset:=tsetconstnode(right).value_set^ * tsetconstnode(left).value_set^;
  449. t:=csetconstnode.create(@resultset,left.resulttype);
  450. end;
  451. subn :
  452. begin
  453. resultset:=tsetconstnode(right).value_set^ - tsetconstnode(left).value_set^;
  454. t:=csetconstnode.create(@resultset,left.resulttype);
  455. end;
  456. symdifn :
  457. begin
  458. resultset:=tsetconstnode(right).value_set^ >< tsetconstnode(left).value_set^;
  459. t:=csetconstnode.create(@resultset,left.resulttype);
  460. end;
  461. unequaln :
  462. begin
  463. b:=tsetconstnode(right).value_set^ <> tsetconstnode(left).value_set^;
  464. t:=cordconstnode.create(byte(b),booltype);
  465. end;
  466. equaln :
  467. begin
  468. b:=tsetconstnode(right).value_set^ = tsetconstnode(left).value_set^;
  469. t:=cordconstnode.create(byte(b),booltype);
  470. end;
  471. lten :
  472. begin
  473. b:=tsetconstnode(right).value_set^ <= tsetconstnode(left).value_set^;
  474. t:=cordconstnode.create(byte(b),booltype);
  475. end;
  476. gten :
  477. begin
  478. b:=tsetconstnode(right).value_set^ >= tsetconstnode(left).value_set^;
  479. t:=cordconstnode.create(byte(b),booltype);
  480. end;
  481. end;
  482. result:=t;
  483. exit;
  484. end;
  485. { but an int/int gives real/real! }
  486. if nodetype=slashn then
  487. begin
  488. CGMessage(type_h_use_div_for_int);
  489. inserttypeconv(right,pbestrealtype^);
  490. inserttypeconv(left,pbestrealtype^);
  491. end
  492. { if both are orddefs then check sub types }
  493. else if (ld.deftype=orddef) and (rd.deftype=orddef) then
  494. begin
  495. { 2 booleans? Make them equal to the largest boolean }
  496. if is_boolean(ld) and is_boolean(rd) then
  497. begin
  498. if torddef(left.resulttype.def).size>torddef(right.resulttype.def).size then
  499. begin
  500. right:=ctypeconvnode.create(right,left.resulttype);
  501. ttypeconvnode(right).convtype:=tc_bool_2_int;
  502. right.toggleflag(nf_explizit);
  503. resulttypepass(right);
  504. end
  505. else if torddef(left.resulttype.def).size<torddef(right.resulttype.def).size then
  506. begin
  507. left:=ctypeconvnode.create(left,right.resulttype);
  508. ttypeconvnode(left).convtype:=tc_bool_2_int;
  509. left.toggleflag(nf_explizit);
  510. resulttypepass(left);
  511. end;
  512. case nodetype of
  513. xorn,
  514. ltn,
  515. lten,
  516. gtn,
  517. gten,
  518. andn,
  519. orn:
  520. begin
  521. end;
  522. unequaln,
  523. equaln:
  524. begin
  525. if not(cs_full_boolean_eval in aktlocalswitches) then
  526. begin
  527. { Remove any compares with constants }
  528. if (left.nodetype=ordconstn) then
  529. begin
  530. hp:=right;
  531. b:=(tordconstnode(left).value<>0);
  532. ot:=nodetype;
  533. left.free;
  534. left:=nil;
  535. right:=nil;
  536. if (not(b) and (ot=equaln)) or
  537. (b and (ot=unequaln)) then
  538. begin
  539. hp:=cnotnode.create(hp);
  540. end;
  541. result:=hp;
  542. exit;
  543. end;
  544. if (right.nodetype=ordconstn) then
  545. begin
  546. hp:=left;
  547. b:=(tordconstnode(right).value<>0);
  548. ot:=nodetype;
  549. right.free;
  550. right:=nil;
  551. left:=nil;
  552. if (not(b) and (ot=equaln)) or
  553. (b and (ot=unequaln)) then
  554. begin
  555. hp:=cnotnode.create(hp);
  556. end;
  557. result:=hp;
  558. exit;
  559. end;
  560. end;
  561. end;
  562. else
  563. CGMessage(type_e_mismatch);
  564. end;
  565. end
  566. { Both are chars? }
  567. else if is_char(rd) and is_char(ld) then
  568. begin
  569. if nodetype=addn then
  570. begin
  571. resulttype:=cshortstringtype;
  572. if not(is_constcharnode(left) and is_constcharnode(right)) then
  573. begin
  574. inserttypeconv(left,cshortstringtype);
  575. hp := genaddsstringcharoptnode(self);
  576. result := hp;
  577. exit;
  578. end;
  579. end;
  580. end
  581. { is there a signed 64 bit type ? }
  582. else if ((torddef(rd).typ=s64bit) or (torddef(ld).typ=s64bit)) then
  583. begin
  584. if (torddef(ld).typ<>s64bit) then
  585. inserttypeconv(left,cs64bittype);
  586. if (torddef(rd).typ<>s64bit) then
  587. inserttypeconv(right,cs64bittype);
  588. end
  589. { is there a unsigned 64 bit type ? }
  590. else if ((torddef(rd).typ=u64bit) or (torddef(ld).typ=u64bit)) then
  591. begin
  592. if (torddef(ld).typ<>u64bit) then
  593. inserttypeconv(left,cu64bittype);
  594. if (torddef(rd).typ<>u64bit) then
  595. inserttypeconv(right,cu64bittype);
  596. end
  597. { is there a cardinal? }
  598. else if ((torddef(rd).typ=u32bit) or (torddef(ld).typ=u32bit)) then
  599. begin
  600. if is_signed(ld) and
  601. { then rd = u32bit }
  602. { convert positive constants to u32bit }
  603. not(is_constintnode(left) and
  604. (tordconstnode(left).value >= 0)) and
  605. { range/overflow checking on mixed signed/cardinal expressions }
  606. { is only possible if you convert everything to 64bit (JM) }
  607. ((aktlocalswitches * [cs_check_overflow,cs_check_range] <> []) and
  608. (nodetype in [addn,subn,muln])) then
  609. begin
  610. { perform the operation in 64bit }
  611. CGMessage(type_w_mixed_signed_unsigned);
  612. inserttypeconv(left,cs64bittype);
  613. inserttypeconv(right,cs64bittype);
  614. end
  615. else
  616. begin
  617. { and,or,xor work on bit patterns and don't care
  618. about the sign }
  619. if nodetype in [andn,orn,xorn] then
  620. inserttypeconv_explicit(left,u32bittype)
  621. else
  622. begin
  623. if is_signed(ld) and
  624. not(is_constintnode(left) and
  625. (tordconstnode(left).value >= 0)) and
  626. (cs_check_range in aktlocalswitches) then
  627. CGMessage(type_w_mixed_signed_unsigned2);
  628. inserttypeconv(left,u32bittype);
  629. end;
  630. if is_signed(rd) and
  631. { then ld = u32bit }
  632. { convert positive constants to u32bit }
  633. not(is_constintnode(right) and
  634. (tordconstnode(right).value >= 0)) and
  635. ((aktlocalswitches * [cs_check_overflow,cs_check_range] <> []) and
  636. (nodetype in [addn,subn,muln])) then
  637. begin
  638. { perform the operation in 64bit }
  639. CGMessage(type_w_mixed_signed_unsigned);
  640. inserttypeconv(left,cs64bittype);
  641. inserttypeconv(right,cs64bittype);
  642. end
  643. else
  644. begin
  645. { and,or,xor work on bit patterns and don't care
  646. about the sign }
  647. if nodetype in [andn,orn,xorn] then
  648. inserttypeconv_explicit(left,u32bittype)
  649. else
  650. begin
  651. if is_signed(rd) and
  652. not(is_constintnode(right) and
  653. (tordconstnode(right).value >= 0)) and
  654. (cs_check_range in aktlocalswitches) then
  655. CGMessage(type_w_mixed_signed_unsigned2);
  656. inserttypeconv(right,u32bittype);
  657. end;
  658. end;
  659. end;
  660. end
  661. { generic ord conversion is s32bit }
  662. else
  663. begin
  664. inserttypeconv(right,s32bittype);
  665. inserttypeconv(left,s32bittype);
  666. end;
  667. end
  668. { if both are floatdefs, conversion is already done before constant folding }
  669. else if (ld.deftype=floatdef) then
  670. begin
  671. { already converted }
  672. end
  673. { left side a setdef, must be before string processing,
  674. else array constructor can be seen as array of char (PFV) }
  675. else if (ld.deftype=setdef) then
  676. begin
  677. { trying to add a set element? }
  678. if (nodetype=addn) and (rd.deftype<>setdef) then
  679. begin
  680. if (rt=setelementn) then
  681. begin
  682. if not(is_equal(tsetdef(ld).elementtype.def,rd)) then
  683. CGMessage(type_e_set_element_are_not_comp);
  684. end
  685. else
  686. CGMessage(type_e_mismatch)
  687. end
  688. else
  689. begin
  690. if not(nodetype in [addn,subn,symdifn,muln,equaln,unequaln,lten,gten]) then
  691. CGMessage(type_e_set_operation_unknown);
  692. { right def must be a also be set }
  693. if (rd.deftype<>setdef) or not(is_equal(rd,ld)) then
  694. CGMessage(type_e_set_element_are_not_comp);
  695. end;
  696. { ranges require normsets }
  697. if (tsetdef(ld).settype=smallset) and
  698. (rt=setelementn) and
  699. assigned(tsetelementnode(right).right) then
  700. begin
  701. { generate a temporary normset def, it'll be destroyed
  702. when the symtable is unloaded }
  703. htype.setdef(tsetdef.create(tsetdef(ld).elementtype,255));
  704. inserttypeconv(left,htype);
  705. end;
  706. { if the right side is also a setdef then the settype must
  707. be the same as the left setdef }
  708. if (rd.deftype=setdef) and
  709. (tsetdef(ld).settype<>tsetdef(rd).settype) then
  710. inserttypeconv(right,left.resulttype);
  711. end
  712. { compare pchar to char arrays by addresses like BP/Delphi }
  713. else if (is_pchar(ld) and is_chararray(rd)) or
  714. (is_pchar(rd) and is_chararray(ld)) then
  715. begin
  716. if is_chararray(rd) then
  717. inserttypeconv(right,left.resulttype)
  718. else
  719. inserttypeconv(left,right.resulttype);
  720. end
  721. { is one of the operands a string?,
  722. chararrays are also handled as strings (after conversion), also take
  723. care of chararray+chararray and chararray+char }
  724. else if (rd.deftype=stringdef) or (ld.deftype=stringdef) or
  725. ((is_chararray(rd) or is_char(rd)) and
  726. (is_chararray(ld) or is_char(ld))) then
  727. begin
  728. if is_widestring(rd) or is_widestring(ld) then
  729. begin
  730. if not(is_widestring(rd)) then
  731. inserttypeconv(right,cwidestringtype);
  732. if not(is_widestring(ld)) then
  733. inserttypeconv(left,cwidestringtype);
  734. end
  735. else if is_ansistring(rd) or is_ansistring(ld) then
  736. begin
  737. if not(is_ansistring(rd)) then
  738. inserttypeconv(right,cansistringtype);
  739. if not(is_ansistring(ld)) then
  740. inserttypeconv(left,cansistringtype);
  741. end
  742. else if is_longstring(rd) or is_longstring(ld) then
  743. begin
  744. if not(is_longstring(rd)) then
  745. inserttypeconv(right,clongstringtype);
  746. if not(is_longstring(ld)) then
  747. inserttypeconv(left,clongstringtype);
  748. location.loc:=LOC_CREFERENCE;
  749. end
  750. else
  751. begin
  752. if not(is_shortstring(ld)) then
  753. inserttypeconv(left,cshortstringtype);
  754. { don't convert char, that can be handled by the optimized node }
  755. if not(is_shortstring(rd) or is_char(rd)) then
  756. inserttypeconv(right,cshortstringtype);
  757. end;
  758. end
  759. { pointer comparision and subtraction }
  760. else if (rd.deftype=pointerdef) and (ld.deftype=pointerdef) then
  761. begin
  762. case nodetype of
  763. equaln,unequaln :
  764. begin
  765. if is_voidpointer(right.resulttype.def) then
  766. inserttypeconv(right,left.resulttype)
  767. else if is_voidpointer(left.resulttype.def) then
  768. inserttypeconv(left,right.resulttype)
  769. else if not(is_equal(ld,rd)) then
  770. CGMessage(type_e_mismatch);
  771. end;
  772. ltn,lten,gtn,gten:
  773. begin
  774. if (cs_extsyntax in aktmoduleswitches) then
  775. begin
  776. if is_voidpointer(right.resulttype.def) then
  777. inserttypeconv(right,left.resulttype)
  778. else if is_voidpointer(left.resulttype.def) then
  779. inserttypeconv(left,right.resulttype)
  780. else if not(is_equal(ld,rd)) then
  781. CGMessage(type_e_mismatch);
  782. end
  783. else
  784. CGMessage(type_e_mismatch);
  785. end;
  786. subn:
  787. begin
  788. if (cs_extsyntax in aktmoduleswitches) then
  789. begin
  790. if is_voidpointer(right.resulttype.def) then
  791. inserttypeconv(right,left.resulttype)
  792. else if is_voidpointer(left.resulttype.def) then
  793. inserttypeconv(left,right.resulttype)
  794. else if not(is_equal(ld,rd)) then
  795. CGMessage(type_e_mismatch);
  796. end
  797. else
  798. CGMessage(type_e_mismatch);
  799. resulttype:=s32bittype;
  800. exit;
  801. end;
  802. addn:
  803. begin
  804. if (cs_extsyntax in aktmoduleswitches) then
  805. begin
  806. if is_voidpointer(right.resulttype.def) then
  807. inserttypeconv(right,left.resulttype)
  808. else if is_voidpointer(left.resulttype.def) then
  809. inserttypeconv(left,right.resulttype)
  810. else if not(is_equal(ld,rd)) then
  811. CGMessage(type_e_mismatch);
  812. end
  813. else
  814. CGMessage(type_e_mismatch);
  815. resulttype:=s32bittype;
  816. exit;
  817. end;
  818. else
  819. CGMessage(type_e_mismatch);
  820. end;
  821. end
  822. { class or interface equation }
  823. else if is_class_or_interface(rd) or is_class_or_interface(ld) then
  824. begin
  825. if is_class_or_interface(rd) and is_class_or_interface(ld) then
  826. begin
  827. if tobjectdef(rd).is_related(tobjectdef(ld)) then
  828. inserttypeconv(right,left.resulttype)
  829. else
  830. inserttypeconv(left,right.resulttype);
  831. end
  832. else if is_class_or_interface(rd) then
  833. inserttypeconv(left,right.resulttype)
  834. else
  835. inserttypeconv(right,left.resulttype);
  836. if not(nodetype in [equaln,unequaln]) then
  837. CGMessage(type_e_mismatch);
  838. end
  839. else if (rd.deftype=classrefdef) and (ld.deftype=classrefdef) then
  840. begin
  841. if tobjectdef(tclassrefdef(rd).pointertype.def).is_related(
  842. tobjectdef(tclassrefdef(ld).pointertype.def)) then
  843. inserttypeconv(right,left.resulttype)
  844. else
  845. inserttypeconv(left,right.resulttype);
  846. if not(nodetype in [equaln,unequaln]) then
  847. CGMessage(type_e_mismatch);
  848. end
  849. { allows comperasion with nil pointer }
  850. else if is_class_or_interface(rd) or (rd.deftype=classrefdef) then
  851. begin
  852. inserttypeconv(left,right.resulttype);
  853. if not(nodetype in [equaln,unequaln]) then
  854. CGMessage(type_e_mismatch);
  855. end
  856. else if is_class_or_interface(ld) or (ld.deftype=classrefdef) then
  857. begin
  858. inserttypeconv(right,left.resulttype);
  859. if not(nodetype in [equaln,unequaln]) then
  860. CGMessage(type_e_mismatch);
  861. end
  862. { support procvar=nil,procvar<>nil }
  863. else if ((ld.deftype=procvardef) and (rt=niln)) or
  864. ((rd.deftype=procvardef) and (lt=niln)) then
  865. begin
  866. if not(nodetype in [equaln,unequaln]) then
  867. CGMessage(type_e_mismatch);
  868. end
  869. {$ifdef SUPPORT_MMX}
  870. { mmx support, this must be before the zero based array
  871. check }
  872. else if (cs_mmx in aktlocalswitches) and
  873. is_mmx_able_array(ld) and
  874. is_mmx_able_array(rd) and
  875. is_equal(ld,rd) then
  876. begin
  877. case nodetype of
  878. addn,subn,xorn,orn,andn:
  879. ;
  880. { mul is a little bit restricted }
  881. muln:
  882. if not(mmx_type(ld) in [mmxu16bit,mmxs16bit,mmxfixed16]) then
  883. CGMessage(type_e_mismatch);
  884. else
  885. CGMessage(type_e_mismatch);
  886. end;
  887. end
  888. {$endif SUPPORT_MMX}
  889. { this is a little bit dangerous, also the left type }
  890. { pointer to should be checked! This broke the mmx support }
  891. else if (rd.deftype=pointerdef) or is_zero_based_array(rd) then
  892. begin
  893. if is_zero_based_array(rd) then
  894. begin
  895. resulttype.setdef(tpointerdef.create(tarraydef(rd).elementtype));
  896. inserttypeconv(right,resulttype);
  897. end;
  898. inserttypeconv(left,s32bittype);
  899. if nodetype=addn then
  900. begin
  901. if not(cs_extsyntax in aktmoduleswitches) or
  902. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  903. CGMessage(type_e_mismatch);
  904. if (rd.deftype=pointerdef) and
  905. (tpointerdef(rd).pointertype.def.size>1) then
  906. left:=caddnode.create(muln,left,cordconstnode.create(tpointerdef(rd).pointertype.def.size,s32bittype));
  907. end
  908. else
  909. CGMessage(type_e_mismatch);
  910. end
  911. else if (ld.deftype=pointerdef) or is_zero_based_array(ld) then
  912. begin
  913. if is_zero_based_array(ld) then
  914. begin
  915. resulttype.setdef(tpointerdef.create(tarraydef(ld).elementtype));
  916. inserttypeconv(left,resulttype);
  917. end;
  918. inserttypeconv(right,s32bittype);
  919. if nodetype in [addn,subn] then
  920. begin
  921. if not(cs_extsyntax in aktmoduleswitches) or
  922. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  923. CGMessage(type_e_mismatch);
  924. if (ld.deftype=pointerdef) and
  925. (tpointerdef(ld).pointertype.def.size>1) then
  926. right:=caddnode.create(muln,right,cordconstnode.create(tpointerdef(ld).pointertype.def.size,s32bittype));
  927. end
  928. else
  929. CGMessage(type_e_mismatch);
  930. end
  931. else if (rd.deftype=procvardef) and (ld.deftype=procvardef) and is_equal(rd,ld) then
  932. begin
  933. if not (nodetype in [equaln,unequaln]) then
  934. CGMessage(type_e_mismatch);
  935. end
  936. { enums }
  937. else if (ld.deftype=enumdef) and (rd.deftype=enumdef) then
  938. begin
  939. if not(is_equal(ld,rd)) then
  940. inserttypeconv(right,left.resulttype);
  941. if not(nodetype in [equaln,unequaln,ltn,lten,gtn,gten]) then
  942. CGMessage(type_e_mismatch);
  943. end
  944. { generic conversion, this is for error recovery }
  945. else
  946. begin
  947. inserttypeconv(left,s32bittype);
  948. inserttypeconv(right,s32bittype);
  949. end;
  950. { set resulttype if not already done }
  951. if not assigned(resulttype.def) then
  952. begin
  953. case nodetype of
  954. ltn,lten,gtn,gten,equaln,unequaln :
  955. resulttype:=booltype;
  956. slashn :
  957. resulttype:=pbestrealtype^;
  958. addn:
  959. begin
  960. { for strings, return is always a 255 char string }
  961. if is_shortstring(left.resulttype.def) then
  962. resulttype:=cshortstringtype
  963. else
  964. resulttype:=left.resulttype;
  965. end;
  966. else
  967. resulttype:=left.resulttype;
  968. end;
  969. end;
  970. end;
  971. function taddnode.first_addstring: tnode;
  972. var
  973. p: tnode;
  974. begin
  975. { when we get here, we are sure that both the left and the right }
  976. { node are both strings of the same stringtype (JM) }
  977. case nodetype of
  978. addn:
  979. begin
  980. { note: if you implemented an fpc_shortstr_concat similar to the }
  981. { one in i386.inc, you have to override first_addstring like in }
  982. { ti386addnode.first_string and implement the shortstring concat }
  983. { manually! The generic routine is different from the i386 one (JM) }
  984. { create the call to the concat routine both strings as arguments }
  985. result := ccallnode.createintern('fpc_'+
  986. tstringdef(resulttype.def).stringtypname+'_concat',
  987. ccallparanode.create(right,ccallparanode.create(left,nil)));
  988. { we reused the arguments }
  989. left := nil;
  990. right := nil;
  991. firstpass(result);
  992. end;
  993. ltn,lten,gtn,gten,equaln,unequaln :
  994. begin
  995. { generate better code for s='' and s<>'' }
  996. if (nodetype in [equaln,unequaln]) and
  997. (((left.nodetype=stringconstn) and (str_length(left)=0)) or
  998. ((right.nodetype=stringconstn) and (str_length(right)=0))) then
  999. begin
  1000. { switch so that the constant is always on the right }
  1001. if left.nodetype = stringconstn then
  1002. begin
  1003. p := left;
  1004. left := right;
  1005. right := p;
  1006. end;
  1007. if is_shortstring(left.resulttype.def) then
  1008. { compare the length with 0 }
  1009. result := caddnode.create(nodetype,
  1010. cinlinenode.create(in_length_x,false,left),
  1011. cordconstnode.create(0,s32bittype))
  1012. else
  1013. begin
  1014. { compare the pointer with nil (for ansistrings etc), }
  1015. { faster than getting the length (JM) }
  1016. result:= caddnode.create(nodetype,
  1017. ctypeconvnode.create(left,voidpointertype),
  1018. cpointerconstnode.create(0,voidpointertype));
  1019. taddnode(result).left.toggleflag(nf_explizit);
  1020. end;
  1021. { left is reused }
  1022. left := nil;
  1023. { right isn't }
  1024. right.free;
  1025. right := nil;
  1026. firstpass(result);
  1027. exit;
  1028. end;
  1029. { no string constant -> call compare routine }
  1030. result := ccallnode.createintern('fpc_'+
  1031. tstringdef(left.resulttype.def).stringtypname+'_compare',
  1032. ccallparanode.create(right,ccallparanode.create(left,nil)));
  1033. { and compare its result with 0 according to the original operator }
  1034. result := caddnode.create(nodetype,result,
  1035. cordconstnode.create(0,s32bittype));
  1036. left := nil;
  1037. right := nil;
  1038. firstpass(result);
  1039. end;
  1040. end;
  1041. end;
  1042. function taddnode.first_addset: tnode;
  1043. var
  1044. procname: string[31];
  1045. tempn: tnode;
  1046. paras: tcallparanode;
  1047. srsym: ttypesym;
  1048. begin
  1049. { get the sym that represents the fpc_normal_set type }
  1050. if not searchsystype('FPC_NORMAL_SET',srsym) then
  1051. internalerror(200108313);
  1052. case nodetype of
  1053. equaln,unequaln,lten,gten:
  1054. begin
  1055. case nodetype of
  1056. equaln,unequaln:
  1057. procname := 'fpc_set_comp_sets';
  1058. lten,gten:
  1059. begin
  1060. procname := 'fpc_set_contains_sets';
  1061. { (left >= right) = (right <= left) }
  1062. if nodetype = gten then
  1063. begin
  1064. tempn := left;
  1065. left := right;
  1066. right := tempn;
  1067. end;
  1068. end;
  1069. end;
  1070. { convert the arguments (explicitely) to fpc_normal_set's }
  1071. left := ctypeconvnode.create(left,srsym.restype);
  1072. left.toggleflag(nf_explizit);
  1073. right := ctypeconvnode.create(right,srsym.restype);
  1074. right.toggleflag(nf_explizit);
  1075. result := ccallnode.createintern(procname,ccallparanode.create(right,
  1076. ccallparanode.create(left,nil)));
  1077. { left and right are reused as parameters }
  1078. left := nil;
  1079. right := nil;
  1080. { for an unequaln, we have to negate the result of comp_sets }
  1081. if nodetype = unequaln then
  1082. result := cnotnode.create(result);
  1083. end;
  1084. addn:
  1085. begin
  1086. { optimize first loading of a set }
  1087. if (right.nodetype=setelementn) and
  1088. not(assigned(tsetelementnode(right).right)) and
  1089. is_emptyset(left) then
  1090. begin
  1091. { type cast the value to pass as argument to a byte, }
  1092. { since that's what the helper expects }
  1093. tsetelementnode(right).left :=
  1094. ctypeconvnode.create(tsetelementnode(right).left,u8bittype);
  1095. tsetelementnode(right).left.toggleflag(nf_explizit);
  1096. { set the resulttype to the actual one (otherwise it's }
  1097. { "fpc_normal_set") }
  1098. result := ccallnode.createinternres('fpc_set_create_element',
  1099. ccallparanode.create(tsetelementnode(right).left,nil),
  1100. resulttype);
  1101. { reused }
  1102. tsetelementnode(right).left := nil;
  1103. end
  1104. else
  1105. begin
  1106. if right.nodetype=setelementn then
  1107. begin
  1108. { convert the arguments to bytes, since that's what }
  1109. { the helper expects }
  1110. tsetelementnode(right).left :=
  1111. ctypeconvnode.create(tsetelementnode(right).left,
  1112. u8bittype);
  1113. tsetelementnode(right).left.toggleflag(nf_explizit);
  1114. { convert the original set (explicitely) to an }
  1115. { fpc_normal_set so we can pass it to the helper }
  1116. left := ctypeconvnode.create(left,srsym.restype);
  1117. left.toggleflag(nf_explizit);
  1118. { add a range or a single element? }
  1119. if assigned(tsetelementnode(right).right) then
  1120. begin
  1121. tsetelementnode(right).right :=
  1122. ctypeconvnode.create(tsetelementnode(right).right,
  1123. u8bittype);
  1124. tsetelementnode(right).right.toggleflag(nf_explizit);
  1125. { create the call }
  1126. result := ccallnode.createinternres('fpc_set_set_range',
  1127. ccallparanode.create(tsetelementnode(right).right,
  1128. ccallparanode.create(tsetelementnode(right).left,
  1129. ccallparanode.create(left,nil))),resulttype);
  1130. end
  1131. else
  1132. begin
  1133. result := ccallnode.createinternres('fpc_set_set_byte',
  1134. ccallparanode.create(tsetelementnode(right).left,
  1135. ccallparanode.create(left,nil)),resulttype);
  1136. end;
  1137. { remove reused parts from original node }
  1138. tsetelementnode(right).right := nil;
  1139. tsetelementnode(right).left := nil;
  1140. left := nil;
  1141. end
  1142. else
  1143. begin
  1144. { add two sets }
  1145. { convert the sets 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.createinternres('fpc_set_add_sets',
  1151. ccallparanode.create(right,
  1152. ccallparanode.create(left,nil)),resulttype);
  1153. { remove reused parts from original node }
  1154. left := nil;
  1155. right := nil;
  1156. end;
  1157. end
  1158. end;
  1159. subn,symdifn,muln:
  1160. begin
  1161. { convert the sets to fpc_normal_set's }
  1162. left := ctypeconvnode.create(left,srsym.restype);
  1163. left.toggleflag(nf_explizit);
  1164. right := ctypeconvnode.create(right,srsym.restype);
  1165. right.toggleflag(nf_explizit);
  1166. paras := ccallparanode.create(right,
  1167. ccallparanode.create(left,nil));
  1168. case nodetype of
  1169. subn:
  1170. result := ccallnode.createinternres('fpc_set_sub_sets',
  1171. paras,resulttype);
  1172. symdifn:
  1173. result := ccallnode.createinternres('fpc_set_symdif_sets',
  1174. paras,resulttype);
  1175. muln:
  1176. result := ccallnode.createinternres('fpc_set_mul_sets',
  1177. paras,resulttype);
  1178. end;
  1179. { remove reused parts from original node }
  1180. left := nil;
  1181. right := nil;
  1182. end;
  1183. else
  1184. internalerror(200108311);
  1185. end;
  1186. firstpass(result);
  1187. end;
  1188. function taddnode.first_add64bitint: tnode;
  1189. var
  1190. procname: string[31];
  1191. temp: tnode;
  1192. power: longint;
  1193. begin
  1194. result := nil;
  1195. { create helper calls mul }
  1196. if nodetype <> muln then
  1197. exit;
  1198. { make sure that if there is a constant, that it's on the right }
  1199. if left.nodetype = ordconstn then
  1200. begin
  1201. temp := right;
  1202. right := left;
  1203. left := temp;
  1204. end;
  1205. { can we use a shift instead of a mul? }
  1206. if (right.nodetype = ordconstn) and
  1207. ispowerof2(tordconstnode(right).value,power) then
  1208. begin
  1209. tordconstnode(right).value := power;
  1210. result := cshlshrnode.create(shln,left,right);
  1211. { left and right are reused }
  1212. left := nil;
  1213. right := nil;
  1214. { return firstpassed new node }
  1215. firstpass(result);
  1216. exit;
  1217. end;
  1218. { otherwise, create the parameters for the helper }
  1219. right := ccallparanode.create(
  1220. cordconstnode.create(ord(cs_check_overflow in aktlocalswitches),booltype),
  1221. ccallparanode.create(right,ccallparanode.create(left,nil)));
  1222. left := nil;
  1223. if torddef(resulttype.def).typ = s64bit then
  1224. procname := 'fpc_mul_int64'
  1225. else
  1226. procname := 'fpc_mul_qword';
  1227. result := ccallnode.createintern(procname,right);
  1228. right := nil;
  1229. firstpass(result);
  1230. end;
  1231. function taddnode.pass_1 : tnode;
  1232. var
  1233. hp : tnode;
  1234. lt,rt : tnodetype;
  1235. rd,ld : tdef;
  1236. begin
  1237. result:=nil;
  1238. { first do the two subtrees }
  1239. firstpass(left);
  1240. firstpass(right);
  1241. if codegenerror then
  1242. exit;
  1243. { load easier access variables }
  1244. rd:=right.resulttype.def;
  1245. ld:=left.resulttype.def;
  1246. rt:=right.nodetype;
  1247. lt:=left.nodetype;
  1248. { int/int gives real/real! }
  1249. if nodetype=slashn then
  1250. begin
  1251. location.loc:=LOC_FPUREGISTER;
  1252. { maybe we need an integer register to save }
  1253. { a reference }
  1254. if ((left.location.loc<>LOC_FPUREGISTER) or
  1255. (right.location.loc<>LOC_FPUREGISTER)) and
  1256. (left.registers32=right.registers32) then
  1257. calcregisters(self,1,1,0)
  1258. else
  1259. calcregisters(self,0,1,0);
  1260. { an add node always first loads both the left and the }
  1261. { right in the fpu before doing the calculation. However, }
  1262. { calcregisters(0,2,0) will overestimate the number of }
  1263. { necessary registers (it will make it 3 in case one of }
  1264. { the operands is already in the fpu) (JM) }
  1265. if ((left.location.loc <> LOC_FPUREGISTER) or
  1266. (right.location.loc <> LOC_FPUREGISTER)) and
  1267. (registersfpu < 2) then
  1268. inc(registersfpu);
  1269. end
  1270. { if both are orddefs then check sub types }
  1271. else if (ld.deftype=orddef) and (rd.deftype=orddef) then
  1272. begin
  1273. { 2 booleans ? }
  1274. if is_boolean(ld) and is_boolean(rd) then
  1275. begin
  1276. if not(cs_full_boolean_eval in aktlocalswitches) and
  1277. (nodetype in [andn,orn]) then
  1278. begin
  1279. location.loc:=LOC_JUMP;
  1280. calcregisters(self,0,0,0);
  1281. end
  1282. else
  1283. begin
  1284. location.loc := LOC_FLAGS;
  1285. if (left.location.loc in [LOC_JUMP,LOC_FLAGS]) and
  1286. (left.location.loc in [LOC_JUMP,LOC_FLAGS]) then
  1287. calcregisters(self,2,0,0)
  1288. else
  1289. calcregisters(self,1,0,0);
  1290. end;
  1291. end
  1292. else
  1293. { Both are chars? only convert to shortstrings for addn }
  1294. if is_char(ld) then
  1295. begin
  1296. if nodetype=addn then
  1297. internalerror(200103291);
  1298. location.loc := LOC_FLAGS;
  1299. calcregisters(self,1,0,0);
  1300. end
  1301. { is there a 64 bit type ? }
  1302. else if (torddef(ld).typ in [s64bit,u64bit]) then
  1303. begin
  1304. result := first_add64bitint;
  1305. if assigned(result) then
  1306. exit;
  1307. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1308. location.loc := LOC_REGISTER
  1309. else
  1310. location.loc := LOC_JUMP;
  1311. calcregisters(self,2,0,0)
  1312. end
  1313. { is there a cardinal? }
  1314. else if (torddef(ld).typ=u32bit) then
  1315. begin
  1316. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1317. location.loc := LOC_REGISTER
  1318. else
  1319. location.loc := LOC_FLAGS;
  1320. calcregisters(self,1,0,0);
  1321. { for unsigned mul we need an extra register }
  1322. if nodetype=muln then
  1323. inc(registers32);
  1324. end
  1325. { generic s32bit conversion }
  1326. else
  1327. begin
  1328. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1329. location.loc := LOC_REGISTER
  1330. else
  1331. location.loc := LOC_FLAGS;
  1332. calcregisters(self,1,0,0);
  1333. end;
  1334. end
  1335. { left side a setdef, must be before string processing,
  1336. else array constructor can be seen as array of char (PFV) }
  1337. else if (ld.deftype=setdef) then
  1338. begin
  1339. if tsetdef(ld).settype=smallset then
  1340. begin
  1341. location.loc:=LOC_REGISTER;
  1342. { are we adding set elements ? }
  1343. if right.nodetype=setelementn then
  1344. calcregisters(self,2,0,0)
  1345. else
  1346. calcregisters(self,1,0,0);
  1347. end
  1348. else
  1349. begin
  1350. result := first_addset;
  1351. if assigned(result) then
  1352. exit;
  1353. location.loc:=LOC_CREFERENCE;
  1354. calcregisters(self,0,0,0);
  1355. { here we call SET... }
  1356. if assigned(procinfo) then
  1357. procinfo^.flags:=procinfo^.flags or pi_do_call;
  1358. end;
  1359. end
  1360. { compare pchar by addresses like BP/Delphi }
  1361. else if is_pchar(ld) then
  1362. begin
  1363. location.loc:=LOC_REGISTER;
  1364. calcregisters(self,1,0,0);
  1365. end
  1366. { is one of the operands a string }
  1367. else if (ld.deftype=stringdef) then
  1368. begin
  1369. if is_widestring(ld) then
  1370. begin
  1371. { we use reference counted widestrings so no fast exit here }
  1372. if assigned(procinfo) then
  1373. procinfo^.no_fast_exit:=true;
  1374. { this is only for add, the comparisaion is handled later }
  1375. location.loc:=LOC_REGISTER;
  1376. end
  1377. else if is_ansistring(ld) then
  1378. begin
  1379. { we use ansistrings so no fast exit here }
  1380. if assigned(procinfo) then
  1381. procinfo^.no_fast_exit:=true;
  1382. { this is only for add, the comparisaion is handled later }
  1383. location.loc:=LOC_REGISTER;
  1384. end
  1385. else if is_longstring(ld) then
  1386. begin
  1387. { this is only for add, the comparisaion is handled later }
  1388. location.loc:=LOC_CREFERENCE;
  1389. end
  1390. else
  1391. begin
  1392. if canbeaddsstringcharoptnode(self) then
  1393. begin
  1394. hp := genaddsstringcharoptnode(self);
  1395. firstpass(hp);
  1396. pass_1 := hp;
  1397. exit;
  1398. end
  1399. else
  1400. begin
  1401. { Fix right to be shortstring }
  1402. if is_char(right.resulttype.def) then
  1403. begin
  1404. inserttypeconv(right,cshortstringtype);
  1405. firstpass(right);
  1406. end;
  1407. end;
  1408. if canbeaddsstringcsstringoptnode(self) then
  1409. begin
  1410. hp := genaddsstringcsstringoptnode(self);
  1411. firstpass(hp);
  1412. pass_1 := hp;
  1413. exit;
  1414. end;
  1415. end;
  1416. { otherwise, let addstring convert everything }
  1417. result := first_addstring;
  1418. exit;
  1419. end
  1420. { is one a real float ? }
  1421. else if (rd.deftype=floatdef) or (ld.deftype=floatdef) then
  1422. begin
  1423. location.loc:=LOC_FPUREGISTER;
  1424. calcregisters(self,0,1,0);
  1425. { an add node always first loads both the left and the }
  1426. { right in the fpu before doing the calculation. However, }
  1427. { calcregisters(0,2,0) will overestimate the number of }
  1428. { necessary registers (it will make it 3 in case one of }
  1429. { the operands is already in the fpu) (JM) }
  1430. if ((left.location.loc <> LOC_FPUREGISTER) or
  1431. (right.location.loc <> LOC_FPUREGISTER)) and
  1432. (registersfpu < 2) then
  1433. inc(registersfpu);
  1434. end
  1435. { pointer comperation and subtraction }
  1436. else if (ld.deftype=pointerdef) then
  1437. begin
  1438. location.loc:=LOC_REGISTER;
  1439. calcregisters(self,1,0,0);
  1440. end
  1441. else if is_class_or_interface(ld) then
  1442. begin
  1443. location.loc:=LOC_REGISTER;
  1444. calcregisters(self,1,0,0);
  1445. end
  1446. else if (ld.deftype=classrefdef) then
  1447. begin
  1448. location.loc:=LOC_REGISTER;
  1449. calcregisters(self,1,0,0);
  1450. end
  1451. { support procvar=nil,procvar<>nil }
  1452. else if ((ld.deftype=procvardef) and (rt=niln)) or
  1453. ((rd.deftype=procvardef) and (lt=niln)) then
  1454. begin
  1455. location.loc:=LOC_REGISTER;
  1456. calcregisters(self,1,0,0);
  1457. end
  1458. {$ifdef SUPPORT_MMX}
  1459. { mmx support, this must be before the zero based array
  1460. check }
  1461. else if (cs_mmx in aktlocalswitches) and is_mmx_able_array(ld) and
  1462. is_mmx_able_array(rd) then
  1463. begin
  1464. location.loc:=LOC_MMXREGISTER;
  1465. calcregisters(self,0,0,1);
  1466. end
  1467. {$endif SUPPORT_MMX}
  1468. else if (rd.deftype=pointerdef) or (ld.deftype=pointerdef) then
  1469. begin
  1470. location.loc:=LOC_REGISTER;
  1471. calcregisters(self,1,0,0);
  1472. end
  1473. else if (rd.deftype=procvardef) and (ld.deftype=procvardef) and is_equal(rd,ld) then
  1474. begin
  1475. location.loc:=LOC_REGISTER;
  1476. calcregisters(self,1,0,0);
  1477. end
  1478. else if (ld.deftype=enumdef) then
  1479. begin
  1480. location.loc := LOC_FLAGS;
  1481. calcregisters(self,1,0,0);
  1482. end
  1483. {$ifdef SUPPORT_MMX}
  1484. else if (cs_mmx in aktlocalswitches) and
  1485. is_mmx_able_array(ld) and
  1486. is_mmx_able_array(rd) then
  1487. begin
  1488. location.loc:=LOC_MMXREGISTER;
  1489. calcregisters(self,0,0,1);
  1490. end
  1491. {$endif SUPPORT_MMX}
  1492. { the general solution is to convert to 32 bit int }
  1493. else
  1494. begin
  1495. location.loc:=LOC_REGISTER;
  1496. calcregisters(self,1,0,0);
  1497. end;
  1498. end;
  1499. {$ifdef state_tracking}
  1500. function Taddnode.track_state_pass(exec_known:boolean):boolean;
  1501. var factval:Tnode;
  1502. begin
  1503. track_state_pass:=false;
  1504. if left.track_state_pass(exec_known) then
  1505. begin
  1506. track_state_pass:=true;
  1507. left.resulttype.def:=nil;
  1508. do_resulttypepass(left);
  1509. end;
  1510. factval:=aktstate.find_fact(left);
  1511. if factval<>nil then
  1512. begin
  1513. track_state_pass:=true;
  1514. left.destroy;
  1515. left:=factval.getcopy;
  1516. end;
  1517. if right.track_state_pass(exec_known) then
  1518. begin
  1519. track_state_pass:=true;
  1520. right.resulttype.def:=nil;
  1521. do_resulttypepass(right);
  1522. end;
  1523. factval:=aktstate.find_fact(right);
  1524. if factval<>nil then
  1525. begin
  1526. track_state_pass:=true;
  1527. right.destroy;
  1528. right:=factval.getcopy;
  1529. end;
  1530. end;
  1531. {$endif}
  1532. begin
  1533. caddnode:=taddnode;
  1534. end.
  1535. {
  1536. $Log$
  1537. Revision 1.55 2002-07-22 11:48:04 daniel
  1538. * Sets are now internally sets.
  1539. Revision 1.54 2002/07/20 11:57:53 florian
  1540. * types.pas renamed to defbase.pas because D6 contains a types
  1541. unit so this would conflicts if D6 programms are compiled
  1542. + Willamette/SSE2 instructions to assembler added
  1543. Revision 1.53 2002/07/19 11:41:34 daniel
  1544. * State tracker work
  1545. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1546. allows the state tracker to change while nodes automatically into
  1547. repeat nodes.
  1548. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1549. 'not(a>b)' is optimized into 'a<=b'.
  1550. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1551. by removing the notn and later switchting the true and falselabels. The
  1552. same is done with 'repeat until not a'.
  1553. Revision 1.52 2002/07/14 18:00:43 daniel
  1554. + Added the beginning of a state tracker. This will track the values of
  1555. variables through procedures and optimize things away.
  1556. Revision 1.51 2002/05/18 13:34:08 peter
  1557. * readded missing revisions
  1558. Revision 1.50 2002/05/16 19:46:37 carl
  1559. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1560. + try to fix temp allocation (still in ifdef)
  1561. + generic constructor calls
  1562. + start of tassembler / tmodulebase class cleanup
  1563. Revision 1.48 2002/05/13 19:54:36 peter
  1564. * removed n386ld and n386util units
  1565. * maybe_save/maybe_restore added instead of the old maybe_push
  1566. Revision 1.47 2002/05/12 16:53:06 peter
  1567. * moved entry and exitcode to ncgutil and cgobj
  1568. * foreach gets extra argument for passing local data to the
  1569. iterator function
  1570. * -CR checks also class typecasts at runtime by changing them
  1571. into as
  1572. * fixed compiler to cycle with the -CR option
  1573. * fixed stabs with elf writer, finally the global variables can
  1574. be watched
  1575. * removed a lot of routines from cga unit and replaced them by
  1576. calls to cgobj
  1577. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1578. u32bit then the other is typecasted also to u32bit without giving
  1579. a rangecheck warning/error.
  1580. * fixed pascal calling method with reversing also the high tree in
  1581. the parast, detected by tcalcst3 test
  1582. Revision 1.46 2002/04/23 19:16:34 peter
  1583. * add pinline unit that inserts compiler supported functions using
  1584. one or more statements
  1585. * moved finalize and setlength from ninl to pinline
  1586. Revision 1.45 2002/04/04 19:05:56 peter
  1587. * removed unused units
  1588. * use tlocation.size in cg.a_*loc*() routines
  1589. Revision 1.44 2002/04/02 17:11:28 peter
  1590. * tlocation,treference update
  1591. * LOC_CONSTANT added for better constant handling
  1592. * secondadd splitted in multiple routines
  1593. * location_force_reg added for loading a location to a register
  1594. of a specified size
  1595. * secondassignment parses now first the right and then the left node
  1596. (this is compatible with Kylix). This saves a lot of push/pop especially
  1597. with string operations
  1598. * adapted some routines to use the new cg methods
  1599. Revision 1.43 2002/03/30 23:12:09 carl
  1600. * avoid crash with procinfo ('merged')
  1601. }