defutil.pas 35 KB

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