nadd.pas 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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 defines.inc}
  20. interface
  21. uses
  22. node;
  23. type
  24. taddnode = class(tbinopnode)
  25. constructor create(tt : tnodetype;l,r : tnode);override;
  26. function pass_1 : tnode;override;
  27. function det_resulttype:tnode;override;
  28. end;
  29. var
  30. { caddnode is used to create nodes of the add type }
  31. { the virtual constructor allows to assign }
  32. { another class type to caddnode => processor }
  33. { specific node types can be created }
  34. caddnode : class of taddnode;
  35. implementation
  36. uses
  37. globtype,systems,
  38. cutils,verbose,globals,
  39. symconst,symtype,symdef,types,
  40. cpuinfo,
  41. {$ifdef newcg}
  42. cgbase,
  43. {$else newcg}
  44. hcodegen,
  45. {$endif newcg}
  46. htypechk,pass_1,
  47. nmat,ncnv,nld,ncon,nset,nopt,
  48. cpubase;
  49. {*****************************************************************************
  50. TADDNODE
  51. *****************************************************************************}
  52. {$ifdef fpc}
  53. {$maxfpuregisters 0}
  54. {$endif fpc}
  55. constructor taddnode.create(tt : tnodetype;l,r : tnode);
  56. begin
  57. inherited create(tt,l,r);
  58. end;
  59. function taddnode.det_resulttype:tnode;
  60. var
  61. hp : tnode;
  62. lt,rt : tnodetype;
  63. rd,ld : pdef;
  64. htype : ttype;
  65. begin
  66. result:=nil;
  67. { first do the two subtrees }
  68. resulttypepass(left);
  69. resulttypepass(right);
  70. { both left and right need to be valid }
  71. set_varstate(left,true);
  72. set_varstate(right,true);
  73. if codegenerror then
  74. exit;
  75. { load easier access variables }
  76. rd:=right.resulttype.def;
  77. ld:=left.resulttype.def;
  78. rt:=right.nodetype;
  79. lt:=left.nodetype;
  80. { convert array constructors to sets, because there is no other operator
  81. possible for array constructors }
  82. if is_array_constructor(ld) then
  83. begin
  84. arrayconstructor_to_set(tarrayconstructornode(left));
  85. resulttypepass(left);
  86. ld:=left.resulttype.def;
  87. end;
  88. if is_array_constructor(rd) then
  89. begin
  90. arrayconstructor_to_set(tarrayconstructornode(right));
  91. resulttypepass(right);
  92. rd:=right.resulttype.def;
  93. end;
  94. { allow operator overloading }
  95. hp:=self;
  96. if isbinaryoverloaded(hp) then
  97. begin
  98. resulttypepass(hp);
  99. result:=hp;
  100. exit;
  101. end;
  102. { but an int/int gives real/real! }
  103. if nodetype=slashn then
  104. begin
  105. CGMessage(type_h_use_div_for_int);
  106. inserttypeconv(right,pbestrealtype^);
  107. inserttypeconv(left,pbestrealtype^);
  108. end
  109. { if both are orddefs then check sub types }
  110. else if (ld^.deftype=orddef) and (rd^.deftype=orddef) then
  111. begin
  112. { 2 booleans? Make them equal to the largest boolean }
  113. if is_boolean(ld) and is_boolean(rd) then
  114. begin
  115. if porddef(left.resulttype.def)^.size>porddef(right.resulttype.def)^.size then
  116. begin
  117. inserttypeconv(right,left.resulttype);
  118. ttypeconvnode(right).convtype:=tc_bool_2_int;
  119. include(right.flags,nf_explizit);
  120. end
  121. else if porddef(left.resulttype.def)^.size<porddef(right.resulttype.def)^.size then
  122. begin
  123. inserttypeconv(left,right.resulttype);
  124. ttypeconvnode(left).convtype:=tc_bool_2_int;
  125. include(left.flags,nf_explizit);
  126. end
  127. end
  128. { Both are chars? }
  129. else if is_char(rd) and is_char(ld) then
  130. begin
  131. if nodetype=addn then
  132. begin
  133. resulttype:=cshortstringtype;
  134. if not(is_constcharnode(left) and is_constcharnode(right)) then
  135. begin
  136. inserttypeconv(left,cshortstringtype);
  137. hp := genaddsstringcharoptnode(self);
  138. resulttypepass(hp);
  139. result := hp;
  140. exit;
  141. end;
  142. end;
  143. end
  144. { is there a signed 64 bit type ? }
  145. else if ((porddef(rd)^.typ=s64bit) or (porddef(ld)^.typ=s64bit)) then
  146. begin
  147. if (porddef(ld)^.typ<>s64bit) then
  148. inserttypeconv(left,cs64bittype);
  149. if (porddef(rd)^.typ<>s64bit) then
  150. inserttypeconv(right,cs64bittype);
  151. end
  152. { is there a unsigned 64 bit type ? }
  153. else if ((porddef(rd)^.typ=u64bit) or (porddef(ld)^.typ=u64bit)) then
  154. begin
  155. if (porddef(ld)^.typ<>u64bit) then
  156. inserttypeconv(left,cu64bittype);
  157. if (porddef(rd)^.typ<>u64bit) then
  158. inserttypeconv(right,cu64bittype);
  159. end
  160. { is there a cardinal? }
  161. else if ((porddef(rd)^.typ=u32bit) or (porddef(ld)^.typ=u32bit)) then
  162. begin
  163. if is_signed(ld) and
  164. { then rd = u32bit }
  165. { convert positive constants to u32bit }
  166. not(is_constintnode(left) and
  167. (tordconstnode(left).value >= 0)) and
  168. { range/overflow checking on mixed signed/cardinal expressions }
  169. { is only possible if you convert everything to 64bit (JM) }
  170. ((aktlocalswitches * [cs_check_overflow,cs_check_range] <> []) and
  171. (nodetype in [addn,subn,muln])) then
  172. begin
  173. { perform the operation in 64bit }
  174. CGMessage(type_w_mixed_signed_unsigned);
  175. inserttypeconv(left,cs64bittype);
  176. inserttypeconv(right,cs64bittype);
  177. end
  178. else
  179. begin
  180. if is_signed(ld) and
  181. not(is_constintnode(left) and
  182. (tordconstnode(left).value >= 0)) and
  183. (cs_check_range in aktlocalswitches) then
  184. CGMessage(type_w_mixed_signed_unsigned2);
  185. inserttypeconv(left,u32bittype);
  186. if is_signed(rd) and
  187. { then ld = u32bit }
  188. { convert positive constants to u32bit }
  189. not(is_constintnode(right) and
  190. (tordconstnode(right).value >= 0)) and
  191. ((aktlocalswitches * [cs_check_overflow,cs_check_range] <> []) and
  192. (nodetype in [addn,subn,muln])) then
  193. begin
  194. { perform the operation in 64bit }
  195. CGMessage(type_w_mixed_signed_unsigned);
  196. inserttypeconv(left,cs64bittype);
  197. inserttypeconv(right,cs64bittype);
  198. end
  199. else
  200. begin
  201. if is_signed(rd) and
  202. not(is_constintnode(right) and
  203. (tordconstnode(right).value >= 0)) and
  204. (cs_check_range in aktlocalswitches) then
  205. CGMessage(type_w_mixed_signed_unsigned2);
  206. inserttypeconv(right,u32bittype);
  207. end;
  208. end;
  209. end
  210. { generic ord conversion is s32bit }
  211. else
  212. begin
  213. inserttypeconv(right,s32bittype);
  214. inserttypeconv(left,s32bittype);
  215. end;
  216. end
  217. { left side a setdef, must be before string processing,
  218. else array constructor can be seen as array of char (PFV) }
  219. else if (ld^.deftype=setdef) then
  220. begin
  221. { trying to add a set element? }
  222. if (nodetype=addn) and (rd^.deftype<>setdef) then
  223. begin
  224. if (rt=setelementn) then
  225. begin
  226. if not(is_equal(psetdef(ld)^.elementtype.def,rd)) then
  227. CGMessage(type_e_set_element_are_not_comp);
  228. end
  229. else
  230. CGMessage(type_e_mismatch)
  231. end
  232. else
  233. begin
  234. if not(nodetype in [addn,subn,symdifn,muln,equaln,unequaln,lten,gten]) then
  235. CGMessage(type_e_set_operation_unknown);
  236. { right def must be a also be set }
  237. if (rd^.deftype<>setdef) or not(is_equal(rd,ld)) then
  238. CGMessage(type_e_set_element_are_not_comp);
  239. end;
  240. { ranges require normsets }
  241. if (psetdef(ld)^.settype=smallset) and
  242. (rt=setelementn) and
  243. assigned(tsetelementnode(right).right) then
  244. begin
  245. { generate a temporary normset def, it'll be destroyed
  246. when the symtable is unloaded }
  247. htype.setdef(new(psetdef,init(psetdef(ld)^.elementtype,255)));
  248. inserttypeconv(left,htype);
  249. end;
  250. end
  251. { compare pchar to char arrays by addresses like BP/Delphi }
  252. else if (is_pchar(ld) and is_chararray(rd)) or
  253. (is_pchar(rd) and is_chararray(ld)) then
  254. begin
  255. if is_chararray(rd) then
  256. inserttypeconv(right,left.resulttype)
  257. else
  258. inserttypeconv(left,right.resulttype);
  259. end
  260. { is one of the operands a string?,
  261. chararrays are also handled as strings (after conversion), also take
  262. care of chararray+chararray and chararray+char }
  263. else if (rd^.deftype=stringdef) or (ld^.deftype=stringdef) or
  264. ((is_chararray(rd) or is_char(rd)) and
  265. (is_chararray(ld) or is_char(ld))) then
  266. begin
  267. if is_widestring(rd) or is_widestring(ld) then
  268. begin
  269. if not(is_widestring(rd)) then
  270. inserttypeconv(right,cwidestringtype);
  271. if not(is_widestring(ld)) then
  272. inserttypeconv(left,cwidestringtype);
  273. end
  274. else if is_ansistring(rd) or is_ansistring(ld) then
  275. begin
  276. if not(is_ansistring(rd)) then
  277. inserttypeconv(right,cansistringtype);
  278. if not(is_ansistring(ld)) then
  279. inserttypeconv(left,cansistringtype);
  280. end
  281. else if is_longstring(rd) or is_longstring(ld) then
  282. begin
  283. if not(is_longstring(rd)) then
  284. inserttypeconv(right,clongstringtype);
  285. if not(is_longstring(ld)) then
  286. inserttypeconv(left,clongstringtype);
  287. location.loc:=LOC_MEM;
  288. end
  289. else
  290. begin
  291. if not(is_shortstring(ld)) then
  292. inserttypeconv(left,cshortstringtype);
  293. { don't convert char, that can be handled by the optimized node }
  294. if not(is_shortstring(rd) or is_char(rd)) then
  295. inserttypeconv(right,cshortstringtype);
  296. end;
  297. end
  298. { is one a real float ? }
  299. else if (rd^.deftype=floatdef) or (ld^.deftype=floatdef) then
  300. begin
  301. { convert both to bestreal }
  302. inserttypeconv(right,pbestrealtype^);
  303. inserttypeconv(left,pbestrealtype^);
  304. end
  305. { pointer comparision and subtraction }
  306. else if (rd^.deftype=pointerdef) and (ld^.deftype=pointerdef) then
  307. begin
  308. case nodetype of
  309. equaln,unequaln :
  310. begin
  311. if is_voidpointer(right.resulttype.def) then
  312. inserttypeconv(right,left.resulttype)
  313. else if is_voidpointer(left.resulttype.def) then
  314. inserttypeconv(left,right.resulttype)
  315. else if not(is_equal(ld,rd)) then
  316. CGMessage(type_e_mismatch);
  317. end;
  318. ltn,lten,gtn,gten:
  319. begin
  320. if (cs_extsyntax in aktmoduleswitches) then
  321. begin
  322. if is_voidpointer(right.resulttype.def) then
  323. inserttypeconv(right,left.resulttype)
  324. else if is_voidpointer(left.resulttype.def) then
  325. inserttypeconv(left,right.resulttype)
  326. else if not(is_equal(ld,rd)) then
  327. CGMessage(type_e_mismatch);
  328. end
  329. else
  330. CGMessage(type_e_mismatch);
  331. end;
  332. subn:
  333. begin
  334. if (cs_extsyntax in aktmoduleswitches) then
  335. begin
  336. if is_voidpointer(right.resulttype.def) then
  337. inserttypeconv(right,left.resulttype)
  338. else if is_voidpointer(left.resulttype.def) then
  339. inserttypeconv(left,right.resulttype)
  340. else if not(is_equal(ld,rd)) then
  341. CGMessage(type_e_mismatch);
  342. end
  343. else
  344. CGMessage(type_e_mismatch);
  345. resulttype:=s32bittype;
  346. exit;
  347. end;
  348. addn:
  349. begin
  350. if (cs_extsyntax in aktmoduleswitches) then
  351. begin
  352. if is_voidpointer(right.resulttype.def) then
  353. inserttypeconv(right,left.resulttype)
  354. else if is_voidpointer(left.resulttype.def) then
  355. inserttypeconv(left,right.resulttype)
  356. else if not(is_equal(ld,rd)) then
  357. CGMessage(type_e_mismatch);
  358. end
  359. else
  360. CGMessage(type_e_mismatch);
  361. resulttype:=s32bittype;
  362. exit;
  363. end;
  364. else
  365. CGMessage(type_e_mismatch);
  366. end;
  367. end
  368. { class or interface equation }
  369. else if is_class_or_interface(rd) or is_class_or_interface(ld) then
  370. begin
  371. if is_class_or_interface(rd) and is_class_or_interface(ld) then
  372. begin
  373. if pobjectdef(rd)^.is_related(pobjectdef(ld)) then
  374. inserttypeconv(right,left.resulttype)
  375. else
  376. inserttypeconv(left,right.resulttype);
  377. end
  378. else if is_class_or_interface(rd) then
  379. inserttypeconv(left,right.resulttype)
  380. else
  381. inserttypeconv(right,left.resulttype);
  382. if not(nodetype in [equaln,unequaln]) then
  383. CGMessage(type_e_mismatch);
  384. end
  385. else if (rd^.deftype=classrefdef) and (ld^.deftype=classrefdef) then
  386. begin
  387. if pobjectdef(pclassrefdef(rd)^.pointertype.def)^.is_related(
  388. pobjectdef(pclassrefdef(ld)^.pointertype.def)) then
  389. inserttypeconv(right,left.resulttype)
  390. else
  391. inserttypeconv(left,right.resulttype);
  392. if not(nodetype in [equaln,unequaln]) then
  393. CGMessage(type_e_mismatch);
  394. end
  395. { allows comperasion with nil pointer }
  396. else if is_class_or_interface(rd) or (rd^.deftype=classrefdef) then
  397. begin
  398. inserttypeconv(left,right.resulttype);
  399. if not(nodetype in [equaln,unequaln]) then
  400. CGMessage(type_e_mismatch);
  401. end
  402. else if is_class_or_interface(ld) or (ld^.deftype=classrefdef) then
  403. begin
  404. inserttypeconv(right,left.resulttype);
  405. if not(nodetype in [equaln,unequaln]) then
  406. CGMessage(type_e_mismatch);
  407. end
  408. { support procvar=nil,procvar<>nil }
  409. else if ((ld^.deftype=procvardef) and (rt=niln)) or
  410. ((rd^.deftype=procvardef) and (lt=niln)) then
  411. begin
  412. if not(nodetype in [equaln,unequaln]) then
  413. CGMessage(type_e_mismatch);
  414. end
  415. {$ifdef SUPPORT_MMX}
  416. { mmx support, this must be before the zero based array
  417. check }
  418. else if (cs_mmx in aktlocalswitches) and
  419. is_mmx_able_array(ld) and
  420. is_mmx_able_array(rd) and
  421. is_equal(ld,rd) then
  422. begin
  423. case nodetype of
  424. addn,subn,xorn,orn,andn:
  425. ;
  426. { mul is a little bit restricted }
  427. muln:
  428. if not(mmx_type(ld) in [mmxu16bit,mmxs16bit,mmxfixed16]) then
  429. CGMessage(type_e_mismatch);
  430. else
  431. CGMessage(type_e_mismatch);
  432. end;
  433. end
  434. {$endif SUPPORT_MMX}
  435. { this is a little bit dangerous, also the left type }
  436. { pointer to should be checked! This broke the mmx support }
  437. else if (rd^.deftype=pointerdef) or is_zero_based_array(rd) then
  438. begin
  439. if is_zero_based_array(rd) then
  440. begin
  441. resulttype.setdef(new(ppointerdef,init(parraydef(rd)^.elementtype)));
  442. inserttypeconv(right,resulttype);
  443. end;
  444. inserttypeconv(left,s32bittype);
  445. if nodetype=addn then
  446. begin
  447. if not(cs_extsyntax in aktmoduleswitches) or
  448. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  449. CGMessage(type_e_mismatch);
  450. if (rd^.deftype=pointerdef) and
  451. (ppointerdef(rd)^.pointertype.def^.size>1) then
  452. left:=caddnode.create(muln,left,cordconstnode.create(ppointerdef(rd)^.pointertype.def^.size,s32bittype));
  453. end
  454. else
  455. CGMessage(type_e_mismatch);
  456. end
  457. else if (ld^.deftype=pointerdef) or is_zero_based_array(ld) then
  458. begin
  459. if is_zero_based_array(ld) then
  460. begin
  461. resulttype.setdef(new(ppointerdef,init(parraydef(ld)^.elementtype)));
  462. inserttypeconv(left,resulttype);
  463. end;
  464. inserttypeconv(right,s32bittype);
  465. if nodetype in [addn,subn] then
  466. begin
  467. if not(cs_extsyntax in aktmoduleswitches) or
  468. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  469. CGMessage(type_e_mismatch);
  470. if (ld^.deftype=pointerdef) and
  471. (ppointerdef(ld)^.pointertype.def^.size>1) then
  472. right:=caddnode.create(muln,right,cordconstnode.create(ppointerdef(ld)^.pointertype.def^.size,s32bittype));
  473. end
  474. else
  475. CGMessage(type_e_mismatch);
  476. end
  477. else if (rd^.deftype=procvardef) and (ld^.deftype=procvardef) and is_equal(rd,ld) then
  478. begin
  479. if not (nodetype in [equaln,unequaln]) then
  480. CGMessage(type_e_mismatch);
  481. end
  482. { enums }
  483. else if (ld^.deftype=enumdef) and (rd^.deftype=enumdef) then
  484. begin
  485. if not(is_equal(ld,rd)) then
  486. inserttypeconv(right,left.resulttype);
  487. if not(nodetype in [equaln,unequaln,ltn,lten,gtn,gten]) then
  488. CGMessage(type_e_mismatch);
  489. end
  490. { generic conversion }
  491. else
  492. begin
  493. {$ifdef EXTDEBUG}
  494. Comment(V_Warning,'Generic conversion to s32bit');
  495. {$endif}
  496. inserttypeconv(right,s32bittype);
  497. inserttypeconv(left,s32bittype);
  498. end;
  499. { set resulttype if not already done }
  500. if not assigned(resulttype.def) then
  501. begin
  502. case nodetype of
  503. ltn,lten,gtn,gten,equaln,unequaln :
  504. resulttype:=booltype;
  505. slashn :
  506. resulttype:=pbestrealtype^;
  507. addn:
  508. begin
  509. { for strings, return is always a 255 char string }
  510. if is_shortstring(left.resulttype.def) then
  511. resulttype:=cshortstringtype
  512. else
  513. resulttype:=left.resulttype;
  514. end;
  515. else
  516. resulttype:=left.resulttype;
  517. end;
  518. end;
  519. end;
  520. function taddnode.pass_1 : tnode;
  521. var
  522. t,hp : tnode;
  523. ot,
  524. lt,rt : tnodetype;
  525. rv,lv : tconstexprint;
  526. rvd,lvd : bestreal;
  527. rd,ld : pdef;
  528. concatstrings : boolean;
  529. { to evalute const sets }
  530. resultset : pconstset;
  531. i : longint;
  532. b : boolean;
  533. s1,s2 : pchar;
  534. l1,l2 : longint;
  535. begin
  536. result:=nil;
  537. { first do the two subtrees }
  538. firstpass(left);
  539. firstpass(right);
  540. if codegenerror then
  541. exit;
  542. { load easier access variables }
  543. rd:=right.resulttype.def;
  544. ld:=left.resulttype.def;
  545. rt:=right.nodetype;
  546. lt:=left.nodetype;
  547. { both are int constants }
  548. if (((is_constintnode(left) and is_constintnode(right)) or
  549. (is_constboolnode(left) and is_constboolnode(right) and
  550. (nodetype in [ltn,lten,gtn,gten,equaln,unequaln,andn,xorn,orn])))) or
  551. { support pointer arithmetics on constants (JM) }
  552. ((lt = pointerconstn) and is_constintnode(right) and
  553. (nodetype in [addn,subn])) or
  554. ((lt = pointerconstn) and (rt = pointerconstn) and
  555. (nodetype in [ltn,lten,gtn,gten,equaln,unequaln,subn])) then
  556. begin
  557. if (lt = ordconstn) then
  558. lv:=tordconstnode(left).value
  559. else
  560. lv:=tpointerconstnode(left).value;
  561. if (rt = ordconstn) then
  562. rv:=tordconstnode(right).value
  563. else
  564. rv:=tpointerconstnode(right).value;
  565. if (lt = pointerconstn) and
  566. (rt <> pointerconstn) then
  567. rv := rv * ppointerdef(left.resulttype.def)^.pointertype.def^.size;
  568. if (rt = pointerconstn) and
  569. (lt <> pointerconstn) then
  570. lv := lv * ppointerdef(right.resulttype.def)^.pointertype.def^.size;
  571. case nodetype of
  572. addn :
  573. if (lt <> pointerconstn) then
  574. t := cordconstnode.create(lv+rv,resulttype)
  575. else
  576. t := cpointerconstnode.create(lv+rv,resulttype);
  577. subn :
  578. if (lt <> pointerconstn) or (rt = pointerconstn) then
  579. t := cordconstnode.create(lv-rv,resulttype)
  580. else
  581. t := cpointerconstnode.create(lv-rv,resulttype);
  582. muln :
  583. t:=cordconstnode.create(lv*rv,resulttype);
  584. xorn :
  585. t:=cordconstnode.create(lv xor rv,resulttype);
  586. orn :
  587. t:=cordconstnode.create(lv or rv,resulttype);
  588. andn :
  589. t:=cordconstnode.create(lv and rv,resulttype);
  590. ltn :
  591. t:=cordconstnode.create(ord(lv<rv),resulttype);
  592. lten :
  593. t:=cordconstnode.create(ord(lv<=rv),resulttype);
  594. gtn :
  595. t:=cordconstnode.create(ord(lv>rv),resulttype);
  596. gten :
  597. t:=cordconstnode.create(ord(lv>=rv),resulttype);
  598. equaln :
  599. t:=cordconstnode.create(ord(lv=rv),resulttype);
  600. unequaln :
  601. t:=cordconstnode.create(ord(lv<>rv),resulttype);
  602. slashn :
  603. begin
  604. { int/int becomes a real }
  605. if int(rv)=0 then
  606. begin
  607. Message(parser_e_invalid_float_operation);
  608. t:=crealconstnode.create(0,resulttype);
  609. end
  610. else
  611. t:=crealconstnode.create(int(lv)/int(rv),resulttype);
  612. end;
  613. else
  614. CGMessage(type_e_mismatch);
  615. end;
  616. firstpass(t);
  617. result:=t;
  618. exit;
  619. end;
  620. { both real constants ? }
  621. if (lt=realconstn) and (rt=realconstn) then
  622. begin
  623. lvd:=trealconstnode(left).value_real;
  624. rvd:=trealconstnode(right).value_real;
  625. case nodetype of
  626. addn :
  627. t:=crealconstnode.create(lvd+rvd,pbestrealtype^);
  628. subn :
  629. t:=crealconstnode.create(lvd-rvd,pbestrealtype^);
  630. muln :
  631. t:=crealconstnode.create(lvd*rvd,pbestrealtype^);
  632. starstarn,
  633. caretn :
  634. begin
  635. if lvd<0 then
  636. begin
  637. Message(parser_e_invalid_float_operation);
  638. t:=crealconstnode.create(0,pbestrealtype^);
  639. end
  640. else if lvd=0 then
  641. t:=crealconstnode.create(1.0,pbestrealtype^)
  642. else
  643. t:=crealconstnode.create(exp(ln(lvd)*rvd),pbestrealtype^);
  644. end;
  645. slashn :
  646. begin
  647. if rvd=0 then
  648. begin
  649. Message(parser_e_invalid_float_operation);
  650. t:=crealconstnode.create(0,pbestrealtype^);
  651. end
  652. else
  653. t:=crealconstnode.create(lvd/rvd,pbestrealtype^);
  654. end;
  655. ltn :
  656. t:=cordconstnode.create(ord(lvd<rvd),booltype);
  657. lten :
  658. t:=cordconstnode.create(ord(lvd<=rvd),booltype);
  659. gtn :
  660. t:=cordconstnode.create(ord(lvd>rvd),booltype);
  661. gten :
  662. t:=cordconstnode.create(ord(lvd>=rvd),booltype);
  663. equaln :
  664. t:=cordconstnode.create(ord(lvd=rvd),booltype);
  665. unequaln :
  666. t:=cordconstnode.create(ord(lvd<>rvd),booltype);
  667. else
  668. CGMessage(type_e_mismatch);
  669. end;
  670. firstpass(t);
  671. result:=t;
  672. exit;
  673. end;
  674. { concating strings ? }
  675. concatstrings:=false;
  676. s1:=nil;
  677. s2:=nil;
  678. if (lt=ordconstn) and (rt=ordconstn) and
  679. is_char(ld) and is_char(rd) then
  680. begin
  681. s1:=strpnew(char(byte(tordconstnode(left).value)));
  682. s2:=strpnew(char(byte(tordconstnode(right).value)));
  683. l1:=1;
  684. l2:=1;
  685. concatstrings:=true;
  686. end
  687. else
  688. if (lt=stringconstn) and (rt=ordconstn) and is_char(rd) then
  689. begin
  690. s1:=tstringconstnode(left).getpcharcopy;
  691. l1:=tstringconstnode(left).len;
  692. s2:=strpnew(char(byte(tordconstnode(right).value)));
  693. l2:=1;
  694. concatstrings:=true;
  695. end
  696. else
  697. if (lt=ordconstn) and (rt=stringconstn) and is_char(ld) then
  698. begin
  699. s1:=strpnew(char(byte(tordconstnode(left).value)));
  700. l1:=1;
  701. s2:=tstringconstnode(right).getpcharcopy;
  702. l2:=tstringconstnode(right).len;
  703. concatstrings:=true;
  704. end
  705. else if (lt=stringconstn) and (rt=stringconstn) then
  706. begin
  707. s1:=tstringconstnode(left).getpcharcopy;
  708. l1:=tstringconstnode(left).len;
  709. s2:=tstringconstnode(right).getpcharcopy;
  710. l2:=tstringconstnode(right).len;
  711. concatstrings:=true;
  712. end;
  713. if concatstrings then
  714. begin
  715. case nodetype of
  716. addn :
  717. t:=cstringconstnode.createpchar(concatansistrings(s1,s2,l1,l2),l1+l2);
  718. ltn :
  719. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)<0),booltype);
  720. lten :
  721. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)<=0),booltype);
  722. gtn :
  723. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)>0),booltype);
  724. gten :
  725. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)>=0),booltype);
  726. equaln :
  727. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)=0),booltype);
  728. unequaln :
  729. t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)<>0),booltype);
  730. end;
  731. ansistringdispose(s1,l1);
  732. ansistringdispose(s2,l2);
  733. firstpass(t);
  734. result:=t;
  735. exit;
  736. end;
  737. { set constant evaluation }
  738. if (right.nodetype=setconstn) and
  739. not assigned(tsetconstnode(right).left) and
  740. (left.nodetype=setconstn) and
  741. not assigned(tsetconstnode(left).left) then
  742. begin
  743. new(resultset);
  744. case nodetype of
  745. addn :
  746. begin
  747. for i:=0 to 31 do
  748. resultset^[i]:=tsetconstnode(right).value_set^[i] or tsetconstnode(left).value_set^[i];
  749. t:=csetconstnode.create(resultset,left.resulttype);
  750. end;
  751. muln :
  752. begin
  753. for i:=0 to 31 do
  754. resultset^[i]:=tsetconstnode(right).value_set^[i] and tsetconstnode(left).value_set^[i];
  755. t:=csetconstnode.create(resultset,left.resulttype);
  756. end;
  757. subn :
  758. begin
  759. for i:=0 to 31 do
  760. resultset^[i]:=tsetconstnode(left).value_set^[i] and not(tsetconstnode(right).value_set^[i]);
  761. t:=csetconstnode.create(resultset,left.resulttype);
  762. end;
  763. symdifn :
  764. begin
  765. for i:=0 to 31 do
  766. resultset^[i]:=tsetconstnode(left).value_set^[i] xor tsetconstnode(right).value_set^[i];
  767. t:=csetconstnode.create(resultset,left.resulttype);
  768. end;
  769. unequaln :
  770. begin
  771. b:=true;
  772. for i:=0 to 31 do
  773. if tsetconstnode(right).value_set^[i]=tsetconstnode(left).value_set^[i] then
  774. begin
  775. b:=false;
  776. break;
  777. end;
  778. t:=cordconstnode.create(ord(b),booltype);
  779. end;
  780. equaln :
  781. begin
  782. b:=true;
  783. for i:=0 to 31 do
  784. if tsetconstnode(right).value_set^[i]<>tsetconstnode(left).value_set^[i] then
  785. begin
  786. b:=false;
  787. break;
  788. end;
  789. t:=cordconstnode.create(ord(b),booltype);
  790. end;
  791. lten :
  792. begin
  793. b := true;
  794. For i := 0 to 31 Do
  795. If (tsetconstnode(right).value_set^[i] And tsetconstnode(left).value_set^[i]) <>
  796. tsetconstnode(left).value_set^[i] Then
  797. Begin
  798. b := false;
  799. Break
  800. End;
  801. t := cordconstnode.create(ord(b),booltype);
  802. End;
  803. gten :
  804. Begin
  805. b := true;
  806. For i := 0 to 31 Do
  807. If (tsetconstnode(left).value_set^[i] And tsetconstnode(right).value_set^[i]) <>
  808. tsetconstnode(right).value_set^[i] Then
  809. Begin
  810. b := false;
  811. Break
  812. End;
  813. t := cordconstnode.create(ord(b),booltype);
  814. End;
  815. end;
  816. dispose(resultset);
  817. firstpass(t);
  818. result:=t;
  819. exit;
  820. end;
  821. { int/int gives real/real! }
  822. if nodetype=slashn then
  823. begin
  824. { maybe we need an integer register to save }
  825. { a reference }
  826. if ((left.location.loc<>LOC_FPU) or
  827. (right.location.loc<>LOC_FPU)) and
  828. (left.registers32=right.registers32) then
  829. calcregisters(self,1,1,0)
  830. else
  831. calcregisters(self,0,1,0);
  832. location.loc:=LOC_FPU;
  833. end
  834. { if both are orddefs then check sub types }
  835. else if (ld^.deftype=orddef) and (rd^.deftype=orddef) then
  836. begin
  837. { 2 booleans ? }
  838. if is_boolean(ld) and is_boolean(rd) then
  839. begin
  840. if (cs_full_boolean_eval in aktlocalswitches) or
  841. (nodetype in [xorn,ltn,lten,gtn,gten]) then
  842. begin
  843. if (left.location.loc in [LOC_JUMP,LOC_FLAGS]) and
  844. (left.location.loc in [LOC_JUMP,LOC_FLAGS]) then
  845. calcregisters(self,2,0,0)
  846. else
  847. calcregisters(self,1,0,0);
  848. end
  849. else
  850. case nodetype of
  851. andn,
  852. orn:
  853. begin
  854. calcregisters(self,0,0,0);
  855. location.loc:=LOC_JUMP;
  856. end;
  857. unequaln,
  858. equaln:
  859. begin
  860. { Remove any compares with constants }
  861. if (left.nodetype=ordconstn) then
  862. begin
  863. hp:=right;
  864. b:=(tordconstnode(left).value<>0);
  865. ot:=nodetype;
  866. left.free;
  867. left:=nil;
  868. right:=nil;
  869. if (not(b) and (ot=equaln)) or
  870. (b and (ot=unequaln)) then
  871. begin
  872. hp:=cnotnode.create(hp);
  873. firstpass(hp);
  874. end;
  875. result:=hp;
  876. exit;
  877. end;
  878. if (right.nodetype=ordconstn) then
  879. begin
  880. hp:=left;
  881. b:=(tordconstnode(right).value<>0);
  882. ot:=nodetype;
  883. right.free;
  884. right:=nil;
  885. left:=nil;
  886. if (not(b) and (ot=equaln)) or
  887. (b and (ot=unequaln)) then
  888. begin
  889. hp:=cnotnode.create(hp);
  890. firstpass(hp);
  891. end;
  892. result:=hp;
  893. exit;
  894. end;
  895. if (left.location.loc in [LOC_JUMP,LOC_FLAGS]) and
  896. (left.location.loc in [LOC_JUMP,LOC_FLAGS]) then
  897. calcregisters(self,2,0,0)
  898. else
  899. calcregisters(self,1,0,0);
  900. end;
  901. else
  902. CGMessage(type_e_mismatch);
  903. end;
  904. end
  905. else
  906. { Both are chars? only convert to shortstrings for addn }
  907. if is_char(ld) then
  908. begin
  909. if nodetype=addn then
  910. internalerror(200103291);
  911. calcregisters(self,1,0,0);
  912. end
  913. { is there a 64 bit type ? }
  914. else if (porddef(ld)^.typ in [s64bit,u64bit]) then
  915. calcregisters(self,2,0,0)
  916. { is there a cardinal? }
  917. else if (porddef(ld)^.typ=u32bit) then
  918. begin
  919. calcregisters(self,1,0,0);
  920. { for unsigned mul we need an extra register }
  921. if nodetype=muln then
  922. inc(registers32);
  923. end
  924. { generic s32bit conversion }
  925. else
  926. calcregisters(self,1,0,0);
  927. end
  928. { left side a setdef, must be before string processing,
  929. else array constructor can be seen as array of char (PFV) }
  930. else if (ld^.deftype=setdef) then
  931. begin
  932. if psetdef(ld)^.settype=smallset then
  933. begin
  934. { are we adding set elements ? }
  935. if right.nodetype=setelementn then
  936. calcregisters(self,2,0,0)
  937. else
  938. calcregisters(self,1,0,0);
  939. location.loc:=LOC_REGISTER;
  940. end
  941. else
  942. begin
  943. calcregisters(self,0,0,0);
  944. { here we call SET... }
  945. procinfo^.flags:=procinfo^.flags or pi_do_call;
  946. location.loc:=LOC_MEM;
  947. end;
  948. end
  949. { compare pchar by addresses like BP/Delphi }
  950. else if is_pchar(ld) then
  951. begin
  952. location.loc:=LOC_REGISTER;
  953. calcregisters(self,1,0,0);
  954. end
  955. { is one of the operands a string }
  956. else if (ld^.deftype=stringdef) then
  957. begin
  958. if is_widestring(ld) then
  959. begin
  960. { we use reference counted widestrings so no fast exit here }
  961. procinfo^.no_fast_exit:=true;
  962. { this is only for add, the comparisaion is handled later }
  963. location.loc:=LOC_REGISTER;
  964. end
  965. else if is_ansistring(ld) then
  966. begin
  967. { we use ansistrings so no fast exit here }
  968. procinfo^.no_fast_exit:=true;
  969. { this is only for add, the comparisaion is handled later }
  970. location.loc:=LOC_REGISTER;
  971. end
  972. else if is_longstring(ld) then
  973. begin
  974. { this is only for add, the comparisaion is handled later }
  975. location.loc:=LOC_MEM;
  976. end
  977. else
  978. begin
  979. if canbeaddsstringcharoptnode(self) then
  980. begin
  981. hp := genaddsstringcharoptnode(self);
  982. firstpass(hp);
  983. pass_1 := hp;
  984. exit;
  985. end
  986. else
  987. begin
  988. { Fix right to be shortstring }
  989. if is_char(right.resulttype.def) then
  990. begin
  991. inserttypeconv(right,cshortstringtype);
  992. firstpass(right);
  993. end;
  994. end;
  995. if canbeaddsstringcsstringoptnode(self) then
  996. begin
  997. hp := genaddsstringcsstringoptnode(self);
  998. firstpass(hp);
  999. pass_1 := hp;
  1000. exit;
  1001. end;
  1002. { this is only for add, the comparisaion is handled later }
  1003. location.loc:=LOC_MEM;
  1004. end;
  1005. { here we call STRCONCAT or STRCMP or STRCOPY }
  1006. procinfo^.flags:=procinfo^.flags or pi_do_call;
  1007. if location.loc=LOC_MEM then
  1008. calcregisters(self,0,0,0)
  1009. else
  1010. calcregisters(self,1,0,0);
  1011. end
  1012. { is one a real float ? }
  1013. else if (rd^.deftype=floatdef) or (ld^.deftype=floatdef) then
  1014. begin
  1015. calcregisters(self,0,1,0);
  1016. location.loc:=LOC_FPU;
  1017. end
  1018. { pointer comperation and subtraction }
  1019. else if (ld^.deftype=pointerdef) then
  1020. begin
  1021. location.loc:=LOC_REGISTER;
  1022. calcregisters(self,1,0,0);
  1023. end
  1024. else if is_class_or_interface(ld) then
  1025. begin
  1026. location.loc:=LOC_REGISTER;
  1027. calcregisters(self,1,0,0);
  1028. end
  1029. else if (ld^.deftype=classrefdef) then
  1030. begin
  1031. location.loc:=LOC_REGISTER;
  1032. calcregisters(self,1,0,0);
  1033. end
  1034. { support procvar=nil,procvar<>nil }
  1035. else if ((ld^.deftype=procvardef) and (rt=niln)) or
  1036. ((rd^.deftype=procvardef) and (lt=niln)) then
  1037. begin
  1038. calcregisters(self,1,0,0);
  1039. location.loc:=LOC_REGISTER;
  1040. end
  1041. {$ifdef SUPPORT_MMX}
  1042. { mmx support, this must be before the zero based array
  1043. check }
  1044. else if (cs_mmx in aktlocalswitches) and is_mmx_able_array(ld) and
  1045. is_mmx_able_array(rd) then
  1046. begin
  1047. location.loc:=LOC_MMXREGISTER;
  1048. calcregisters(self,0,0,1);
  1049. end
  1050. {$endif SUPPORT_MMX}
  1051. else if (rd^.deftype=pointerdef) or (ld^.deftype=pointerdef) then
  1052. begin
  1053. location.loc:=LOC_REGISTER;
  1054. calcregisters(self,1,0,0);
  1055. end
  1056. else if (rd^.deftype=procvardef) and (ld^.deftype=procvardef) and is_equal(rd,ld) then
  1057. begin
  1058. calcregisters(self,1,0,0);
  1059. location.loc:=LOC_REGISTER;
  1060. end
  1061. else if (ld^.deftype=enumdef) then
  1062. begin
  1063. calcregisters(self,1,0,0);
  1064. end
  1065. {$ifdef SUPPORT_MMX}
  1066. else if (cs_mmx in aktlocalswitches) and
  1067. is_mmx_able_array(ld) and
  1068. is_mmx_able_array(rd) then
  1069. begin
  1070. location.loc:=LOC_MMXREGISTER;
  1071. calcregisters(self,0,0,1);
  1072. end
  1073. {$endif SUPPORT_MMX}
  1074. { the general solution is to convert to 32 bit int }
  1075. else
  1076. begin
  1077. calcregisters(self,1,0,0);
  1078. location.loc:=LOC_REGISTER;
  1079. end;
  1080. case nodetype of
  1081. ltn,lten,gtn,gten,equaln,unequaln:
  1082. begin
  1083. if is_64bitint(left.resulttype.def) then
  1084. location.loc:=LOC_JUMP
  1085. else
  1086. location.loc:=LOC_FLAGS;
  1087. end;
  1088. xorn:
  1089. begin
  1090. location.loc:=LOC_REGISTER;
  1091. end;
  1092. end;
  1093. end;
  1094. begin
  1095. caddnode:=taddnode;
  1096. end.
  1097. {
  1098. $Log$
  1099. Revision 1.23 2001-04-02 21:20:30 peter
  1100. * resulttype rewrite
  1101. Revision 1.22 2001/02/04 11:12:17 jonas
  1102. * fixed web bug 1377 & const pointer arithmtic
  1103. Revision 1.21 2001/01/14 22:13:13 peter
  1104. * constant calculation fixed. The type of the new constant is now
  1105. defined after the calculation is done. This should remove a lot
  1106. of wrong warnings (and errors with -Cr).
  1107. Revision 1.20 2000/12/31 11:14:10 jonas
  1108. + implemented/fixed docompare() mathods for all nodes (not tested)
  1109. + nopt.pas, nadd.pas, i386/n386opt.pas: optimized nodes for adding strings
  1110. and constant strings/chars together
  1111. * n386add.pas: don't copy temp strings (of size 256) to another temp string
  1112. when adding
  1113. Revision 1.19 2000/12/16 15:55:32 jonas
  1114. + warning when there is a chance to get a range check error because of
  1115. automatic type conversion to u32bit
  1116. * arithmetic operations with a cardinal and a signed operand are carried
  1117. out in 64bit when range checking is on ("merged" from fixes branch)
  1118. Revision 1.18 2000/11/29 00:30:31 florian
  1119. * unused units removed from uses clause
  1120. * some changes for widestrings
  1121. Revision 1.17 2000/11/20 15:30:42 jonas
  1122. * changed types of values used for constant expression evaluation to
  1123. tconstexprint
  1124. Revision 1.16 2000/11/13 11:30:55 florian
  1125. * some bugs with interfaces and NIL fixed
  1126. Revision 1.15 2000/11/04 14:25:20 florian
  1127. + merged Attila's changes for interfaces, not tested yet
  1128. Revision 1.14 2000/10/31 22:02:47 peter
  1129. * symtable splitted, no real code changes
  1130. Revision 1.13 2000/10/14 10:14:50 peter
  1131. * moehrendorf oct 2000 rewrite
  1132. Revision 1.12 2000/10/01 19:48:23 peter
  1133. * lot of compile updates for cg11
  1134. Revision 1.11 2000/09/30 16:08:45 peter
  1135. * more cg11 updates
  1136. Revision 1.10 2000/09/28 19:49:52 florian
  1137. *** empty log message ***
  1138. Revision 1.9 2000/09/27 21:33:22 florian
  1139. * finally nadd.pas compiles
  1140. Revision 1.8 2000/09/27 20:25:44 florian
  1141. * more stuff fixed
  1142. Revision 1.7 2000/09/27 18:14:31 florian
  1143. * fixed a lot of syntax errors in the n*.pas stuff
  1144. Revision 1.6 2000/09/24 15:06:19 peter
  1145. * use defines.inc
  1146. Revision 1.5 2000/09/22 22:42:52 florian
  1147. * more fixes
  1148. Revision 1.4 2000/09/21 12:22:42 jonas
  1149. * put piece of code between -dnewoptimizations2 since it wasn't
  1150. necessary otherwise
  1151. + support for full boolean evaluation (from tcadd)
  1152. Revision 1.3 2000/09/20 21:50:59 florian
  1153. * updated
  1154. Revision 1.2 2000/08/29 08:24:45 jonas
  1155. * some modifications to -dcardinalmulfix code
  1156. Revision 1.1 2000/08/26 12:24:20 florian
  1157. * initial release
  1158. }