nadd.pas 87 KB

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