nadd.pas 84 KB

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