2
0

defutil.pas 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This unit provides some help routines for type handling
  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 defutil;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. cclasses,
  23. globals,
  24. symconst,symbase,symtype,symdef,
  25. cgbase,cpuinfo,cpubase;
  26. type
  27. tmmxtype = (mmxno,mmxu8bit,mmxs8bit,mmxu16bit,mmxs16bit,
  28. mmxu32bit,mmxs32bit,mmxfixed16,mmxsingle);
  29. {*****************************************************************************
  30. Basic type functions
  31. *****************************************************************************}
  32. {# Returns true, if definition defines an ordinal type }
  33. function is_ordinal(def : tdef) : boolean;
  34. {# Returns the minimal integer value of the type }
  35. function get_min_value(def : tdef) : TConstExprInt;
  36. {# Returns basetype of the specified integer range }
  37. function range_to_basetype(l,h:TConstExprInt):tbasetype;
  38. procedure int_to_type(v:TConstExprInt;var tt:ttype);
  39. {# Returns true, if definition defines an integer type }
  40. function is_integer(def : tdef) : boolean;
  41. {# Returns true if definition is a boolean }
  42. function is_boolean(def : tdef) : boolean;
  43. {# Returns true if definition is a char
  44. This excludes the unicode char.
  45. }
  46. function is_char(def : tdef) : boolean;
  47. {# Returns true if definition is a widechar }
  48. function is_widechar(def : tdef) : boolean;
  49. {# Returns true if definition is a void}
  50. function is_void(def : tdef) : boolean;
  51. {# Returns true if definition is a smallset}
  52. function is_smallset(p : tdef) : boolean;
  53. {# Returns true, if def defines a signed data type
  54. (only for ordinal types)
  55. }
  56. function is_signed(def : tdef) : boolean;
  57. {# Returns true whether def_from's range is comprised in def_to's if both are
  58. orddefs, false otherwise }
  59. function is_in_limit(def_from,def_to : tdef) : boolean;
  60. function is_in_limit_value(val_from:TConstExprInt;def_from,def_to : tdef) : boolean;
  61. {*****************************************************************************
  62. Array helper functions
  63. *****************************************************************************}
  64. {# Returns true, if p points to a zero based (non special like open or
  65. dynamic array def).
  66. This is mainly used to see if the array
  67. is convertable to a pointer
  68. }
  69. function is_zero_based_array(p : tdef) : boolean;
  70. {# Returns true if p points to an open array definition }
  71. function is_open_array(p : tdef) : boolean;
  72. {# Returns true if p points to a dynamic array definition }
  73. function is_dynamic_array(p : tdef) : boolean;
  74. {# Returns true, if p points to an array of const definition }
  75. function is_array_constructor(p : tdef) : boolean;
  76. {# Returns true, if p points to a variant array }
  77. function is_variant_array(p : tdef) : boolean;
  78. {# Returns true, if p points to an array of const }
  79. function is_array_of_const(p : tdef) : boolean;
  80. {# Returns true, if p points any kind of special array
  81. That is if the array is an open array, a variant
  82. array, an array constants constructor, or an
  83. array of const.
  84. }
  85. function is_special_array(p : tdef) : boolean;
  86. {# Returns true if p is a char array def }
  87. function is_chararray(p : tdef) : boolean;
  88. {# Returns true if p is a wide char array def }
  89. function is_widechararray(p : tdef) : boolean;
  90. {*****************************************************************************
  91. String helper functions
  92. *****************************************************************************}
  93. {# Returns true if p points to an open string type }
  94. function is_open_string(p : tdef) : boolean;
  95. {# Returns true if p is an ansi string type }
  96. function is_ansistring(p : tdef) : boolean;
  97. {# Returns true if p is a long string type }
  98. function is_longstring(p : tdef) : boolean;
  99. {# returns true if p is a wide string type }
  100. function is_widestring(p : tdef) : boolean;
  101. {# Returns true if p is a short string type }
  102. function is_shortstring(p : tdef) : boolean;
  103. {# Returns true if p is a pchar def }
  104. function is_pchar(p : tdef) : boolean;
  105. {# Returns true if p is a pwidechar def }
  106. function is_pwidechar(p : tdef) : boolean;
  107. {# Returns true if p is a voidpointer def }
  108. function is_voidpointer(p : tdef) : boolean;
  109. {# Returns true, if definition is a float }
  110. function is_fpu(def : tdef) : boolean;
  111. {# Returns true, if def is a currency type }
  112. function is_currency(def : tdef) : boolean;
  113. {# Returns true, if def is a single type }
  114. function is_single(def : tdef) : boolean;
  115. {# Returns true, if def is a double type }
  116. function is_double(def : tdef) : boolean;
  117. {# Returns true, if def is an extended type }
  118. function is_extended(def : tdef) : boolean;
  119. {# Returns true, if def is a 64 bit integer type }
  120. function is_64bitint(def : tdef) : boolean;
  121. {# Returns true, if def is a 64 bit type }
  122. function is_64bit(def : tdef) : boolean;
  123. {# If @var(l) isn't in the range of def a range check error (if not explicit) is generated and
  124. the value is placed within the range
  125. }
  126. procedure testrange(def : tdef;var l : tconstexprint;explicit:boolean);
  127. {# Returns the range of def, where @var(l) is the low-range and @var(h) is
  128. the high-range.
  129. }
  130. procedure getrange(def : tdef;var l : TConstExprInt;var h : TConstExprInt);
  131. { some type helper routines for MMX support }
  132. function is_mmx_able_array(p : tdef) : boolean;
  133. {# returns the mmx type }
  134. function mmx_type(p : tdef) : tmmxtype;
  135. {# From a definition return the abstract code generator size enum. It is
  136. to note that the value returned can be @var(OS_NO) }
  137. function def_cgsize(def: tdef): tcgsize;
  138. implementation
  139. uses
  140. globtype,tokens,systems,verbose;
  141. { returns true, if def uses FPU }
  142. function is_fpu(def : tdef) : boolean;
  143. begin
  144. is_fpu:=(def.deftype=floatdef);
  145. end;
  146. { returns true, if def is a currency type }
  147. function is_currency(def : tdef) : boolean;
  148. begin
  149. case s64currencytype.def.deftype of
  150. orddef :
  151. result:=(def.deftype=orddef) and
  152. (torddef(s64currencytype.def).typ=torddef(def).typ);
  153. floatdef :
  154. result:=(def.deftype=floatdef) and
  155. (tfloatdef(s64currencytype.def).typ=tfloatdef(def).typ);
  156. else
  157. internalerror(200304222);
  158. end;
  159. end;
  160. { returns true, if def is a single type }
  161. function is_single(def : tdef) : boolean;
  162. begin
  163. result:=(def.deftype=floatdef) and
  164. (tfloatdef(def).typ=s32real);
  165. end;
  166. { returns true, if def is a double type }
  167. function is_double(def : tdef) : boolean;
  168. begin
  169. result:=(def.deftype=floatdef) and
  170. (tfloatdef(def).typ=s64real);
  171. end;
  172. function is_extended(def : tdef) : boolean;
  173. begin
  174. result:=(def.deftype=floatdef) and
  175. (tfloatdef(def).typ=s80real);
  176. end;
  177. function range_to_basetype(l,h:TConstExprInt):tbasetype;
  178. begin
  179. { generate a unsigned range if high<0 and low>=0 }
  180. if (l>=0) and (h<=255) then
  181. range_to_basetype:=u8bit
  182. else if (l>=-128) and (h<=127) then
  183. range_to_basetype:=s8bit
  184. else if (l>=0) and (h<=65535) then
  185. range_to_basetype:=u16bit
  186. else if (l>=-32768) and (h<=32767) then
  187. range_to_basetype:=s16bit
  188. else if (l>=low(longint)) and (h<=high(longint)) then
  189. range_to_basetype:=s32bit
  190. else if (l>=low(cardinal)) and (h<=high(cardinal)) then
  191. range_to_basetype:=u32bit
  192. else
  193. range_to_basetype:=s64bit;
  194. end;
  195. procedure int_to_type(v:TConstExprInt;var tt:ttype);
  196. begin
  197. if (v>=0) and (v<=255) then
  198. tt:=u8inttype
  199. else if (v>=-128) and (v<=127) then
  200. tt:=s8inttype
  201. else if (v>=0) and (v<=65535) then
  202. tt:=u16inttype
  203. else if (v>=-32768) and (v<=32767) then
  204. tt:=s16inttype
  205. else if (v>=low(longint)) and (v<=high(longint)) then
  206. tt:=s32inttype
  207. else if (v>=low(cardinal)) and (v<=high(cardinal)) then
  208. tt:=u32inttype
  209. else
  210. tt:=s64inttype;
  211. end;
  212. { true if p is an ordinal }
  213. function is_ordinal(def : tdef) : boolean;
  214. var
  215. dt : tbasetype;
  216. begin
  217. case def.deftype of
  218. orddef :
  219. begin
  220. dt:=torddef(def).typ;
  221. is_ordinal:=dt in [uchar,uwidechar,
  222. u8bit,u16bit,u32bit,u64bit,
  223. s8bit,s16bit,s32bit,s64bit,
  224. bool8bit,bool16bit,bool32bit];
  225. end;
  226. enumdef :
  227. is_ordinal:=true;
  228. else
  229. is_ordinal:=false;
  230. end;
  231. end;
  232. { returns the min. value of the type }
  233. function get_min_value(def : tdef) : TConstExprInt;
  234. begin
  235. case def.deftype of
  236. orddef:
  237. get_min_value:=torddef(def).low;
  238. enumdef:
  239. get_min_value:=tenumdef(def).min;
  240. else
  241. get_min_value:=0;
  242. end;
  243. end;
  244. { true if p is an integer }
  245. function is_integer(def : tdef) : boolean;
  246. begin
  247. is_integer:=(def.deftype=orddef) and
  248. (torddef(def).typ in [u8bit,u16bit,u32bit,u64bit,
  249. s8bit,s16bit,s32bit,s64bit]);
  250. end;
  251. { true if p is a boolean }
  252. function is_boolean(def : tdef) : boolean;
  253. begin
  254. is_boolean:=(def.deftype=orddef) and
  255. (torddef(def).typ in [bool8bit,bool16bit,bool32bit]);
  256. end;
  257. { true if p is a void }
  258. function is_void(def : tdef) : boolean;
  259. begin
  260. is_void:=(def.deftype=orddef) and
  261. (torddef(def).typ=uvoid);
  262. end;
  263. { true if p is a char }
  264. function is_char(def : tdef) : boolean;
  265. begin
  266. is_char:=(def.deftype=orddef) and
  267. (torddef(def).typ=uchar);
  268. end;
  269. { true if p is a wchar }
  270. function is_widechar(def : tdef) : boolean;
  271. begin
  272. is_widechar:=(def.deftype=orddef) and
  273. (torddef(def).typ=uwidechar);
  274. end;
  275. { true if p is signed (integer) }
  276. function is_signed(def : tdef) : boolean;
  277. var
  278. dt : tbasetype;
  279. begin
  280. case def.deftype of
  281. orddef :
  282. begin
  283. dt:=torddef(def).typ;
  284. is_signed:=(dt in [s8bit,s16bit,s32bit,s64bit,scurrency]);
  285. end;
  286. enumdef :
  287. is_signed:=tenumdef(def).min < 0;
  288. arraydef :
  289. is_signed:=is_signed(tarraydef(def).rangetype.def);
  290. else
  291. is_signed:=false;
  292. end;
  293. end;
  294. function is_in_limit(def_from,def_to : tdef) : boolean;
  295. var
  296. fromqword, toqword: boolean;
  297. begin
  298. if (def_from.deftype <> orddef) or
  299. (def_to.deftype <> orddef) then
  300. begin
  301. is_in_limit := false;
  302. exit;
  303. end;
  304. fromqword := torddef(def_from).typ = u64bit;
  305. toqword := torddef(def_to).typ = u64bit;
  306. is_in_limit:=(toqword and is_signed(def_from)) or
  307. ((not fromqword) and
  308. (torddef(def_from).low>=torddef(def_to).low) and
  309. (torddef(def_from).high<=torddef(def_to).high));
  310. end;
  311. function is_in_limit_value(val_from:TConstExprInt;def_from,def_to : tdef) : boolean;
  312. begin
  313. if (def_from.deftype <> orddef) and
  314. (def_to.deftype <> orddef) then
  315. internalerror(200210062);
  316. if (torddef(def_to).typ = u64bit) then
  317. begin
  318. is_in_limit_value:=((TConstExprUInt(val_from)>=TConstExprUInt(torddef(def_to).low)) and
  319. (TConstExprUInt(val_from)<=TConstExprUInt(torddef(def_to).high)));
  320. end
  321. else
  322. begin;
  323. is_in_limit_value:=((val_from>=torddef(def_to).low) and
  324. (val_from<=torddef(def_to).high));
  325. end;
  326. end;
  327. { true, if p points to an open array def }
  328. function is_open_string(p : tdef) : boolean;
  329. begin
  330. is_open_string:=(p.deftype=stringdef) and
  331. (tstringdef(p).string_typ=st_shortstring) and
  332. (tstringdef(p).len=0);
  333. end;
  334. { true, if p points to a zero based array def }
  335. function is_zero_based_array(p : tdef) : boolean;
  336. begin
  337. is_zero_based_array:=(p.deftype=arraydef) and
  338. (tarraydef(p).lowrange=0) and
  339. not(is_special_array(p));
  340. end;
  341. { true if p points to a dynamic array def }
  342. function is_dynamic_array(p : tdef) : boolean;
  343. begin
  344. is_dynamic_array:=(p.deftype=arraydef) and
  345. tarraydef(p).IsDynamicArray;
  346. end;
  347. { true, if p points to an open array def }
  348. function is_open_array(p : tdef) : boolean;
  349. begin
  350. { check for s32inttype is needed, because for u32bit the high
  351. range is also -1 ! (PFV) }
  352. is_open_array:=(p.deftype=arraydef) and
  353. (tarraydef(p).rangetype.def=s32inttype.def) and
  354. (tarraydef(p).lowrange=0) and
  355. (tarraydef(p).highrange=-1) and
  356. not(tarraydef(p).IsConstructor) and
  357. not(tarraydef(p).IsVariant) and
  358. not(tarraydef(p).IsArrayOfConst) and
  359. not(tarraydef(p).IsDynamicArray);
  360. end;
  361. { true, if p points to an array of const def }
  362. function is_array_constructor(p : tdef) : boolean;
  363. begin
  364. is_array_constructor:=(p.deftype=arraydef) and
  365. (tarraydef(p).IsConstructor);
  366. end;
  367. { true, if p points to a variant array }
  368. function is_variant_array(p : tdef) : boolean;
  369. begin
  370. is_variant_array:=(p.deftype=arraydef) and
  371. (tarraydef(p).IsVariant);
  372. end;
  373. { true, if p points to an array of const }
  374. function is_array_of_const(p : tdef) : boolean;
  375. begin
  376. is_array_of_const:=(p.deftype=arraydef) and
  377. (tarraydef(p).IsArrayOfConst);
  378. end;
  379. { true, if p points to a special array }
  380. function is_special_array(p : tdef) : boolean;
  381. begin
  382. is_special_array:=(p.deftype=arraydef) and
  383. ((tarraydef(p).IsVariant) or
  384. (tarraydef(p).IsArrayOfConst) or
  385. (tarraydef(p).IsConstructor) or
  386. (tarraydef(p).IsDynamicArray) or
  387. is_open_array(p)
  388. );
  389. end;
  390. { true if p is an ansi string def }
  391. function is_ansistring(p : tdef) : boolean;
  392. begin
  393. is_ansistring:=(p.deftype=stringdef) and
  394. (tstringdef(p).string_typ=st_ansistring);
  395. end;
  396. { true if p is an long string def }
  397. function is_longstring(p : tdef) : boolean;
  398. begin
  399. is_longstring:=(p.deftype=stringdef) and
  400. (tstringdef(p).string_typ=st_longstring);
  401. end;
  402. { true if p is an wide string def }
  403. function is_widestring(p : tdef) : boolean;
  404. begin
  405. is_widestring:=(p.deftype=stringdef) and
  406. (tstringdef(p).string_typ=st_widestring);
  407. end;
  408. { true if p is an short string def }
  409. function is_shortstring(p : tdef) : boolean;
  410. begin
  411. is_shortstring:=(p.deftype=stringdef) and
  412. (tstringdef(p).string_typ=st_shortstring);
  413. end;
  414. { true if p is a char array def }
  415. function is_chararray(p : tdef) : boolean;
  416. begin
  417. is_chararray:=(p.deftype=arraydef) and
  418. is_char(tarraydef(p).elementtype.def) and
  419. not(is_special_array(p));
  420. end;
  421. { true if p is a widechar array def }
  422. function is_widechararray(p : tdef) : boolean;
  423. begin
  424. is_widechararray:=(p.deftype=arraydef) and
  425. is_widechar(tarraydef(p).elementtype.def) and
  426. not(is_special_array(p));
  427. end;
  428. { true if p is a pchar def }
  429. function is_pchar(p : tdef) : boolean;
  430. begin
  431. is_pchar:=(p.deftype=pointerdef) and
  432. (is_char(tpointerdef(p).pointertype.def) or
  433. (is_zero_based_array(tpointerdef(p).pointertype.def) and
  434. is_chararray(tpointerdef(p).pointertype.def)));
  435. end;
  436. { true if p is a pchar def }
  437. function is_pwidechar(p : tdef) : boolean;
  438. begin
  439. is_pwidechar:=(p.deftype=pointerdef) and
  440. (is_widechar(tpointerdef(p).pointertype.def) or
  441. (is_zero_based_array(tpointerdef(p).pointertype.def) and
  442. is_widechararray(tpointerdef(p).pointertype.def)));
  443. end;
  444. { true if p is a voidpointer def }
  445. function is_voidpointer(p : tdef) : boolean;
  446. begin
  447. is_voidpointer:=(p.deftype=pointerdef) and
  448. (tpointerdef(p).pointertype.def.deftype=orddef) and
  449. (torddef(tpointerdef(p).pointertype.def).typ=uvoid);
  450. end;
  451. { true if p is a smallset def }
  452. function is_smallset(p : tdef) : boolean;
  453. begin
  454. is_smallset:=(p.deftype=setdef) and
  455. (tsetdef(p).settype=smallset);
  456. end;
  457. { true, if def is a 64 bit int type }
  458. function is_64bitint(def : tdef) : boolean;
  459. begin
  460. is_64bitint:=(def.deftype=orddef) and (torddef(def).typ in [u64bit,s64bit])
  461. end;
  462. { true, if def is a 64 bit type }
  463. function is_64bit(def : tdef) : boolean;
  464. begin
  465. is_64bit:=(def.deftype=orddef) and (torddef(def).typ in [u64bit,s64bit,scurrency])
  466. end;
  467. { if l isn't in the range of def a range check error (if not explicit) is generated and
  468. the value is placed within the range }
  469. procedure testrange(def : tdef;var l : tconstexprint;explicit:boolean);
  470. var
  471. lv,hv: TConstExprInt;
  472. error: boolean;
  473. begin
  474. error := false;
  475. { for 64 bit types we need only to check if it is less than }
  476. { zero, if def is a qword node }
  477. if is_64bitint(def) then
  478. begin
  479. if (l<0) and (torddef(def).typ=u64bit) then
  480. begin
  481. { don't zero the result, because it may come from hex notation
  482. like $ffffffffffffffff! (JM)
  483. l:=0; }
  484. if not explicit then
  485. begin
  486. if (cs_check_range in aktlocalswitches) then
  487. Message(parser_e_range_check_error)
  488. else
  489. Message(parser_w_range_check_error);
  490. end;
  491. error := true;
  492. end;
  493. end
  494. else
  495. begin
  496. getrange(def,lv,hv);
  497. if (def.deftype=orddef) and
  498. (torddef(def).typ=u32bit) then
  499. begin
  500. if (l < cardinal(lv)) or
  501. (l > cardinal(hv)) then
  502. begin
  503. if not explicit then
  504. begin
  505. if (cs_check_range in aktlocalswitches) then
  506. Message(parser_e_range_check_error)
  507. else
  508. Message(parser_w_range_check_error);
  509. end;
  510. error := true;
  511. end;
  512. end
  513. else if (l<lv) or (l>hv) then
  514. begin
  515. if not explicit then
  516. begin
  517. if ((def.deftype=enumdef) and
  518. { delphi allows range check errors in
  519. enumeration type casts FK }
  520. not(m_delphi in aktmodeswitches)) or
  521. (cs_check_range in aktlocalswitches) then
  522. Message(parser_e_range_check_error)
  523. else
  524. Message(parser_w_range_check_error);
  525. end;
  526. error := true;
  527. end;
  528. end;
  529. if error then
  530. begin
  531. { Fix the value to fit in the allocated space for this type of variable }
  532. case def.size of
  533. 1: l := l and $ff;
  534. 2: l := l and $ffff;
  535. { work around sign extension bug (to be fixed) (JM) }
  536. 4: l := l and (int64($fffffff) shl 4 + $f);
  537. end;
  538. { do sign extension if necessary (JM) }
  539. if is_signed(def) then
  540. begin
  541. case def.size of
  542. 1: l := shortint(l);
  543. 2: l := smallint(l);
  544. 4: l := longint(l);
  545. end;
  546. end;
  547. end;
  548. end;
  549. { return the range from def in l and h }
  550. procedure getrange(def : tdef;var l : TConstExprInt;var h : TConstExprInt);
  551. begin
  552. case def.deftype of
  553. orddef :
  554. begin
  555. l:=torddef(def).low;
  556. h:=torddef(def).high;
  557. end;
  558. enumdef :
  559. begin
  560. l:=tenumdef(def).min;
  561. h:=tenumdef(def).max;
  562. end;
  563. arraydef :
  564. begin
  565. l:=tarraydef(def).lowrange;
  566. h:=tarraydef(def).highrange;
  567. end;
  568. else
  569. internalerror(987);
  570. end;
  571. end;
  572. function mmx_type(p : tdef) : tmmxtype;
  573. begin
  574. mmx_type:=mmxno;
  575. if is_mmx_able_array(p) then
  576. begin
  577. if tarraydef(p).elementtype.def.deftype=floatdef then
  578. case tfloatdef(tarraydef(p).elementtype.def).typ of
  579. s32real:
  580. mmx_type:=mmxsingle;
  581. end
  582. else
  583. case torddef(tarraydef(p).elementtype.def).typ of
  584. u8bit:
  585. mmx_type:=mmxu8bit;
  586. s8bit:
  587. mmx_type:=mmxs8bit;
  588. u16bit:
  589. mmx_type:=mmxu16bit;
  590. s16bit:
  591. mmx_type:=mmxs16bit;
  592. u32bit:
  593. mmx_type:=mmxu32bit;
  594. s32bit:
  595. mmx_type:=mmxs32bit;
  596. end;
  597. end;
  598. end;
  599. function is_mmx_able_array(p : tdef) : boolean;
  600. begin
  601. {$ifdef SUPPORT_MMX}
  602. if (cs_mmx_saturation in aktlocalswitches) then
  603. begin
  604. is_mmx_able_array:=(p.deftype=arraydef) and
  605. not(is_special_array(p)) and
  606. (
  607. (
  608. (tarraydef(p).elementtype.def.deftype=orddef) and
  609. (
  610. (
  611. (tarraydef(p).lowrange=0) and
  612. (tarraydef(p).highrange=1) and
  613. (torddef(tarraydef(p).elementtype.def).typ in [u32bit,s32bit])
  614. )
  615. or
  616. (
  617. (tarraydef(p).lowrange=0) and
  618. (tarraydef(p).highrange=3) and
  619. (torddef(tarraydef(p).elementtype.def).typ in [u16bit,s16bit])
  620. )
  621. )
  622. )
  623. or
  624. (
  625. (
  626. (tarraydef(p).elementtype.def.deftype=floatdef) and
  627. (
  628. (tarraydef(p).lowrange=0) and
  629. (tarraydef(p).highrange=1) and
  630. (tfloatdef(tarraydef(p).elementtype.def).typ=s32real)
  631. )
  632. )
  633. )
  634. );
  635. end
  636. else
  637. begin
  638. is_mmx_able_array:=(p.deftype=arraydef) and
  639. (
  640. (
  641. (tarraydef(p).elementtype.def.deftype=orddef) and
  642. (
  643. (
  644. (tarraydef(p).lowrange=0) and
  645. (tarraydef(p).highrange=1) and
  646. (torddef(tarraydef(p).elementtype.def).typ in [u32bit,s32bit])
  647. )
  648. or
  649. (
  650. (tarraydef(p).lowrange=0) and
  651. (tarraydef(p).highrange=3) and
  652. (torddef(tarraydef(p).elementtype.def).typ in [u16bit,s16bit])
  653. )
  654. or
  655. (
  656. (tarraydef(p).lowrange=0) and
  657. (tarraydef(p).highrange=7) and
  658. (torddef(tarraydef(p).elementtype.def).typ in [u8bit,s8bit])
  659. )
  660. )
  661. )
  662. or
  663. (
  664. (tarraydef(p).elementtype.def.deftype=floatdef) and
  665. (
  666. (tarraydef(p).lowrange=0) and
  667. (tarraydef(p).highrange=1) and
  668. (tfloatdef(tarraydef(p).elementtype.def).typ=s32real)
  669. )
  670. )
  671. );
  672. end;
  673. {$else SUPPORT_MMX}
  674. is_mmx_able_array:=false;
  675. {$endif SUPPORT_MMX}
  676. end;
  677. function def_cgsize(def: tdef): tcgsize;
  678. begin
  679. case def.deftype of
  680. orddef,
  681. enumdef,
  682. setdef:
  683. begin
  684. result := int_cgsize(def.size);
  685. if is_signed(def) then
  686. result := tcgsize(ord(result)+(ord(OS_S8)-ord(OS_8)));
  687. end;
  688. classrefdef,
  689. pointerdef:
  690. result := OS_ADDR;
  691. procvardef:
  692. begin
  693. if tprocvardef(def).is_methodpointer and
  694. (not tprocvardef(def).is_addressonly) then
  695. result := OS_64
  696. else
  697. result := OS_ADDR;
  698. end;
  699. stringdef :
  700. begin
  701. if is_ansistring(def) or is_widestring(def) then
  702. result := OS_ADDR
  703. else
  704. result := OS_NO;
  705. end;
  706. objectdef :
  707. begin
  708. if is_class_or_interface(def) then
  709. result := OS_ADDR
  710. else
  711. result := OS_NO;
  712. end;
  713. floatdef:
  714. result := tfloat2tcgsize[tfloatdef(def).typ];
  715. recorddef :
  716. result:=int_cgsize(def.size);
  717. arraydef :
  718. begin
  719. if not is_special_array(def) then
  720. result := int_cgsize(def.size)
  721. else
  722. begin
  723. if is_dynamic_array(def) then
  724. result := OS_ADDR
  725. else
  726. result := OS_NO;
  727. end;
  728. end;
  729. else
  730. begin
  731. { undefined size }
  732. result:=OS_NO;
  733. end;
  734. end;
  735. end;
  736. end.
  737. {
  738. $Log$
  739. Revision 1.11 2004-03-23 22:34:49 peter
  740. * constants ordinals now always have a type assigned
  741. * integer constants have the smallest type, unsigned prefered over
  742. signed
  743. Revision 1.10 2004/02/04 22:01:13 peter
  744. * first try to get cpupara working for x86_64
  745. Revision 1.9 2004/02/03 22:32:53 peter
  746. * renamed xNNbittype to xNNinttype
  747. * renamed registers32 to registersint
  748. * replace some s32bit,u32bit with torddef([su]inttype).def.typ
  749. Revision 1.8 2003/12/25 01:07:09 florian
  750. + $fputype directive support
  751. + single data type operations with sse unit
  752. * fixed more x86-64 stuff
  753. Revision 1.7 2003/11/10 18:05:16 florian
  754. + is_single added
  755. Revision 1.6 2003/10/01 20:34:48 peter
  756. * procinfo unit contains tprocinfo
  757. * cginfo renamed to cgbase
  758. * moved cgmessage to verbose
  759. * fixed ppc and sparc compiles
  760. Revision 1.5 2003/04/25 20:59:33 peter
  761. * removed funcretn,funcretsym, function result is now in varsym
  762. and aliases for result and function name are added using absolutesym
  763. * vs_hidden parameter for funcret passed in parameter
  764. * vs_hidden fixes
  765. * writenode changed to printnode and released from extdebug
  766. * -vp option added to generate a tree.log with the nodetree
  767. * nicer printnode for statements, callnode
  768. Revision 1.4 2003/04/23 20:16:04 peter
  769. + added currency support based on int64
  770. + is_64bit for use in cg units instead of is_64bitint
  771. * removed cgmessage from n386add, replace with internalerrors
  772. Revision 1.3 2003/03/17 19:05:08 peter
  773. * dynamic array is also a special array
  774. Revision 1.2 2002/12/23 20:58:03 peter
  775. * remove unused global var
  776. Revision 1.1 2002/11/25 17:43:17 peter
  777. * splitted defbase in defutil,symutil,defcmp
  778. * merged isconvertable and is_equal into compare_defs(_ext)
  779. * made operator search faster by walking the list only once
  780. Revision 1.26 2002/11/17 16:31:55 carl
  781. * memory optimization (3-4%) : cleanup of tai fields,
  782. cleanup of tdef and tsym fields.
  783. * make it work for m68k
  784. Revision 1.25 2002/11/16 18:00:53 peter
  785. * fix merged proc-procvar check
  786. Revision 1.24 2002/11/15 01:58:46 peter
  787. * merged changes from 1.0.7 up to 04-11
  788. - -V option for generating bug report tracing
  789. - more tracing for option parsing
  790. - errors for cdecl and high()
  791. - win32 import stabs
  792. - win32 records<=8 are returned in eax:edx (turned off by default)
  793. - heaptrc update
  794. - more info for temp management in .s file with EXTDEBUG
  795. Revision 1.23 2002/10/20 15:34:16 peter
  796. * removed df_unique flag. It breaks code. For a good type=type <id>
  797. a def copy is required
  798. Revision 1.22 2002/10/10 16:07:57 florian
  799. + several widestring/pwidechar related stuff added
  800. Revision 1.21 2002/10/09 21:01:41 florian
  801. * variants aren't compatible with nil
  802. Revision 1.20 2002/10/07 09:49:42 florian
  803. * overloaded :=-operator is now searched when looking for possible
  804. variant type conversions
  805. Revision 1.19 2002/10/06 21:02:17 peter
  806. * fixed limit checking for qword
  807. Revision 1.18 2002/10/06 15:08:59 peter
  808. * only check for forwarddefs the definitions that really belong to
  809. the current procsym
  810. Revision 1.17 2002/10/06 12:25:04 florian
  811. + proper support of type <id> = type <another id>;
  812. Revision 1.16 2002/10/05 12:43:24 carl
  813. * fixes for Delphi 6 compilation
  814. (warning : Some features do not work under Delphi)
  815. Revision 1.15 2002/10/05 00:50:01 peter
  816. * check parameters from left to right in equal_paras, so default
  817. parameters are checked at the end
  818. Revision 1.14 2002/09/30 07:00:44 florian
  819. * fixes to common code to get the alpha compiler compiled applied
  820. Revision 1.13 2002/09/22 14:02:34 carl
  821. * stack checking cannot be called before system unit is initialized
  822. * MC68020 define
  823. Revision 1.12 2002/09/16 14:11:12 peter
  824. * add argument to equal_paras() to support default values or not
  825. Revision 1.11 2002/09/15 17:54:46 peter
  826. * allow default parameters in equal_paras
  827. Revision 1.10 2002/09/08 11:10:17 carl
  828. * bugfix 2109 (bad imho, but only way)
  829. Revision 1.9 2002/09/07 15:25:02 peter
  830. * old logs removed and tabs fixed
  831. Revision 1.8 2002/09/07 09:16:55 carl
  832. * fix my stupid copy and paste bug
  833. Revision 1.7 2002/09/06 19:58:31 carl
  834. * start bugfix 1996
  835. * 64-bit typed constant now work correctly and fully (bugfix 2001)
  836. Revision 1.6 2002/08/20 10:31:26 daniel
  837. * Tcallnode.det_resulttype rewritten
  838. Revision 1.5 2002/08/12 20:39:17 florian
  839. * casting of classes to interface fixed when the interface was
  840. implemented by a parent class
  841. Revision 1.4 2002/08/12 14:17:56 florian
  842. * nil is now recognized as being compatible with a dynamic array
  843. Revision 1.3 2002/08/05 18:27:48 carl
  844. + more more more documentation
  845. + first version include/exclude (can't test though, not enough scratch for i386 :()...
  846. Revision 1.2 2002/07/23 09:51:22 daniel
  847. * Tried to make Tprocsym.defs protected. I didn't succeed but the cleanups
  848. are worth comitting.
  849. Revision 1.1 2002/07/20 11:57:53 florian
  850. * types.pas renamed to defbase.pas because D6 contains a types
  851. unit so this would conflicts if D6 programms are compiled
  852. + Willamette/SSE2 instructions to assembler added
  853. Revision 1.75 2002/07/11 14:41:32 florian
  854. * start of the new generic parameter handling
  855. Revision 1.74 2002/07/01 16:23:54 peter
  856. * cg64 patch
  857. * basics for currency
  858. * asnode updates for class and interface (not finished)
  859. Revision 1.73 2002/05/18 13:34:21 peter
  860. * readded missing revisions
  861. Revision 1.72 2002/05/16 19:46:47 carl
  862. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  863. + try to fix temp allocation (still in ifdef)
  864. + generic constructor calls
  865. + start of tassembler / tmodulebase class cleanup
  866. Revision 1.70 2002/05/12 16:53:16 peter
  867. * moved entry and exitcode to ncgutil and cgobj
  868. * foreach gets extra argument for passing local data to the
  869. iterator function
  870. * -CR checks also class typecasts at runtime by changing them
  871. into as
  872. * fixed compiler to cycle with the -CR option
  873. * fixed stabs with elf writer, finally the global variables can
  874. be watched
  875. * removed a lot of routines from cga unit and replaced them by
  876. calls to cgobj
  877. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  878. u32bit then the other is typecasted also to u32bit without giving
  879. a rangecheck warning/error.
  880. * fixed pascal calling method with reversing also the high tree in
  881. the parast, detected by tcalcst3 test
  882. Revision 1.69 2002/04/25 20:16:39 peter
  883. * moved more routines from cga/n386util
  884. Revision 1.68 2002/04/15 19:08:22 carl
  885. + target_info.size_of_pointer -> pointer_size
  886. + some cleanup of unused types/variables
  887. Revision 1.67 2002/04/07 13:40:29 carl
  888. + update documentation
  889. Revision 1.66 2002/04/02 17:11:32 peter
  890. * tlocation,treference update
  891. * LOC_CONSTANT added for better constant handling
  892. * secondadd splitted in multiple routines
  893. * location_force_reg added for loading a location to a register
  894. of a specified size
  895. * secondassignment parses now first the right and then the left node
  896. (this is compatible with Kylix). This saves a lot of push/pop especially
  897. with string operations
  898. * adapted some routines to use the new cg methods
  899. Revision 1.65 2002/04/01 20:57:14 jonas
  900. * fixed web bug 1907
  901. * fixed some other procvar related bugs (all related to accepting procvar
  902. constructs with either too many or too little parameters)
  903. (both merged, includes second typo fix of pexpr.pas)
  904. Revision 1.64 2002/01/24 18:25:53 peter
  905. * implicit result variable generation for assembler routines
  906. * removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
  907. Revision 1.63 2002/01/24 12:33:53 jonas
  908. * adapted ranges of native types to int64 (e.g. high cardinal is no
  909. longer longint($ffffffff), but just $fffffff in psystem)
  910. * small additional fix in 64bit rangecheck code generation for 32 bit
  911. processors
  912. * adaption of ranges required the matching talgorithm used for selecting
  913. which overloaded procedure to call to be adapted. It should now always
  914. select the closest match for ordinal parameters.
  915. + inttostr(qword) in sysstr.inc/sysstrh.inc
  916. + abs(int64), sqr(int64), sqr(qword) in systemh.inc/generic.inc (previous
  917. fixes were required to be able to add them)
  918. * is_in_limit() moved from ncal to types unit, should always be used
  919. instead of direct comparisons of low/high values of orddefs because
  920. qword is a special case
  921. }