tcmat.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. Type checking and register allocation for math 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 tcmat;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. tree;
  23. procedure firstmoddiv(var p : ptree);
  24. procedure firstshlshr(var p : ptree);
  25. procedure firstunaryminus(var p : ptree);
  26. procedure firstnot(var p : ptree);
  27. implementation
  28. uses
  29. globtype,systems,tokens,
  30. cobjects,verbose,globals,
  31. symconst,symtable,aasm,types,
  32. htypechk,pass_1,cpubase,cpuinfo,
  33. {$ifdef newcg}
  34. cgbase,
  35. {$else newcg}
  36. hcodegen,
  37. {$endif newcg}
  38. { for isbinaryoverloaded function }
  39. tcadd;
  40. {*****************************************************************************
  41. FirstModDiv
  42. *****************************************************************************}
  43. procedure firstmoddiv(var p : ptree);
  44. var
  45. t : ptree;
  46. rv,lv : tconstexprint;
  47. rd,ld : pdef;
  48. begin
  49. firstpass(p^.left);
  50. set_varstate(p^.left,true);
  51. firstpass(p^.right);
  52. set_varstate(p^.right,true);
  53. if codegenerror then
  54. exit;
  55. if isbinaryoverloaded(p) then
  56. exit;
  57. { check for division by zero }
  58. rv:=p^.right^.value;
  59. lv:=p^.left^.value;
  60. if is_constintnode(p^.right) and (rv=0) then
  61. begin
  62. Message(parser_e_division_by_zero);
  63. { recover }
  64. rv:=1;
  65. end;
  66. if is_constintnode(p^.left) and is_constintnode(p^.right) then
  67. begin
  68. case p^.treetype of
  69. modn:
  70. t:=genintconstnode(lv mod rv);
  71. divn:
  72. t:=genintconstnode(lv div rv);
  73. end;
  74. disposetree(p);
  75. firstpass(t);
  76. p:=t;
  77. exit;
  78. end;
  79. if (p^.left^.resulttype^.deftype=orddef) and (p^.right^.resulttype^.deftype=orddef) and
  80. (is_64bitint(p^.left^.resulttype) or is_64bitint(p^.right^.resulttype)) then
  81. begin
  82. rd:=p^.right^.resulttype;
  83. ld:=p^.left^.resulttype;
  84. if (porddef(rd)^.typ=s64bit) or (porddef(ld)^.typ=s64bit) then
  85. begin
  86. if (porddef(ld)^.typ<>s64bit) then
  87. begin
  88. p^.left:=gentypeconvnode(p^.left,cs64bitdef);
  89. firstpass(p^.left);
  90. end;
  91. if (porddef(rd)^.typ<>s64bit) then
  92. begin
  93. p^.right:=gentypeconvnode(p^.right,cs64bitdef);
  94. firstpass(p^.right);
  95. end;
  96. calcregisters(p,2,0,0);
  97. end
  98. else if (porddef(rd)^.typ=u64bit) or (porddef(ld)^.typ=u64bit) then
  99. begin
  100. if (porddef(ld)^.typ<>u64bit) then
  101. begin
  102. p^.left:=gentypeconvnode(p^.left,cu64bitdef);
  103. firstpass(p^.left);
  104. end;
  105. if (porddef(rd)^.typ<>u64bit) then
  106. begin
  107. p^.right:=gentypeconvnode(p^.right,cu64bitdef);
  108. firstpass(p^.right);
  109. end;
  110. calcregisters(p,2,0,0);
  111. end;
  112. p^.resulttype:=p^.left^.resulttype;
  113. end
  114. else
  115. begin
  116. if not(p^.right^.resulttype^.deftype=orddef) or
  117. not(porddef(p^.right^.resulttype)^.typ in [s32bit,u32bit]) then
  118. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  119. if not(p^.left^.resulttype^.deftype=orddef) or
  120. not(porddef(p^.left^.resulttype)^.typ in [s32bit,u32bit]) then
  121. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  122. firstpass(p^.left);
  123. firstpass(p^.right);
  124. {$ifdef cardinalmulfix}
  125. { if we divide a u32bit by a positive constant, the result is also u32bit (JM) }
  126. if (p^.left^.resulttype^.deftype = orddef) and
  127. (p^.left^.resulttype^.deftype = orddef) then
  128. begin
  129. if (porddef(p^.left^.resulttype)^.typ = u32bit) and
  130. is_constintnode(p^.right) and
  131. { (porddef(p^.right^.resulttype)^.typ <> u32bit) and}
  132. (p^.right^.value > 0) then
  133. begin
  134. p^.right := gentypeconvnode(p^.right,u32bitdef);
  135. firstpass(p^.right);
  136. end;
  137. { adjust also the left resulttype if necessary }
  138. if (porddef(p^.right^.resulttype)^.typ = u32bit) and
  139. is_constintnode(p^.left) and
  140. { (porddef(p^.left^.resulttype)^.typ <> u32bit) and}
  141. (p^.left^.value > 0) then
  142. begin
  143. p^.left := gentypeconvnode(p^.left,u32bitdef);
  144. firstpass(p^.left);
  145. end;
  146. end;
  147. {$endif cardinalmulfix}
  148. { the resulttype depends on the right side, because the left becomes }
  149. { always 64 bit }
  150. p^.resulttype:=p^.right^.resulttype;
  151. if codegenerror then
  152. exit;
  153. left_right_max(p);
  154. if p^.left^.registers32<=p^.right^.registers32 then
  155. inc(p^.registers32);
  156. end;
  157. p^.location.loc:=LOC_REGISTER;
  158. end;
  159. {*****************************************************************************
  160. FirstShlShr
  161. *****************************************************************************}
  162. procedure firstshlshr(var p : ptree);
  163. var
  164. t : ptree;
  165. regs : longint;
  166. begin
  167. firstpass(p^.left);
  168. set_varstate(p^.left,true);
  169. firstpass(p^.right);
  170. set_varstate(p^.right,true);
  171. if codegenerror then
  172. exit;
  173. if isbinaryoverloaded(p) then
  174. exit;
  175. if is_constintnode(p^.left) and is_constintnode(p^.right) then
  176. begin
  177. case p^.treetype of
  178. shrn:
  179. t:=genintconstnode(p^.left^.value shr p^.right^.value);
  180. shln:
  181. t:=genintconstnode(p^.left^.value shl p^.right^.value);
  182. end;
  183. disposetree(p);
  184. firstpass(t);
  185. p:=t;
  186. exit;
  187. end;
  188. { 64 bit ints have their own shift handling }
  189. if not(is_64bitint(p^.left^.resulttype)) then
  190. begin
  191. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  192. firstpass(p^.left);
  193. regs:=1;
  194. p^.resulttype:=s32bitdef;
  195. end
  196. else
  197. begin
  198. p^.resulttype:=p^.left^.resulttype;
  199. regs:=2;
  200. end;
  201. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  202. firstpass(p^.right);
  203. if codegenerror then
  204. exit;
  205. if (p^.right^.treetype<>ordconstn) then
  206. inc(regs);
  207. calcregisters(p,regs,0,0);
  208. p^.location.loc:=LOC_REGISTER;
  209. end;
  210. {*****************************************************************************
  211. FirstUnaryMinus
  212. *****************************************************************************}
  213. procedure firstunaryminus(var p : ptree);
  214. var
  215. t : ptree;
  216. minusdef : pprocdef;
  217. begin
  218. firstpass(p^.left);
  219. set_varstate(p^.left,true);
  220. p^.registers32:=p^.left^.registers32;
  221. p^.registersfpu:=p^.left^.registersfpu;
  222. {$ifdef SUPPORT_MMX}
  223. p^.registersmmx:=p^.left^.registersmmx;
  224. {$endif SUPPORT_MMX}
  225. p^.resulttype:=p^.left^.resulttype;
  226. if codegenerror then
  227. exit;
  228. if is_constintnode(p^.left) then
  229. begin
  230. t:=genintconstnode(-p^.left^.value);
  231. disposetree(p);
  232. firstpass(t);
  233. p:=t;
  234. exit;
  235. end;
  236. { nasm can not cope with negativ reals !! }
  237. if is_constrealnode(p^.left)
  238. {$ifdef i386}
  239. and not(aktoutputformat in [as_i386_nasmcoff,as_i386_nasmelf,as_i386_nasmobj])
  240. {$endif i386}
  241. then
  242. begin
  243. t:=genrealconstnode(-p^.left^.value_real,bestrealdef^);
  244. disposetree(p);
  245. firstpass(t);
  246. p:=t;
  247. exit;
  248. end;
  249. if (p^.left^.resulttype^.deftype=floatdef) then
  250. begin
  251. if pfloatdef(p^.left^.resulttype)^.typ=f32bit then
  252. begin
  253. if (p^.left^.location.loc<>LOC_REGISTER) and
  254. (p^.registers32<1) then
  255. p^.registers32:=1;
  256. p^.location.loc:=LOC_REGISTER;
  257. end
  258. else
  259. p^.location.loc:=LOC_FPU;
  260. end
  261. {$ifdef SUPPORT_MMX}
  262. else if (cs_mmx in aktlocalswitches) and
  263. is_mmx_able_array(p^.left^.resulttype) then
  264. begin
  265. if (p^.left^.location.loc<>LOC_MMXREGISTER) and
  266. (p^.registersmmx<1) then
  267. p^.registersmmx:=1;
  268. { if saturation is on, p^.left^.resulttype isn't
  269. "mmx able" (FK)
  270. if (cs_mmx_saturation in aktlocalswitches^) and
  271. (porddef(parraydef(p^.resulttype)^.definition)^.typ in
  272. [s32bit,u32bit]) then
  273. CGMessage(type_e_mismatch);
  274. }
  275. end
  276. {$endif SUPPORT_MMX}
  277. else if is_64bitint(p^.left^.resulttype) then
  278. begin
  279. firstpass(p^.left);
  280. p^.registersfpu:=p^.left^.registersfpu;
  281. {$ifdef SUPPORT_MMX}
  282. p^.registersmmx:=p^.left^.registersmmx;
  283. {$endif SUPPORT_MMX}
  284. p^.registers32:=p^.left^.registers32;
  285. if codegenerror then
  286. exit;
  287. if (p^.left^.location.loc<>LOC_REGISTER) and
  288. (p^.registers32<2) then
  289. p^.registers32:=2;
  290. p^.location.loc:=LOC_REGISTER;
  291. p^.resulttype:=p^.left^.resulttype;
  292. end
  293. else if (p^.left^.resulttype^.deftype=orddef) then
  294. begin
  295. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  296. firstpass(p^.left);
  297. p^.registersfpu:=p^.left^.registersfpu;
  298. {$ifdef SUPPORT_MMX}
  299. p^.registersmmx:=p^.left^.registersmmx;
  300. {$endif SUPPORT_MMX}
  301. p^.registers32:=p^.left^.registers32;
  302. if codegenerror then
  303. exit;
  304. if (p^.left^.location.loc<>LOC_REGISTER) and
  305. (p^.registers32<1) then
  306. p^.registers32:=1;
  307. p^.location.loc:=LOC_REGISTER;
  308. p^.resulttype:=p^.left^.resulttype;
  309. end
  310. else
  311. begin
  312. if assigned(overloaded_operators[_minus]) then
  313. minusdef:=overloaded_operators[_minus]^.definition
  314. else
  315. minusdef:=nil;
  316. while assigned(minusdef) do
  317. begin
  318. if is_equal(pparaitem(minusdef^.para^.first)^.paratype.def,p^.left^.resulttype) and
  319. (pparaitem(minusdef^.para^.first)^.next=nil) then
  320. begin
  321. t:=gencallnode(overloaded_operators[_minus],nil);
  322. t^.left:=gencallparanode(p^.left,nil);
  323. putnode(p);
  324. p:=t;
  325. firstpass(p);
  326. exit;
  327. end;
  328. minusdef:=minusdef^.nextoverloaded;
  329. end;
  330. CGMessage(type_e_mismatch);
  331. end;
  332. end;
  333. {*****************************************************************************
  334. FirstNot
  335. *****************************************************************************}
  336. procedure firstnot(var p : ptree);
  337. var
  338. t : ptree;
  339. notdef : pprocdef;
  340. begin
  341. firstpass(p^.left);
  342. set_varstate(p^.left,true);
  343. if codegenerror then
  344. exit;
  345. if (p^.left^.treetype=ordconstn) then
  346. begin
  347. if is_boolean(p^.left^.resulttype) then
  348. { here we do a boolena(byte(..)) type cast because }
  349. { boolean(<int64>) is buggy in 1.00 }
  350. t:=genordinalconstnode(byte(not(boolean(byte(p^.left^.value)))),p^.left^.resulttype)
  351. else
  352. t:=genordinalconstnode(not(p^.left^.value),p^.left^.resulttype);
  353. disposetree(p);
  354. firstpass(t);
  355. p:=t;
  356. exit;
  357. end;
  358. p^.resulttype:=p^.left^.resulttype;
  359. p^.location.loc:=p^.left^.location.loc;
  360. {$ifdef SUPPORT_MMX}
  361. p^.registersmmx:=p^.left^.registersmmx;
  362. {$endif SUPPORT_MMX}
  363. if is_boolean(p^.resulttype) then
  364. begin
  365. p^.registers32:=p^.left^.registers32;
  366. if (p^.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
  367. begin
  368. p^.location.loc:=LOC_REGISTER;
  369. if (p^.registers32<1) then
  370. p^.registers32:=1;
  371. end;
  372. { before loading it into flags we need to load it into
  373. a register thus 1 register is need PM }
  374. {$ifdef i386}
  375. if p^.left^.location.loc<>LOC_JUMP then
  376. p^.location.loc:=LOC_FLAGS;
  377. {$endif def i386}
  378. end
  379. else
  380. {$ifdef SUPPORT_MMX}
  381. if (cs_mmx in aktlocalswitches) and
  382. is_mmx_able_array(p^.left^.resulttype) then
  383. begin
  384. if (p^.left^.location.loc<>LOC_MMXREGISTER) and
  385. (p^.registersmmx<1) then
  386. p^.registersmmx:=1;
  387. end
  388. else
  389. {$endif SUPPORT_MMX}
  390. if is_64bitint(p^.left^.resulttype) then
  391. begin
  392. p^.registers32:=p^.left^.registers32;
  393. if (p^.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
  394. begin
  395. p^.location.loc:=LOC_REGISTER;
  396. if (p^.registers32<2) then
  397. p^.registers32:=2;
  398. end;
  399. end
  400. else if is_integer(p^.left^.resulttype) then
  401. begin
  402. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  403. firstpass(p^.left);
  404. if codegenerror then
  405. exit;
  406. p^.resulttype:=p^.left^.resulttype;
  407. p^.registers32:=p^.left^.registers32;
  408. {$ifdef SUPPORT_MMX}
  409. p^.registersmmx:=p^.left^.registersmmx;
  410. {$endif SUPPORT_MMX}
  411. if (p^.left^.location.loc<>LOC_REGISTER) and
  412. (p^.registers32<1) then
  413. p^.registers32:=1;
  414. p^.location.loc:=LOC_REGISTER;
  415. end
  416. else
  417. begin
  418. if assigned(overloaded_operators[_op_not]) then
  419. notdef:=overloaded_operators[_op_not]^.definition
  420. else
  421. notdef:=nil;
  422. while assigned(notdef) do
  423. begin
  424. if is_equal(pparaitem(notdef^.para^.first)^.paratype.def,p^.left^.resulttype) and
  425. (pparaitem(notdef^.para^.first)^.next=nil) then
  426. begin
  427. t:=gencallnode(overloaded_operators[_op_not],nil);
  428. t^.left:=gencallparanode(p^.left,nil);
  429. putnode(p);
  430. p:=t;
  431. firstpass(p);
  432. exit;
  433. end;
  434. notdef:=notdef^.nextoverloaded;
  435. end;
  436. CGMessage(type_e_mismatch);
  437. end;
  438. p^.registersfpu:=p^.left^.registersfpu;
  439. end;
  440. end.
  441. {
  442. $Log$
  443. Revision 1.5 2000-09-24 21:19:53 peter
  444. * delphi compile fixes
  445. Revision 1.4 2000/08/17 12:03:48 florian
  446. * fixed several problems with the int64 constants
  447. Revision 1.3 2000/08/16 13:06:07 florian
  448. + support of 64 bit integer constants
  449. Revision 1.2 2000/07/13 11:32:52 michael
  450. + removed logs
  451. }