nadd.pas 83 KB

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