defutil.pas 34 KB

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