nadd.pas 83 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187
  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. tsetdef(right.resulttype.def).changesettype(normset);
  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.92 2003-06-03 21:04:43 peter
  1844. * widen cardinal+signed operations
  1845. Revision 1.91 2003/05/26 21:15:18 peter
  1846. * disable string node optimizations for the moment
  1847. Revision 1.90 2003/05/26 19:38:28 peter
  1848. * generic fpc_shorstr_concat
  1849. + fpc_shortstr_append_shortstr optimization
  1850. Revision 1.89 2003/05/24 21:12:57 florian
  1851. * if something doesn't work with callparatemp, the define callparatemp
  1852. should be used because other processors with reigster calling conventions
  1853. depend on this as well
  1854. Revision 1.88 2003/05/23 22:57:38 jonas
  1855. - disable addoptnodes for powerpc, because they can generate calls in
  1856. pass_2, so -dcallparatemp can't detect them as nested calls
  1857. Revision 1.87 2003/04/27 11:21:32 peter
  1858. * aktprocdef renamed to current_procdef
  1859. * procinfo renamed to current_procinfo
  1860. * procinfo will now be stored in current_module so it can be
  1861. cleaned up properly
  1862. * gen_main_procsym changed to create_main_proc and release_main_proc
  1863. to also generate a tprocinfo structure
  1864. * fixed unit implicit initfinal
  1865. Revision 1.86 2003/04/26 09:12:55 peter
  1866. * add string returns in LOC_REFERENCE
  1867. Revision 1.85 2003/04/24 22:29:57 florian
  1868. * fixed a lot of PowerPC related stuff
  1869. Revision 1.84 2003/04/23 20:16:04 peter
  1870. + added currency support based on int64
  1871. + is_64bit for use in cg units instead of is_64bitint
  1872. * removed cgmessage from n386add, replace with internalerrors
  1873. Revision 1.83 2003/04/23 10:10:07 peter
  1874. * expectloc fixes
  1875. Revision 1.82 2003/04/22 23:50:22 peter
  1876. * firstpass uses expectloc
  1877. * checks if there are differences between the expectloc and
  1878. location.loc from secondpass in EXTDEBUG
  1879. Revision 1.81 2003/02/15 22:20:14 carl
  1880. * bugfix for generic calls to FPU emulation code
  1881. Revision 1.80 2003/02/12 22:10:07 carl
  1882. * load_frame_pointer is now generic
  1883. * change fpu emulation routine names
  1884. Revision 1.79 2003/01/02 22:19:54 peter
  1885. * support pchar-char operations converting to string first
  1886. * support chararray-nil
  1887. Revision 1.78 2002/12/11 22:41:03 peter
  1888. * stop processing assignment node when the binaryoverload generates
  1889. a codegenerror
  1890. Revision 1.77 2002/12/06 16:56:57 peter
  1891. * only compile cs_fp_emulation support when cpufpuemu is defined
  1892. * define cpufpuemu for m68k only
  1893. Revision 1.76 2002/11/30 21:32:24 carl
  1894. + Add loading of softfpu in emulation mode
  1895. + Correct routine call for softfpu
  1896. * Extended type must also be defined even with softfpu
  1897. Revision 1.75 2002/11/27 13:11:38 peter
  1898. * more currency fixes, taddcurr runs now successfull
  1899. Revision 1.74 2002/11/27 11:28:40 peter
  1900. * when both flaottypes are the same then handle the addnode using
  1901. that floattype instead of bestrealtype
  1902. Revision 1.73 2002/11/25 18:43:32 carl
  1903. - removed the invalid if <> checking (Delphi is strange on this)
  1904. + implemented abstract warning on instance creation of class with
  1905. abstract methods.
  1906. * some error message cleanups
  1907. Revision 1.72 2002/11/25 17:43:17 peter
  1908. * splitted defbase in defutil,symutil,defcmp
  1909. * merged isconvertable and is_equal into compare_defs(_ext)
  1910. * made operator search faster by walking the list only once
  1911. Revision 1.71 2002/11/23 22:50:06 carl
  1912. * some small speed optimizations
  1913. + added several new warnings/hints
  1914. Revision 1.70 2002/11/16 14:20:22 peter
  1915. * fix tbs0417
  1916. Revision 1.69 2002/11/15 01:58:50 peter
  1917. * merged changes from 1.0.7 up to 04-11
  1918. - -V option for generating bug report tracing
  1919. - more tracing for option parsing
  1920. - errors for cdecl and high()
  1921. - win32 import stabs
  1922. - win32 records<=8 are returned in eax:edx (turned off by default)
  1923. - heaptrc update
  1924. - more info for temp management in .s file with EXTDEBUG
  1925. Revision 1.68 2002/10/08 16:50:43 jonas
  1926. * fixed web bug 2136
  1927. Revision 1.67 2002/10/05 00:47:03 peter
  1928. * support dynamicarray<>nil
  1929. Revision 1.66 2002/10/04 21:19:28 jonas
  1930. * fixed web bug 2139: checking for division by zero fixed
  1931. Revision 1.65 2002/09/07 15:25:02 peter
  1932. * old logs removed and tabs fixed
  1933. Revision 1.64 2002/09/07 12:16:05 carl
  1934. * second part bug report 1996 fix, testrange in cordconstnode
  1935. only called if option is set (also make parsing a tiny faster)
  1936. Revision 1.63 2002/09/04 19:32:56 jonas
  1937. * changed some ctypeconvnode/toggleflag(nf_explizit) combo's to
  1938. ctypeconvnode.create_explicit() statements
  1939. Revision 1.62 2002/08/17 09:23:34 florian
  1940. * first part of current_procinfo rewrite
  1941. Revision 1.61 2002/08/15 15:15:55 carl
  1942. * jmpbuf size allocation for exceptions is now cpu specific (as it should)
  1943. * more generic nodes for maths
  1944. * several fixes for better m68k support
  1945. Revision 1.60 2002/08/12 15:08:39 carl
  1946. + stab register indexes for powerpc (moved from gdb to cpubase)
  1947. + tprocessor enumeration moved to cpuinfo
  1948. + linker in target_info is now a class
  1949. * many many updates for m68k (will soon start to compile)
  1950. - removed some ifdef or correct them for correct cpu
  1951. Revision 1.59 2002/08/02 07:44:30 jonas
  1952. * made assigned() handling generic
  1953. * add nodes now can also evaluate constant expressions at compile time
  1954. that contain nil nodes
  1955. Revision 1.58 2002/07/26 11:17:52 jonas
  1956. * the optimization of converting a multiplication with a power of two to
  1957. a shl is moved from n386add/secondpass to nadd/resulttypepass
  1958. Revision 1.57 2002/07/23 13:08:16 jonas
  1959. * fixed constant set evaluation of new set handling for non-commutative
  1960. operators
  1961. Revision 1.56 2002/07/23 12:34:29 daniel
  1962. * Readded old set code. To use it define 'oldset'. Activated by default
  1963. for ppc.
  1964. Revision 1.55 2002/07/22 11:48:04 daniel
  1965. * Sets are now internally sets.
  1966. Revision 1.54 2002/07/20 11:57:53 florian
  1967. * types.pas renamed to defbase.pas because D6 contains a types
  1968. unit so this would conflicts if D6 programms are compiled
  1969. + Willamette/SSE2 instructions to assembler added
  1970. Revision 1.53 2002/07/19 11:41:34 daniel
  1971. * State tracker work
  1972. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1973. allows the state tracker to change while nodes automatically into
  1974. repeat nodes.
  1975. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1976. 'not(a>b)' is optimized into 'a<=b'.
  1977. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1978. by removing the notn and later switchting the true and falselabels. The
  1979. same is done with 'repeat until not a'.
  1980. Revision 1.52 2002/07/14 18:00:43 daniel
  1981. + Added the beginning of a state tracker. This will track the values of
  1982. variables through procedures and optimize things away.
  1983. Revision 1.51 2002/05/18 13:34:08 peter
  1984. * readded missing revisions
  1985. Revision 1.50 2002/05/16 19:46:37 carl
  1986. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1987. + try to fix temp allocation (still in ifdef)
  1988. + generic constructor calls
  1989. + start of tassembler / tmodulebase class cleanup
  1990. Revision 1.48 2002/05/13 19:54:36 peter
  1991. * removed n386ld and n386util units
  1992. * maybe_save/maybe_restore added instead of the old maybe_push
  1993. Revision 1.47 2002/05/12 16:53:06 peter
  1994. * moved entry and exitcode to ncgutil and cgobj
  1995. * foreach gets extra argument for passing local data to the
  1996. iterator function
  1997. * -CR checks also class typecasts at runtime by changing them
  1998. into as
  1999. * fixed compiler to cycle with the -CR option
  2000. * fixed stabs with elf writer, finally the global variables can
  2001. be watched
  2002. * removed a lot of routines from cga unit and replaced them by
  2003. calls to cgobj
  2004. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  2005. u32bit then the other is typecasted also to u32bit without giving
  2006. a rangecheck warning/error.
  2007. * fixed pascal calling method with reversing also the high tree in
  2008. the parast, detected by tcalcst3 test
  2009. Revision 1.46 2002/04/23 19:16:34 peter
  2010. * add pinline unit that inserts compiler supported functions using
  2011. one or more statements
  2012. * moved finalize and setlength from ninl to pinline
  2013. Revision 1.45 2002/04/04 19:05:56 peter
  2014. * removed unused units
  2015. * use tlocation.size in cg.a_*loc*() routines
  2016. Revision 1.44 2002/04/02 17:11:28 peter
  2017. * tlocation,treference update
  2018. * LOC_CONSTANT added for better constant handling
  2019. * secondadd splitted in multiple routines
  2020. * location_force_reg added for loading a location to a register
  2021. of a specified size
  2022. * secondassignment parses now first the right and then the left node
  2023. (this is compatible with Kylix). This saves a lot of push/pop especially
  2024. with string operations
  2025. * adapted some routines to use the new cg methods
  2026. }