nadd.pas 81 KB

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