nadd.pas 82 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069
  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 of integers }
  742. else if (nodetype in [andn,orn,xorn]) and
  743. is_integer(ld) and is_integer(rd) then
  744. begin
  745. if rd.size>ld.size then
  746. inserttypeconv_explicit(left,right.resulttype)
  747. else
  748. inserttypeconv_explicit(right,left.resulttype);
  749. end
  750. { is there a signed 64 bit type ? }
  751. else if ((torddef(rd).typ=s64bit) or (torddef(ld).typ=s64bit)) then
  752. begin
  753. if (torddef(ld).typ<>s64bit) then
  754. inserttypeconv(left,s64inttype);
  755. if (torddef(rd).typ<>s64bit) then
  756. inserttypeconv(right,s64inttype);
  757. end
  758. { is there a unsigned 64 bit type ? }
  759. else if ((torddef(rd).typ=u64bit) or (torddef(ld).typ=u64bit)) then
  760. begin
  761. if (torddef(ld).typ<>u64bit) then
  762. inserttypeconv(left,u64inttype);
  763. if (torddef(rd).typ<>u64bit) then
  764. inserttypeconv(right,u64inttype);
  765. end
  766. { 64 bit cpus do calculations always in 64 bit }
  767. {$ifndef cpu64bit}
  768. { is there a cardinal? }
  769. else if ((torddef(rd).typ=u32bit) or (torddef(ld).typ=u32bit)) then
  770. begin
  771. { convert positive constants to u32bit }
  772. if (torddef(ld).typ<>u32bit) and
  773. is_constintnode(left) and
  774. (tordconstnode(left).value >= 0) then
  775. inserttypeconv(left,u32inttype);
  776. if (torddef(rd).typ<>u32bit) and
  777. is_constintnode(right) and
  778. (tordconstnode(right).value >= 0) then
  779. inserttypeconv(right,u32inttype);
  780. { when one of the operand is signed perform
  781. the operation in 64bit, can't use rd/ld here because there
  782. could be already typeconvs inserted }
  783. if is_signed(left.resulttype.def) or is_signed(right.resulttype.def) then
  784. begin
  785. CGMessage(type_w_mixed_signed_unsigned);
  786. inserttypeconv(left,s64inttype);
  787. inserttypeconv(right,s64inttype);
  788. end
  789. else
  790. begin
  791. { convert positive constants to u32bit }
  792. if (torddef(ld).typ<>u32bit) and
  793. is_constintnode(left) and
  794. (tordconstnode(left).value >= 0) then
  795. inserttypeconv(left,u32inttype);
  796. if (torddef(rd).typ<>u32bit) and
  797. is_constintnode(right) and
  798. (tordconstnode(right).value >= 0) then
  799. inserttypeconv(right,u32inttype);
  800. { when one of the operand is signed perform
  801. the operation in 64bit, can't use rd/ld here because there
  802. could be already typeconvs inserted }
  803. if is_signed(left.resulttype.def) or is_signed(right.resulttype.def) then
  804. begin
  805. CGMessage(type_w_mixed_signed_unsigned);
  806. inserttypeconv(left,s64inttype);
  807. inserttypeconv(right,s64inttype);
  808. end
  809. else
  810. begin
  811. if (torddef(left.resulttype.def).typ<>u32bit) then
  812. inserttypeconv(left,u32inttype);
  813. if (torddef(right.resulttype.def).typ<>u32bit) then
  814. inserttypeconv(right,u32inttype);
  815. end;
  816. end;
  817. end
  818. {$endif cpu64bit}
  819. { generic ord conversion is sinttype }
  820. else
  821. begin
  822. { if the left or right value is smaller than the normal
  823. type s32inttype and is unsigned, and the other value
  824. is a constant < 0, the result will always be false/true
  825. for equal / unequal nodes.
  826. }
  827. if (
  828. { left : unsigned ordinal var, right : < 0 constant }
  829. (
  830. ((is_signed(ld)=false) and (is_constintnode(left) =false)) and
  831. ((is_constintnode(right)) and (tordconstnode(right).value < 0))
  832. ) or
  833. { right : unsigned ordinal var, left : < 0 constant }
  834. (
  835. ((is_signed(rd)=false) and (is_constintnode(right) =false)) and
  836. ((is_constintnode(left)) and (tordconstnode(left).value < 0))
  837. )
  838. ) then
  839. begin
  840. if nodetype = equaln then
  841. CGMessage(type_w_signed_unsigned_always_false)
  842. else
  843. if nodetype = unequaln then
  844. CGMessage(type_w_signed_unsigned_always_true)
  845. else
  846. if (is_constintnode(left) and (nodetype in [ltn,lten])) or
  847. (is_constintnode(right) and (nodetype in [gtn,gten])) then
  848. CGMessage(type_w_signed_unsigned_always_true)
  849. else
  850. if (is_constintnode(right) and (nodetype in [ltn,lten])) or
  851. (is_constintnode(left) and (nodetype in [gtn,gten])) then
  852. CGMessage(type_w_signed_unsigned_always_false);
  853. end;
  854. inserttypeconv(right,sinttype);
  855. inserttypeconv(left,sinttype);
  856. end;
  857. end
  858. { if both are floatdefs, conversion is already done before constant folding }
  859. else if (ld.deftype=floatdef) then
  860. begin
  861. { already converted }
  862. end
  863. { left side a setdef, must be before string processing,
  864. else array constructor can be seen as array of char (PFV) }
  865. else if (ld.deftype=setdef) then
  866. begin
  867. { trying to add a set element? }
  868. if (nodetype=addn) and (rd.deftype<>setdef) then
  869. begin
  870. if (rt=setelementn) then
  871. begin
  872. if not(equal_defs(tsetdef(ld).elementtype.def,rd)) then
  873. CGMessage(type_e_set_element_are_not_comp);
  874. end
  875. else
  876. CGMessage(type_e_mismatch)
  877. end
  878. else
  879. begin
  880. if not(nodetype in [addn,subn,symdifn,muln,equaln,unequaln,lten,gten]) then
  881. CGMessage(type_e_set_operation_unknown);
  882. { right def must be a also be set }
  883. if (rd.deftype<>setdef) or not(equal_defs(rd,ld)) then
  884. CGMessage(type_e_set_element_are_not_comp);
  885. end;
  886. { ranges require normsets }
  887. if (tsetdef(ld).settype=smallset) and
  888. (rt=setelementn) and
  889. assigned(tsetelementnode(right).right) then
  890. begin
  891. { generate a temporary normset def, it'll be destroyed
  892. when the symtable is unloaded }
  893. htype.setdef(tsetdef.create(tsetdef(ld).elementtype,255));
  894. inserttypeconv(left,htype);
  895. end;
  896. { if the right side is also a setdef then the settype must
  897. be the same as the left setdef }
  898. if (rd.deftype=setdef) and
  899. (tsetdef(ld).settype<>tsetdef(rd).settype) then
  900. begin
  901. { when right is a normset we need to typecast both
  902. to normsets }
  903. if (tsetdef(rd).settype=normset) then
  904. inserttypeconv(left,right.resulttype)
  905. else
  906. inserttypeconv(right,left.resulttype);
  907. end;
  908. end
  909. { compare pchar to char arrays by addresses like BP/Delphi }
  910. else if ((is_pchar(ld) or (lt=niln)) and is_chararray(rd)) or
  911. ((is_pchar(rd) or (rt=niln)) and is_chararray(ld)) then
  912. begin
  913. if is_chararray(rd) then
  914. inserttypeconv(right,charpointertype)
  915. else
  916. inserttypeconv(left,charpointertype);
  917. end
  918. { pointer comparision and subtraction }
  919. else if (rd.deftype=pointerdef) and (ld.deftype=pointerdef) then
  920. begin
  921. case nodetype of
  922. equaln,unequaln :
  923. begin
  924. if is_voidpointer(right.resulttype.def) then
  925. inserttypeconv(right,left.resulttype)
  926. else if is_voidpointer(left.resulttype.def) then
  927. inserttypeconv(left,right.resulttype)
  928. else if not(equal_defs(ld,rd)) then
  929. IncompatibleTypes(ld,rd);
  930. { now that the type checking is done, convert both to charpointer, }
  931. { because methodpointers are 8 bytes even though only the first 4 }
  932. { bytes must be compared. This can happen here if we are in }
  933. { TP/Delphi mode, because there @methodpointer = voidpointer (but }
  934. { a voidpointer of 8 bytes). A conversion to voidpointer would be }
  935. { optimized away, since the result already was a voidpointer, so }
  936. { use a charpointer instead (JM) }
  937. inserttypeconv_explicit(left,charpointertype);
  938. inserttypeconv_explicit(right,charpointertype);
  939. end;
  940. ltn,lten,gtn,gten:
  941. begin
  942. if (cs_extsyntax in aktmoduleswitches) then
  943. begin
  944. if is_voidpointer(right.resulttype.def) then
  945. inserttypeconv(right,left.resulttype)
  946. else if is_voidpointer(left.resulttype.def) then
  947. inserttypeconv(left,right.resulttype)
  948. else if not(equal_defs(ld,rd)) then
  949. IncompatibleTypes(ld,rd);
  950. end
  951. else
  952. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  953. end;
  954. subn:
  955. begin
  956. if (cs_extsyntax in aktmoduleswitches) then
  957. begin
  958. if is_voidpointer(right.resulttype.def) then
  959. inserttypeconv(right,left.resulttype)
  960. else if is_voidpointer(left.resulttype.def) then
  961. inserttypeconv(left,right.resulttype)
  962. else if not(equal_defs(ld,rd)) then
  963. IncompatibleTypes(ld,rd);
  964. end
  965. else
  966. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  967. if not(nf_has_pointerdiv in flags) and
  968. (tpointerdef(rd).pointertype.def.size>1) then
  969. begin
  970. hp:=getcopy;
  971. include(hp.flags,nf_has_pointerdiv);
  972. result:=cmoddivnode.create(divn,hp,cordconstnode.create(tpointerdef(rd).pointertype.def.size,sinttype,false));
  973. end;
  974. resulttype:=sinttype;
  975. exit;
  976. end;
  977. addn:
  978. begin
  979. if (cs_extsyntax in aktmoduleswitches) then
  980. begin
  981. if is_voidpointer(right.resulttype.def) then
  982. inserttypeconv(right,left.resulttype)
  983. else if is_voidpointer(left.resulttype.def) then
  984. inserttypeconv(left,right.resulttype)
  985. else if not(equal_defs(ld,rd)) then
  986. IncompatibleTypes(ld,rd);
  987. end
  988. else
  989. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  990. resulttype:=sinttype;
  991. exit;
  992. end;
  993. else
  994. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  995. end;
  996. end
  997. { is one of the operands a string?,
  998. chararrays are also handled as strings (after conversion), also take
  999. care of chararray+chararray and chararray+char.
  1000. Note: Must be done after pointerdef+pointerdef has been checked, else
  1001. pchar is converted to string }
  1002. else if (rd.deftype=stringdef) or (ld.deftype=stringdef) or
  1003. ((is_pchar(rd) or is_chararray(rd) or is_char(rd)) and
  1004. (is_pchar(ld) or is_chararray(ld) or is_char(ld))) then
  1005. begin
  1006. if (nodetype in [addn,equaln,unequaln,lten,gten,ltn,gtn]) then
  1007. begin
  1008. if is_widestring(rd) or is_widestring(ld) then
  1009. begin
  1010. if not(is_widestring(rd)) then
  1011. inserttypeconv(right,cwidestringtype);
  1012. if not(is_widestring(ld)) then
  1013. inserttypeconv(left,cwidestringtype);
  1014. end
  1015. else if is_ansistring(rd) or is_ansistring(ld) then
  1016. begin
  1017. if not(is_ansistring(rd)) then
  1018. begin
  1019. {$ifdef ansistring_bits}
  1020. case Tstringdef(ld).string_typ of
  1021. st_ansistring16:
  1022. inserttypeconv(right,cansistringtype16);
  1023. st_ansistring32:
  1024. inserttypeconv(right,cansistringtype32);
  1025. st_ansistring64:
  1026. inserttypeconv(right,cansistringtype64);
  1027. end;
  1028. {$else}
  1029. inserttypeconv(right,cansistringtype);
  1030. {$endif}
  1031. end;
  1032. if not(is_ansistring(ld)) then
  1033. begin
  1034. {$ifdef ansistring_bits}
  1035. case Tstringdef(rd).string_typ of
  1036. st_ansistring16:
  1037. inserttypeconv(left,cansistringtype16);
  1038. st_ansistring32:
  1039. inserttypeconv(left,cansistringtype32);
  1040. st_ansistring64:
  1041. inserttypeconv(left,cansistringtype64);
  1042. end;
  1043. {$else}
  1044. inserttypeconv(left,cansistringtype);
  1045. {$endif}
  1046. end;
  1047. end
  1048. else if is_longstring(rd) or is_longstring(ld) then
  1049. begin
  1050. if not(is_longstring(rd)) then
  1051. inserttypeconv(right,clongstringtype);
  1052. if not(is_longstring(ld)) then
  1053. inserttypeconv(left,clongstringtype);
  1054. end
  1055. else
  1056. begin
  1057. if not(is_shortstring(ld)) then
  1058. inserttypeconv(left,cshortstringtype);
  1059. { don't convert char, that can be handled by the optimized node }
  1060. if not(is_shortstring(rd) or is_char(rd)) then
  1061. inserttypeconv(right,cshortstringtype);
  1062. end;
  1063. end
  1064. else
  1065. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1066. end
  1067. { class or interface equation }
  1068. else if is_class_or_interface(rd) or is_class_or_interface(ld) then
  1069. begin
  1070. if (nodetype in [equaln,unequaln]) then
  1071. begin
  1072. if is_class_or_interface(rd) and is_class_or_interface(ld) then
  1073. begin
  1074. if tobjectdef(rd).is_related(tobjectdef(ld)) then
  1075. inserttypeconv(right,left.resulttype)
  1076. else
  1077. inserttypeconv(left,right.resulttype);
  1078. end
  1079. else if is_class_or_interface(rd) then
  1080. inserttypeconv(left,right.resulttype)
  1081. else
  1082. inserttypeconv(right,left.resulttype);
  1083. end
  1084. else
  1085. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1086. end
  1087. else if (rd.deftype=classrefdef) and (ld.deftype=classrefdef) then
  1088. begin
  1089. if (nodetype in [equaln,unequaln]) then
  1090. begin
  1091. if tobjectdef(tclassrefdef(rd).pointertype.def).is_related(
  1092. tobjectdef(tclassrefdef(ld).pointertype.def)) then
  1093. inserttypeconv(right,left.resulttype)
  1094. else
  1095. inserttypeconv(left,right.resulttype);
  1096. end
  1097. else
  1098. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1099. end
  1100. { allows comperasion with nil pointer }
  1101. else if is_class_or_interface(rd) or (rd.deftype=classrefdef) then
  1102. begin
  1103. if (nodetype in [equaln,unequaln]) then
  1104. inserttypeconv(left,right.resulttype)
  1105. else
  1106. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1107. end
  1108. else if is_class_or_interface(ld) or (ld.deftype=classrefdef) then
  1109. begin
  1110. if (nodetype in [equaln,unequaln]) then
  1111. inserttypeconv(right,left.resulttype)
  1112. else
  1113. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1114. end
  1115. { support procvar=nil,procvar<>nil }
  1116. else if ((ld.deftype=procvardef) and (rt=niln)) or
  1117. ((rd.deftype=procvardef) and (lt=niln)) then
  1118. begin
  1119. if not(nodetype in [equaln,unequaln]) then
  1120. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1121. end
  1122. { support dynamicarray=nil,dynamicarray<>nil }
  1123. else if (is_dynamic_array(ld) and (rt=niln)) or
  1124. (is_dynamic_array(rd) and (lt=niln)) or
  1125. (is_dynamic_array(ld) and is_dynamic_array(rd)) then
  1126. begin
  1127. if not(nodetype in [equaln,unequaln]) then
  1128. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1129. end
  1130. {$ifdef SUPPORT_MMX}
  1131. { mmx support, this must be before the zero based array
  1132. check }
  1133. else if (cs_mmx in aktlocalswitches) and
  1134. is_mmx_able_array(ld) and
  1135. is_mmx_able_array(rd) and
  1136. equal_defs(ld,rd) then
  1137. begin
  1138. case nodetype of
  1139. addn,subn,xorn,orn,andn:
  1140. ;
  1141. { mul is a little bit restricted }
  1142. muln:
  1143. if not(mmx_type(ld) in [mmxu16bit,mmxs16bit,mmxfixed16]) then
  1144. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1145. else
  1146. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1147. end;
  1148. end
  1149. {$endif SUPPORT_MMX}
  1150. { this is a little bit dangerous, also the left type }
  1151. { pointer to should be checked! This broke the mmx support }
  1152. else if (rd.deftype=pointerdef) or is_zero_based_array(rd) then
  1153. begin
  1154. if is_zero_based_array(rd) then
  1155. begin
  1156. resulttype.setdef(tpointerdef.create(tarraydef(rd).elementtype));
  1157. inserttypeconv(right,resulttype);
  1158. end
  1159. else
  1160. resulttype:=right.resulttype;
  1161. inserttypeconv(left,sinttype);
  1162. if nodetype=addn then
  1163. begin
  1164. if not(cs_extsyntax in aktmoduleswitches) or
  1165. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  1166. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1167. if (rd.deftype=pointerdef) and
  1168. (tpointerdef(rd).pointertype.def.size>1) then
  1169. begin
  1170. left:=caddnode.create(muln,left,
  1171. cordconstnode.create(tpointerdef(rd).pointertype.def.size,sinttype,true));
  1172. end;
  1173. end
  1174. else
  1175. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1176. end
  1177. else if (ld.deftype=pointerdef) or is_zero_based_array(ld) then
  1178. begin
  1179. if is_zero_based_array(ld) then
  1180. begin
  1181. resulttype.setdef(tpointerdef.create(tarraydef(ld).elementtype));
  1182. inserttypeconv(left,resulttype);
  1183. end
  1184. else
  1185. resulttype:=left.resulttype;
  1186. inserttypeconv(right,sinttype);
  1187. if nodetype in [addn,subn] then
  1188. begin
  1189. if not(cs_extsyntax in aktmoduleswitches) or
  1190. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  1191. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1192. if (ld.deftype=pointerdef) and
  1193. (tpointerdef(ld).pointertype.def.size>1) then
  1194. begin
  1195. right:=caddnode.create(muln,right,
  1196. cordconstnode.create(tpointerdef(ld).pointertype.def.size,sinttype,true));
  1197. end;
  1198. end
  1199. else
  1200. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1201. end
  1202. else if (rd.deftype=procvardef) and
  1203. (ld.deftype=procvardef) and
  1204. equal_defs(rd,ld) then
  1205. begin
  1206. if (nodetype in [equaln,unequaln]) then
  1207. begin
  1208. { convert both to voidpointer, because methodpointers are 8 bytes }
  1209. { even though only the first 4 bytes must be compared (JM) }
  1210. inserttypeconv_explicit(left,voidpointertype);
  1211. inserttypeconv_explicit(right,voidpointertype);
  1212. end
  1213. else
  1214. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1215. end
  1216. { enums }
  1217. else if (ld.deftype=enumdef) and (rd.deftype=enumdef) then
  1218. begin
  1219. if (nodetype in [equaln,unequaln,ltn,lten,gtn,gten]) then
  1220. inserttypeconv(right,left.resulttype)
  1221. else
  1222. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
  1223. end
  1224. { generic conversion, this is for error recovery }
  1225. else
  1226. begin
  1227. inserttypeconv(left,sinttype);
  1228. inserttypeconv(right,sinttype);
  1229. end;
  1230. { set resulttype if not already done }
  1231. if not assigned(resulttype.def) then
  1232. begin
  1233. case nodetype of
  1234. ltn,lten,gtn,gten,equaln,unequaln :
  1235. resulttype:=booltype;
  1236. slashn :
  1237. resulttype:=resultrealtype;
  1238. addn:
  1239. begin
  1240. { for strings, return is always a 255 char string }
  1241. if is_shortstring(left.resulttype.def) then
  1242. resulttype:=cshortstringtype
  1243. else
  1244. resulttype:=left.resulttype;
  1245. end;
  1246. else
  1247. resulttype:=left.resulttype;
  1248. end;
  1249. end;
  1250. { when the result is currency we need some extra code for
  1251. multiplication and division. this should not be done when
  1252. the muln or slashn node is created internally }
  1253. if not(nf_is_currency in flags) and
  1254. is_currency(resulttype.def) then
  1255. begin
  1256. case nodetype of
  1257. slashn :
  1258. begin
  1259. { slashn will only work with floats }
  1260. hp:=caddnode.create(muln,getcopy,crealconstnode.create(10000.0,s64currencytype));
  1261. include(hp.flags,nf_is_currency);
  1262. result:=hp;
  1263. end;
  1264. muln :
  1265. begin
  1266. if s64currencytype.def.deftype=floatdef then
  1267. hp:=caddnode.create(slashn,getcopy,crealconstnode.create(10000.0,s64currencytype))
  1268. else
  1269. hp:=cmoddivnode.create(divn,getcopy,cordconstnode.create(10000,s64currencytype,false));
  1270. include(hp.flags,nf_is_currency);
  1271. result:=hp
  1272. end;
  1273. end;
  1274. end;
  1275. end;
  1276. function taddnode.first_addstring: tnode;
  1277. var
  1278. p: tnode;
  1279. begin
  1280. { when we get here, we are sure that both the left and the right }
  1281. { node are both strings of the same stringtype (JM) }
  1282. case nodetype of
  1283. addn:
  1284. begin
  1285. { create the call to the concat routine both strings as arguments }
  1286. result := ccallnode.createintern('fpc_'+
  1287. tstringdef(resulttype.def).stringtypname+'_concat',
  1288. ccallparanode.create(right,ccallparanode.create(left,nil)));
  1289. { we reused the arguments }
  1290. left := nil;
  1291. right := nil;
  1292. end;
  1293. ltn,lten,gtn,gten,equaln,unequaln :
  1294. begin
  1295. { generate better code for s='' and s<>'' }
  1296. if (nodetype in [equaln,unequaln]) and
  1297. (((left.nodetype=stringconstn) and (str_length(left)=0)) or
  1298. ((right.nodetype=stringconstn) and (str_length(right)=0))) then
  1299. begin
  1300. { switch so that the constant is always on the right }
  1301. if left.nodetype = stringconstn then
  1302. begin
  1303. p := left;
  1304. left := right;
  1305. right := p;
  1306. end;
  1307. if is_shortstring(left.resulttype.def) then
  1308. { compare the length with 0 }
  1309. result := caddnode.create(nodetype,
  1310. cinlinenode.create(in_length_x,false,left),
  1311. cordconstnode.create(0,s32inttype,false))
  1312. else
  1313. begin
  1314. { compare the pointer with nil (for ansistrings etc), }
  1315. { faster than getting the length (JM) }
  1316. result:= caddnode.create(nodetype,
  1317. ctypeconvnode.create_explicit(left,voidpointertype),
  1318. cpointerconstnode.create(0,voidpointertype));
  1319. end;
  1320. { left is reused }
  1321. left := nil;
  1322. { right isn't }
  1323. right.free;
  1324. right := nil;
  1325. exit;
  1326. end;
  1327. { no string constant -> call compare routine }
  1328. result := ccallnode.createintern('fpc_'+
  1329. tstringdef(left.resulttype.def).stringtypname+'_compare',
  1330. ccallparanode.create(right,ccallparanode.create(left,nil)));
  1331. { and compare its result with 0 according to the original operator }
  1332. result := caddnode.create(nodetype,result,
  1333. cordconstnode.create(0,s32inttype,false));
  1334. left := nil;
  1335. right := nil;
  1336. end;
  1337. end;
  1338. end;
  1339. function taddnode.first_addset: tnode;
  1340. var
  1341. procname: string[31];
  1342. tempn: tnode;
  1343. paras: tcallparanode;
  1344. srsym: ttypesym;
  1345. begin
  1346. { get the sym that represents the fpc_normal_set type }
  1347. if not searchsystype('FPC_NORMAL_SET',srsym) then
  1348. internalerror(200108313);
  1349. case nodetype of
  1350. equaln,unequaln,lten,gten:
  1351. begin
  1352. case nodetype of
  1353. equaln,unequaln:
  1354. procname := 'fpc_set_comp_sets';
  1355. lten,gten:
  1356. begin
  1357. procname := 'fpc_set_contains_sets';
  1358. { (left >= right) = (right <= left) }
  1359. if nodetype = gten then
  1360. begin
  1361. tempn := left;
  1362. left := right;
  1363. right := tempn;
  1364. end;
  1365. end;
  1366. end;
  1367. { convert the arguments (explicitely) to fpc_normal_set's }
  1368. left := ctypeconvnode.create_explicit(left,srsym.restype);
  1369. right := ctypeconvnode.create_explicit(right,srsym.restype);
  1370. result := ccallnode.createintern(procname,ccallparanode.create(right,
  1371. ccallparanode.create(left,nil)));
  1372. { left and right are reused as parameters }
  1373. left := nil;
  1374. right := nil;
  1375. { for an unequaln, we have to negate the result of comp_sets }
  1376. if nodetype = unequaln then
  1377. result := cnotnode.create(result);
  1378. end;
  1379. addn:
  1380. begin
  1381. { optimize first loading of a set }
  1382. if (right.nodetype=setelementn) and
  1383. not(assigned(tsetelementnode(right).right)) and
  1384. is_emptyset(left) then
  1385. begin
  1386. { type cast the value to pass as argument to a byte, }
  1387. { since that's what the helper expects }
  1388. tsetelementnode(right).left :=
  1389. ctypeconvnode.create_explicit(tsetelementnode(right).left,u8inttype);
  1390. { set the resulttype to the actual one (otherwise it's }
  1391. { "fpc_normal_set") }
  1392. result := ccallnode.createinternres('fpc_set_create_element',
  1393. ccallparanode.create(tsetelementnode(right).left,nil),
  1394. resulttype);
  1395. { reused }
  1396. tsetelementnode(right).left := nil;
  1397. end
  1398. else
  1399. begin
  1400. if right.nodetype=setelementn then
  1401. begin
  1402. { convert the arguments to bytes, since that's what }
  1403. { the helper expects }
  1404. tsetelementnode(right).left :=
  1405. ctypeconvnode.create_explicit(tsetelementnode(right).left,
  1406. u8inttype);
  1407. { convert the original set (explicitely) to an }
  1408. { fpc_normal_set so we can pass it to the helper }
  1409. left := ctypeconvnode.create_explicit(left,srsym.restype);
  1410. { add a range or a single element? }
  1411. if assigned(tsetelementnode(right).right) then
  1412. begin
  1413. tsetelementnode(right).right :=
  1414. ctypeconvnode.create_explicit(tsetelementnode(right).right,
  1415. u8inttype);
  1416. { create the call }
  1417. result := ccallnode.createinternres('fpc_set_set_range',
  1418. ccallparanode.create(tsetelementnode(right).right,
  1419. ccallparanode.create(tsetelementnode(right).left,
  1420. ccallparanode.create(left,nil))),resulttype);
  1421. end
  1422. else
  1423. begin
  1424. result := ccallnode.createinternres('fpc_set_set_byte',
  1425. ccallparanode.create(tsetelementnode(right).left,
  1426. ccallparanode.create(left,nil)),resulttype);
  1427. end;
  1428. { remove reused parts from original node }
  1429. tsetelementnode(right).right := nil;
  1430. tsetelementnode(right).left := nil;
  1431. left := nil;
  1432. end
  1433. else
  1434. begin
  1435. { add two sets }
  1436. { convert the sets to fpc_normal_set's }
  1437. result := ccallnode.createinternres('fpc_set_add_sets',
  1438. ccallparanode.create(
  1439. ctypeconvnode.create_explicit(right,srsym.restype),
  1440. ccallparanode.create(
  1441. ctypeconvnode.create_explicit(left,srsym.restype),nil)),resulttype);
  1442. { remove reused parts from original node }
  1443. left := nil;
  1444. right := nil;
  1445. end;
  1446. end
  1447. end;
  1448. subn,symdifn,muln:
  1449. begin
  1450. { convert the sets to fpc_normal_set's }
  1451. paras := ccallparanode.create(ctypeconvnode.create_explicit(right,srsym.restype),
  1452. ccallparanode.create(ctypeconvnode.create_explicit(left,srsym.restype),nil));
  1453. case nodetype of
  1454. subn:
  1455. result := ccallnode.createinternres('fpc_set_sub_sets',
  1456. paras,resulttype);
  1457. symdifn:
  1458. result := ccallnode.createinternres('fpc_set_symdif_sets',
  1459. paras,resulttype);
  1460. muln:
  1461. result := ccallnode.createinternres('fpc_set_mul_sets',
  1462. paras,resulttype);
  1463. end;
  1464. { remove reused parts from original node }
  1465. left := nil;
  1466. right := nil;
  1467. end;
  1468. else
  1469. internalerror(200108311);
  1470. end;
  1471. end;
  1472. function taddnode.first_add64bitint: tnode;
  1473. var
  1474. procname: string[31];
  1475. temp: tnode;
  1476. power: longint;
  1477. begin
  1478. result := nil;
  1479. { create helper calls mul }
  1480. if nodetype <> muln then
  1481. exit;
  1482. { make sure that if there is a constant, that it's on the right }
  1483. if left.nodetype = ordconstn then
  1484. begin
  1485. temp := right;
  1486. right := left;
  1487. left := temp;
  1488. end;
  1489. { can we use a shift instead of a mul? }
  1490. if not (cs_check_overflow in aktlocalswitches) and
  1491. (right.nodetype = ordconstn) and
  1492. ispowerof2(tordconstnode(right).value,power) then
  1493. begin
  1494. tordconstnode(right).value := power;
  1495. result := cshlshrnode.create(shln,left,right);
  1496. { left and right are reused }
  1497. left := nil;
  1498. right := nil;
  1499. { return firstpassed new node }
  1500. exit;
  1501. end;
  1502. { when currency is used set the result of the
  1503. parameters to s64bit, so they are not converted }
  1504. if is_currency(resulttype.def) then
  1505. begin
  1506. left.resulttype:=s64inttype;
  1507. right.resulttype:=s64inttype;
  1508. end;
  1509. { otherwise, create the parameters for the helper }
  1510. right := ccallparanode.create(
  1511. cordconstnode.create(ord(cs_check_overflow in aktlocalswitches),booltype,true),
  1512. ccallparanode.create(right,ccallparanode.create(left,nil)));
  1513. left := nil;
  1514. { only qword needs the unsigned code, the
  1515. signed code is also used for currency }
  1516. if is_signed(resulttype.def) then
  1517. procname := 'fpc_mul_int64'
  1518. else
  1519. procname := 'fpc_mul_qword';
  1520. result := ccallnode.createintern(procname,right);
  1521. right := nil;
  1522. end;
  1523. {$ifdef cpufpemu}
  1524. function taddnode.first_addfloat: tnode;
  1525. var
  1526. procname: string[31];
  1527. temp: tnode;
  1528. power: longint;
  1529. { do we need to reverse the result ? }
  1530. notnode : boolean;
  1531. begin
  1532. result := nil;
  1533. notnode := false;
  1534. { In non-emulation mode, real opcodes are
  1535. emitted for floating point values.
  1536. }
  1537. if not (cs_fp_emulation in aktmoduleswitches) then
  1538. exit;
  1539. case nodetype of
  1540. addn : procname := 'fpc_single_add';
  1541. muln : procname := 'fpc_single_mul';
  1542. subn : procname := 'fpc_single_sub';
  1543. slashn : procname := 'fpc_single_div';
  1544. ltn : procname := 'fpc_single_lt';
  1545. lten: procname := 'fpc_single_le';
  1546. gtn:
  1547. begin
  1548. procname := 'fpc_single_le';
  1549. notnode := true;
  1550. end;
  1551. gten:
  1552. begin
  1553. procname := 'fpc_single_lt';
  1554. notnode := true;
  1555. end;
  1556. equaln: procname := 'fpc_single_eq';
  1557. unequaln :
  1558. begin
  1559. procname := 'fpc_single_eq';
  1560. notnode := true;
  1561. end;
  1562. else
  1563. CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),left.resulttype.def.typename,right.resulttype.def.typename);
  1564. end;
  1565. { convert the arguments (explicitely) to fpc_normal_set's }
  1566. result := ccallnode.createintern(procname,ccallparanode.create(right,
  1567. ccallparanode.create(left,nil)));
  1568. left:=nil;
  1569. right:=nil;
  1570. { do we need to reverse the result }
  1571. if notnode then
  1572. result := cnotnode.create(result);
  1573. end;
  1574. {$endif cpufpemu}
  1575. function taddnode.pass_1 : tnode;
  1576. var
  1577. {$ifdef addstringopt}
  1578. hp : tnode;
  1579. {$endif addstringopt}
  1580. lt,rt : tnodetype;
  1581. rd,ld : tdef;
  1582. begin
  1583. result:=nil;
  1584. { first do the two subtrees }
  1585. firstpass(left);
  1586. firstpass(right);
  1587. if codegenerror then
  1588. exit;
  1589. { load easier access variables }
  1590. rd:=right.resulttype.def;
  1591. ld:=left.resulttype.def;
  1592. rt:=right.nodetype;
  1593. lt:=left.nodetype;
  1594. { int/int gives real/real! }
  1595. if nodetype=slashn then
  1596. begin
  1597. {$ifdef cpufpemu}
  1598. result := first_addfloat;
  1599. if assigned(result) then
  1600. exit;
  1601. {$endif cpufpemu}
  1602. expectloc:=LOC_FPUREGISTER;
  1603. { maybe we need an integer register to save }
  1604. { a reference }
  1605. if ((left.expectloc<>LOC_FPUREGISTER) or
  1606. (right.expectloc<>LOC_FPUREGISTER)) and
  1607. (left.registersint=right.registersint) then
  1608. calcregisters(self,1,1,0)
  1609. else
  1610. calcregisters(self,0,1,0);
  1611. { an add node always first loads both the left and the }
  1612. { right in the fpu before doing the calculation. However, }
  1613. { calcregisters(0,2,0) will overestimate the number of }
  1614. { necessary registers (it will make it 3 in case one of }
  1615. { the operands is already in the fpu) (JM) }
  1616. if ((left.expectloc<>LOC_FPUREGISTER) or
  1617. (right.expectloc<>LOC_FPUREGISTER)) and
  1618. (registersfpu < 2) then
  1619. inc(registersfpu);
  1620. end
  1621. { if both are orddefs then check sub types }
  1622. else if (ld.deftype=orddef) and (rd.deftype=orddef) then
  1623. begin
  1624. { 2 booleans ? }
  1625. if is_boolean(ld) and is_boolean(rd) then
  1626. begin
  1627. if not(cs_full_boolean_eval in aktlocalswitches) and
  1628. (nodetype in [andn,orn]) then
  1629. begin
  1630. expectloc:=LOC_JUMP;
  1631. calcregisters(self,0,0,0);
  1632. end
  1633. else
  1634. begin
  1635. if nodetype in [ltn,lten,gtn,gten,equaln,unequaln] then
  1636. begin
  1637. expectloc:=LOC_FLAGS;
  1638. if (left.expectloc in [LOC_JUMP,LOC_FLAGS]) and
  1639. (left.expectloc in [LOC_JUMP,LOC_FLAGS]) then
  1640. calcregisters(self,2,0,0)
  1641. else
  1642. calcregisters(self,1,0,0);
  1643. end
  1644. else
  1645. begin
  1646. expectloc:=LOC_REGISTER;
  1647. calcregisters(self,0,0,0);
  1648. end;
  1649. end;
  1650. end
  1651. else
  1652. { Both are chars? only convert to shortstrings for addn }
  1653. if is_char(ld) then
  1654. begin
  1655. if nodetype=addn then
  1656. internalerror(200103291);
  1657. expectloc:=LOC_FLAGS;
  1658. calcregisters(self,1,0,0);
  1659. end
  1660. {$ifndef cpu64bit}
  1661. { is there a 64 bit type ? }
  1662. else if (torddef(ld).typ in [s64bit,u64bit,scurrency]) then
  1663. begin
  1664. result := first_add64bitint;
  1665. if assigned(result) then
  1666. exit;
  1667. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1668. expectloc:=LOC_REGISTER
  1669. else
  1670. expectloc:=LOC_JUMP;
  1671. calcregisters(self,2,0,0)
  1672. end
  1673. {$endif cpu64bit}
  1674. { is there a cardinal? }
  1675. else if (torddef(ld).typ=u32bit) then
  1676. begin
  1677. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1678. expectloc:=LOC_REGISTER
  1679. else
  1680. expectloc:=LOC_FLAGS;
  1681. calcregisters(self,1,0,0);
  1682. { for unsigned mul we need an extra register }
  1683. if nodetype=muln then
  1684. inc(registersint);
  1685. end
  1686. { generic s32bit conversion }
  1687. else
  1688. begin
  1689. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1690. expectloc:=LOC_REGISTER
  1691. else
  1692. expectloc:=LOC_FLAGS;
  1693. calcregisters(self,1,0,0);
  1694. end;
  1695. end
  1696. { left side a setdef, must be before string processing,
  1697. else array constructor can be seen as array of char (PFV) }
  1698. else if (ld.deftype=setdef) then
  1699. begin
  1700. if tsetdef(ld).settype=smallset then
  1701. begin
  1702. if nodetype in [ltn,lten,gtn,gten,equaln,unequaln] then
  1703. expectloc:=LOC_FLAGS
  1704. else
  1705. expectloc:=LOC_REGISTER;
  1706. { are we adding set elements ? }
  1707. if right.nodetype=setelementn then
  1708. calcregisters(self,2,0,0)
  1709. else
  1710. calcregisters(self,1,0,0);
  1711. end
  1712. else
  1713. {$ifdef MMXSET}
  1714. {$ifdef i386}
  1715. if cs_mmx in aktlocalswitches then
  1716. begin
  1717. expectloc:=LOC_MMXREGISTER;
  1718. calcregisters(self,0,0,4);
  1719. end
  1720. else
  1721. {$endif}
  1722. {$endif MMXSET}
  1723. begin
  1724. result := first_addset;
  1725. if assigned(result) then
  1726. exit;
  1727. expectloc:=LOC_CREFERENCE;
  1728. calcregisters(self,0,0,0);
  1729. { here we call SET... }
  1730. include(current_procinfo.flags,pi_do_call);
  1731. end;
  1732. end
  1733. { compare pchar by addresses like BP/Delphi }
  1734. else if is_pchar(ld) then
  1735. begin
  1736. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1737. expectloc:=LOC_REGISTER
  1738. else
  1739. expectloc:=LOC_FLAGS;
  1740. calcregisters(self,1,0,0);
  1741. end
  1742. { is one of the operands a string }
  1743. else if (ld.deftype=stringdef) then
  1744. begin
  1745. if is_widestring(ld) then
  1746. begin
  1747. { this is only for add, the comparisaion is handled later }
  1748. expectloc:=LOC_REGISTER;
  1749. end
  1750. else if is_ansistring(ld) then
  1751. begin
  1752. { this is only for add, the comparisaion is handled later }
  1753. expectloc:=LOC_REGISTER;
  1754. end
  1755. else if is_longstring(ld) then
  1756. begin
  1757. { this is only for add, the comparisaion is handled later }
  1758. expectloc:=LOC_REFERENCE;
  1759. end
  1760. else
  1761. begin
  1762. {$ifdef addstringopt}
  1763. { can create a call which isn't handled by callparatemp }
  1764. if canbeaddsstringcharoptnode(self) then
  1765. begin
  1766. hp := genaddsstringcharoptnode(self);
  1767. pass_1 := hp;
  1768. exit;
  1769. end
  1770. else
  1771. {$endif addstringopt}
  1772. begin
  1773. { Fix right to be shortstring }
  1774. if is_char(right.resulttype.def) then
  1775. begin
  1776. inserttypeconv(right,cshortstringtype);
  1777. firstpass(right);
  1778. end;
  1779. end;
  1780. {$ifdef addstringopt}
  1781. { can create a call which isn't handled by callparatemp }
  1782. if canbeaddsstringcsstringoptnode(self) then
  1783. begin
  1784. hp := genaddsstringcsstringoptnode(self);
  1785. pass_1 := hp;
  1786. exit;
  1787. end;
  1788. {$endif addstringopt}
  1789. end;
  1790. { otherwise, let addstring convert everything }
  1791. result := first_addstring;
  1792. exit;
  1793. end
  1794. { is one a real float ? }
  1795. else if (rd.deftype=floatdef) or (ld.deftype=floatdef) then
  1796. begin
  1797. {$ifdef cpufpemu}
  1798. result := first_addfloat;
  1799. if assigned(result) then
  1800. exit;
  1801. {$endif cpufpemu}
  1802. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1803. expectloc:=LOC_FPUREGISTER
  1804. else
  1805. expectloc:=LOC_FLAGS;
  1806. calcregisters(self,0,1,0);
  1807. { an add node always first loads both the left and the }
  1808. { right in the fpu before doing the calculation. However, }
  1809. { calcregisters(0,2,0) will overestimate the number of }
  1810. { necessary registers (it will make it 3 in case one of }
  1811. { the operands is already in the fpu) (JM) }
  1812. if ((left.expectloc<>LOC_FPUREGISTER) or
  1813. (right.expectloc<>LOC_FPUREGISTER)) and
  1814. (registersfpu < 2) then
  1815. inc(registersfpu);
  1816. end
  1817. { pointer comperation and subtraction }
  1818. else if (ld.deftype=pointerdef) then
  1819. begin
  1820. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1821. expectloc:=LOC_REGISTER
  1822. else
  1823. expectloc:=LOC_FLAGS;
  1824. calcregisters(self,1,0,0);
  1825. end
  1826. else if is_class_or_interface(ld) then
  1827. begin
  1828. expectloc:=LOC_FLAGS;
  1829. calcregisters(self,1,0,0);
  1830. end
  1831. else if (ld.deftype=classrefdef) then
  1832. begin
  1833. expectloc:=LOC_FLAGS;
  1834. calcregisters(self,1,0,0);
  1835. end
  1836. { support procvar=nil,procvar<>nil }
  1837. else if ((ld.deftype=procvardef) and (rt=niln)) or
  1838. ((rd.deftype=procvardef) and (lt=niln)) then
  1839. begin
  1840. expectloc:=LOC_FLAGS;
  1841. calcregisters(self,1,0,0);
  1842. end
  1843. {$ifdef SUPPORT_MMX}
  1844. { mmx support, this must be before the zero based array
  1845. check }
  1846. else if (cs_mmx in aktlocalswitches) and is_mmx_able_array(ld) and
  1847. is_mmx_able_array(rd) then
  1848. begin
  1849. expectloc:=LOC_MMXREGISTER;
  1850. calcregisters(self,0,0,1);
  1851. end
  1852. {$endif SUPPORT_MMX}
  1853. else if (rd.deftype=pointerdef) or (ld.deftype=pointerdef) then
  1854. begin
  1855. expectloc:=LOC_REGISTER;
  1856. calcregisters(self,1,0,0);
  1857. end
  1858. else if (rd.deftype=procvardef) and
  1859. (ld.deftype=procvardef) and
  1860. equal_defs(rd,ld) then
  1861. begin
  1862. expectloc:=LOC_FLAGS;
  1863. calcregisters(self,1,0,0);
  1864. end
  1865. else if (ld.deftype=enumdef) then
  1866. begin
  1867. expectloc:=LOC_FLAGS;
  1868. calcregisters(self,1,0,0);
  1869. end
  1870. {$ifdef SUPPORT_MMX}
  1871. else if (cs_mmx in aktlocalswitches) and
  1872. is_mmx_able_array(ld) and
  1873. is_mmx_able_array(rd) then
  1874. begin
  1875. expectloc:=LOC_MMXREGISTER;
  1876. calcregisters(self,0,0,1);
  1877. end
  1878. {$endif SUPPORT_MMX}
  1879. { the general solution is to convert to 32 bit int }
  1880. else
  1881. begin
  1882. expectloc:=LOC_REGISTER;
  1883. calcregisters(self,1,0,0);
  1884. end;
  1885. end;
  1886. {$ifdef state_tracking}
  1887. function Taddnode.track_state_pass(exec_known:boolean):boolean;
  1888. var factval:Tnode;
  1889. begin
  1890. track_state_pass:=false;
  1891. if left.track_state_pass(exec_known) then
  1892. begin
  1893. track_state_pass:=true;
  1894. left.resulttype.def:=nil;
  1895. do_resulttypepass(left);
  1896. end;
  1897. factval:=aktstate.find_fact(left);
  1898. if factval<>nil then
  1899. begin
  1900. track_state_pass:=true;
  1901. left.destroy;
  1902. left:=factval.getcopy;
  1903. end;
  1904. if right.track_state_pass(exec_known) then
  1905. begin
  1906. track_state_pass:=true;
  1907. right.resulttype.def:=nil;
  1908. do_resulttypepass(right);
  1909. end;
  1910. factval:=aktstate.find_fact(right);
  1911. if factval<>nil then
  1912. begin
  1913. track_state_pass:=true;
  1914. right.destroy;
  1915. right:=factval.getcopy;
  1916. end;
  1917. end;
  1918. {$endif}
  1919. begin
  1920. caddnode:=taddnode;
  1921. end.
  1922. {
  1923. $Log$
  1924. Revision 1.129 2004-09-21 17:25:12 peter
  1925. * paraloc branch merged
  1926. Revision 1.128 2004/09/13 20:32:53 peter
  1927. * only make both operands the same for xor,and,or when both are
  1928. integer types
  1929. Revision 1.127.4.1 2004/09/19 18:08:30 peter
  1930. * int64 compare fixed
  1931. Revision 1.127 2004/08/17 19:04:36 jonas
  1932. * fixed "if @procvar_of_object <> nil" in Delphi/TP mode for for non-x86
  1933. Revision 1.126 2004/08/08 15:22:29 florian
  1934. * fixed several ie9999s when illegal operators were used
  1935. Revision 1.125 2004/06/20 08:55:29 florian
  1936. * logs truncated
  1937. Revision 1.124 2004/06/16 20:07:07 florian
  1938. * dwarf branch merged
  1939. Revision 1.123 2004/05/28 21:13:44 peter
  1940. * fix cardinal+constint
  1941. Revision 1.122 2004/05/23 14:14:18 florian
  1942. + added set of widechar support (limited to 256 chars, is delphi compatible)
  1943. Revision 1.121 2004/05/23 14:08:39 peter
  1944. * only convert widechar to widestring when both operands are
  1945. constant
  1946. * support widechar-widechar operations in orddef part
  1947. Revision 1.120 2004/05/21 13:08:14 florian
  1948. * fixed <ordinal>+<pointer>
  1949. }