tcmat.pas 17 KB

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