nadd.pas 84 KB

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