nadd.pas 84 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190
  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. { convert positive constants to u32bit }
  780. not(is_constintnode(left) and
  781. (tordconstnode(left).value >= 0)) and
  782. { range/overflow checking on mixed signed/cardinal expressions }
  783. { is only possible if you convert everything to 64bit (JM) }
  784. ((aktlocalswitches * [cs_check_overflow,cs_check_range] <> []) and
  785. (nodetype in [addn,subn,muln])) then
  786. begin
  787. { perform the operation in 64bit }
  788. CGMessage(type_w_mixed_signed_unsigned);
  789. inserttypeconv(left,cs64bittype);
  790. inserttypeconv(right,cs64bittype);
  791. end
  792. else
  793. begin
  794. { and,or,xor work on bit patterns and don't care
  795. about the sign }
  796. if nodetype in [andn,orn,xorn] then
  797. inserttypeconv_explicit(left,u32bittype)
  798. else
  799. begin
  800. if is_signed(ld) and
  801. not(is_constintnode(left) and
  802. (tordconstnode(left).value >= 0)) and
  803. (cs_check_range in aktlocalswitches) then
  804. CGMessage(type_w_mixed_signed_unsigned2);
  805. inserttypeconv(left,u32bittype);
  806. end;
  807. if is_signed(rd) and
  808. { then ld = u32bit }
  809. { convert positive constants to u32bit }
  810. not(is_constintnode(right) and
  811. (tordconstnode(right).value >= 0)) and
  812. ((aktlocalswitches * [cs_check_overflow,cs_check_range] <> []) and
  813. (nodetype in [addn,subn,muln])) then
  814. begin
  815. { perform the operation in 64bit }
  816. CGMessage(type_w_mixed_signed_unsigned);
  817. inserttypeconv(left,cs64bittype);
  818. inserttypeconv(right,cs64bittype);
  819. end
  820. else
  821. begin
  822. { and,or,xor work on bit patterns and don't care
  823. about the sign }
  824. if nodetype in [andn,orn,xorn] then
  825. inserttypeconv_explicit(left,u32bittype)
  826. else
  827. begin
  828. if is_signed(rd) and
  829. not(is_constintnode(right) and
  830. (tordconstnode(right).value >= 0)) and
  831. (cs_check_range in aktlocalswitches) then
  832. CGMessage(type_w_mixed_signed_unsigned2);
  833. inserttypeconv(right,u32bittype);
  834. end;
  835. end;
  836. end;
  837. end
  838. { generic ord conversion is s32bit }
  839. else
  840. begin
  841. { if the left or right value is smaller than the normal
  842. type s32bittype and is unsigned, and the other value
  843. is a constant < 0, the result will always be false/true
  844. for equal / unequal nodes.
  845. }
  846. if (
  847. { left : unsigned ordinal var, right : < 0 constant }
  848. (
  849. ((is_signed(ld)=false) and (is_constintnode(left) =false)) and
  850. ((is_constintnode(right)) and (tordconstnode(right).value < 0))
  851. ) or
  852. { right : unsigned ordinal var, left : < 0 constant }
  853. (
  854. ((is_signed(rd)=false) and (is_constintnode(right) =false)) and
  855. ((is_constintnode(left)) and (tordconstnode(left).value < 0))
  856. )
  857. ) then
  858. begin
  859. if nodetype = equaln then
  860. CGMessage(type_w_signed_unsigned_always_false)
  861. else
  862. if nodetype = unequaln then
  863. CGMessage(type_w_signed_unsigned_always_true)
  864. else
  865. if (is_constintnode(left) and (nodetype in [ltn,lten])) or
  866. (is_constintnode(right) and (nodetype in [gtn,gten])) then
  867. CGMessage(type_w_signed_unsigned_always_true)
  868. else
  869. if (is_constintnode(right) and (nodetype in [ltn,lten])) or
  870. (is_constintnode(left) and (nodetype in [gtn,gten])) then
  871. CGMessage(type_w_signed_unsigned_always_false);
  872. end;
  873. inserttypeconv(right,s32bittype);
  874. inserttypeconv(left,s32bittype);
  875. end;
  876. end
  877. { if both are floatdefs, conversion is already done before constant folding }
  878. else if (ld.deftype=floatdef) then
  879. begin
  880. { already converted }
  881. end
  882. { left side a setdef, must be before string processing,
  883. else array constructor can be seen as array of char (PFV) }
  884. else if (ld.deftype=setdef) then
  885. begin
  886. { trying to add a set element? }
  887. if (nodetype=addn) and (rd.deftype<>setdef) then
  888. begin
  889. if (rt=setelementn) then
  890. begin
  891. if not(equal_defs(tsetdef(ld).elementtype.def,rd)) then
  892. CGMessage(type_e_set_element_are_not_comp);
  893. end
  894. else
  895. CGMessage(type_e_mismatch)
  896. end
  897. else
  898. begin
  899. if not(nodetype in [addn,subn,symdifn,muln,equaln,unequaln,lten,gten]) then
  900. CGMessage(type_e_set_operation_unknown);
  901. { right def must be a also be set }
  902. if (rd.deftype<>setdef) or not(equal_defs(rd,ld)) then
  903. CGMessage(type_e_set_element_are_not_comp);
  904. end;
  905. { ranges require normsets }
  906. if (tsetdef(ld).settype=smallset) and
  907. (rt=setelementn) and
  908. assigned(tsetelementnode(right).right) then
  909. begin
  910. { generate a temporary normset def, it'll be destroyed
  911. when the symtable is unloaded }
  912. htype.setdef(tsetdef.create(tsetdef(ld).elementtype,255));
  913. inserttypeconv(left,htype);
  914. end;
  915. { if the right side is also a setdef then the settype must
  916. be the same as the left setdef }
  917. if (rd.deftype=setdef) and
  918. (tsetdef(ld).settype<>tsetdef(rd).settype) then
  919. begin
  920. { when right is a normset we need to typecast both
  921. to normsets }
  922. if (tsetdef(rd).settype=normset) then
  923. inserttypeconv(left,right.resulttype)
  924. else
  925. inserttypeconv(right,left.resulttype);
  926. end;
  927. end
  928. { compare pchar to char arrays by addresses like BP/Delphi }
  929. else if ((is_pchar(ld) or (lt=niln)) and is_chararray(rd)) or
  930. ((is_pchar(rd) or (rt=niln)) and is_chararray(ld)) then
  931. begin
  932. if is_chararray(rd) then
  933. inserttypeconv(right,charpointertype)
  934. else
  935. inserttypeconv(left,charpointertype);
  936. end
  937. { pointer comparision and subtraction }
  938. else if (rd.deftype=pointerdef) and (ld.deftype=pointerdef) then
  939. begin
  940. case nodetype of
  941. equaln,unequaln :
  942. begin
  943. if is_voidpointer(right.resulttype.def) then
  944. inserttypeconv(right,left.resulttype)
  945. else if is_voidpointer(left.resulttype.def) then
  946. inserttypeconv(left,right.resulttype)
  947. else if not(equal_defs(ld,rd)) then
  948. CGMessage2(type_e_incompatible_types,ld.typename,rd.typename);
  949. end;
  950. ltn,lten,gtn,gten:
  951. begin
  952. if (cs_extsyntax in aktmoduleswitches) then
  953. begin
  954. if is_voidpointer(right.resulttype.def) then
  955. inserttypeconv(right,left.resulttype)
  956. else if is_voidpointer(left.resulttype.def) then
  957. inserttypeconv(left,right.resulttype)
  958. else if not(equal_defs(ld,rd)) then
  959. CGMessage2(type_e_incompatible_types,ld.typename,rd.typename);
  960. end
  961. else
  962. CGMessage(type_e_mismatch);
  963. end;
  964. subn:
  965. begin
  966. if (cs_extsyntax in aktmoduleswitches) then
  967. begin
  968. if is_voidpointer(right.resulttype.def) then
  969. inserttypeconv(right,left.resulttype)
  970. else if is_voidpointer(left.resulttype.def) then
  971. inserttypeconv(left,right.resulttype)
  972. else if not(equal_defs(ld,rd)) then
  973. CGMessage2(type_e_incompatible_types,ld.typename,rd.typename);
  974. end
  975. else
  976. CGMessage(type_e_mismatch);
  977. resulttype:=s32bittype;
  978. exit;
  979. end;
  980. addn:
  981. begin
  982. if (cs_extsyntax in aktmoduleswitches) then
  983. begin
  984. if is_voidpointer(right.resulttype.def) then
  985. inserttypeconv(right,left.resulttype)
  986. else if is_voidpointer(left.resulttype.def) then
  987. inserttypeconv(left,right.resulttype)
  988. else if not(equal_defs(ld,rd)) then
  989. CGMessage2(type_e_incompatible_types,ld.typename,rd.typename);
  990. end
  991. else
  992. CGMessage(type_e_mismatch);
  993. resulttype:=s32bittype;
  994. exit;
  995. end;
  996. else
  997. CGMessage(type_e_mismatch);
  998. end;
  999. end
  1000. { is one of the operands a string?,
  1001. chararrays are also handled as strings (after conversion), also take
  1002. care of chararray+chararray and chararray+char.
  1003. Note: Must be done after pointerdef+pointerdef has been checked, else
  1004. pchar is converted to string }
  1005. else if (rd.deftype=stringdef) or (ld.deftype=stringdef) or
  1006. ((is_pchar(rd) or is_chararray(rd) or is_char(rd)) and
  1007. (is_pchar(ld) or is_chararray(ld) or is_char(ld))) then
  1008. begin
  1009. if is_widestring(rd) or is_widestring(ld) then
  1010. begin
  1011. if not(is_widestring(rd)) then
  1012. inserttypeconv(right,cwidestringtype);
  1013. if not(is_widestring(ld)) then
  1014. inserttypeconv(left,cwidestringtype);
  1015. end
  1016. else if is_ansistring(rd) or is_ansistring(ld) then
  1017. begin
  1018. if not(is_ansistring(rd)) then
  1019. inserttypeconv(right,cansistringtype);
  1020. if not(is_ansistring(ld)) then
  1021. inserttypeconv(left,cansistringtype);
  1022. end
  1023. else if is_longstring(rd) or is_longstring(ld) then
  1024. begin
  1025. if not(is_longstring(rd)) then
  1026. inserttypeconv(right,clongstringtype);
  1027. if not(is_longstring(ld)) then
  1028. inserttypeconv(left,clongstringtype);
  1029. end
  1030. else
  1031. begin
  1032. if not(is_shortstring(ld)) then
  1033. inserttypeconv(left,cshortstringtype);
  1034. { don't convert char, that can be handled by the optimized node }
  1035. if not(is_shortstring(rd) or is_char(rd)) then
  1036. inserttypeconv(right,cshortstringtype);
  1037. end;
  1038. end
  1039. { class or interface equation }
  1040. else if is_class_or_interface(rd) or is_class_or_interface(ld) then
  1041. begin
  1042. if is_class_or_interface(rd) and is_class_or_interface(ld) then
  1043. begin
  1044. if tobjectdef(rd).is_related(tobjectdef(ld)) then
  1045. inserttypeconv(right,left.resulttype)
  1046. else
  1047. inserttypeconv(left,right.resulttype);
  1048. end
  1049. else if is_class_or_interface(rd) then
  1050. inserttypeconv(left,right.resulttype)
  1051. else
  1052. inserttypeconv(right,left.resulttype);
  1053. if not(nodetype in [equaln,unequaln]) then
  1054. CGMessage(type_e_mismatch);
  1055. end
  1056. else if (rd.deftype=classrefdef) and (ld.deftype=classrefdef) then
  1057. begin
  1058. if tobjectdef(tclassrefdef(rd).pointertype.def).is_related(
  1059. tobjectdef(tclassrefdef(ld).pointertype.def)) then
  1060. inserttypeconv(right,left.resulttype)
  1061. else
  1062. inserttypeconv(left,right.resulttype);
  1063. if not(nodetype in [equaln,unequaln]) then
  1064. CGMessage(type_e_mismatch);
  1065. end
  1066. { allows comperasion with nil pointer }
  1067. else if is_class_or_interface(rd) or (rd.deftype=classrefdef) then
  1068. begin
  1069. inserttypeconv(left,right.resulttype);
  1070. if not(nodetype in [equaln,unequaln]) then
  1071. CGMessage(type_e_mismatch);
  1072. end
  1073. else if is_class_or_interface(ld) or (ld.deftype=classrefdef) then
  1074. begin
  1075. inserttypeconv(right,left.resulttype);
  1076. if not(nodetype in [equaln,unequaln]) then
  1077. CGMessage(type_e_mismatch);
  1078. end
  1079. { support procvar=nil,procvar<>nil }
  1080. else if ((ld.deftype=procvardef) and (rt=niln)) or
  1081. ((rd.deftype=procvardef) and (lt=niln)) then
  1082. begin
  1083. if not(nodetype in [equaln,unequaln]) then
  1084. CGMessage(type_e_mismatch);
  1085. end
  1086. { support dynamicarray=nil,dynamicarray<>nil }
  1087. else if (is_dynamic_array(ld) and (rt=niln)) or
  1088. (is_dynamic_array(rd) and (lt=niln)) then
  1089. begin
  1090. if not(nodetype in [equaln,unequaln]) then
  1091. CGMessage(type_e_mismatch);
  1092. end
  1093. {$ifdef SUPPORT_MMX}
  1094. { mmx support, this must be before the zero based array
  1095. check }
  1096. else if (cs_mmx in aktlocalswitches) and
  1097. is_mmx_able_array(ld) and
  1098. is_mmx_able_array(rd) and
  1099. equal_defs(ld,rd) then
  1100. begin
  1101. case nodetype of
  1102. addn,subn,xorn,orn,andn:
  1103. ;
  1104. { mul is a little bit restricted }
  1105. muln:
  1106. if not(mmx_type(ld) in [mmxu16bit,mmxs16bit,mmxfixed16]) then
  1107. CGMessage(type_e_mismatch);
  1108. else
  1109. CGMessage(type_e_mismatch);
  1110. end;
  1111. end
  1112. {$endif SUPPORT_MMX}
  1113. { this is a little bit dangerous, also the left type }
  1114. { pointer to should be checked! This broke the mmx support }
  1115. else if (rd.deftype=pointerdef) or is_zero_based_array(rd) then
  1116. begin
  1117. if is_zero_based_array(rd) then
  1118. begin
  1119. resulttype.setdef(tpointerdef.create(tarraydef(rd).elementtype));
  1120. inserttypeconv(right,resulttype);
  1121. end;
  1122. inserttypeconv(left,s32bittype);
  1123. if nodetype=addn then
  1124. begin
  1125. if not(cs_extsyntax in aktmoduleswitches) or
  1126. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  1127. CGMessage(type_e_mismatch);
  1128. if (rd.deftype=pointerdef) and
  1129. (tpointerdef(rd).pointertype.def.size>1) then
  1130. left:=caddnode.create(muln,left,
  1131. cordconstnode.create(tpointerdef(rd).pointertype.def.size,s32bittype,true));
  1132. end
  1133. else
  1134. CGMessage(type_e_mismatch);
  1135. end
  1136. else if (ld.deftype=pointerdef) or is_zero_based_array(ld) then
  1137. begin
  1138. if is_zero_based_array(ld) then
  1139. begin
  1140. resulttype.setdef(tpointerdef.create(tarraydef(ld).elementtype));
  1141. inserttypeconv(left,resulttype);
  1142. end;
  1143. inserttypeconv(right,s32bittype);
  1144. if nodetype in [addn,subn] then
  1145. begin
  1146. if not(cs_extsyntax in aktmoduleswitches) or
  1147. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  1148. CGMessage(type_e_mismatch);
  1149. if (ld.deftype=pointerdef) and
  1150. (tpointerdef(ld).pointertype.def.size>1) then
  1151. right:=caddnode.create(muln,right,
  1152. cordconstnode.create(tpointerdef(ld).pointertype.def.size,s32bittype,true));
  1153. end
  1154. else
  1155. CGMessage(type_e_mismatch);
  1156. end
  1157. else if (rd.deftype=procvardef) and
  1158. (ld.deftype=procvardef) and
  1159. equal_defs(rd,ld) then
  1160. begin
  1161. if not (nodetype in [equaln,unequaln]) then
  1162. CGMessage(type_e_mismatch);
  1163. end
  1164. { enums }
  1165. else if (ld.deftype=enumdef) and (rd.deftype=enumdef) then
  1166. begin
  1167. if not(equal_defs(ld,rd)) then
  1168. inserttypeconv(right,left.resulttype);
  1169. if not(nodetype in [equaln,unequaln,ltn,lten,gtn,gten]) then
  1170. CGMessage(type_e_mismatch);
  1171. end
  1172. { generic conversion, this is for error recovery }
  1173. else
  1174. begin
  1175. inserttypeconv(left,s32bittype);
  1176. inserttypeconv(right,s32bittype);
  1177. end;
  1178. { set resulttype if not already done }
  1179. if not assigned(resulttype.def) then
  1180. begin
  1181. case nodetype of
  1182. ltn,lten,gtn,gten,equaln,unequaln :
  1183. resulttype:=booltype;
  1184. slashn :
  1185. resulttype:=resultrealtype;
  1186. addn:
  1187. begin
  1188. { for strings, return is always a 255 char string }
  1189. if is_shortstring(left.resulttype.def) then
  1190. resulttype:=cshortstringtype
  1191. else
  1192. resulttype:=left.resulttype;
  1193. end;
  1194. else
  1195. resulttype:=left.resulttype;
  1196. end;
  1197. end;
  1198. { when the result is currency we need some extra code for
  1199. multiplication and division. this should not be done when
  1200. the muln or slashn node is created internally }
  1201. if not(nf_is_currency in flags) and
  1202. is_currency(resulttype.def) then
  1203. begin
  1204. case nodetype of
  1205. slashn :
  1206. begin
  1207. { slashn will only work with floats }
  1208. hp:=caddnode.create(muln,getcopy,crealconstnode.create(10000.0,s64currencytype));
  1209. include(hp.flags,nf_is_currency);
  1210. result:=hp;
  1211. end;
  1212. muln :
  1213. begin
  1214. if s64currencytype.def.deftype=floatdef then
  1215. hp:=caddnode.create(slashn,getcopy,crealconstnode.create(10000.0,s64currencytype))
  1216. else
  1217. hp:=cmoddivnode.create(divn,getcopy,cordconstnode.create(10000,s64currencytype,false));
  1218. include(hp.flags,nf_is_currency);
  1219. result:=hp
  1220. end;
  1221. end;
  1222. end;
  1223. end;
  1224. function taddnode.first_addstring: tnode;
  1225. var
  1226. p: tnode;
  1227. begin
  1228. { when we get here, we are sure that both the left and the right }
  1229. { node are both strings of the same stringtype (JM) }
  1230. case nodetype of
  1231. addn:
  1232. begin
  1233. { create the call to the concat routine both strings as arguments }
  1234. result := ccallnode.createintern('fpc_'+
  1235. tstringdef(resulttype.def).stringtypname+'_concat',
  1236. ccallparanode.create(right,ccallparanode.create(left,nil)));
  1237. { we reused the arguments }
  1238. left := nil;
  1239. right := nil;
  1240. end;
  1241. ltn,lten,gtn,gten,equaln,unequaln :
  1242. begin
  1243. { generate better code for s='' and s<>'' }
  1244. if (nodetype in [equaln,unequaln]) and
  1245. (((left.nodetype=stringconstn) and (str_length(left)=0)) or
  1246. ((right.nodetype=stringconstn) and (str_length(right)=0))) then
  1247. begin
  1248. { switch so that the constant is always on the right }
  1249. if left.nodetype = stringconstn then
  1250. begin
  1251. p := left;
  1252. left := right;
  1253. right := p;
  1254. end;
  1255. if is_shortstring(left.resulttype.def) then
  1256. { compare the length with 0 }
  1257. result := caddnode.create(nodetype,
  1258. cinlinenode.create(in_length_x,false,left),
  1259. cordconstnode.create(0,s32bittype,false))
  1260. else
  1261. begin
  1262. { compare the pointer with nil (for ansistrings etc), }
  1263. { faster than getting the length (JM) }
  1264. result:= caddnode.create(nodetype,
  1265. ctypeconvnode.create_explicit(left,voidpointertype),
  1266. cpointerconstnode.create(0,voidpointertype));
  1267. end;
  1268. { left is reused }
  1269. left := nil;
  1270. { right isn't }
  1271. right.free;
  1272. right := nil;
  1273. exit;
  1274. end;
  1275. { no string constant -> call compare routine }
  1276. result := ccallnode.createintern('fpc_'+
  1277. tstringdef(left.resulttype.def).stringtypname+'_compare',
  1278. ccallparanode.create(right,ccallparanode.create(left,nil)));
  1279. { and compare its result with 0 according to the original operator }
  1280. result := caddnode.create(nodetype,result,
  1281. cordconstnode.create(0,s32bittype,false));
  1282. left := nil;
  1283. right := nil;
  1284. end;
  1285. end;
  1286. end;
  1287. function taddnode.first_addset: tnode;
  1288. var
  1289. procname: string[31];
  1290. tempn: tnode;
  1291. paras: tcallparanode;
  1292. srsym: ttypesym;
  1293. begin
  1294. { get the sym that represents the fpc_normal_set type }
  1295. if not searchsystype('FPC_NORMAL_SET',srsym) then
  1296. internalerror(200108313);
  1297. case nodetype of
  1298. equaln,unequaln,lten,gten:
  1299. begin
  1300. case nodetype of
  1301. equaln,unequaln:
  1302. procname := 'fpc_set_comp_sets';
  1303. lten,gten:
  1304. begin
  1305. procname := 'fpc_set_contains_sets';
  1306. { (left >= right) = (right <= left) }
  1307. if nodetype = gten then
  1308. begin
  1309. tempn := left;
  1310. left := right;
  1311. right := tempn;
  1312. end;
  1313. end;
  1314. end;
  1315. { convert the arguments (explicitely) to fpc_normal_set's }
  1316. left := ctypeconvnode.create_explicit(left,srsym.restype);
  1317. right := ctypeconvnode.create_explicit(right,srsym.restype);
  1318. result := ccallnode.createintern(procname,ccallparanode.create(right,
  1319. ccallparanode.create(left,nil)));
  1320. { left and right are reused as parameters }
  1321. left := nil;
  1322. right := nil;
  1323. { for an unequaln, we have to negate the result of comp_sets }
  1324. if nodetype = unequaln then
  1325. result := cnotnode.create(result);
  1326. end;
  1327. addn:
  1328. begin
  1329. { optimize first loading of a set }
  1330. if (right.nodetype=setelementn) and
  1331. not(assigned(tsetelementnode(right).right)) and
  1332. is_emptyset(left) then
  1333. begin
  1334. { type cast the value to pass as argument to a byte, }
  1335. { since that's what the helper expects }
  1336. tsetelementnode(right).left :=
  1337. ctypeconvnode.create_explicit(tsetelementnode(right).left,u8bittype);
  1338. { set the resulttype to the actual one (otherwise it's }
  1339. { "fpc_normal_set") }
  1340. result := ccallnode.createinternres('fpc_set_create_element',
  1341. ccallparanode.create(tsetelementnode(right).left,nil),
  1342. resulttype);
  1343. { reused }
  1344. tsetelementnode(right).left := nil;
  1345. end
  1346. else
  1347. begin
  1348. if right.nodetype=setelementn then
  1349. begin
  1350. { convert the arguments to bytes, since that's what }
  1351. { the helper expects }
  1352. tsetelementnode(right).left :=
  1353. ctypeconvnode.create_explicit(tsetelementnode(right).left,
  1354. u8bittype);
  1355. { convert the original set (explicitely) to an }
  1356. { fpc_normal_set so we can pass it to the helper }
  1357. left := ctypeconvnode.create_explicit(left,srsym.restype);
  1358. { add a range or a single element? }
  1359. if assigned(tsetelementnode(right).right) then
  1360. begin
  1361. tsetelementnode(right).right :=
  1362. ctypeconvnode.create_explicit(tsetelementnode(right).right,
  1363. u8bittype);
  1364. { create the call }
  1365. result := ccallnode.createinternres('fpc_set_set_range',
  1366. ccallparanode.create(tsetelementnode(right).right,
  1367. ccallparanode.create(tsetelementnode(right).left,
  1368. ccallparanode.create(left,nil))),resulttype);
  1369. end
  1370. else
  1371. begin
  1372. result := ccallnode.createinternres('fpc_set_set_byte',
  1373. ccallparanode.create(tsetelementnode(right).left,
  1374. ccallparanode.create(left,nil)),resulttype);
  1375. end;
  1376. { remove reused parts from original node }
  1377. tsetelementnode(right).right := nil;
  1378. tsetelementnode(right).left := nil;
  1379. left := nil;
  1380. end
  1381. else
  1382. begin
  1383. { add two sets }
  1384. { convert the sets to fpc_normal_set's }
  1385. result := ccallnode.createinternres('fpc_set_add_sets',
  1386. ccallparanode.create(
  1387. ctypeconvnode.create_explicit(right,srsym.restype),
  1388. ccallparanode.create(
  1389. ctypeconvnode.create_explicit(left,srsym.restype),nil)),resulttype);
  1390. { remove reused parts from original node }
  1391. left := nil;
  1392. right := nil;
  1393. end;
  1394. end
  1395. end;
  1396. subn,symdifn,muln:
  1397. begin
  1398. { convert the sets to fpc_normal_set's }
  1399. paras := ccallparanode.create(ctypeconvnode.create_explicit(right,srsym.restype),
  1400. ccallparanode.create(ctypeconvnode.create_explicit(left,srsym.restype),nil));
  1401. case nodetype of
  1402. subn:
  1403. result := ccallnode.createinternres('fpc_set_sub_sets',
  1404. paras,resulttype);
  1405. symdifn:
  1406. result := ccallnode.createinternres('fpc_set_symdif_sets',
  1407. paras,resulttype);
  1408. muln:
  1409. result := ccallnode.createinternres('fpc_set_mul_sets',
  1410. paras,resulttype);
  1411. end;
  1412. { remove reused parts from original node }
  1413. left := nil;
  1414. right := nil;
  1415. end;
  1416. else
  1417. internalerror(200108311);
  1418. end;
  1419. end;
  1420. function taddnode.first_add64bitint: tnode;
  1421. var
  1422. procname: string[31];
  1423. temp: tnode;
  1424. power: longint;
  1425. begin
  1426. result := nil;
  1427. { create helper calls mul }
  1428. if nodetype <> muln then
  1429. exit;
  1430. { make sure that if there is a constant, that it's on the right }
  1431. if left.nodetype = ordconstn then
  1432. begin
  1433. temp := right;
  1434. right := left;
  1435. left := temp;
  1436. end;
  1437. { can we use a shift instead of a mul? }
  1438. if (right.nodetype = ordconstn) and
  1439. ispowerof2(tordconstnode(right).value,power) then
  1440. begin
  1441. tordconstnode(right).value := power;
  1442. result := cshlshrnode.create(shln,left,right);
  1443. { left and right are reused }
  1444. left := nil;
  1445. right := nil;
  1446. { return firstpassed new node }
  1447. exit;
  1448. end;
  1449. { when currency is used set the result of the
  1450. parameters to s64bit, so they are not converted }
  1451. if is_currency(resulttype.def) then
  1452. begin
  1453. left.resulttype:=cs64bittype;
  1454. right.resulttype:=cs64bittype;
  1455. end;
  1456. { otherwise, create the parameters for the helper }
  1457. right := ccallparanode.create(
  1458. cordconstnode.create(ord(cs_check_overflow in aktlocalswitches),booltype,true),
  1459. ccallparanode.create(right,ccallparanode.create(left,nil)));
  1460. left := nil;
  1461. { only qword needs the unsigned code, the
  1462. signed code is also used for currency }
  1463. if is_signed(resulttype.def) then
  1464. procname := 'fpc_mul_int64'
  1465. else
  1466. procname := 'fpc_mul_qword';
  1467. result := ccallnode.createintern(procname,right);
  1468. right := nil;
  1469. end;
  1470. {$ifdef cpufpemu}
  1471. function taddnode.first_addfloat: tnode;
  1472. var
  1473. procname: string[31];
  1474. temp: tnode;
  1475. power: longint;
  1476. { do we need to reverse the result ? }
  1477. notnode : boolean;
  1478. begin
  1479. result := nil;
  1480. notnode := false;
  1481. { In non-emulation mode, real opcodes are
  1482. emitted for floating point values.
  1483. }
  1484. if not (cs_fp_emulation in aktmoduleswitches) then
  1485. exit;
  1486. case nodetype of
  1487. addn : procname := 'fpc_single_add';
  1488. muln : procname := 'fpc_single_mul';
  1489. subn : procname := 'fpc_single_sub';
  1490. slashn : procname := 'fpc_single_div';
  1491. ltn : procname := 'fpc_single_lt';
  1492. lten: procname := 'fpc_single_le';
  1493. gtn:
  1494. begin
  1495. procname := 'fpc_single_le';
  1496. notnode := true;
  1497. end;
  1498. gten:
  1499. begin
  1500. procname := 'fpc_single_lt';
  1501. notnode := true;
  1502. end;
  1503. equaln: procname := 'fpc_single_eq';
  1504. unequaln :
  1505. begin
  1506. procname := 'fpc_single_eq';
  1507. notnode := true;
  1508. end;
  1509. else
  1510. CGMessage(type_e_mismatch);
  1511. end;
  1512. { convert the arguments (explicitely) to fpc_normal_set's }
  1513. result := ccallnode.createintern(procname,ccallparanode.create(right,
  1514. ccallparanode.create(left,nil)));
  1515. left:=nil;
  1516. right:=nil;
  1517. { do we need to reverse the result }
  1518. if notnode then
  1519. result := cnotnode.create(result);
  1520. end;
  1521. {$endif cpufpemu}
  1522. function taddnode.pass_1 : tnode;
  1523. var
  1524. hp : tnode;
  1525. lt,rt : tnodetype;
  1526. rd,ld : tdef;
  1527. begin
  1528. result:=nil;
  1529. { first do the two subtrees }
  1530. firstpass(left);
  1531. firstpass(right);
  1532. if codegenerror then
  1533. exit;
  1534. { load easier access variables }
  1535. rd:=right.resulttype.def;
  1536. ld:=left.resulttype.def;
  1537. rt:=right.nodetype;
  1538. lt:=left.nodetype;
  1539. { int/int gives real/real! }
  1540. if nodetype=slashn then
  1541. begin
  1542. {$ifdef cpufpemu}
  1543. result := first_addfloat;
  1544. if assigned(result) then
  1545. exit;
  1546. {$endif cpufpemu}
  1547. expectloc:=LOC_FPUREGISTER;
  1548. { maybe we need an integer register to save }
  1549. { a reference }
  1550. if ((left.expectloc<>LOC_FPUREGISTER) or
  1551. (right.expectloc<>LOC_FPUREGISTER)) and
  1552. (left.registers32=right.registers32) then
  1553. calcregisters(self,1,1,0)
  1554. else
  1555. calcregisters(self,0,1,0);
  1556. { an add node always first loads both the left and the }
  1557. { right in the fpu before doing the calculation. However, }
  1558. { calcregisters(0,2,0) will overestimate the number of }
  1559. { necessary registers (it will make it 3 in case one of }
  1560. { the operands is already in the fpu) (JM) }
  1561. if ((left.expectloc<>LOC_FPUREGISTER) or
  1562. (right.expectloc<>LOC_FPUREGISTER)) and
  1563. (registersfpu < 2) then
  1564. inc(registersfpu);
  1565. end
  1566. { if both are orddefs then check sub types }
  1567. else if (ld.deftype=orddef) and (rd.deftype=orddef) then
  1568. begin
  1569. { 2 booleans ? }
  1570. if is_boolean(ld) and is_boolean(rd) then
  1571. begin
  1572. if not(cs_full_boolean_eval in aktlocalswitches) and
  1573. (nodetype in [andn,orn]) then
  1574. begin
  1575. expectloc:=LOC_JUMP;
  1576. calcregisters(self,0,0,0);
  1577. end
  1578. else
  1579. begin
  1580. expectloc:=LOC_FLAGS;
  1581. if (left.expectloc in [LOC_JUMP,LOC_FLAGS]) and
  1582. (left.expectloc in [LOC_JUMP,LOC_FLAGS]) then
  1583. calcregisters(self,2,0,0)
  1584. else
  1585. calcregisters(self,1,0,0);
  1586. end;
  1587. end
  1588. else
  1589. { Both are chars? only convert to shortstrings for addn }
  1590. if is_char(ld) then
  1591. begin
  1592. if nodetype=addn then
  1593. internalerror(200103291);
  1594. expectloc:=LOC_FLAGS;
  1595. calcregisters(self,1,0,0);
  1596. end
  1597. { is there a 64 bit type ? }
  1598. else if (torddef(ld).typ in [s64bit,u64bit,scurrency]) then
  1599. begin
  1600. result := first_add64bitint;
  1601. if assigned(result) then
  1602. exit;
  1603. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1604. expectloc:=LOC_REGISTER
  1605. else
  1606. expectloc:=LOC_JUMP;
  1607. calcregisters(self,2,0,0)
  1608. end
  1609. { is there a cardinal? }
  1610. else if (torddef(ld).typ=u32bit) then
  1611. begin
  1612. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1613. expectloc:=LOC_REGISTER
  1614. else
  1615. expectloc:=LOC_FLAGS;
  1616. calcregisters(self,1,0,0);
  1617. { for unsigned mul we need an extra register }
  1618. if nodetype=muln then
  1619. inc(registers32);
  1620. end
  1621. { generic s32bit conversion }
  1622. else
  1623. begin
  1624. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1625. expectloc:=LOC_REGISTER
  1626. else
  1627. expectloc:=LOC_FLAGS;
  1628. calcregisters(self,1,0,0);
  1629. end;
  1630. end
  1631. { left side a setdef, must be before string processing,
  1632. else array constructor can be seen as array of char (PFV) }
  1633. else if (ld.deftype=setdef) then
  1634. begin
  1635. if tsetdef(ld).settype=smallset then
  1636. begin
  1637. if nodetype in [ltn,lten,gtn,gten,equaln,unequaln] then
  1638. expectloc:=LOC_FLAGS
  1639. else
  1640. expectloc:=LOC_REGISTER;
  1641. { are we adding set elements ? }
  1642. if right.nodetype=setelementn then
  1643. calcregisters(self,2,0,0)
  1644. else
  1645. calcregisters(self,1,0,0);
  1646. end
  1647. else
  1648. begin
  1649. result := first_addset;
  1650. if assigned(result) then
  1651. exit;
  1652. expectloc:=LOC_CREFERENCE;
  1653. calcregisters(self,0,0,0);
  1654. { here we call SET... }
  1655. include(current_procinfo.flags,pi_do_call);
  1656. end;
  1657. end
  1658. { compare pchar by addresses like BP/Delphi }
  1659. else if is_pchar(ld) then
  1660. begin
  1661. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1662. expectloc:=LOC_REGISTER
  1663. else
  1664. expectloc:=LOC_FLAGS;
  1665. calcregisters(self,1,0,0);
  1666. end
  1667. { is one of the operands a string }
  1668. else if (ld.deftype=stringdef) then
  1669. begin
  1670. if is_widestring(ld) then
  1671. begin
  1672. { this is only for add, the comparisaion is handled later }
  1673. expectloc:=LOC_REGISTER;
  1674. end
  1675. else if is_ansistring(ld) then
  1676. begin
  1677. { this is only for add, the comparisaion is handled later }
  1678. expectloc:=LOC_REGISTER;
  1679. end
  1680. else if is_longstring(ld) then
  1681. begin
  1682. { this is only for add, the comparisaion is handled later }
  1683. expectloc:=LOC_REFERENCE;
  1684. end
  1685. else
  1686. begin
  1687. {$ifdef addstringopt}
  1688. { can create a call which isn't handled by callparatemp }
  1689. if canbeaddsstringcharoptnode(self) then
  1690. begin
  1691. hp := genaddsstringcharoptnode(self);
  1692. pass_1 := hp;
  1693. exit;
  1694. end
  1695. else
  1696. {$endif addstringopt}
  1697. begin
  1698. { Fix right to be shortstring }
  1699. if is_char(right.resulttype.def) then
  1700. begin
  1701. inserttypeconv(right,cshortstringtype);
  1702. firstpass(right);
  1703. end;
  1704. end;
  1705. {$ifdef addstringopt}
  1706. { can create a call which isn't handled by callparatemp }
  1707. if canbeaddsstringcsstringoptnode(self) then
  1708. begin
  1709. hp := genaddsstringcsstringoptnode(self);
  1710. pass_1 := hp;
  1711. exit;
  1712. end;
  1713. {$endif addstringopt}
  1714. end;
  1715. { otherwise, let addstring convert everything }
  1716. result := first_addstring;
  1717. exit;
  1718. end
  1719. { is one a real float ? }
  1720. else if (rd.deftype=floatdef) or (ld.deftype=floatdef) then
  1721. begin
  1722. {$ifdef cpufpemu}
  1723. result := first_addfloat;
  1724. if assigned(result) then
  1725. exit;
  1726. {$endif cpufpemu}
  1727. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1728. expectloc:=LOC_FPUREGISTER
  1729. else
  1730. expectloc:=LOC_FLAGS;
  1731. calcregisters(self,0,1,0);
  1732. { an add node always first loads both the left and the }
  1733. { right in the fpu before doing the calculation. However, }
  1734. { calcregisters(0,2,0) will overestimate the number of }
  1735. { necessary registers (it will make it 3 in case one of }
  1736. { the operands is already in the fpu) (JM) }
  1737. if ((left.expectloc<>LOC_FPUREGISTER) or
  1738. (right.expectloc<>LOC_FPUREGISTER)) and
  1739. (registersfpu < 2) then
  1740. inc(registersfpu);
  1741. end
  1742. { pointer comperation and subtraction }
  1743. else if (ld.deftype=pointerdef) then
  1744. begin
  1745. if nodetype in [addn,subn,muln,andn,orn,xorn] then
  1746. expectloc:=LOC_REGISTER
  1747. else
  1748. expectloc:=LOC_FLAGS;
  1749. calcregisters(self,1,0,0);
  1750. end
  1751. else if is_class_or_interface(ld) then
  1752. begin
  1753. expectloc:=LOC_FLAGS;
  1754. calcregisters(self,1,0,0);
  1755. end
  1756. else if (ld.deftype=classrefdef) then
  1757. begin
  1758. expectloc:=LOC_FLAGS;
  1759. calcregisters(self,1,0,0);
  1760. end
  1761. { support procvar=nil,procvar<>nil }
  1762. else if ((ld.deftype=procvardef) and (rt=niln)) or
  1763. ((rd.deftype=procvardef) and (lt=niln)) then
  1764. begin
  1765. expectloc:=LOC_FLAGS;
  1766. calcregisters(self,1,0,0);
  1767. end
  1768. {$ifdef SUPPORT_MMX}
  1769. { mmx support, this must be before the zero based array
  1770. check }
  1771. else if (cs_mmx in aktlocalswitches) and is_mmx_able_array(ld) and
  1772. is_mmx_able_array(rd) then
  1773. begin
  1774. expectloc:=LOC_MMXREGISTER;
  1775. calcregisters(self,0,0,1);
  1776. end
  1777. {$endif SUPPORT_MMX}
  1778. else if (rd.deftype=pointerdef) or (ld.deftype=pointerdef) then
  1779. begin
  1780. expectloc:=LOC_REGISTER;
  1781. calcregisters(self,1,0,0);
  1782. end
  1783. else if (rd.deftype=procvardef) and
  1784. (ld.deftype=procvardef) and
  1785. equal_defs(rd,ld) then
  1786. begin
  1787. expectloc:=LOC_FLAGS;
  1788. calcregisters(self,1,0,0);
  1789. end
  1790. else if (ld.deftype=enumdef) then
  1791. begin
  1792. expectloc:=LOC_FLAGS;
  1793. calcregisters(self,1,0,0);
  1794. end
  1795. {$ifdef SUPPORT_MMX}
  1796. else if (cs_mmx in aktlocalswitches) and
  1797. is_mmx_able_array(ld) and
  1798. is_mmx_able_array(rd) then
  1799. begin
  1800. expectloc:=LOC_MMXREGISTER;
  1801. calcregisters(self,0,0,1);
  1802. end
  1803. {$endif SUPPORT_MMX}
  1804. { the general solution is to convert to 32 bit int }
  1805. else
  1806. begin
  1807. expectloc:=LOC_REGISTER;
  1808. calcregisters(self,1,0,0);
  1809. end;
  1810. end;
  1811. {$ifdef state_tracking}
  1812. function Taddnode.track_state_pass(exec_known:boolean):boolean;
  1813. var factval:Tnode;
  1814. begin
  1815. track_state_pass:=false;
  1816. if left.track_state_pass(exec_known) then
  1817. begin
  1818. track_state_pass:=true;
  1819. left.resulttype.def:=nil;
  1820. do_resulttypepass(left);
  1821. end;
  1822. factval:=aktstate.find_fact(left);
  1823. if factval<>nil then
  1824. begin
  1825. track_state_pass:=true;
  1826. left.destroy;
  1827. left:=factval.getcopy;
  1828. end;
  1829. if right.track_state_pass(exec_known) then
  1830. begin
  1831. track_state_pass:=true;
  1832. right.resulttype.def:=nil;
  1833. do_resulttypepass(right);
  1834. end;
  1835. factval:=aktstate.find_fact(right);
  1836. if factval<>nil then
  1837. begin
  1838. track_state_pass:=true;
  1839. right.destroy;
  1840. right:=factval.getcopy;
  1841. end;
  1842. end;
  1843. {$endif}
  1844. begin
  1845. caddnode:=taddnode;
  1846. end.
  1847. {
  1848. $Log$
  1849. Revision 1.91 2003-05-26 21:15:18 peter
  1850. * disable string node optimizations for the moment
  1851. Revision 1.90 2003/05/26 19:38:28 peter
  1852. * generic fpc_shorstr_concat
  1853. + fpc_shortstr_append_shortstr optimization
  1854. Revision 1.89 2003/05/24 21:12:57 florian
  1855. * if something doesn't work with callparatemp, the define callparatemp
  1856. should be used because other processors with reigster calling conventions
  1857. depend on this as well
  1858. Revision 1.88 2003/05/23 22:57:38 jonas
  1859. - disable addoptnodes for powerpc, because they can generate calls in
  1860. pass_2, so -dcallparatemp can't detect them as nested calls
  1861. Revision 1.87 2003/04/27 11:21:32 peter
  1862. * aktprocdef renamed to current_procdef
  1863. * procinfo renamed to current_procinfo
  1864. * procinfo will now be stored in current_module so it can be
  1865. cleaned up properly
  1866. * gen_main_procsym changed to create_main_proc and release_main_proc
  1867. to also generate a tprocinfo structure
  1868. * fixed unit implicit initfinal
  1869. Revision 1.86 2003/04/26 09:12:55 peter
  1870. * add string returns in LOC_REFERENCE
  1871. Revision 1.85 2003/04/24 22:29:57 florian
  1872. * fixed a lot of PowerPC related stuff
  1873. Revision 1.84 2003/04/23 20:16:04 peter
  1874. + added currency support based on int64
  1875. + is_64bit for use in cg units instead of is_64bitint
  1876. * removed cgmessage from n386add, replace with internalerrors
  1877. Revision 1.83 2003/04/23 10:10:07 peter
  1878. * expectloc fixes
  1879. Revision 1.82 2003/04/22 23:50:22 peter
  1880. * firstpass uses expectloc
  1881. * checks if there are differences between the expectloc and
  1882. location.loc from secondpass in EXTDEBUG
  1883. Revision 1.81 2003/02/15 22:20:14 carl
  1884. * bugfix for generic calls to FPU emulation code
  1885. Revision 1.80 2003/02/12 22:10:07 carl
  1886. * load_frame_pointer is now generic
  1887. * change fpu emulation routine names
  1888. Revision 1.79 2003/01/02 22:19:54 peter
  1889. * support pchar-char operations converting to string first
  1890. * support chararray-nil
  1891. Revision 1.78 2002/12/11 22:41:03 peter
  1892. * stop processing assignment node when the binaryoverload generates
  1893. a codegenerror
  1894. Revision 1.77 2002/12/06 16:56:57 peter
  1895. * only compile cs_fp_emulation support when cpufpuemu is defined
  1896. * define cpufpuemu for m68k only
  1897. Revision 1.76 2002/11/30 21:32:24 carl
  1898. + Add loading of softfpu in emulation mode
  1899. + Correct routine call for softfpu
  1900. * Extended type must also be defined even with softfpu
  1901. Revision 1.75 2002/11/27 13:11:38 peter
  1902. * more currency fixes, taddcurr runs now successfull
  1903. Revision 1.74 2002/11/27 11:28:40 peter
  1904. * when both flaottypes are the same then handle the addnode using
  1905. that floattype instead of bestrealtype
  1906. Revision 1.73 2002/11/25 18:43:32 carl
  1907. - removed the invalid if <> checking (Delphi is strange on this)
  1908. + implemented abstract warning on instance creation of class with
  1909. abstract methods.
  1910. * some error message cleanups
  1911. Revision 1.72 2002/11/25 17:43:17 peter
  1912. * splitted defbase in defutil,symutil,defcmp
  1913. * merged isconvertable and is_equal into compare_defs(_ext)
  1914. * made operator search faster by walking the list only once
  1915. Revision 1.71 2002/11/23 22:50:06 carl
  1916. * some small speed optimizations
  1917. + added several new warnings/hints
  1918. Revision 1.70 2002/11/16 14:20:22 peter
  1919. * fix tbs0417
  1920. Revision 1.69 2002/11/15 01:58:50 peter
  1921. * merged changes from 1.0.7 up to 04-11
  1922. - -V option for generating bug report tracing
  1923. - more tracing for option parsing
  1924. - errors for cdecl and high()
  1925. - win32 import stabs
  1926. - win32 records<=8 are returned in eax:edx (turned off by default)
  1927. - heaptrc update
  1928. - more info for temp management in .s file with EXTDEBUG
  1929. Revision 1.68 2002/10/08 16:50:43 jonas
  1930. * fixed web bug 2136
  1931. Revision 1.67 2002/10/05 00:47:03 peter
  1932. * support dynamicarray<>nil
  1933. Revision 1.66 2002/10/04 21:19:28 jonas
  1934. * fixed web bug 2139: checking for division by zero fixed
  1935. Revision 1.65 2002/09/07 15:25:02 peter
  1936. * old logs removed and tabs fixed
  1937. Revision 1.64 2002/09/07 12:16:05 carl
  1938. * second part bug report 1996 fix, testrange in cordconstnode
  1939. only called if option is set (also make parsing a tiny faster)
  1940. Revision 1.63 2002/09/04 19:32:56 jonas
  1941. * changed some ctypeconvnode/toggleflag(nf_explizit) combo's to
  1942. ctypeconvnode.create_explicit() statements
  1943. Revision 1.62 2002/08/17 09:23:34 florian
  1944. * first part of current_procinfo rewrite
  1945. Revision 1.61 2002/08/15 15:15:55 carl
  1946. * jmpbuf size allocation for exceptions is now cpu specific (as it should)
  1947. * more generic nodes for maths
  1948. * several fixes for better m68k support
  1949. Revision 1.60 2002/08/12 15:08:39 carl
  1950. + stab register indexes for powerpc (moved from gdb to cpubase)
  1951. + tprocessor enumeration moved to cpuinfo
  1952. + linker in target_info is now a class
  1953. * many many updates for m68k (will soon start to compile)
  1954. - removed some ifdef or correct them for correct cpu
  1955. Revision 1.59 2002/08/02 07:44:30 jonas
  1956. * made assigned() handling generic
  1957. * add nodes now can also evaluate constant expressions at compile time
  1958. that contain nil nodes
  1959. Revision 1.58 2002/07/26 11:17:52 jonas
  1960. * the optimization of converting a multiplication with a power of two to
  1961. a shl is moved from n386add/secondpass to nadd/resulttypepass
  1962. Revision 1.57 2002/07/23 13:08:16 jonas
  1963. * fixed constant set evaluation of new set handling for non-commutative
  1964. operators
  1965. Revision 1.56 2002/07/23 12:34:29 daniel
  1966. * Readded old set code. To use it define 'oldset'. Activated by default
  1967. for ppc.
  1968. Revision 1.55 2002/07/22 11:48:04 daniel
  1969. * Sets are now internally sets.
  1970. Revision 1.54 2002/07/20 11:57:53 florian
  1971. * types.pas renamed to defbase.pas because D6 contains a types
  1972. unit so this would conflicts if D6 programms are compiled
  1973. + Willamette/SSE2 instructions to assembler added
  1974. Revision 1.53 2002/07/19 11:41:34 daniel
  1975. * State tracker work
  1976. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1977. allows the state tracker to change while nodes automatically into
  1978. repeat nodes.
  1979. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1980. 'not(a>b)' is optimized into 'a<=b'.
  1981. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1982. by removing the notn and later switchting the true and falselabels. The
  1983. same is done with 'repeat until not a'.
  1984. Revision 1.52 2002/07/14 18:00:43 daniel
  1985. + Added the beginning of a state tracker. This will track the values of
  1986. variables through procedures and optimize things away.
  1987. Revision 1.51 2002/05/18 13:34:08 peter
  1988. * readded missing revisions
  1989. Revision 1.50 2002/05/16 19:46:37 carl
  1990. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1991. + try to fix temp allocation (still in ifdef)
  1992. + generic constructor calls
  1993. + start of tassembler / tmodulebase class cleanup
  1994. Revision 1.48 2002/05/13 19:54:36 peter
  1995. * removed n386ld and n386util units
  1996. * maybe_save/maybe_restore added instead of the old maybe_push
  1997. Revision 1.47 2002/05/12 16:53:06 peter
  1998. * moved entry and exitcode to ncgutil and cgobj
  1999. * foreach gets extra argument for passing local data to the
  2000. iterator function
  2001. * -CR checks also class typecasts at runtime by changing them
  2002. into as
  2003. * fixed compiler to cycle with the -CR option
  2004. * fixed stabs with elf writer, finally the global variables can
  2005. be watched
  2006. * removed a lot of routines from cga unit and replaced them by
  2007. calls to cgobj
  2008. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  2009. u32bit then the other is typecasted also to u32bit without giving
  2010. a rangecheck warning/error.
  2011. * fixed pascal calling method with reversing also the high tree in
  2012. the parast, detected by tcalcst3 test
  2013. Revision 1.46 2002/04/23 19:16:34 peter
  2014. * add pinline unit that inserts compiler supported functions using
  2015. one or more statements
  2016. * moved finalize and setlength from ninl to pinline
  2017. Revision 1.45 2002/04/04 19:05:56 peter
  2018. * removed unused units
  2019. * use tlocation.size in cg.a_*loc*() routines
  2020. Revision 1.44 2002/04/02 17:11:28 peter
  2021. * tlocation,treference update
  2022. * LOC_CONSTANT added for better constant handling
  2023. * secondadd splitted in multiple routines
  2024. * location_force_reg added for loading a location to a register
  2025. of a specified size
  2026. * secondassignment parses now first the right and then the left node
  2027. (this is compatible with Kylix). This saves a lot of push/pop especially
  2028. with string operations
  2029. * adapted some routines to use the new cg methods
  2030. }