tcmat.pas 17 KB

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