nadd.pas 85 KB

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