nadd.pas 71 KB

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