nadd.pas 83 KB

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