defutil.pas 37 KB

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