nadd.pas 82 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062
  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. { define addstringopt}
  21. interface
  22. uses
  23. node;
  24. type
  25. taddnode = class(tbinopnode)
  26. constructor create(tt : tnodetype;l,r : tnode);override;
  27. function pass_1 : tnode;override;
  28. function det_resulttype:tnode;override;
  29. {$ifdef state_tracking}
  30. function track_state_pass(exec_known:boolean):boolean;override;
  31. {$endif}
  32. protected
  33. { override the following if you want to implement }
  34. { parts explicitely in the code generator (JM) }
  35. function first_addstring: tnode; virtual;
  36. function first_addset: tnode; virtual;
  37. { only implements "muln" nodes, the rest always has to be done in }
  38. { the code generator for performance reasons (JM) }
  39. function first_add64bitint: tnode; virtual;
  40. {$ifdef cpufpemu}
  41. { This routine calls internal runtime library helpers
  42. for all floating point arithmetic in the case
  43. where the emulation switches is on. Otherwise
  44. returns nil, and everything must be done in
  45. the code generation phase.
  46. }
  47. function first_addfloat : tnode; virtual;
  48. {$endif cpufpemu}
  49. end;
  50. taddnodeclass = class of taddnode;
  51. var
  52. { caddnode is used to create nodes of the add type }
  53. { the virtual constructor allows to assign }
  54. { another class type to caddnode => processor }
  55. { specific node types can be created }
  56. caddnode : taddnodeclass;
  57. implementation
  58. uses
  59. globtype,systems,
  60. cutils,verbose,globals,widestr,
  61. symconst,symtype,symdef,symsym,symtable,defutil,defcmp,
  62. cgbase,
  63. htypechk,pass_1,
  64. nbas,nmat,ncnv,ncon,nset,nopt,ncal,ninl,nmem,nutils,
  65. {$ifdef state_tracking}
  66. nstate,
  67. {$endif}
  68. cpuinfo,procinfo;
  69. {*****************************************************************************
  70. TADDNODE
  71. *****************************************************************************}
  72. {$ifdef fpc}
  73. {$maxfpuregisters 0}
  74. {$endif fpc}
  75. constructor taddnode.create(tt : tnodetype;l,r : tnode);
  76. begin
  77. inherited create(tt,l,r);
  78. end;
  79. function taddnode.det_resulttype:tnode;
  80. var
  81. hp,t : tnode;
  82. lt,rt : tnodetype;
  83. rd,ld : tdef;
  84. htype : ttype;
  85. ot : tnodetype;
  86. concatstrings : boolean;
  87. resultset : Tconstset;
  88. i : longint;
  89. b : boolean;
  90. c1,c2 :char;
  91. s1,s2 : pchar;
  92. ws1,ws2 : pcompilerwidestring;
  93. l1,l2 : longint;
  94. rv,lv : tconstexprint;
  95. rvd,lvd : bestreal;
  96. resultrealtype : ttype;
  97. {$ifdef state_tracking}
  98. factval : Tnode;
  99. change : boolean;
  100. {$endif}
  101. begin
  102. result:=nil;
  103. { first do the two subtrees }
  104. resulttypepass(left);
  105. resulttypepass(right);
  106. { both left and right need to be valid }
  107. set_varstate(left,vs_used,true);
  108. set_varstate(right,vs_used,true);
  109. if codegenerror then
  110. exit;
  111. { tp procvar support }
  112. maybe_call_procvar(left,true);
  113. maybe_call_procvar(right,true);
  114. { convert array constructors to sets, because there is no other operator
  115. possible for array constructors }
  116. if is_array_constructor(left.resulttype.def) then
  117. begin
  118. arrayconstructor_to_set(left);
  119. resulttypepass(left);
  120. end;
  121. if is_array_constructor(right.resulttype.def) then
  122. begin
  123. arrayconstructor_to_set(right);
  124. resulttypepass(right);
  125. end;
  126. { allow operator overloading }
  127. hp:=self;
  128. if isbinaryoverloaded(hp) then
  129. begin
  130. result:=hp;
  131. exit;
  132. end;
  133. { Stop checking when an error was found in the operator checking }
  134. if codegenerror then
  135. begin
  136. result:=cerrornode.create;
  137. exit;
  138. end;
  139. { Kylix allows enum+ordconstn in an enum declaration (blocktype
  140. is bt_type), we need to do the conversion here before the
  141. constant folding }
  142. if (m_delphi in aktmodeswitches) and
  143. (blocktype=bt_type) then
  144. begin
  145. if (left.resulttype.def.deftype=enumdef) and
  146. (right.resulttype.def.deftype=orddef) then
  147. begin
  148. { insert explicit typecast to default signed int }
  149. left:=ctypeconvnode.create_explicit(left,sinttype);
  150. resulttypepass(left);
  151. end
  152. else
  153. if (left.resulttype.def.deftype=orddef) and
  154. (right.resulttype.def.deftype=enumdef) then
  155. begin
  156. { insert explicit typecast to default signed int }
  157. right:=ctypeconvnode.create_explicit(right,sinttype);
  158. resulttypepass(right);
  159. end;
  160. end;
  161. { is one a real float, then both need to be floats, this
  162. need to be done before the constant folding so constant
  163. operation on a float and int are also handled }
  164. resultrealtype:=pbestrealtype^;
  165. if (right.resulttype.def.deftype=floatdef) or (left.resulttype.def.deftype=floatdef) then
  166. begin
  167. { when both floattypes are already equal then use that
  168. floattype for results }
  169. if (right.resulttype.def.deftype=floatdef) and
  170. (left.resulttype.def.deftype=floatdef) and
  171. (tfloatdef(left.resulttype.def).typ=tfloatdef(right.resulttype.def).typ) then
  172. resultrealtype:=left.resulttype
  173. { when there is a currency type then use currency, but
  174. only when currency is defined as float }
  175. else
  176. if (is_currency(right.resulttype.def) or
  177. is_currency(left.resulttype.def)) and
  178. ((s64currencytype.def.deftype = floatdef) or
  179. (nodetype <> slashn)) then
  180. begin
  181. resultrealtype:=s64currencytype;
  182. inserttypeconv(right,resultrealtype);
  183. inserttypeconv(left,resultrealtype);
  184. end
  185. else
  186. begin
  187. inserttypeconv(right,resultrealtype);
  188. inserttypeconv(left,resultrealtype);
  189. end;
  190. end;
  191. { If both operands are constant and there is a widechar
  192. or widestring then convert everything to widestring. This
  193. allows constant folding like char+widechar }
  194. if is_constnode(right) and is_constnode(left) and
  195. (is_widestring(right.resulttype.def) or
  196. is_widestring(left.resulttype.def) or
  197. is_widechar(right.resulttype.def) or
  198. is_widechar(left.resulttype.def)) then
  199. begin
  200. inserttypeconv(right,cwidestringtype);
  201. inserttypeconv(left,cwidestringtype);
  202. end;
  203. { load easier access variables }
  204. rd:=right.resulttype.def;
  205. ld:=left.resulttype.def;
  206. rt:=right.nodetype;
  207. lt:=left.nodetype;
  208. if (nodetype = slashn) and
  209. (((rt = ordconstn) and
  210. (tordconstnode(right).value = 0)) or
  211. ((rt = realconstn) and
  212. (trealconstnode(right).value_real = 0.0))) then
  213. begin
  214. if (cs_check_range in aktlocalswitches) or
  215. (cs_check_overflow in aktlocalswitches) then
  216. begin
  217. result:=crealconstnode.create(1,pbestrealtype^);
  218. Message(parser_e_division_by_zero);
  219. exit;
  220. end;
  221. end;
  222. { both are int constants }
  223. if ((is_constintnode(left) and is_constintnode(right)) or
  224. (is_constboolnode(left) and is_constboolnode(right) and
  225. (nodetype in [slashn,ltn,lten,gtn,gten,equaln,unequaln,andn,xorn,orn])) or
  226. (is_constenumnode(left) and is_constenumnode(right) and
  227. (nodetype in [equaln,unequaln,ltn,lten,gtn,gten]))) or
  228. { support pointer arithmetics on constants (JM) }
  229. ((lt = pointerconstn) and is_constintnode(right) and
  230. (nodetype in [addn,subn])) or
  231. (((lt = pointerconstn) or (lt = niln)) and
  232. ((rt = pointerconstn) or (rt = niln)) and
  233. (nodetype in [ltn,lten,gtn,gten,equaln,unequaln,subn])) then
  234. begin
  235. { when comparing/substracting pointers, make sure they are }
  236. { of the same type (JM) }
  237. if (lt = pointerconstn) and (rt = pointerconstn) then
  238. begin
  239. if not(cs_extsyntax in aktmoduleswitches) and
  240. not(nodetype in [equaln,unequaln]) then
  241. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename)
  242. else
  243. if (nodetype <> subn) and
  244. is_voidpointer(rd) then
  245. inserttypeconv(right,left.resulttype)
  246. else if (nodetype <> subn) and
  247. is_voidpointer(ld) then
  248. inserttypeconv(left,right.resulttype)
  249. else if not(equal_defs(ld,rd)) then
  250. IncompatibleTypes(ld,rd);
  251. end
  252. else if (ld.deftype=enumdef) and (rd.deftype=enumdef) then
  253. begin
  254. if not(equal_defs(ld,rd)) then
  255. inserttypeconv(right,left.resulttype);
  256. end;
  257. { load values }
  258. case lt of
  259. ordconstn:
  260. lv:=tordconstnode(left).value;
  261. pointerconstn:
  262. lv:=tpointerconstnode(left).value;
  263. niln:
  264. lv:=0;
  265. else
  266. internalerror(2002080202);
  267. end;
  268. case rt of
  269. ordconstn:
  270. rv:=tordconstnode(right).value;
  271. pointerconstn:
  272. rv:=tpointerconstnode(right).value;
  273. niln:
  274. rv:=0;
  275. else
  276. internalerror(2002080203);
  277. end;
  278. if (lt = pointerconstn) and
  279. (rt <> pointerconstn) then
  280. rv := rv * tpointerdef(left.resulttype.def).pointertype.def.size;
  281. if (rt = pointerconstn) and
  282. (lt <> pointerconstn) then
  283. lv := lv * tpointerdef(right.resulttype.def).pointertype.def.size;
  284. case nodetype of
  285. addn :
  286. if (lt <> pointerconstn) then
  287. t := genintconstnode(lv+rv)
  288. else
  289. t := cpointerconstnode.create(lv+rv,left.resulttype);
  290. subn :
  291. if (lt=pointerconstn) and (rt=pointerconstn) and
  292. (tpointerdef(rd).pointertype.def.size>1) then
  293. t := genintconstnode((lv-rv) div tpointerdef(left.resulttype.def).pointertype.def.size)
  294. else if (lt <> pointerconstn) or (rt = pointerconstn) then
  295. t := genintconstnode(lv-rv)
  296. else
  297. t := cpointerconstnode.create(lv-rv,left.resulttype);
  298. muln :
  299. if (torddef(ld).typ <> u64bit) or
  300. (torddef(rd).typ <> u64bit) then
  301. t:=genintconstnode(lv*rv)
  302. else
  303. t:=genintconstnode(int64(qword(lv)*qword(rv)));
  304. xorn :
  305. if is_integer(ld) then
  306. t:=genintconstnode(lv xor rv)
  307. else
  308. t:=cordconstnode.create(lv xor rv,left.resulttype,true);
  309. orn :
  310. if is_integer(ld) then
  311. t:=genintconstnode(lv or rv)
  312. else
  313. t:=cordconstnode.create(lv or rv,left.resulttype,true);
  314. andn :
  315. if is_integer(ld) then
  316. t:=genintconstnode(lv and rv)
  317. else
  318. t:=cordconstnode.create(lv and rv,left.resulttype,true);
  319. ltn :
  320. t:=cordconstnode.create(ord(lv<rv),booltype,true);
  321. lten :
  322. t:=cordconstnode.create(ord(lv<=rv),booltype,true);
  323. gtn :
  324. t:=cordconstnode.create(ord(lv>rv),booltype,true);
  325. gten :
  326. t:=cordconstnode.create(ord(lv>=rv),booltype,true);
  327. equaln :
  328. t:=cordconstnode.create(ord(lv=rv),booltype,true);
  329. unequaln :
  330. t:=cordconstnode.create(ord(lv<>rv),booltype,true);
  331. slashn :
  332. begin
  333. { int/int becomes a real }
  334. rvd:=rv;
  335. lvd:=lv;
  336. t:=crealconstnode.create(lvd/rvd,resultrealtype);
  337. end;
  338. else
  339. begin
  340. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  341. t:=cnothingnode.create;
  342. end;
  343. end;
  344. result:=t;
  345. exit;
  346. end;
  347. { both real constants ? }
  348. if (lt=realconstn) and (rt=realconstn) then
  349. begin
  350. lvd:=trealconstnode(left).value_real;
  351. rvd:=trealconstnode(right).value_real;
  352. case nodetype of
  353. addn :
  354. t:=crealconstnode.create(lvd+rvd,resultrealtype);
  355. subn :
  356. t:=crealconstnode.create(lvd-rvd,resultrealtype);
  357. muln :
  358. t:=crealconstnode.create(lvd*rvd,resultrealtype);
  359. starstarn,
  360. caretn :
  361. begin
  362. if lvd<0 then
  363. begin
  364. Message(parser_e_invalid_float_operation);
  365. t:=crealconstnode.create(0,resultrealtype);
  366. end
  367. else if lvd=0 then
  368. t:=crealconstnode.create(1.0,resultrealtype)
  369. else
  370. t:=crealconstnode.create(exp(ln(lvd)*rvd),resultrealtype);
  371. end;
  372. slashn :
  373. t:=crealconstnode.create(lvd/rvd,resultrealtype);
  374. ltn :
  375. t:=cordconstnode.create(ord(lvd<rvd),booltype,true);
  376. lten :
  377. t:=cordconstnode.create(ord(lvd<=rvd),booltype,true);
  378. gtn :
  379. t:=cordconstnode.create(ord(lvd>rvd),booltype,true);
  380. gten :
  381. t:=cordconstnode.create(ord(lvd>=rvd),booltype,true);
  382. equaln :
  383. t:=cordconstnode.create(ord(lvd=rvd),booltype,true);
  384. unequaln :
  385. t:=cordconstnode.create(ord(lvd<>rvd),booltype,true);
  386. else
  387. begin
  388. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  389. t:=cnothingnode.create;
  390. end;
  391. end;
  392. result:=t;
  393. exit;
  394. end;
  395. { first, we handle widestrings, so we can check later for }
  396. { stringconstn only }
  397. { widechars are converted above to widestrings too }
  398. { this isn't veryy efficient, but I don't think }
  399. { that it does matter that much (FK) }
  400. if (lt=stringconstn) and (rt=stringconstn) and
  401. (tstringconstnode(left).st_type=st_widestring) and
  402. (tstringconstnode(right).st_type=st_widestring) then
  403. begin
  404. initwidestring(ws1);
  405. initwidestring(ws2);
  406. copywidestring(pcompilerwidestring(tstringconstnode(left).value_str),ws1);
  407. copywidestring(pcompilerwidestring(tstringconstnode(right).value_str),ws2);
  408. case nodetype of
  409. addn :
  410. begin
  411. concatwidestrings(ws1,ws2);
  412. t:=cstringconstnode.createwstr(ws1);
  413. end;
  414. ltn :
  415. t:=cordconstnode.create(byte(comparewidestrings(ws1,ws2)<0),booltype,true);
  416. lten :
  417. t:=cordconstnode.create(byte(comparewidestrings(ws1,ws2)<=0),booltype,true);
  418. gtn :
  419. t:=cordconstnode.create(byte(comparewidestrings(ws1,ws2)>0),booltype,true);
  420. gten :
  421. t:=cordconstnode.create(byte(comparewidestrings(ws1,ws2)>=0),booltype,true);
  422. equaln :
  423. t:=cordconstnode.create(byte(comparewidestrings(ws1,ws2)=0),booltype,true);
  424. unequaln :
  425. t:=cordconstnode.create(byte(comparewidestrings(ws1,ws2)<>0),booltype,true);
  426. else
  427. begin
  428. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  429. t:=cnothingnode.create;
  430. end;
  431. end;
  432. donewidestring(ws1);
  433. donewidestring(ws2);
  434. result:=t;
  435. exit;
  436. end;
  437. { concating strings ? }
  438. concatstrings:=false;
  439. if (lt=ordconstn) and (rt=ordconstn) and
  440. is_char(ld) and is_char(rd) then
  441. begin
  442. c1:=char(byte(tordconstnode(left).value));
  443. l1:=1;
  444. c2:=char(byte(tordconstnode(right).value));
  445. l2:=1;
  446. s1:=@c1;
  447. s2:=@c2;
  448. concatstrings:=true;
  449. end
  450. else if (lt=stringconstn) and (rt=ordconstn) and is_char(rd) then
  451. begin
  452. s1:=tstringconstnode(left).value_str;
  453. l1:=tstringconstnode(left).len;
  454. c2:=char(byte(tordconstnode(right).value));
  455. s2:=@c2;
  456. l2:=1;
  457. concatstrings:=true;
  458. end
  459. else if (lt=ordconstn) and (rt=stringconstn) and is_char(ld) then
  460. begin
  461. c1:=char(byte(tordconstnode(left).value));
  462. l1:=1;
  463. s1:=@c1;
  464. s2:=tstringconstnode(right).value_str;
  465. l2:=tstringconstnode(right).len;
  466. concatstrings:=true;
  467. end
  468. else if (lt=stringconstn) and (rt=stringconstn) then
  469. begin
  470. s1:=tstringconstnode(left).value_str;
  471. l1:=tstringconstnode(left).len;
  472. s2:=tstringconstnode(right).value_str;
  473. l2:=tstringconstnode(right).len;
  474. concatstrings:=true;
  475. end;
  476. if concatstrings then
  477. begin
  478. case nodetype of
  479. addn :
  480. t:=cstringconstnode.createpchar(concatansistrings(s1,s2,l1,l2),l1+l2);
  481. ltn :
  482. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)<0),booltype,true);
  483. lten :
  484. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)<=0),booltype,true);
  485. gtn :
  486. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)>0),booltype,true);
  487. gten :
  488. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)>=0),booltype,true);
  489. equaln :
  490. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)=0),booltype,true);
  491. unequaln :
  492. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)<>0),booltype,true);
  493. else
  494. begin
  495. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  496. t:=cnothingnode.create;
  497. end;
  498. end;
  499. result:=t;
  500. exit;
  501. end;
  502. { set constant evaluation }
  503. if (right.nodetype=setconstn) and
  504. not assigned(tsetconstnode(right).left) and
  505. (left.nodetype=setconstn) and
  506. not assigned(tsetconstnode(left).left) then
  507. begin
  508. { check if size adjusting is needed, only for left
  509. to right as the other way is checked in the typeconv }
  510. if (tsetdef(right.resulttype.def).settype=smallset) and
  511. (tsetdef(left.resulttype.def).settype<>smallset) then
  512. right.resulttype.setdef(tsetdef.create(tsetdef(right.resulttype.def).elementtype,255));
  513. { check base types }
  514. inserttypeconv(left,right.resulttype);
  515. if codegenerror then
  516. begin
  517. { recover by only returning the left part }
  518. result:=left;
  519. left:=nil;
  520. exit;
  521. end;
  522. case nodetype of
  523. addn :
  524. begin
  525. resultset:=tsetconstnode(right).value_set^ + tsetconstnode(left).value_set^;
  526. t:=csetconstnode.create(@resultset,left.resulttype);
  527. end;
  528. muln :
  529. begin
  530. resultset:=tsetconstnode(right).value_set^ * tsetconstnode(left).value_set^;
  531. t:=csetconstnode.create(@resultset,left.resulttype);
  532. end;
  533. subn :
  534. begin
  535. resultset:=tsetconstnode(left).value_set^ - tsetconstnode(right).value_set^;
  536. t:=csetconstnode.create(@resultset,left.resulttype);
  537. end;
  538. symdifn :
  539. begin
  540. resultset:=tsetconstnode(right).value_set^ >< tsetconstnode(left).value_set^;
  541. t:=csetconstnode.create(@resultset,left.resulttype);
  542. end;
  543. unequaln :
  544. begin
  545. b:=tsetconstnode(right).value_set^ <> tsetconstnode(left).value_set^;
  546. t:=cordconstnode.create(byte(b),booltype,true);
  547. end;
  548. equaln :
  549. begin
  550. b:=tsetconstnode(right).value_set^ = tsetconstnode(left).value_set^;
  551. t:=cordconstnode.create(byte(b),booltype,true);
  552. end;
  553. lten :
  554. begin
  555. b:=tsetconstnode(left).value_set^ <= tsetconstnode(right).value_set^;
  556. t:=cordconstnode.create(byte(b),booltype,true);
  557. end;
  558. gten :
  559. begin
  560. b:=tsetconstnode(left).value_set^ >= tsetconstnode(right).value_set^;
  561. t:=cordconstnode.create(byte(b),booltype,true);
  562. end;
  563. else
  564. begin
  565. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  566. t:=cnothingnode.create;
  567. end;
  568. end;
  569. result:=t;
  570. exit;
  571. end;
  572. { but an int/int gives real/real! }
  573. if nodetype=slashn then
  574. begin
  575. if is_currency(left.resulttype.def) and
  576. is_currency(right.resulttype.def) then
  577. { In case of currency, converting to float means dividing by 10000 }
  578. { However, since this is already a division, both divisions by }
  579. { 10000 are eliminated when we divide the results -> we can skip }
  580. { them. }
  581. if s64currencytype.def.deftype = floatdef then
  582. begin
  583. { there's no s64comptype or so, how do we avoid the type conversion?
  584. left.resulttype := s64comptype;
  585. right.resulttype := s64comptype; }
  586. end
  587. else
  588. begin
  589. left.resulttype := s64inttype;
  590. right.resulttype := s64inttype;
  591. end
  592. else if (left.resulttype.def.deftype <> floatdef) and
  593. (right.resulttype.def.deftype <> floatdef) then
  594. CGMessage(type_h_use_div_for_int);
  595. inserttypeconv(right,resultrealtype);
  596. inserttypeconv(left,resultrealtype);
  597. end
  598. { if both are orddefs then check sub types }
  599. else if (ld.deftype=orddef) and (rd.deftype=orddef) then
  600. begin
  601. { optimize multiplacation by a power of 2 }
  602. if not(cs_check_overflow in aktlocalswitches) and
  603. (nodetype = muln) and
  604. (((left.nodetype = ordconstn) and
  605. ispowerof2(tordconstnode(left).value,i)) or
  606. ((right.nodetype = ordconstn) and
  607. ispowerof2(tordconstnode(right).value,i))) then
  608. begin
  609. if left.nodetype = ordconstn then
  610. begin
  611. tordconstnode(left).value := i;
  612. result := cshlshrnode.create(shln,right,left);
  613. end
  614. else
  615. begin
  616. tordconstnode(right).value := i;
  617. result := cshlshrnode.create(shln,left,right);
  618. end;
  619. left := nil;
  620. right := nil;
  621. exit;
  622. end;
  623. { 2 booleans? Make them equal to the largest boolean }
  624. if is_boolean(ld) and is_boolean(rd) then
  625. begin
  626. if torddef(left.resulttype.def).size>torddef(right.resulttype.def).size then
  627. begin
  628. right:=ctypeconvnode.create_explicit(right,left.resulttype);
  629. ttypeconvnode(right).convtype:=tc_bool_2_int;
  630. resulttypepass(right);
  631. end
  632. else if torddef(left.resulttype.def).size<torddef(right.resulttype.def).size then
  633. begin
  634. left:=ctypeconvnode.create_explicit(left,right.resulttype);
  635. ttypeconvnode(left).convtype:=tc_bool_2_int;
  636. resulttypepass(left);
  637. end;
  638. case nodetype of
  639. xorn,
  640. ltn,
  641. lten,
  642. gtn,
  643. gten,
  644. andn,
  645. orn:
  646. begin
  647. end;
  648. unequaln,
  649. equaln:
  650. begin
  651. if not(cs_full_boolean_eval in aktlocalswitches) then
  652. begin
  653. { Remove any compares with constants }
  654. if (left.nodetype=ordconstn) then
  655. begin
  656. hp:=right;
  657. b:=(tordconstnode(left).value<>0);
  658. ot:=nodetype;
  659. left.free;
  660. left:=nil;
  661. right:=nil;
  662. if (not(b) and (ot=equaln)) or
  663. (b and (ot=unequaln)) then
  664. begin
  665. hp:=cnotnode.create(hp);
  666. end;
  667. result:=hp;
  668. exit;
  669. end;
  670. if (right.nodetype=ordconstn) then
  671. begin
  672. hp:=left;
  673. b:=(tordconstnode(right).value<>0);
  674. ot:=nodetype;
  675. right.free;
  676. right:=nil;
  677. left:=nil;
  678. if (not(b) and (ot=equaln)) or
  679. (b and (ot=unequaln)) then
  680. begin
  681. hp:=cnotnode.create(hp);
  682. end;
  683. result:=hp;
  684. exit;
  685. end;
  686. end;
  687. end;
  688. else
  689. begin
  690. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  691. result:=cnothingnode.create;
  692. exit;
  693. end;
  694. end;
  695. end
  696. { Both are chars? }
  697. else if is_char(rd) and is_char(ld) then
  698. begin
  699. if nodetype=addn then
  700. begin
  701. resulttype:=cshortstringtype;
  702. if not(is_constcharnode(left) and is_constcharnode(right)) then
  703. begin
  704. inserttypeconv(left,cshortstringtype);
  705. {$ifdef addstringopt}
  706. hp := genaddsstringcharoptnode(self);
  707. result := hp;
  708. exit;
  709. {$endif addstringopt}
  710. end;
  711. end;
  712. end
  713. { There is a widechar? }
  714. else if is_widechar(rd) or is_widechar(ld) then
  715. begin
  716. { widechar+widechar gives widestring }
  717. if nodetype=addn then
  718. begin
  719. inserttypeconv(left,cwidestringtype);
  720. if (torddef(rd).typ<>uwidechar) then
  721. inserttypeconv(right,cwidechartype);
  722. resulttype:=cwidestringtype;
  723. end
  724. else
  725. begin
  726. if (torddef(ld).typ<>uwidechar) then
  727. inserttypeconv(left,cwidechartype);
  728. if (torddef(rd).typ<>uwidechar) then
  729. inserttypeconv(right,cwidechartype);
  730. end;
  731. end
  732. { is there a currency type ? }
  733. else if ((torddef(rd).typ=scurrency) or (torddef(ld).typ=scurrency)) then
  734. begin
  735. if (torddef(ld).typ<>scurrency) then
  736. inserttypeconv(left,s64currencytype);
  737. if (torddef(rd).typ<>scurrency) then
  738. inserttypeconv(right,s64currencytype);
  739. end
  740. { and,or,xor work on bit patterns and don't care
  741. about the sign }
  742. else if nodetype in [andn,orn,xorn] then
  743. begin
  744. if rd.size>ld.size then
  745. inserttypeconv_explicit(left,right.resulttype)
  746. else
  747. inserttypeconv_explicit(right,left.resulttype);
  748. end
  749. { is there a signed 64 bit type ? }
  750. else if ((torddef(rd).typ=s64bit) or (torddef(ld).typ=s64bit)) then
  751. begin
  752. if (torddef(ld).typ<>s64bit) then
  753. inserttypeconv(left,s64inttype);
  754. if (torddef(rd).typ<>s64bit) then
  755. inserttypeconv(right,s64inttype);
  756. end
  757. { is there a unsigned 64 bit type ? }
  758. else if ((torddef(rd).typ=u64bit) or (torddef(ld).typ=u64bit)) then
  759. begin
  760. if (torddef(ld).typ<>u64bit) then
  761. inserttypeconv(left,u64inttype);
  762. if (torddef(rd).typ<>u64bit) then
  763. inserttypeconv(right,u64inttype);
  764. end
  765. { 64 bit cpus do calculations always in 64 bit }
  766. {$ifndef cpu64bit}
  767. { is there a cardinal? }
  768. else if ((torddef(rd).typ=u32bit) or (torddef(ld).typ=u32bit)) then
  769. begin
  770. { convert positive constants to u32bit }
  771. if (torddef(ld).typ<>u32bit) and
  772. is_constintnode(left) and
  773. (tordconstnode(left).value >= 0) then
  774. inserttypeconv(left,u32inttype);
  775. if (torddef(rd).typ<>u32bit) and
  776. is_constintnode(right) and
  777. (tordconstnode(right).value >= 0) then
  778. inserttypeconv(right,u32inttype);
  779. { when one of the operand is signed perform
  780. the operation in 64bit, can't use rd/ld here because there
  781. could be already typeconvs inserted }
  782. if is_signed(left.resulttype.def) or is_signed(right.resulttype.def) then
  783. begin
  784. CGMessage(type_w_mixed_signed_unsigned);
  785. inserttypeconv(left,s64inttype);
  786. inserttypeconv(right,s64inttype);
  787. end
  788. else
  789. begin
  790. { convert positive constants to u32bit }
  791. if (torddef(ld).typ<>u32bit) and
  792. is_constintnode(left) and
  793. (tordconstnode(left).value >= 0) then
  794. inserttypeconv(left,u32inttype);
  795. if (torddef(rd).typ<>u32bit) and
  796. is_constintnode(right) and
  797. (tordconstnode(right).value >= 0) then
  798. inserttypeconv(right,u32inttype);
  799. { when one of the operand is signed perform
  800. the operation in 64bit, can't use rd/ld here because there
  801. could be already typeconvs inserted }
  802. if is_signed(left.resulttype.def) or is_signed(right.resulttype.def) then
  803. begin
  804. CGMessage(type_w_mixed_signed_unsigned);
  805. inserttypeconv(left,s64inttype);
  806. inserttypeconv(right,s64inttype);
  807. end
  808. else
  809. begin
  810. if (torddef(left.resulttype.def).typ<>u32bit) then
  811. inserttypeconv(left,u32inttype);
  812. if (torddef(right.resulttype.def).typ<>u32bit) then
  813. inserttypeconv(right,u32inttype);
  814. end;
  815. end;
  816. end
  817. {$endif cpu64bit}
  818. { generic ord conversion is sinttype }
  819. else
  820. begin
  821. { if the left or right value is smaller than the normal
  822. type s32inttype and is unsigned, and the other value
  823. is a constant < 0, the result will always be false/true
  824. for equal / unequal nodes.
  825. }
  826. if (
  827. { left : unsigned ordinal var, right : < 0 constant }
  828. (
  829. ((is_signed(ld)=false) and (is_constintnode(left) =false)) and
  830. ((is_constintnode(right)) and (tordconstnode(right).value < 0))
  831. ) or
  832. { right : unsigned ordinal var, left : < 0 constant }
  833. (
  834. ((is_signed(rd)=false) and (is_constintnode(right) =false)) and
  835. ((is_constintnode(left)) and (tordconstnode(left).value < 0))
  836. )
  837. ) then
  838. begin
  839. if nodetype = equaln then
  840. CGMessage(type_w_signed_unsigned_always_false)
  841. else
  842. if nodetype = unequaln then
  843. CGMessage(type_w_signed_unsigned_always_true)
  844. else
  845. if (is_constintnode(left) and (nodetype in [ltn,lten])) or
  846. (is_constintnode(right) and (nodetype in [gtn,gten])) then
  847. CGMessage(type_w_signed_unsigned_always_true)
  848. else
  849. if (is_constintnode(right) and (nodetype in [ltn,lten])) or
  850. (is_constintnode(left) and (nodetype in [gtn,gten])) then
  851. CGMessage(type_w_signed_unsigned_always_false);
  852. end;
  853. inserttypeconv(right,sinttype);
  854. inserttypeconv(left,sinttype);
  855. end;
  856. end
  857. { if both are floatdefs, conversion is already done before constant folding }
  858. else if (ld.deftype=floatdef) then
  859. begin
  860. { already converted }
  861. end
  862. { left side a setdef, must be before string processing,
  863. else array constructor can be seen as array of char (PFV) }
  864. else if (ld.deftype=setdef) then
  865. begin
  866. { trying to add a set element? }
  867. if (nodetype=addn) and (rd.deftype<>setdef) then
  868. begin
  869. if (rt=setelementn) then
  870. begin
  871. if not(equal_defs(tsetdef(ld).elementtype.def,rd)) then
  872. CGMessage(type_e_set_element_are_not_comp);
  873. end
  874. else
  875. CGMessage(type_e_mismatch)
  876. end
  877. else
  878. begin
  879. if not(nodetype in [addn,subn,symdifn,muln,equaln,unequaln,lten,gten]) then
  880. CGMessage(type_e_set_operation_unknown);
  881. { right def must be a also be set }
  882. if (rd.deftype<>setdef) or not(equal_defs(rd,ld)) then
  883. CGMessage(type_e_set_element_are_not_comp);
  884. end;
  885. { ranges require normsets }
  886. if (tsetdef(ld).settype=smallset) and
  887. (rt=setelementn) and
  888. assigned(tsetelementnode(right).right) then
  889. begin
  890. { generate a temporary normset def, it'll be destroyed
  891. when the symtable is unloaded }
  892. htype.setdef(tsetdef.create(tsetdef(ld).elementtype,255));
  893. inserttypeconv(left,htype);
  894. end;
  895. { if the right side is also a setdef then the settype must
  896. be the same as the left setdef }
  897. if (rd.deftype=setdef) and
  898. (tsetdef(ld).settype<>tsetdef(rd).settype) then
  899. begin
  900. { when right is a normset we need to typecast both
  901. to normsets }
  902. if (tsetdef(rd).settype=normset) then
  903. inserttypeconv(left,right.resulttype)
  904. else
  905. inserttypeconv(right,left.resulttype);
  906. end;
  907. end
  908. { compare pchar to char arrays by addresses like BP/Delphi }
  909. else if ((is_pchar(ld) or (lt=niln)) and is_chararray(rd)) or
  910. ((is_pchar(rd) or (rt=niln)) and is_chararray(ld)) then
  911. begin
  912. if is_chararray(rd) then
  913. inserttypeconv(right,charpointertype)
  914. else
  915. inserttypeconv(left,charpointertype);
  916. end
  917. { pointer comparision and subtraction }
  918. else if (rd.deftype=pointerdef) and (ld.deftype=pointerdef) then
  919. begin
  920. case nodetype of
  921. equaln,unequaln :
  922. begin
  923. if is_voidpointer(right.resulttype.def) then
  924. inserttypeconv(right,left.resulttype)
  925. else if is_voidpointer(left.resulttype.def) then
  926. inserttypeconv(left,right.resulttype)
  927. else if not(equal_defs(ld,rd)) then
  928. IncompatibleTypes(ld,rd);
  929. { now that the type checking is done, convert both to charpointer, }
  930. { because methodpointers are 8 bytes even though only the first 4 }
  931. { bytes must be compared. This can happen here if we are in }
  932. { TP/Delphi mode, because there @methodpointer = voidpointer (but }
  933. { a voidpointer of 8 bytes). A conversion to voidpointer would be }
  934. { optimized away, since the result already was a voidpointer, so }
  935. { use a charpointer instead (JM) }
  936. inserttypeconv_explicit(left,charpointertype);
  937. inserttypeconv_explicit(right,charpointertype);
  938. end;
  939. ltn,lten,gtn,gten:
  940. begin
  941. if (cs_extsyntax in aktmoduleswitches) then
  942. begin
  943. if is_voidpointer(right.resulttype.def) then
  944. inserttypeconv(right,left.resulttype)
  945. else if is_voidpointer(left.resulttype.def) then
  946. inserttypeconv(left,right.resulttype)
  947. else if not(equal_defs(ld,rd)) then
  948. IncompatibleTypes(ld,rd);
  949. end
  950. else
  951. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  952. end;
  953. subn:
  954. begin
  955. if (cs_extsyntax in aktmoduleswitches) then
  956. begin
  957. if is_voidpointer(right.resulttype.def) then
  958. inserttypeconv(right,left.resulttype)
  959. else if is_voidpointer(left.resulttype.def) then
  960. inserttypeconv(left,right.resulttype)
  961. else if not(equal_defs(ld,rd)) then
  962. IncompatibleTypes(ld,rd);
  963. end
  964. else
  965. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  966. if not(nf_has_pointerdiv in flags) and
  967. (tpointerdef(rd).pointertype.def.size>1) then
  968. begin
  969. hp:=getcopy;
  970. include(hp.flags,nf_has_pointerdiv);
  971. result:=cmoddivnode.create(divn,hp,cordconstnode.create(tpointerdef(rd).pointertype.def.size,sinttype,false));
  972. end;
  973. resulttype:=sinttype;
  974. exit;
  975. end;
  976. addn:
  977. begin
  978. if (cs_extsyntax in aktmoduleswitches) then
  979. begin
  980. if is_voidpointer(right.resulttype.def) then
  981. inserttypeconv(right,left.resulttype)
  982. else if is_voidpointer(left.resulttype.def) then
  983. inserttypeconv(left,right.resulttype)
  984. else if not(equal_defs(ld,rd)) then
  985. IncompatibleTypes(ld,rd);
  986. end
  987. else
  988. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  989. resulttype:=sinttype;
  990. exit;
  991. end;
  992. else
  993. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  994. end;
  995. end
  996. { is one of the operands a string?,
  997. chararrays are also handled as strings (after conversion), also take
  998. care of chararray+chararray and chararray+char.
  999. Note: Must be done after pointerdef+pointerdef has been checked, else
  1000. pchar is converted to string }
  1001. else if (rd.deftype=stringdef) or (ld.deftype=stringdef) or
  1002. ((is_pchar(rd) or is_chararray(rd) or is_char(rd)) and
  1003. (is_pchar(ld) or is_chararray(ld) or is_char(ld))) then
  1004. begin
  1005. if (nodetype in [addn,equaln,unequaln,lten,gten,ltn,gtn]) then
  1006. begin
  1007. if is_widestring(rd) or is_widestring(ld) then
  1008. begin
  1009. if not(is_widestring(rd)) then
  1010. inserttypeconv(right,cwidestringtype);
  1011. if not(is_widestring(ld)) then
  1012. inserttypeconv(left,cwidestringtype);
  1013. end
  1014. else if is_ansistring(rd) or is_ansistring(ld) then
  1015. begin
  1016. if not(is_ansistring(rd)) then
  1017. begin
  1018. {$ifdef ansistring_bits}
  1019. case Tstringdef(ld).string_typ of
  1020. st_ansistring16:
  1021. inserttypeconv(right,cansistringtype16);
  1022. st_ansistring32:
  1023. inserttypeconv(right,cansistringtype32);
  1024. st_ansistring64:
  1025. inserttypeconv(right,cansistringtype64);
  1026. end;
  1027. {$else}
  1028. inserttypeconv(right,cansistringtype);
  1029. {$endif}
  1030. end;
  1031. if not(is_ansistring(ld)) then
  1032. begin
  1033. {$ifdef ansistring_bits}
  1034. case Tstringdef(rd).string_typ of
  1035. st_ansistring16:
  1036. inserttypeconv(left,cansistringtype16);
  1037. st_ansistring32:
  1038. inserttypeconv(left,cansistringtype32);
  1039. st_ansistring64:
  1040. inserttypeconv(left,cansistringtype64);
  1041. end;
  1042. {$else}
  1043. inserttypeconv(left,cansistringtype);
  1044. {$endif}
  1045. end;
  1046. end
  1047. else if is_longstring(rd) or is_longstring(ld) then
  1048. begin
  1049. if not(is_longstring(rd)) then
  1050. inserttypeconv(right,clongstringtype);
  1051. if not(is_longstring(ld)) then
  1052. inserttypeconv(left,clongstringtype);
  1053. end
  1054. else
  1055. begin
  1056. if not(is_shortstring(ld)) then
  1057. inserttypeconv(left,cshortstringtype);
  1058. { don't convert char, that can be handled by the optimized node }
  1059. if not(is_shortstring(rd) or is_char(rd)) then
  1060. inserttypeconv(right,cshortstringtype);
  1061. end;
  1062. end
  1063. else
  1064. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1065. end
  1066. { class or interface equation }
  1067. else if is_class_or_interface(rd) or is_class_or_interface(ld) then
  1068. begin
  1069. if (nodetype in [equaln,unequaln]) then
  1070. begin
  1071. if is_class_or_interface(rd) and is_class_or_interface(ld) then
  1072. begin
  1073. if tobjectdef(rd).is_related(tobjectdef(ld)) then
  1074. inserttypeconv(right,left.resulttype)
  1075. else
  1076. inserttypeconv(left,right.resulttype);
  1077. end
  1078. else if is_class_or_interface(rd) then
  1079. inserttypeconv(left,right.resulttype)
  1080. else
  1081. inserttypeconv(right,left.resulttype);
  1082. end
  1083. else
  1084. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1085. end
  1086. else if (rd.deftype=classrefdef) and (ld.deftype=classrefdef) then
  1087. begin
  1088. if (nodetype in [equaln,unequaln]) then
  1089. begin
  1090. if tobjectdef(tclassrefdef(rd).pointertype.def).is_related(
  1091. tobjectdef(tclassrefdef(ld).pointertype.def)) then
  1092. inserttypeconv(right,left.resulttype)
  1093. else
  1094. inserttypeconv(left,right.resulttype);
  1095. end
  1096. else
  1097. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1098. end
  1099. { allows comperasion with nil pointer }
  1100. else if is_class_or_interface(rd) or (rd.deftype=classrefdef) then
  1101. begin
  1102. if (nodetype in [equaln,unequaln]) then
  1103. inserttypeconv(left,right.resulttype)
  1104. else
  1105. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1106. end
  1107. else if is_class_or_interface(ld) or (ld.deftype=classrefdef) then
  1108. begin
  1109. if (nodetype in [equaln,unequaln]) then
  1110. inserttypeconv(right,left.resulttype)
  1111. else
  1112. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1113. end
  1114. { support procvar=nil,procvar<>nil }
  1115. else if ((ld.deftype=procvardef) and (rt=niln)) or
  1116. ((rd.deftype=procvardef) and (lt=niln)) then
  1117. begin
  1118. if not(nodetype in [equaln,unequaln]) then
  1119. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1120. end
  1121. { support dynamicarray=nil,dynamicarray<>nil }
  1122. else if (is_dynamic_array(ld) and (rt=niln)) or
  1123. (is_dynamic_array(rd) and (lt=niln)) or
  1124. (is_dynamic_array(ld) and is_dynamic_array(rd)) then
  1125. begin
  1126. if not(nodetype in [equaln,unequaln]) then
  1127. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1128. end
  1129. {$ifdef SUPPORT_MMX}
  1130. { mmx support, this must be before the zero based array
  1131. check }
  1132. else if (cs_mmx in aktlocalswitches) and
  1133. is_mmx_able_array(ld) and
  1134. is_mmx_able_array(rd) and
  1135. equal_defs(ld,rd) then
  1136. begin
  1137. case nodetype of
  1138. addn,subn,xorn,orn,andn:
  1139. ;
  1140. { mul is a little bit restricted }
  1141. muln:
  1142. if not(mmx_type(ld) in [mmxu16bit,mmxs16bit,mmxfixed16]) then
  1143. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1144. else
  1145. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1146. end;
  1147. end
  1148. {$endif SUPPORT_MMX}
  1149. { this is a little bit dangerous, also the left type }
  1150. { pointer to should be checked! This broke the mmx support }
  1151. else if (rd.deftype=pointerdef) or is_zero_based_array(rd) then
  1152. begin
  1153. if is_zero_based_array(rd) then
  1154. begin
  1155. resulttype.setdef(tpointerdef.create(tarraydef(rd).elementtype));
  1156. inserttypeconv(right,resulttype);
  1157. end
  1158. else
  1159. resulttype:=right.resulttype;
  1160. inserttypeconv(left,sinttype);
  1161. if nodetype=addn then
  1162. begin
  1163. if not(cs_extsyntax in aktmoduleswitches) or
  1164. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  1165. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1166. if (rd.deftype=pointerdef) and
  1167. (tpointerdef(rd).pointertype.def.size>1) then
  1168. begin
  1169. left:=caddnode.create(muln,left,
  1170. cordconstnode.create(tpointerdef(rd).pointertype.def.size,sinttype,true));
  1171. end;
  1172. end
  1173. else
  1174. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1175. end
  1176. else if (ld.deftype=pointerdef) or is_zero_based_array(ld) then
  1177. begin
  1178. if is_zero_based_array(ld) then
  1179. begin
  1180. resulttype.setdef(tpointerdef.create(tarraydef(ld).elementtype));
  1181. inserttypeconv(left,resulttype);
  1182. end
  1183. else
  1184. resulttype:=left.resulttype;
  1185. inserttypeconv(right,sinttype);
  1186. if nodetype in [addn,subn] then
  1187. begin
  1188. if not(cs_extsyntax in aktmoduleswitches) or
  1189. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  1190. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1191. if (ld.deftype=pointerdef) and
  1192. (tpointerdef(ld).pointertype.def.size>1) then
  1193. begin
  1194. right:=caddnode.create(muln,right,
  1195. cordconstnode.create(tpointerdef(ld).pointertype.def.size,sinttype,true));
  1196. end;
  1197. end
  1198. else
  1199. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1200. end
  1201. else if (rd.deftype=procvardef) and
  1202. (ld.deftype=procvardef) and
  1203. equal_defs(rd,ld) then
  1204. begin
  1205. if (nodetype in [equaln,unequaln]) then
  1206. begin
  1207. { convert both to voidpointer, because methodpointers are 8 bytes }
  1208. { even though only the first 4 bytes must be compared (JM) }
  1209. inserttypeconv_explicit(left,voidpointertype);
  1210. inserttypeconv_explicit(right,voidpointertype);
  1211. end
  1212. else
  1213. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1214. end
  1215. { enums }
  1216. else if (ld.deftype=enumdef) and (rd.deftype=enumdef) then
  1217. begin
  1218. if (nodetype in [equaln,unequaln,ltn,lten,gtn,gten]) then
  1219. inserttypeconv(right,left.resulttype)
  1220. else
  1221. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1222. end
  1223. { generic conversion, this is for error recovery }
  1224. else
  1225. begin
  1226. inserttypeconv(left,sinttype);
  1227. inserttypeconv(right,sinttype);
  1228. end;
  1229. { set resulttype if not already done }
  1230. if not assigned(resulttype.def) then
  1231. begin
  1232. case nodetype of
  1233. ltn,lten,gtn,gten,equaln,unequaln :
  1234. resulttype:=booltype;
  1235. slashn :
  1236. resulttype:=resultrealtype;
  1237. addn:
  1238. begin
  1239. { for strings, return is always a 255 char string }
  1240. if is_shortstring(left.resulttype.def) then
  1241. resulttype:=cshortstringtype
  1242. else
  1243. resulttype:=left.resulttype;
  1244. end;
  1245. else
  1246. resulttype:=left.resulttype;
  1247. end;
  1248. end;
  1249. { when the result is currency we need some extra code for
  1250. multiplication and division. this should not be done when
  1251. the muln or slashn node is created internally }
  1252. if not(nf_is_currency in flags) and
  1253. is_currency(resulttype.def) then
  1254. begin
  1255. case nodetype of
  1256. slashn :
  1257. begin
  1258. { slashn will only work with floats }
  1259. hp:=caddnode.create(muln,getcopy,crealconstnode.create(10000.0,s64currencytype));
  1260. include(hp.flags,nf_is_currency);
  1261. result:=hp;
  1262. end;
  1263. muln :
  1264. begin
  1265. if s64currencytype.def.deftype=floatdef then
  1266. hp:=caddnode.create(slashn,getcopy,crealconstnode.create(10000.0,s64currencytype))
  1267. else
  1268. hp:=cmoddivnode.create(divn,getcopy,cordconstnode.create(10000,s64currencytype,false));
  1269. include(hp.flags,nf_is_currency);
  1270. result:=hp
  1271. end;
  1272. end;
  1273. end;
  1274. end;
  1275. function taddnode.first_addstring: tnode;
  1276. var
  1277. p: tnode;
  1278. begin
  1279. { when we get here, we are sure that both the left and the right }
  1280. { node are both strings of the same stringtype (JM) }
  1281. case nodetype of
  1282. addn:
  1283. begin
  1284. { create the call to the concat routine both strings as arguments }
  1285. result := ccallnode.createintern('fpc_'+
  1286. tstringdef(resulttype.def).stringtypname+'_concat',
  1287. ccallparanode.create(right,ccallparanode.create(left,nil)));
  1288. { we reused the arguments }
  1289. left := nil;
  1290. right := nil;
  1291. end;
  1292. ltn,lten,gtn,gten,equaln,unequaln :
  1293. begin
  1294. { generate better code for s='' and s<>'' }
  1295. if (nodetype in [equaln,unequaln]) and
  1296. (((left.nodetype=stringconstn) and (str_length(left)=0)) or
  1297. ((right.nodetype=stringconstn) and (str_length(right)=0))) then
  1298. begin
  1299. { switch so that the constant is always on the right }
  1300. if left.nodetype = stringconstn then
  1301. begin
  1302. p := left;
  1303. left := right;
  1304. right := p;
  1305. end;
  1306. if is_shortstring(left.resulttype.def) then
  1307. { compare the length with 0 }
  1308. result := caddnode.create(nodetype,
  1309. cinlinenode.create(in_length_x,false,left),
  1310. cordconstnode.create(0,s32inttype,false))
  1311. else
  1312. begin
  1313. { compare the pointer with nil (for ansistrings etc), }
  1314. { faster than getting the length (JM) }
  1315. result:= caddnode.create(nodetype,
  1316. ctypeconvnode.create_explicit(left,voidpointertype),
  1317. cpointerconstnode.create(0,voidpointertype));
  1318. end;
  1319. { left is reused }
  1320. left := nil;
  1321. { right isn't }
  1322. right.free;
  1323. right := nil;
  1324. exit;
  1325. end;
  1326. { no string constant -> call compare routine }
  1327. result := ccallnode.createintern('fpc_'+
  1328. tstringdef(left.resulttype.def).stringtypname+'_compare',
  1329. ccallparanode.create(right,ccallparanode.create(left,nil)));
  1330. { and compare its result with 0 according to the original operator }
  1331. result := caddnode.create(nodetype,result,
  1332. cordconstnode.create(0,s32inttype,false));
  1333. left := nil;
  1334. right := nil;
  1335. end;
  1336. end;
  1337. end;
  1338. function taddnode.first_addset: tnode;
  1339. var
  1340. procname: string[31];
  1341. tempn: tnode;
  1342. paras: tcallparanode;
  1343. srsym: ttypesym;
  1344. begin
  1345. { get the sym that represents the fpc_normal_set type }
  1346. if not searchsystype('FPC_NORMAL_SET',srsym) then
  1347. internalerror(200108313);
  1348. case nodetype of
  1349. equaln,unequaln,lten,gten:
  1350. begin
  1351. case nodetype of
  1352. equaln,unequaln:
  1353. procname := 'fpc_set_comp_sets';
  1354. lten,gten:
  1355. begin
  1356. procname := 'fpc_set_contains_sets';
  1357. { (left >= right) = (right <= left) }
  1358. if nodetype = gten then
  1359. begin
  1360. tempn := left;
  1361. left := right;
  1362. right := tempn;
  1363. end;
  1364. end;
  1365. end;
  1366. { convert the arguments (explicitely) to fpc_normal_set's }
  1367. left := ctypeconvnode.create_explicit(left,srsym.restype);
  1368. right := ctypeconvnode.create_explicit(right,srsym.restype);
  1369. result := ccallnode.createintern(procname,ccallparanode.create(right,
  1370. ccallparanode.create(left,nil)));
  1371. { left and right are reused as parameters }
  1372. left := nil;
  1373. right := nil;
  1374. { for an unequaln, we have to negate the result of comp_sets }
  1375. if nodetype = unequaln then
  1376. result := cnotnode.create(result);
  1377. end;
  1378. addn:
  1379. begin
  1380. { optimize first loading of a set }
  1381. if (right.nodetype=setelementn) and
  1382. not(assigned(tsetelementnode(right).right)) and
  1383. is_emptyset(left) then
  1384. begin
  1385. { type cast the value to pass as argument to a byte, }
  1386. { since that's what the helper expects }
  1387. tsetelementnode(right).left :=
  1388. ctypeconvnode.create_explicit(tsetelementnode(right).left,u8inttype);
  1389. { set the resulttype to the actual one (otherwise it's }
  1390. { "fpc_normal_set") }
  1391. result := ccallnode.createinternres('fpc_set_create_element',
  1392. ccallparanode.create(tsetelementnode(right).left,nil),
  1393. resulttype);
  1394. { reused }
  1395. tsetelementnode(right).left := nil;
  1396. end
  1397. else
  1398. begin
  1399. if right.nodetype=setelementn then
  1400. begin
  1401. { convert the arguments to bytes, since that's what }
  1402. { the helper expects }
  1403. tsetelementnode(right).left :=
  1404. ctypeconvnode.create_explicit(tsetelementnode(right).left,
  1405. u8inttype);
  1406. { convert the original set (explicitely) to an }
  1407. { fpc_normal_set so we can pass it to the helper }
  1408. left := ctypeconvnode.create_explicit(left,srsym.restype);
  1409. { add a range or a single element? }
  1410. if assigned(tsetelementnode(right).right) then
  1411. begin
  1412. tsetelementnode(right).right :=
  1413. ctypeconvnode.create_explicit(tsetelementnode(right).right,
  1414. u8inttype);
  1415. { create the call }
  1416. result := ccallnode.createinternres('fpc_set_set_range',
  1417. ccallparanode.create(tsetelementnode(right).right,
  1418. ccallparanode.create(tsetelementnode(right).left,
  1419. ccallparanode.create(left,nil))),resulttype);
  1420. end
  1421. else
  1422. begin
  1423. result := ccallnode.createinternres('fpc_set_set_byte',
  1424. ccallparanode.create(tsetelementnode(right).left,
  1425. ccallparanode.create(left,nil)),resulttype);
  1426. end;
  1427. { remove reused parts from original node }
  1428. tsetelementnode(right).right := nil;
  1429. tsetelementnode(right).left := nil;
  1430. left := nil;
  1431. end
  1432. else
  1433. begin
  1434. { add two sets }
  1435. { convert the sets to fpc_normal_set's }
  1436. result := ccallnode.createinternres('fpc_set_add_sets',
  1437. ccallparanode.create(
  1438. ctypeconvnode.create_explicit(right,srsym.restype),
  1439. ccallparanode.create(
  1440. ctypeconvnode.create_explicit(left,srsym.restype),nil)),resulttype);
  1441. { remove reused parts from original node }
  1442. left := nil;
  1443. right := nil;
  1444. end;
  1445. end
  1446. end;
  1447. subn,symdifn,muln:
  1448. begin
  1449. { convert the sets to fpc_normal_set's }
  1450. paras := ccallparanode.create(ctypeconvnode.create_explicit(right,srsym.restype),
  1451. ccallparanode.create(ctypeconvnode.create_explicit(left,srsym.restype),nil));
  1452. case nodetype of
  1453. subn:
  1454. result := ccallnode.createinternres('fpc_set_sub_sets',
  1455. paras,resulttype);
  1456. symdifn:
  1457. result := ccallnode.createinternres('fpc_set_symdif_sets',
  1458. paras,resulttype);
  1459. muln:
  1460. result := ccallnode.createinternres('fpc_set_mul_sets',
  1461. paras,resulttype);
  1462. end;
  1463. { remove reused parts from original node }
  1464. left := nil;
  1465. right := nil;
  1466. end;
  1467. else
  1468. internalerror(200108311);
  1469. end;
  1470. end;
  1471. function taddnode.first_add64bitint: tnode;
  1472. var
  1473. procname: string[31];
  1474. temp: tnode;
  1475. power: longint;
  1476. begin
  1477. result := nil;
  1478. { create helper calls mul }
  1479. if nodetype <> muln then
  1480. exit;
  1481. { make sure that if there is a constant, that it's on the right }
  1482. if left.nodetype = ordconstn then
  1483. begin
  1484. temp := right;
  1485. right := left;
  1486. left := temp;
  1487. end;
  1488. { can we use a shift instead of a mul? }
  1489. if not (cs_check_overflow in aktlocalswitches) and
  1490. (right.nodetype = ordconstn) and
  1491. ispowerof2(tordconstnode(right).value,power) then
  1492. begin
  1493. tordconstnode(right).value := power;
  1494. result := cshlshrnode.create(shln,left,right);
  1495. { left and right are reused }
  1496. left := nil;
  1497. right := nil;
  1498. { return firstpassed new node }
  1499. exit;
  1500. end;
  1501. { when currency is used set the result of the
  1502. parameters to s64bit, so they are not converted }
  1503. if is_currency(resulttype.def) then
  1504. begin
  1505. left.resulttype:=s64inttype;
  1506. right.resulttype:=s64inttype;
  1507. end;
  1508. { otherwise, create the parameters for the helper }
  1509. right := ccallparanode.create(
  1510. cordconstnode.create(ord(cs_check_overflow in aktlocalswitches),booltype,true),
  1511. ccallparanode.create(right,ccallparanode.create(left,nil)));
  1512. left := nil;
  1513. { only qword needs the unsigned code, the
  1514. signed code is also used for currency }
  1515. if is_signed(resulttype.def) then
  1516. procname := 'fpc_mul_int64'
  1517. else
  1518. procname := 'fpc_mul_qword';
  1519. result := ccallnode.createintern(procname,right);
  1520. right := nil;
  1521. end;
  1522. {$ifdef cpufpemu}
  1523. function taddnode.first_addfloat: tnode;
  1524. var
  1525. procname: string[31];
  1526. temp: tnode;
  1527. power: longint;
  1528. { do we need to reverse the result ? }
  1529. notnode : boolean;
  1530. begin
  1531. result := nil;
  1532. notnode := false;
  1533. { In non-emulation mode, real opcodes are
  1534. emitted for floating point values.
  1535. }
  1536. if not (cs_fp_emulation in aktmoduleswitches) then
  1537. exit;
  1538. case nodetype of
  1539. addn : procname := 'fpc_single_add';
  1540. muln : procname := 'fpc_single_mul';
  1541. subn : procname := 'fpc_single_sub';
  1542. slashn : procname := 'fpc_single_div';
  1543. ltn : procname := 'fpc_single_lt';
  1544. lten: procname := 'fpc_single_le';
  1545. gtn:
  1546. begin
  1547. procname := 'fpc_single_le';
  1548. notnode := true;
  1549. end;
  1550. gten:
  1551. begin
  1552. procname := 'fpc_single_lt';
  1553. notnode := true;
  1554. end;
  1555. equaln: procname := 'fpc_single_eq';
  1556. unequaln :
  1557. begin
  1558. procname := 'fpc_single_eq';
  1559. notnode := true;
  1560. end;
  1561. else
  1562. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),left.resulttype.def.typename,right.resulttype.def.typename);
  1563. end;
  1564. { convert the arguments (explicitely) to fpc_normal_set's }
  1565. result := ccallnode.createintern(procname,ccallparanode.create(right,
  1566. ccallparanode.create(left,nil)));
  1567. left:=nil;
  1568. right:=nil;
  1569. { do we need to reverse the result }
  1570. if notnode then
  1571. result := cnotnode.create(result);
  1572. end;
  1573. {$endif cpufpemu}
  1574. function taddnode.pass_1 : tnode;
  1575. var
  1576. {$ifdef addstringopt}
  1577. hp : tnode;
  1578. {$endif addstringopt}
  1579. lt,rt : tnodetype;
  1580. rd,ld : tdef;
  1581. begin
  1582. result:=nil;
  1583. { first do the two subtrees }
  1584. firstpass(left);
  1585. firstpass(right);
  1586. if codegenerror then
  1587. exit;
  1588. { load easier access variables }
  1589. rd:=right.resulttype.def;
  1590. ld:=left.resulttype.def;
  1591. rt:=right.nodetype;
  1592. lt:=left.nodetype;
  1593. { int/int gives real/real! }
  1594. if nodetype=slashn then
  1595. begin
  1596. {$ifdef cpufpemu}
  1597. result := first_addfloat;
  1598. if assigned(result) then
  1599. exit;
  1600. {$endif cpufpemu}
  1601. expectloc:=LOC_FPUREGISTER;
  1602. { maybe we need an integer register to save }
  1603. { a reference }
  1604. if ((left.expectloc<>LOC_FPUREGISTER) or
  1605. (right.expectloc<>LOC_FPUREGISTER)) and
  1606. (left.registersint=right.registersint) then
  1607. calcregisters(self,1,1,0)
  1608. else
  1609. calcregisters(self,0,1,0);
  1610. { an add node always first loads both the left and the }
  1611. { right in the fpu before doing the calculation. However, }
  1612. { calcregisters(0,2,0) will overestimate the number of }
  1613. { necessary registers (it will make it 3 in case one of }
  1614. { the operands is already in the fpu) (JM) }
  1615. if ((left.expectloc<>LOC_FPUREGISTER) or
  1616. (right.expectloc<>LOC_FPUREGISTER)) and
  1617. (registersfpu < 2) then
  1618. inc(registersfpu);
  1619. end
  1620. { if both are orddefs then check sub types }
  1621. else if (ld.deftype=orddef) and (rd.deftype=orddef) then
  1622. begin
  1623. { 2 booleans ? }
  1624. if is_boolean(ld) and is_boolean(rd) then
  1625. begin
  1626. if not(cs_full_boolean_eval in aktlocalswitches) and
  1627. (nodetype in [andn,orn]) then
  1628. begin
  1629. expectloc:=LOC_JUMP;
  1630. calcregisters(self,0,0,0);
  1631. end
  1632. else
  1633. begin
  1634. if nodetype in [ltn,lten,gtn,gten,equaln,unequaln] then
  1635. begin
  1636. expectloc:=LOC_FLAGS;
  1637. if (left.expectloc in [LOC_JUMP,LOC_FLAGS]) and
  1638. (left.expectloc in [LOC_JUMP,LOC_FLAGS]) then
  1639. calcregisters(self,2,0,0)
  1640. else
  1641. calcregisters(self,1,0,0);
  1642. end
  1643. else
  1644. begin
  1645. expectloc:=LOC_REGISTER;
  1646. calcregisters(self,0,0,0);
  1647. end;
  1648. end;
  1649. end
  1650. else
  1651. { Both are chars? only convert to shortstrings for addn }
  1652. if is_char(ld) then
  1653. begin
  1654. if nodetype=addn then
  1655. internalerror(200103291);
  1656. expectloc:=LOC_FLAGS;
  1657. calcregisters(self,1,0,0);
  1658. end
  1659. {$ifndef cpu64bit}
  1660. { is there a 64 bit type ? }
  1661. else if (torddef(ld).typ in [s64bit,u64bit,scurrency]) then
  1662. begin
  1663. result := first_add64bitint;
  1664. if assigned(result) then
  1665. exit;
  1666. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1667. expectloc:=LOC_REGISTER
  1668. else
  1669. {$ifdef sparc}
  1670. expectloc:=LOC_FLAGS;
  1671. {$else sparc}
  1672. expectloc:=LOC_JUMP;
  1673. {$endif sparc}
  1674. calcregisters(self,2,0,0)
  1675. end
  1676. {$endif cpu64bit}
  1677. { is there a cardinal? }
  1678. else if (torddef(ld).typ=u32bit) then
  1679. begin
  1680. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1681. expectloc:=LOC_REGISTER
  1682. else
  1683. expectloc:=LOC_FLAGS;
  1684. calcregisters(self,1,0,0);
  1685. { for unsigned mul we need an extra register }
  1686. if nodetype=muln then
  1687. inc(registersint);
  1688. end
  1689. { generic s32bit conversion }
  1690. else
  1691. begin
  1692. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1693. expectloc:=LOC_REGISTER
  1694. else
  1695. expectloc:=LOC_FLAGS;
  1696. calcregisters(self,1,0,0);
  1697. end;
  1698. end
  1699. { left side a setdef, must be before string processing,
  1700. else array constructor can be seen as array of char (PFV) }
  1701. else if (ld.deftype=setdef) then
  1702. begin
  1703. if tsetdef(ld).settype=smallset then
  1704. begin
  1705. if nodetype in [ltn,lten,gtn,gten,equaln,unequaln] then
  1706. expectloc:=LOC_FLAGS
  1707. else
  1708. expectloc:=LOC_REGISTER;
  1709. { are we adding set elements ? }
  1710. if right.nodetype=setelementn then
  1711. calcregisters(self,2,0,0)
  1712. else
  1713. calcregisters(self,1,0,0);
  1714. end
  1715. else
  1716. {$ifdef MMXSET}
  1717. {$ifdef i386}
  1718. if cs_mmx in aktlocalswitches then
  1719. begin
  1720. expectloc:=LOC_MMXREGISTER;
  1721. calcregisters(self,0,0,4);
  1722. end
  1723. else
  1724. {$endif}
  1725. {$endif MMXSET}
  1726. begin
  1727. result := first_addset;
  1728. if assigned(result) then
  1729. exit;
  1730. expectloc:=LOC_CREFERENCE;
  1731. calcregisters(self,0,0,0);
  1732. { here we call SET... }
  1733. include(current_procinfo.flags,pi_do_call);
  1734. end;
  1735. end
  1736. { compare pchar by addresses like BP/Delphi }
  1737. else if is_pchar(ld) then
  1738. begin
  1739. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1740. expectloc:=LOC_REGISTER
  1741. else
  1742. expectloc:=LOC_FLAGS;
  1743. calcregisters(self,1,0,0);
  1744. end
  1745. { is one of the operands a string }
  1746. else if (ld.deftype=stringdef) then
  1747. begin
  1748. if is_widestring(ld) then
  1749. begin
  1750. { this is only for add, the comparisaion is handled later }
  1751. expectloc:=LOC_REGISTER;
  1752. end
  1753. else if is_ansistring(ld) then
  1754. begin
  1755. { this is only for add, the comparisaion is handled later }
  1756. expectloc:=LOC_REGISTER;
  1757. end
  1758. else if is_longstring(ld) then
  1759. begin
  1760. { this is only for add, the comparisaion is handled later }
  1761. expectloc:=LOC_REFERENCE;
  1762. end
  1763. else
  1764. begin
  1765. {$ifdef addstringopt}
  1766. { can create a call which isn't handled by callparatemp }
  1767. if canbeaddsstringcharoptnode(self) then
  1768. begin
  1769. hp := genaddsstringcharoptnode(self);
  1770. pass_1 := hp;
  1771. exit;
  1772. end
  1773. else
  1774. {$endif addstringopt}
  1775. begin
  1776. { Fix right to be shortstring }
  1777. if is_char(right.resulttype.def) then
  1778. begin
  1779. inserttypeconv(right,cshortstringtype);
  1780. firstpass(right);
  1781. end;
  1782. end;
  1783. {$ifdef addstringopt}
  1784. { can create a call which isn't handled by callparatemp }
  1785. if canbeaddsstringcsstringoptnode(self) then
  1786. begin
  1787. hp := genaddsstringcsstringoptnode(self);
  1788. pass_1 := hp;
  1789. exit;
  1790. end;
  1791. {$endif addstringopt}
  1792. end;
  1793. { otherwise, let addstring convert everything }
  1794. result := first_addstring;
  1795. exit;
  1796. end
  1797. { is one a real float ? }
  1798. else if (rd.deftype=floatdef) or (ld.deftype=floatdef) then
  1799. begin
  1800. {$ifdef cpufpemu}
  1801. result := first_addfloat;
  1802. if assigned(result) then
  1803. exit;
  1804. {$endif cpufpemu}
  1805. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1806. expectloc:=LOC_FPUREGISTER
  1807. else
  1808. expectloc:=LOC_FLAGS;
  1809. calcregisters(self,0,1,0);
  1810. { an add node always first loads both the left and the }
  1811. { right in the fpu before doing the calculation. However, }
  1812. { calcregisters(0,2,0) will overestimate the number of }
  1813. { necessary registers (it will make it 3 in case one of }
  1814. { the operands is already in the fpu) (JM) }
  1815. if ((left.expectloc<>LOC_FPUREGISTER) or
  1816. (right.expectloc<>LOC_FPUREGISTER)) and
  1817. (registersfpu < 2) then
  1818. inc(registersfpu);
  1819. end
  1820. { pointer comperation and subtraction }
  1821. else if (ld.deftype=pointerdef) then
  1822. begin
  1823. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1824. expectloc:=LOC_REGISTER
  1825. else
  1826. expectloc:=LOC_FLAGS;
  1827. calcregisters(self,1,0,0);
  1828. end
  1829. else if is_class_or_interface(ld) then
  1830. begin
  1831. expectloc:=LOC_FLAGS;
  1832. calcregisters(self,1,0,0);
  1833. end
  1834. else if (ld.deftype=classrefdef) then
  1835. begin
  1836. expectloc:=LOC_FLAGS;
  1837. calcregisters(self,1,0,0);
  1838. end
  1839. { support procvar=nil,procvar<>nil }
  1840. else if ((ld.deftype=procvardef) and (rt=niln)) or
  1841. ((rd.deftype=procvardef) and (lt=niln)) then
  1842. begin
  1843. expectloc:=LOC_FLAGS;
  1844. calcregisters(self,1,0,0);
  1845. end
  1846. {$ifdef SUPPORT_MMX}
  1847. { mmx support, this must be before the zero based array
  1848. check }
  1849. else if (cs_mmx in aktlocalswitches) and is_mmx_able_array(ld) and
  1850. is_mmx_able_array(rd) then
  1851. begin
  1852. expectloc:=LOC_MMXREGISTER;
  1853. calcregisters(self,0,0,1);
  1854. end
  1855. {$endif SUPPORT_MMX}
  1856. else if (rd.deftype=pointerdef) or (ld.deftype=pointerdef) then
  1857. begin
  1858. expectloc:=LOC_REGISTER;
  1859. calcregisters(self,1,0,0);
  1860. end
  1861. else if (rd.deftype=procvardef) and
  1862. (ld.deftype=procvardef) and
  1863. equal_defs(rd,ld) then
  1864. begin
  1865. expectloc:=LOC_FLAGS;
  1866. calcregisters(self,1,0,0);
  1867. end
  1868. else if (ld.deftype=enumdef) then
  1869. begin
  1870. expectloc:=LOC_FLAGS;
  1871. calcregisters(self,1,0,0);
  1872. end
  1873. {$ifdef SUPPORT_MMX}
  1874. else if (cs_mmx in aktlocalswitches) and
  1875. is_mmx_able_array(ld) and
  1876. is_mmx_able_array(rd) then
  1877. begin
  1878. expectloc:=LOC_MMXREGISTER;
  1879. calcregisters(self,0,0,1);
  1880. end
  1881. {$endif SUPPORT_MMX}
  1882. { the general solution is to convert to 32 bit int }
  1883. else
  1884. begin
  1885. expectloc:=LOC_REGISTER;
  1886. calcregisters(self,1,0,0);
  1887. end;
  1888. end;
  1889. {$ifdef state_tracking}
  1890. function Taddnode.track_state_pass(exec_known:boolean):boolean;
  1891. var factval:Tnode;
  1892. begin
  1893. track_state_pass:=false;
  1894. if left.track_state_pass(exec_known) then
  1895. begin
  1896. track_state_pass:=true;
  1897. left.resulttype.def:=nil;
  1898. do_resulttypepass(left);
  1899. end;
  1900. factval:=aktstate.find_fact(left);
  1901. if factval<>nil then
  1902. begin
  1903. track_state_pass:=true;
  1904. left.destroy;
  1905. left:=factval.getcopy;
  1906. end;
  1907. if right.track_state_pass(exec_known) then
  1908. begin
  1909. track_state_pass:=true;
  1910. right.resulttype.def:=nil;
  1911. do_resulttypepass(right);
  1912. end;
  1913. factval:=aktstate.find_fact(right);
  1914. if factval<>nil then
  1915. begin
  1916. track_state_pass:=true;
  1917. right.destroy;
  1918. right:=factval.getcopy;
  1919. end;
  1920. end;
  1921. {$endif}
  1922. begin
  1923. caddnode:=taddnode;
  1924. end.
  1925. {
  1926. $Log$
  1927. Revision 1.127 2004-08-17 19:04:36 jonas
  1928. * fixed "if @procvar_of_object <> nil" in Delphi/TP mode for for non-x86
  1929. Revision 1.126 2004/08/08 15:22:29 florian
  1930. * fixed several ie9999s when illegal operators were used
  1931. Revision 1.125 2004/06/20 08:55:29 florian
  1932. * logs truncated
  1933. Revision 1.124 2004/06/16 20:07:07 florian
  1934. * dwarf branch merged
  1935. Revision 1.123 2004/05/28 21:13:44 peter
  1936. * fix cardinal+constint
  1937. Revision 1.122 2004/05/23 14:14:18 florian
  1938. + added set of widechar support (limited to 256 chars, is delphi compatible)
  1939. Revision 1.121 2004/05/23 14:08:39 peter
  1940. * only convert widechar to widestring when both operands are
  1941. constant
  1942. * support widechar-widechar operations in orddef part
  1943. Revision 1.120 2004/05/21 13:08:14 florian
  1944. * fixed <ordinal>+<pointer>
  1945. }