tcmat.pas 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 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 firstumminus(var p : ptree);
  25. procedure firstnot(var p : ptree);
  26. implementation
  27. uses
  28. cobjects,verbose,globals,systems,
  29. symtable,aasm,types,
  30. hcodegen,htypechk,pass_1
  31. {$ifdef i386}
  32. ,i386
  33. {$endif}
  34. {$ifdef m68k}
  35. ,m68k
  36. {$endif}
  37. ;
  38. {*****************************************************************************
  39. FirstModDiv
  40. *****************************************************************************}
  41. procedure firstmoddiv(var p : ptree);
  42. var
  43. t : ptree;
  44. begin
  45. firstpass(p^.left);
  46. firstpass(p^.right);
  47. if codegenerror then
  48. exit;
  49. if is_constintnode(p^.left) and is_constintnode(p^.right) then
  50. begin
  51. case p^.treetype of
  52. modn : t:=genordinalconstnode(p^.left^.value mod p^.right^.value,s32bitdef);
  53. divn : t:=genordinalconstnode(p^.left^.value div p^.right^.value,s32bitdef);
  54. end;
  55. disposetree(p);
  56. firstpass(t);
  57. p:=t;
  58. exit;
  59. end;
  60. if not(p^.right^.resulttype^.deftype=orddef) or
  61. not(porddef(p^.right^.resulttype)^.typ in [s32bit,u32bit]) then
  62. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  63. if not(p^.left^.resulttype^.deftype=orddef) or
  64. not(porddef(p^.left^.resulttype)^.typ in [s32bit,u32bit]) then
  65. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  66. firstpass(p^.left);
  67. firstpass(p^.right);
  68. { the resulttype depends on the right side, because the left becomes }
  69. { always 64 bit }
  70. p^.resulttype:=p^.right^.resulttype;
  71. if codegenerror then
  72. exit;
  73. left_right_max(p);
  74. if p^.left^.registers32<=p^.right^.registers32 then
  75. inc(p^.registers32);
  76. p^.location.loc:=LOC_REGISTER;
  77. end;
  78. {*****************************************************************************
  79. FirstShlShr
  80. *****************************************************************************}
  81. procedure firstshlshr(var p : ptree);
  82. var
  83. t : ptree;
  84. begin
  85. firstpass(p^.left);
  86. firstpass(p^.right);
  87. if codegenerror then
  88. exit;
  89. if is_constintnode(p^.left) and is_constintnode(p^.right) then
  90. begin
  91. case p^.treetype of
  92. shrn : t:=genordinalconstnode(p^.left^.value shr p^.right^.value,s32bitdef);
  93. shln : t:=genordinalconstnode(p^.left^.value shl p^.right^.value,s32bitdef);
  94. end;
  95. disposetree(p);
  96. firstpass(t);
  97. p:=t;
  98. exit;
  99. end;
  100. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  101. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  102. firstpass(p^.left);
  103. firstpass(p^.right);
  104. if codegenerror then
  105. exit;
  106. calcregisters(p,2,0,0);
  107. p^.resulttype:=s32bitdef;
  108. p^.location.loc:=LOC_REGISTER;
  109. end;
  110. {*****************************************************************************
  111. FirstUmMinus
  112. *****************************************************************************}
  113. procedure firstumminus(var p : ptree);
  114. var
  115. t : ptree;
  116. minusdef : pprocdef;
  117. begin
  118. firstpass(p^.left);
  119. p^.registers32:=p^.left^.registers32;
  120. p^.registersfpu:=p^.left^.registersfpu;
  121. {$ifdef SUPPORT_MMX}
  122. p^.registersmmx:=p^.left^.registersmmx;
  123. {$endif SUPPORT_MMX}
  124. p^.resulttype:=p^.left^.resulttype;
  125. if codegenerror then
  126. exit;
  127. if is_constintnode(p^.left) then
  128. begin
  129. t:=genordinalconstnode(-p^.left^.value,s32bitdef);
  130. disposetree(p);
  131. firstpass(t);
  132. p:=t;
  133. exit;
  134. end;
  135. { nasm can not cope with negativ reals !! }
  136. if is_constrealnode(p^.left)
  137. {$ifdef i386}
  138. and not(aktoutputformat in [as_nasmcoff,as_nasmelf,as_nasmobj])
  139. {$endif}
  140. then
  141. begin
  142. t:=genrealconstnode(-p^.left^.value_real);
  143. disposetree(p);
  144. firstpass(t);
  145. p:=t;
  146. exit;
  147. end;
  148. if (p^.left^.resulttype^.deftype=floatdef) then
  149. begin
  150. if pfloatdef(p^.left^.resulttype)^.typ=f32bit then
  151. begin
  152. if (p^.left^.location.loc<>LOC_REGISTER) and
  153. (p^.registers32<1) then
  154. p^.registers32:=1;
  155. p^.location.loc:=LOC_REGISTER;
  156. end
  157. else
  158. p^.location.loc:=LOC_FPU;
  159. end
  160. {$ifdef SUPPORT_MMX}
  161. else if (cs_mmx in aktlocalswitches) and
  162. is_mmx_able_array(p^.left^.resulttype) then
  163. begin
  164. if (p^.left^.location.loc<>LOC_MMXREGISTER) and
  165. (p^.registersmmx<1) then
  166. p^.registersmmx:=1;
  167. { if saturation is on, p^.left^.resulttype isn't
  168. "mmx able" (FK)
  169. if (cs_mmx_saturation in aktlocalswitches^) and
  170. (porddef(parraydef(p^.resulttype)^.definition)^.typ in
  171. [s32bit,u32bit]) then
  172. CGMessage(type_e_mismatch);
  173. }
  174. end
  175. {$endif SUPPORT_MMX}
  176. else if (p^.left^.resulttype^.deftype=orddef) then
  177. begin
  178. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  179. firstpass(p^.left);
  180. p^.registersfpu:=p^.left^.registersfpu;
  181. {$ifdef SUPPORT_MMX}
  182. p^.registersmmx:=p^.left^.registersmmx;
  183. {$endif SUPPORT_MMX}
  184. p^.registers32:=p^.left^.registers32;
  185. if codegenerror then
  186. exit;
  187. if (p^.left^.location.loc<>LOC_REGISTER) and
  188. (p^.registers32<1) then
  189. p^.registers32:=1;
  190. p^.location.loc:=LOC_REGISTER;
  191. p^.resulttype:=p^.left^.resulttype;
  192. end
  193. else
  194. begin
  195. if assigned(overloaded_operators[minus]) then
  196. minusdef:=overloaded_operators[minus]^.definition
  197. else
  198. minusdef:=nil;
  199. while assigned(minusdef) do
  200. begin
  201. if (minusdef^.para1^.data=p^.left^.resulttype) and
  202. (minusdef^.para1^.next=nil) then
  203. begin
  204. t:=gencallnode(overloaded_operators[minus],nil);
  205. t^.left:=gencallparanode(p^.left,nil);
  206. putnode(p);
  207. p:=t;
  208. firstpass(p);
  209. exit;
  210. end;
  211. minusdef:=minusdef^.nextoverloaded;
  212. end;
  213. CGMessage(type_e_mismatch);
  214. end;
  215. end;
  216. {*****************************************************************************
  217. FirstNot
  218. *****************************************************************************}
  219. procedure firstnot(var p : ptree);
  220. var
  221. t : ptree;
  222. begin
  223. firstpass(p^.left);
  224. if codegenerror then
  225. exit;
  226. if (p^.left^.treetype=ordconstn) then
  227. begin
  228. t:=genordinalconstnode(not(p^.left^.value),p^.left^.resulttype);
  229. disposetree(p);
  230. firstpass(t);
  231. p:=t;
  232. exit;
  233. end;
  234. p^.resulttype:=p^.left^.resulttype;
  235. p^.location.loc:=p^.left^.location.loc;
  236. {$ifdef SUPPORT_MMX}
  237. p^.registersmmx:=p^.left^.registersmmx;
  238. {$endif SUPPORT_MMX}
  239. if is_equal(p^.resulttype,booldef) then
  240. begin
  241. p^.registers32:=p^.left^.registers32;
  242. if ((p^.location.loc=LOC_REFERENCE) or
  243. (p^.location.loc=LOC_CREGISTER)) and
  244. (p^.registers32<1) then
  245. p^.registers32:=1;
  246. end
  247. else
  248. {$ifdef SUPPORT_MMX}
  249. if (cs_mmx in aktlocalswitches) and
  250. is_mmx_able_array(p^.left^.resulttype) then
  251. begin
  252. if (p^.left^.location.loc<>LOC_MMXREGISTER) and
  253. (p^.registersmmx<1) then
  254. p^.registersmmx:=1;
  255. end
  256. else
  257. {$endif SUPPORT_MMX}
  258. begin
  259. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  260. firstpass(p^.left);
  261. if codegenerror then
  262. exit;
  263. p^.resulttype:=p^.left^.resulttype;
  264. p^.registers32:=p^.left^.registers32;
  265. {$ifdef SUPPORT_MMX}
  266. p^.registersmmx:=p^.left^.registersmmx;
  267. {$endif SUPPORT_MMX}
  268. if (p^.left^.location.loc<>LOC_REGISTER) and
  269. (p^.registers32<1) then
  270. p^.registers32:=1;
  271. p^.location.loc:=LOC_REGISTER;
  272. end;
  273. p^.registersfpu:=p^.left^.registersfpu;
  274. end;
  275. end.
  276. {
  277. $Log$
  278. Revision 1.1 1998-09-23 20:42:24 peter
  279. * splitted pass_1
  280. }