nadd.pas 88 KB

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