defutil.pas 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147
  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. globtype,globals,
  24. symconst,symbase,symtype,symdef,
  25. cgbase,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 32 bit integer type }
  121. function is_32bitint(def : tdef) : boolean;
  122. {# Returns true, if def is a 64 bit integer type }
  123. function is_64bitint(def : tdef) : boolean;
  124. {# Returns true, if def is a 64 bit type }
  125. function is_64bit(def : tdef) : boolean;
  126. {# If @var(l) isn't in the range of def a range check error (if not explicit) is generated and
  127. the value is placed within the range
  128. }
  129. procedure testrange(def : tdef;var l : tconstexprint;explicit:boolean);
  130. {# Returns the range of def, where @var(l) is the low-range and @var(h) is
  131. the high-range.
  132. }
  133. procedure getrange(def : tdef;var l : TConstExprInt;var h : TConstExprInt);
  134. { some type helper routines for MMX support }
  135. function is_mmx_able_array(p : tdef) : boolean;
  136. {# returns the mmx type }
  137. function mmx_type(p : tdef) : tmmxtype;
  138. {# From a definition return the abstract code generator size enum. It is
  139. to note that the value returned can be @var(OS_NO) }
  140. function def_cgsize(def: tdef): tcgsize;
  141. implementation
  142. uses
  143. tokens,systems,verbose;
  144. { returns true, if def uses FPU }
  145. function is_fpu(def : tdef) : boolean;
  146. begin
  147. is_fpu:=(def.deftype=floatdef);
  148. end;
  149. { returns true, if def is a currency type }
  150. function is_currency(def : tdef) : boolean;
  151. begin
  152. case s64currencytype.def.deftype of
  153. orddef :
  154. result:=(def.deftype=orddef) and
  155. (torddef(s64currencytype.def).typ=torddef(def).typ);
  156. floatdef :
  157. result:=(def.deftype=floatdef) and
  158. (tfloatdef(s64currencytype.def).typ=tfloatdef(def).typ);
  159. else
  160. internalerror(200304222);
  161. end;
  162. end;
  163. { returns true, if def is a single type }
  164. function is_single(def : tdef) : boolean;
  165. begin
  166. result:=(def.deftype=floatdef) and
  167. (tfloatdef(def).typ=s32real);
  168. end;
  169. { returns true, if def is a double type }
  170. function is_double(def : tdef) : boolean;
  171. begin
  172. result:=(def.deftype=floatdef) and
  173. (tfloatdef(def).typ=s64real);
  174. end;
  175. function is_extended(def : tdef) : boolean;
  176. begin
  177. result:=(def.deftype=floatdef) and
  178. (tfloatdef(def).typ=s80real);
  179. end;
  180. function range_to_basetype(l,h:TConstExprInt):tbasetype;
  181. begin
  182. { prefer signed over unsigned }
  183. if (l>=-128) and (h<=127) then
  184. range_to_basetype:=s8bit
  185. else if (l>=0) and (h<=255) then
  186. range_to_basetype:=u8bit
  187. else if (l>=-32768) and (h<=32767) then
  188. range_to_basetype:=s16bit
  189. else if (l>=0) and (h<=65535) then
  190. range_to_basetype:=u16bit
  191. else if (l>=low(longint)) and (h<=high(longint)) then
  192. range_to_basetype:=s32bit
  193. else if (l>=low(cardinal)) and (h<=high(cardinal)) then
  194. range_to_basetype:=u32bit
  195. else
  196. range_to_basetype:=s64bit;
  197. end;
  198. procedure range_to_type(l,h:TConstExprInt;var tt:ttype);
  199. begin
  200. { prefer signed over unsigned }
  201. if (l>=-128) and (h<=127) then
  202. tt:=s8inttype
  203. else if (l>=0) and (h<=255) then
  204. tt:=u8inttype
  205. else if (l>=-32768) and (h<=32767) then
  206. tt:=s16inttype
  207. else if (l>=0) and (h<=65535) then
  208. tt:=u16inttype
  209. else if (l>=low(longint)) and (h<=high(longint)) then
  210. tt:=s32inttype
  211. else if (l>=low(cardinal)) and (h<=high(cardinal)) then
  212. tt:=u32inttype
  213. else
  214. tt:=s64inttype;
  215. end;
  216. procedure int_to_type(v:TConstExprInt;var tt:ttype);
  217. begin
  218. range_to_type(v,v,tt);
  219. end;
  220. { true if p is an ordinal }
  221. function is_ordinal(def : tdef) : boolean;
  222. var
  223. dt : tbasetype;
  224. begin
  225. case def.deftype of
  226. orddef :
  227. begin
  228. dt:=torddef(def).typ;
  229. is_ordinal:=dt in [uchar,uwidechar,
  230. u8bit,u16bit,u32bit,u64bit,
  231. s8bit,s16bit,s32bit,s64bit,
  232. bool8bit,bool16bit,bool32bit];
  233. end;
  234. enumdef :
  235. is_ordinal:=true;
  236. else
  237. is_ordinal:=false;
  238. end;
  239. end;
  240. { returns the min. value of the type }
  241. function get_min_value(def : tdef) : TConstExprInt;
  242. begin
  243. case def.deftype of
  244. orddef:
  245. get_min_value:=torddef(def).low;
  246. enumdef:
  247. get_min_value:=tenumdef(def).min;
  248. else
  249. get_min_value:=0;
  250. end;
  251. end;
  252. { true if p is an integer }
  253. function is_integer(def : tdef) : boolean;
  254. begin
  255. is_integer:=(def.deftype=orddef) and
  256. (torddef(def).typ in [u8bit,u16bit,u32bit,u64bit,
  257. s8bit,s16bit,s32bit,s64bit]);
  258. end;
  259. { true if p is a boolean }
  260. function is_boolean(def : tdef) : boolean;
  261. begin
  262. is_boolean:=(def.deftype=orddef) and
  263. (torddef(def).typ in [bool8bit,bool16bit,bool32bit]);
  264. end;
  265. { true if p is a void }
  266. function is_void(def : tdef) : boolean;
  267. begin
  268. is_void:=(def.deftype=orddef) and
  269. (torddef(def).typ=uvoid);
  270. end;
  271. { true if p is a char }
  272. function is_char(def : tdef) : boolean;
  273. begin
  274. is_char:=(def.deftype=orddef) and
  275. (torddef(def).typ=uchar);
  276. end;
  277. { true if p is a wchar }
  278. function is_widechar(def : tdef) : boolean;
  279. begin
  280. is_widechar:=(def.deftype=orddef) and
  281. (torddef(def).typ=uwidechar);
  282. end;
  283. { true if p is signed (integer) }
  284. function is_signed(def : tdef) : boolean;
  285. var
  286. dt : tbasetype;
  287. begin
  288. case def.deftype of
  289. orddef :
  290. begin
  291. dt:=torddef(def).typ;
  292. is_signed:=(dt in [s8bit,s16bit,s32bit,s64bit,scurrency]);
  293. end;
  294. enumdef :
  295. is_signed:=tenumdef(def).min < 0;
  296. arraydef :
  297. is_signed:=is_signed(tarraydef(def).rangetype.def);
  298. else
  299. is_signed:=false;
  300. end;
  301. end;
  302. function is_in_limit(def_from,def_to : tdef) : boolean;
  303. var
  304. fromqword, toqword: boolean;
  305. begin
  306. if (def_from.deftype <> orddef) or
  307. (def_to.deftype <> orddef) then
  308. begin
  309. is_in_limit := false;
  310. exit;
  311. end;
  312. fromqword := torddef(def_from).typ = u64bit;
  313. toqword := torddef(def_to).typ = u64bit;
  314. is_in_limit:=(toqword and is_signed(def_from)) or
  315. ((not fromqword) and
  316. (torddef(def_from).low>=torddef(def_to).low) and
  317. (torddef(def_from).high<=torddef(def_to).high));
  318. end;
  319. function is_in_limit_value(val_from:TConstExprInt;def_from,def_to : tdef) : boolean;
  320. begin
  321. if (def_from.deftype <> orddef) and
  322. (def_to.deftype <> orddef) then
  323. internalerror(200210062);
  324. if (torddef(def_to).typ = u64bit) then
  325. begin
  326. is_in_limit_value:=((TConstExprUInt(val_from)>=TConstExprUInt(torddef(def_to).low)) and
  327. (TConstExprUInt(val_from)<=TConstExprUInt(torddef(def_to).high)));
  328. end
  329. else
  330. begin;
  331. is_in_limit_value:=((val_from>=torddef(def_to).low) and
  332. (val_from<=torddef(def_to).high));
  333. end;
  334. end;
  335. { true, if p points to an open array def }
  336. function is_open_string(p : tdef) : boolean;
  337. begin
  338. is_open_string:=(p.deftype=stringdef) and
  339. (tstringdef(p).string_typ=st_shortstring) and
  340. (tstringdef(p).len=0);
  341. end;
  342. { true, if p points to a zero based array def }
  343. function is_zero_based_array(p : tdef) : boolean;
  344. begin
  345. is_zero_based_array:=(p.deftype=arraydef) and
  346. (tarraydef(p).lowrange=0) and
  347. not(is_special_array(p));
  348. end;
  349. { true if p points to a dynamic array def }
  350. function is_dynamic_array(p : tdef) : boolean;
  351. begin
  352. is_dynamic_array:=(p.deftype=arraydef) and
  353. tarraydef(p).IsDynamicArray;
  354. end;
  355. { true, if p points to an open array def }
  356. function is_open_array(p : tdef) : boolean;
  357. begin
  358. { check for s32inttype is needed, because for u32bit the high
  359. range is also -1 ! (PFV) }
  360. is_open_array:=(p.deftype=arraydef) and
  361. (tarraydef(p).rangetype.def=s32inttype.def) and
  362. (tarraydef(p).lowrange=0) and
  363. (tarraydef(p).highrange=-1) and
  364. not(tarraydef(p).IsConstructor) and
  365. not(tarraydef(p).IsVariant) and
  366. not(tarraydef(p).IsArrayOfConst) and
  367. not(tarraydef(p).IsDynamicArray);
  368. end;
  369. { true, if p points to an array of const def }
  370. function is_array_constructor(p : tdef) : boolean;
  371. begin
  372. is_array_constructor:=(p.deftype=arraydef) and
  373. (tarraydef(p).IsConstructor);
  374. end;
  375. { true, if p points to a variant array }
  376. function is_variant_array(p : tdef) : boolean;
  377. begin
  378. is_variant_array:=(p.deftype=arraydef) and
  379. (tarraydef(p).IsVariant);
  380. end;
  381. { true, if p points to an array of const }
  382. function is_array_of_const(p : tdef) : boolean;
  383. begin
  384. is_array_of_const:=(p.deftype=arraydef) and
  385. (tarraydef(p).IsArrayOfConst);
  386. end;
  387. { true, if p points to a special array }
  388. function is_special_array(p : tdef) : boolean;
  389. begin
  390. is_special_array:=(p.deftype=arraydef) and
  391. ((tarraydef(p).IsVariant) or
  392. (tarraydef(p).IsArrayOfConst) or
  393. (tarraydef(p).IsConstructor) or
  394. (tarraydef(p).IsDynamicArray) or
  395. is_open_array(p)
  396. );
  397. end;
  398. {$ifdef ansistring_bits}
  399. { true if p is an ansi string def }
  400. function is_ansistring(p : tdef) : boolean;
  401. begin
  402. is_ansistring:=(p.deftype=stringdef) and
  403. (tstringdef(p).string_typ in [st_ansistring16,st_ansistring32,st_ansistring64]);
  404. end;
  405. {$else}
  406. { true if p is an ansi string def }
  407. function is_ansistring(p : tdef) : boolean;
  408. begin
  409. is_ansistring:=(p.deftype=stringdef) and
  410. (tstringdef(p).string_typ=st_ansistring);
  411. end;
  412. {$endif}
  413. { true if p is an long string def }
  414. function is_longstring(p : tdef) : boolean;
  415. begin
  416. is_longstring:=(p.deftype=stringdef) and
  417. (tstringdef(p).string_typ=st_longstring);
  418. end;
  419. { true if p is an wide string def }
  420. function is_widestring(p : tdef) : boolean;
  421. begin
  422. is_widestring:=(p.deftype=stringdef) and
  423. (tstringdef(p).string_typ=st_widestring);
  424. end;
  425. { true if p is an short string def }
  426. function is_shortstring(p : tdef) : boolean;
  427. begin
  428. is_shortstring:=(p.deftype=stringdef) and
  429. (tstringdef(p).string_typ=st_shortstring);
  430. end;
  431. { true if p is a char array def }
  432. function is_chararray(p : tdef) : boolean;
  433. begin
  434. is_chararray:=(p.deftype=arraydef) and
  435. is_char(tarraydef(p).elementtype.def) and
  436. not(is_special_array(p));
  437. end;
  438. { true if p is a widechar array def }
  439. function is_widechararray(p : tdef) : boolean;
  440. begin
  441. is_widechararray:=(p.deftype=arraydef) and
  442. is_widechar(tarraydef(p).elementtype.def) and
  443. not(is_special_array(p));
  444. end;
  445. { true if p is a pchar def }
  446. function is_pchar(p : tdef) : boolean;
  447. begin
  448. is_pchar:=(p.deftype=pointerdef) and
  449. (is_char(tpointerdef(p).pointertype.def) or
  450. (is_zero_based_array(tpointerdef(p).pointertype.def) and
  451. is_chararray(tpointerdef(p).pointertype.def)));
  452. end;
  453. { true if p is a pchar def }
  454. function is_pwidechar(p : tdef) : boolean;
  455. begin
  456. is_pwidechar:=(p.deftype=pointerdef) and
  457. (is_widechar(tpointerdef(p).pointertype.def) or
  458. (is_zero_based_array(tpointerdef(p).pointertype.def) and
  459. is_widechararray(tpointerdef(p).pointertype.def)));
  460. end;
  461. { true if p is a voidpointer def }
  462. function is_voidpointer(p : tdef) : boolean;
  463. begin
  464. is_voidpointer:=(p.deftype=pointerdef) and
  465. (tpointerdef(p).pointertype.def.deftype=orddef) and
  466. (torddef(tpointerdef(p).pointertype.def).typ=uvoid);
  467. end;
  468. { true if p is a smallset def }
  469. function is_smallset(p : tdef) : boolean;
  470. begin
  471. is_smallset:=(p.deftype=setdef) and
  472. (tsetdef(p).settype=smallset);
  473. end;
  474. { true, if def is a 32 bit int type }
  475. function is_32bitint(def : tdef) : boolean;
  476. begin
  477. result:=(def.deftype=orddef) and (torddef(def).typ in [u32bit,s32bit])
  478. end;
  479. { true, if def is a 64 bit int type }
  480. function is_64bitint(def : tdef) : boolean;
  481. begin
  482. is_64bitint:=(def.deftype=orddef) and (torddef(def).typ in [u64bit,s64bit])
  483. end;
  484. { true, if def is a 64 bit type }
  485. function is_64bit(def : tdef) : boolean;
  486. begin
  487. is_64bit:=(def.deftype=orddef) and (torddef(def).typ in [u64bit,s64bit,scurrency])
  488. end;
  489. { if l isn't in the range of def a range check error (if not explicit) is generated and
  490. the value is placed within the range }
  491. procedure testrange(def : tdef;var l : tconstexprint;explicit:boolean);
  492. var
  493. lv,hv: TConstExprInt;
  494. error: boolean;
  495. begin
  496. error := false;
  497. { for 64 bit types we need only to check if it is less than }
  498. { zero, if def is a qword node }
  499. if is_64bitint(def) then
  500. begin
  501. if (l<0) and (torddef(def).typ=u64bit) then
  502. begin
  503. { don't zero the result, because it may come from hex notation
  504. like $ffffffffffffffff! (JM)
  505. l:=0; }
  506. if not explicit then
  507. begin
  508. if (cs_check_range in aktlocalswitches) then
  509. Message(parser_e_range_check_error)
  510. else
  511. Message(parser_w_range_check_error);
  512. end;
  513. error := true;
  514. end;
  515. end
  516. else
  517. begin
  518. getrange(def,lv,hv);
  519. 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.17 2004-06-18 15:16:46 peter
  746. * remove obsolete cardinal() typecasts
  747. Revision 1.16 2004/06/16 20:07:07 florian
  748. * dwarf branch merged
  749. Revision 1.15 2004/05/28 21:13:23 peter
  750. * prefer signed constants over unsigned
  751. Revision 1.14 2004/05/01 22:05:01 florian
  752. + added lib support for Amiga/MorphOS syscalls
  753. Revision 1.13 2004/04/29 19:56:36 daniel
  754. * Prepare compiler infrastructure for multiple ansistring types
  755. Revision 1.12.2.2 2004/05/03 16:27:38 peter
  756. * fixed shl for x86-64
  757. Revision 1.12.2.1 2004/05/01 16:02:09 peter
  758. * POINTER_SIZE replaced with sizeof(aint)
  759. * aint,aword,tconst*int moved to globtype
  760. Revision 1.12 2004/03/29 14:44:10 peter
  761. * fixes to previous constant integer commit
  762. Revision 1.11 2004/03/23 22:34:49 peter
  763. * constants ordinals now always have a type assigned
  764. * integer constants have the smallest type, unsigned prefered over
  765. signed
  766. Revision 1.10 2004/02/04 22:01:13 peter
  767. * first try to get cpupara working for x86_64
  768. Revision 1.9 2004/02/03 22:32:53 peter
  769. * renamed xNNbittype to xNNinttype
  770. * renamed registers32 to registersint
  771. * replace some s32bit,u32bit with torddef([su]inttype).def.typ
  772. Revision 1.8 2003/12/25 01:07:09 florian
  773. + $fputype directive support
  774. + single data type operations with sse unit
  775. * fixed more x86-64 stuff
  776. Revision 1.7 2003/11/10 18:05:16 florian
  777. + is_single added
  778. Revision 1.6 2003/10/01 20:34:48 peter
  779. * procinfo unit contains tprocinfo
  780. * cginfo renamed to cgbase
  781. * moved cgmessage to verbose
  782. * fixed ppc and sparc compiles
  783. Revision 1.5 2003/04/25 20:59:33 peter
  784. * removed funcretn,funcretsym, function result is now in varsym
  785. and aliases for result and function name are added using absolutesym
  786. * vs_hidden parameter for funcret passed in parameter
  787. * vs_hidden fixes
  788. * writenode changed to printnode and released from extdebug
  789. * -vp option added to generate a tree.log with the nodetree
  790. * nicer printnode for statements, callnode
  791. Revision 1.4 2003/04/23 20:16:04 peter
  792. + added currency support based on int64
  793. + is_64bit for use in cg units instead of is_64bitint
  794. * removed cgmessage from n386add, replace with internalerrors
  795. Revision 1.3 2003/03/17 19:05:08 peter
  796. * dynamic array is also a special array
  797. Revision 1.2 2002/12/23 20:58:03 peter
  798. * remove unused global var
  799. Revision 1.1 2002/11/25 17:43:17 peter
  800. * splitted defbase in defutil,symutil,defcmp
  801. * merged isconvertable and is_equal into compare_defs(_ext)
  802. * made operator search faster by walking the list only once
  803. Revision 1.26 2002/11/17 16:31:55 carl
  804. * memory optimization (3-4%) : cleanup of tai fields,
  805. cleanup of tdef and tsym fields.
  806. * make it work for m68k
  807. Revision 1.25 2002/11/16 18:00:53 peter
  808. * fix merged proc-procvar check
  809. Revision 1.24 2002/11/15 01:58:46 peter
  810. * merged changes from 1.0.7 up to 04-11
  811. - -V option for generating bug report tracing
  812. - more tracing for option parsing
  813. - errors for cdecl and high()
  814. - win32 import stabs
  815. - win32 records<=8 are returned in eax:edx (turned off by default)
  816. - heaptrc update
  817. - more info for temp management in .s file with EXTDEBUG
  818. Revision 1.23 2002/10/20 15:34:16 peter
  819. * removed df_unique flag. It breaks code. For a good type=type <id>
  820. a def copy is required
  821. Revision 1.22 2002/10/10 16:07:57 florian
  822. + several widestring/pwidechar related stuff added
  823. Revision 1.21 2002/10/09 21:01:41 florian
  824. * variants aren't compatible with nil
  825. Revision 1.20 2002/10/07 09:49:42 florian
  826. * overloaded :=-operator is now searched when looking for possible
  827. variant type conversions
  828. Revision 1.19 2002/10/06 21:02:17 peter
  829. * fixed limit checking for qword
  830. Revision 1.18 2002/10/06 15:08:59 peter
  831. * only check for forwarddefs the definitions that really belong to
  832. the current procsym
  833. Revision 1.17 2002/10/06 12:25:04 florian
  834. + proper support of type <id> = type <another id>;
  835. Revision 1.16 2002/10/05 12:43:24 carl
  836. * fixes for Delphi 6 compilation
  837. (warning : Some features do not work under Delphi)
  838. Revision 1.15 2002/10/05 00:50:01 peter
  839. * check parameters from left to right in equal_paras, so default
  840. parameters are checked at the end
  841. Revision 1.14 2002/09/30 07:00:44 florian
  842. * fixes to common code to get the alpha compiler compiled applied
  843. Revision 1.13 2002/09/22 14:02:34 carl
  844. * stack checking cannot be called before system unit is initialized
  845. * MC68020 define
  846. Revision 1.12 2002/09/16 14:11:12 peter
  847. * add argument to equal_paras() to support default values or not
  848. Revision 1.11 2002/09/15 17:54:46 peter
  849. * allow default parameters in equal_paras
  850. Revision 1.10 2002/09/08 11:10:17 carl
  851. * bugfix 2109 (bad imho, but only way)
  852. Revision 1.9 2002/09/07 15:25:02 peter
  853. * old logs removed and tabs fixed
  854. Revision 1.8 2002/09/07 09:16:55 carl
  855. * fix my stupid copy and paste bug
  856. Revision 1.7 2002/09/06 19:58:31 carl
  857. * start bugfix 1996
  858. * 64-bit typed constant now work correctly and fully (bugfix 2001)
  859. Revision 1.6 2002/08/20 10:31:26 daniel
  860. * Tcallnode.det_resulttype rewritten
  861. Revision 1.5 2002/08/12 20:39:17 florian
  862. * casting of classes to interface fixed when the interface was
  863. implemented by a parent class
  864. Revision 1.4 2002/08/12 14:17:56 florian
  865. * nil is now recognized as being compatible with a dynamic array
  866. Revision 1.3 2002/08/05 18:27:48 carl
  867. + more more more documentation
  868. + first version include/exclude (can't test though, not enough scratch for i386 :()...
  869. Revision 1.2 2002/07/23 09:51:22 daniel
  870. * Tried to make Tprocsym.defs protected. I didn't succeed but the cleanups
  871. are worth comitting.
  872. Revision 1.1 2002/07/20 11:57:53 florian
  873. * types.pas renamed to defbase.pas because D6 contains a types
  874. unit so this would conflicts if D6 programms are compiled
  875. + Willamette/SSE2 instructions to assembler added
  876. Revision 1.75 2002/07/11 14:41:32 florian
  877. * start of the new generic parameter handling
  878. Revision 1.74 2002/07/01 16:23:54 peter
  879. * cg64 patch
  880. * basics for currency
  881. * asnode updates for class and interface (not finished)
  882. Revision 1.73 2002/05/18 13:34:21 peter
  883. * readded missing revisions
  884. Revision 1.72 2002/05/16 19:46:47 carl
  885. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  886. + try to fix temp allocation (still in ifdef)
  887. + generic constructor calls
  888. + start of tassembler / tmodulebase class cleanup
  889. Revision 1.70 2002/05/12 16:53:16 peter
  890. * moved entry and exitcode to ncgutil and cgobj
  891. * foreach gets extra argument for passing local data to the
  892. iterator function
  893. * -CR checks also class typecasts at runtime by changing them
  894. into as
  895. * fixed compiler to cycle with the -CR option
  896. * fixed stabs with elf writer, finally the global variables can
  897. be watched
  898. * removed a lot of routines from cga unit and replaced them by
  899. calls to cgobj
  900. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  901. u32bit then the other is typecasted also to u32bit without giving
  902. a rangecheck warning/error.
  903. * fixed pascal calling method with reversing also the high tree in
  904. the parast, detected by tcalcst3 test
  905. Revision 1.69 2002/04/25 20:16:39 peter
  906. * moved more routines from cga/n386util
  907. Revision 1.68 2002/04/15 19:08:22 carl
  908. + target_info.size_of_pointer -> sizeof(aint)
  909. + some cleanup of unused types/variables
  910. Revision 1.67 2002/04/07 13:40:29 carl
  911. + update documentation
  912. Revision 1.66 2002/04/02 17:11:32 peter
  913. * tlocation,treference update
  914. * LOC_CONSTANT added for better constant handling
  915. * secondadd splitted in multiple routines
  916. * location_force_reg added for loading a location to a register
  917. of a specified size
  918. * secondassignment parses now first the right and then the left node
  919. (this is compatible with Kylix). This saves a lot of push/pop especially
  920. with string operations
  921. * adapted some routines to use the new cg methods
  922. Revision 1.65 2002/04/01 20:57:14 jonas
  923. * fixed web bug 1907
  924. * fixed some other procvar related bugs (all related to accepting procvar
  925. constructs with either too many or too little parameters)
  926. (both merged, includes second typo fix of pexpr.pas)
  927. Revision 1.64 2002/01/24 18:25:53 peter
  928. * implicit result variable generation for assembler routines
  929. * removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
  930. Revision 1.63 2002/01/24 12:33:53 jonas
  931. * adapted ranges of native types to int64 (e.g. high cardinal is no
  932. longer longint($ffffffff), but just $fffffff in psystem)
  933. * small additional fix in 64bit rangecheck code generation for 32 bit
  934. processors
  935. * adaption of ranges required the matching talgorithm used for selecting
  936. which overloaded procedure to call to be adapted. It should now always
  937. select the closest match for ordinal parameters.
  938. + inttostr(qword) in sysstr.inc/sysstrh.inc
  939. + abs(int64), sqr(int64), sqr(qword) in systemh.inc/generic.inc (previous
  940. fixes were required to be able to add them)
  941. * is_in_limit() moved from ncal to types unit, should always be used
  942. instead of direct comparisons of low/high values of orddefs because
  943. qword is a special case
  944. }