nadd.pas 84 KB

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