nadd.pas 83 KB

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