nadd.pas 85 KB

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