defutil.pas 35 KB

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