defutil.pas 35 KB

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