generic.inc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by the Free Pascal development team.
  5. Processor independent implementation for the system unit
  6. (adapted for intel i386.inc file)
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  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.
  12. **********************************************************************}
  13. {****************************************************************************
  14. Primitives
  15. ****************************************************************************}
  16. type
  17. pstring = ^shortstring;
  18. {$ifndef FPC_SYSTEM_HAS_MOVE}
  19. procedure Move(const source;var dest;count:longint);
  20. type
  21. bytearray = array [0..maxlongint] of byte;
  22. var
  23. i,size : longint;
  24. begin
  25. Dec(count);
  26. for i:=0 to count do
  27. bytearray(dest)[i]:=bytearray(source)[i];
  28. end;
  29. {$endif ndef FPC_SYSTEM_HAS_MOVE}
  30. {$ifndef FPC_SYSTEM_HAS_FILLCHAR}
  31. Procedure FillChar(var x;count:longint;value:byte);
  32. type
  33. longintarray = array [0..maxlongint] of longint;
  34. bytearray = array [0..maxlongint] of byte;
  35. var
  36. i,v : longint;
  37. begin
  38. if count = 0 then exit;
  39. v := 0;
  40. v:=(value shl 8) or (value and $FF);
  41. v:=(v shl 16) or (v and $ffff);
  42. for i:=0 to (count div 4) -1 do
  43. longintarray(x)[i]:=v;
  44. for i:=(count div 4)*4 to count-1 do
  45. bytearray(x)[i]:=value;
  46. end;
  47. {$endif ndef FPC_SYSTEM_HAS_FILLCHAR}
  48. {$ifndef FPC_SYSTEM_HAS_FILLBYTE}
  49. procedure FillByte (var x;count : longint;value : byte );
  50. begin
  51. FillChar (X,Count,CHR(VALUE));
  52. end;
  53. {$endif ndef FPC_SYSTEM_HAS_FILLBYTE}
  54. {$ifndef FPC_SYSTEM_HAS_FILLWORD}
  55. procedure fillword(var x;count : longint;value : word);
  56. type
  57. longintarray = array [0..maxlongint] of longint;
  58. wordarray = array [0..maxlongint] of word;
  59. var
  60. i,v : longint;
  61. begin
  62. v:=value*$10000+value;
  63. for i:=0 to (count div 2) -1 do
  64. longintarray(x)[i]:=v;
  65. for i:=(count div 2)*2 to count-1 do
  66. wordarray(x)[i]:=value;
  67. end;
  68. {$endif ndef FPC_SYSTEM_HAS_FILLWORD}
  69. {$ifndef FPC_SYSTEM_HAS_FILLDWORD}
  70. procedure FillDWord(var x;count : longint;value : DWord);
  71. type
  72. longintarray = array [0..maxlongint] of longint;
  73. var
  74. I : longint;
  75. begin
  76. if Count<>0 then
  77. begin
  78. I:=Count;
  79. while I<>0 do
  80. begin
  81. longintarray(X)[I-1]:=Value;
  82. Dec(I);
  83. end;
  84. end;
  85. end;
  86. {$endif ndef FPC_SYSTEM_HAS_FILLDWORD}
  87. {$ifndef FPC_SYSTEM_HAS_INDEXCHAR}
  88. function IndexChar(var buf;len:longint;b:char):longint;
  89. begin
  90. IndexChar:=IndexByte(Buf,Len,byte(B));
  91. end;
  92. {$endif ndef FPC_SYSTEM_HAS_INDEXCHAR}
  93. {$ifndef FPC_SYSTEM_HAS_INDEXBYTE}
  94. function IndexByte(var buf;len:longint;b:byte):longint;
  95. type
  96. bytearray = array [0..maxlongint] of byte;
  97. var
  98. I : longint;
  99. begin
  100. I:=0;
  101. while (bytearray(buf)[I]<>b) and (I<Len) do
  102. inc(I);
  103. if (i=Len) then
  104. i:=-1; {Can't use 0, since it is a possible value}
  105. IndexByte:=I;
  106. end;
  107. {$endif ndef FPC_SYSTEM_HAS_INDEXBYTE}
  108. {$ifndef FPC_SYSTEM_HAS_INDEXWORD}
  109. function Indexword(var buf;len:longint;b:word):longint;
  110. type
  111. wordarray = array [0..maxlongint] of word;
  112. var
  113. I : longint;
  114. begin
  115. I:=0;
  116. while (wordarray(buf)[I]<>b) and (I<Len) do
  117. inc(I);
  118. if (i=Len) then
  119. i:=-1; {Can't use 0, since it is a possible value for index}
  120. Indexword:=I;
  121. end;
  122. {$endif ndef FPC_SYSTEM_HAS_INDEXWORD}
  123. {$ifndef FPC_SYSTEM_HAS_INDEXDWORD}
  124. function IndexDWord(var buf;len:longint;b:DWord):longint;
  125. type
  126. longintarray = array [0..maxlongint] of longint;
  127. var
  128. I : longint;
  129. begin
  130. I:=0;
  131. while (longintarray(buf)[I]<>b) and (I<Len) do inc(I);
  132. if (i=Len) then
  133. i:=-1; {Can't use 0, since it is a possible value for index}
  134. IndexDWord:=I;
  135. end;
  136. {$endif ndef FPC_SYSTEM_HAS_INDEXDWORD}
  137. {$ifndef FPC_SYSTEM_HAS_COMPARECHAR}
  138. function CompareChar(var buf1,buf2;len:longint):longint;
  139. begin
  140. CompareChar:=CompareByte(buf1,buf2,len);
  141. end;
  142. {$endif ndef FPC_SYSTEM_HAS_COMPARECHAR}
  143. {$ifndef FPC_SYSTEM_HAS_COMPAREBYTE}
  144. function CompareByte(var buf1,buf2;len:longint):longint;
  145. type
  146. bytearray = array [0..maxlongint] of byte;
  147. var
  148. I,J : longint;
  149. begin
  150. I:=0;
  151. if (Len<>0) and (@Buf1<>@Buf2) then
  152. begin
  153. while (bytearray(Buf1)[I]=bytearray(Buf2)[I]) and (I<Len) do
  154. inc(I);
  155. if I=Len then {No difference}
  156. I:=0
  157. else
  158. begin
  159. I:=bytearray(Buf1)[I]-bytearray(Buf2)[I];
  160. if I>0 then
  161. I:=1
  162. else
  163. if I<0 then
  164. I:=-1;
  165. end;
  166. end;
  167. CompareByte:=I;
  168. end;
  169. {$endif ndef FPC_SYSTEM_HAS_COMPAREBYTE}
  170. {$ifndef FPC_SYSTEM_HAS_COMPAREWORD}
  171. function CompareWord(var buf1,buf2;len:longint):longint;
  172. type
  173. wordarray = array [0..maxlongint] of word;
  174. var
  175. I,J : longint;
  176. begin
  177. I:=0;
  178. if (Len<>0) and (@Buf1<>@Buf2) then
  179. begin
  180. while (wordarray(Buf1)[I]=wordarray(Buf2)[I]) and (I<Len) do
  181. inc(I);
  182. if I=Len then {No difference}
  183. I:=0
  184. else
  185. begin
  186. I:=wordarray(Buf1)[I]-wordarray(Buf2)[I];
  187. if I>0 then
  188. I:=1
  189. else
  190. if I<0 then
  191. I:=-1;
  192. end;
  193. end;
  194. CompareWord:=I;
  195. end;
  196. {$endif ndef FPC_SYSTEM_HAS_COMPAREWORD}
  197. {$ifndef FPC_SYSTEM_HAS_COMPAREDWORD}
  198. function CompareDWord(var buf1,buf2;len:longint):longint;
  199. type
  200. longintarray = array [0..maxlongint] of longint;
  201. var
  202. I,J : longint;
  203. begin
  204. I:=0;
  205. if (Len<>0) and (@Buf1<>@Buf2) then
  206. begin
  207. while (longintarray(Buf1)[I]=longintarray(Buf2)[I]) and (I<Len) do
  208. inc(I);
  209. if I=Len then {No difference}
  210. I:=0
  211. else
  212. begin
  213. I:=longintarray(Buf1)[I]-longintarray(Buf2)[I];
  214. if I>0 then
  215. I:=1
  216. else
  217. if I<0 then
  218. I:=-1;
  219. end;
  220. end;
  221. CompareDWord:=I;
  222. end;
  223. {$endif ndef FPC_SYSTEM_HAS_COMPAREDWORD}
  224. {$ifndef FPC_SYSTEM_HAS_MOVECHAR0}
  225. procedure MoveChar0(var buf1,buf2;len:longint);
  226. var
  227. I : longint;
  228. begin
  229. if Len<> 0 then
  230. begin
  231. I:=IndexByte(Buf1,Len,0);
  232. if I<>0 then
  233. Move(Buf1,Buf2,I);
  234. end;
  235. end;
  236. {$endif ndef FPC_SYSTEM_HAS_MOVECHAR0}
  237. {$ifndef FPC_SYSTEM_HAS_INDEXCHAR0}
  238. function IndexChar0(var buf;len:longint;b:Char):longint;
  239. var
  240. I : longint;
  241. begin
  242. if Len<>0 then
  243. begin
  244. I:=IndexByte(Buf,Len,0);
  245. IndexChar0:=IndexByte(Buf,I,0);
  246. end
  247. else
  248. IndexChar0:=0;
  249. end;
  250. {$endif ndef FPC_SYSTEM_HAS_INDEXCHAR0}
  251. {$ifndef FPC_SYSTEM_HAS_COMPARECHAR0}
  252. function CompareChar0(var buf1,buf2;len:longint):longint;
  253. type
  254. bytearray = array [0..maxlongint] of byte;
  255. Var i : longint;
  256. begin
  257. I:=0;
  258. if (Len<>0) and (@Buf1<>@Buf2) then
  259. begin
  260. while (I<Len) And
  261. ((Pbyte(@Buf1)[i]<>0) and (PByte(@buf2)[i]<>0)) and
  262. (pbyte(@Buf1)[I]=pbyte(@Buf2)[I]) do
  263. inc(I);
  264. if (I=Len) or
  265. (PByte(@Buf1)[i]=0) or
  266. (PByte(@buf2)[I]=0) then {No difference or 0 reached }
  267. I:=0
  268. else
  269. begin
  270. I:=bytearray(Buf1)[I]-bytearray(Buf2)[I];
  271. if I>0 then
  272. I:=1
  273. else
  274. if I<0 then
  275. I:=-1;
  276. end;
  277. end;
  278. CompareChar0:=I;
  279. end;
  280. {$endif ndef FPC_SYSTEM_HAS_COMPARECHAR0}
  281. {****************************************************************************
  282. Object Helpers
  283. ****************************************************************************}
  284. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_CONSTRUCTOR}
  285. { Generic code does not set the register used for self !
  286. So this needs to be done by the compiler after calling
  287. FPC_HELP_CONSTRUCTOR : generic allways means aa little less efficient (PM) }
  288. procedure int_help_constructor(var _self : pointer; vmt : pointer; vmt_pos : cardinal); [public,alias:'FPC_HELP_CONSTRUCTOR'];
  289. type
  290. ppointer = ^pointer;
  291. pvmt = ^tvmt;
  292. tvmt = packed record
  293. size,msize : longint;
  294. parent : pointer;
  295. end;
  296. var
  297. objectsize : longint;
  298. begin
  299. objectsize:=pvmt(vmt)^.size;
  300. getmem(_self,objectsize);
  301. fillchar(_self,objectsize,#0);
  302. ppointer(_self+vmt_pos)^:=vmt;
  303. end;
  304. {$endif ndef FPC_SYSTEM_HAS_FPC_HELP_CONSTRUCTOR}
  305. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_DESTRUCTOR}
  306. procedure int_help_destructor(var _self : pointer; vmt : pointer; vmt_pos : cardinal);[public,alias:'FPC_HELP_DESTRUCTOR'];
  307. type
  308. ppointer = ^pointer;
  309. pvmt = ^tvmt;
  310. tvmt = packed record
  311. size,msize : longint;
  312. parent : pointer;
  313. end;
  314. var
  315. objectsize : longint;
  316. begin
  317. if (_self=nil) then
  318. exit;
  319. if (pvmt(ppointer(_self+vmt_pos)^)^.size=0) or
  320. (pvmt(ppointer(_self+vmt_pos)^)^.size+pvmt(ppointer(_self+vmt_pos)^)^.msize<>0) then
  321. RunError(210);
  322. objectsize:=pvmt(vmt)^.size;
  323. { reset vmt to nil for protection }
  324. ppointer(_self+vmt_pos)^:=nil;
  325. freemem(_self,objectsize);
  326. _self:=nil;
  327. end;
  328. {$endif ndef FPC_SYSTEM_HAS_FPC_HELP_DESTRUCTOR}
  329. {$ifndef FPC_SYSTEM_HAS_FPC_NEW_CLASS}
  330. {$error No pascal version of Int_new_class}
  331. (* procedure int_new_class;assembler;[public,alias:'FPC_NEW_CLASS'];
  332. asm
  333. { to be sure in the future, we save also edit }
  334. pushl %edi
  335. { create class ? }
  336. movl 8(%ebp),%edi
  337. orl %edi,%edi
  338. jz .LNEW_CLASS1
  339. { save registers !! }
  340. pushl %ebx
  341. pushl %ecx
  342. pushl %edx
  343. { esi contains the vmt }
  344. pushl %esi
  345. { call newinstance (class method!) }
  346. call *16(%esi)
  347. popl %edx
  348. popl %ecx
  349. popl %ebx
  350. { newinstance returns a pointer to the new created }
  351. { instance in eax }
  352. { load esi and insert self }
  353. movl %eax,%esi
  354. .LNEW_CLASS1:
  355. movl %esi,8(%ebp)
  356. orl %eax,%eax
  357. popl %edi
  358. end; *)
  359. {$endif ndef FPC_SYSTEM_HAS_FPC_NEW_CLASS}
  360. {$ifndef FPC_SYSTEM_HAS_FPC_DISPOSE_CLASS}
  361. {$error No pascal version of Int_dispose_class}
  362. (* procedure int_dispose_class;assembler;[public,alias:'FPC_DISPOSE_CLASS'];
  363. asm
  364. { to be sure in the future, we save also edit }
  365. pushl %edi
  366. { destroy class ? }
  367. movl 12(%ebp),%edi
  368. orl %edi,%edi
  369. jz .LDISPOSE_CLASS1
  370. { no inherited call }
  371. movl (%esi),%edi
  372. { save registers !! }
  373. pushl %eax
  374. pushl %ebx
  375. pushl %ecx
  376. pushl %edx
  377. { push self }
  378. pushl %esi
  379. { call freeinstance }
  380. call *20(%edi)
  381. popl %edx
  382. popl %ecx
  383. popl %ebx
  384. popl %eax
  385. .LDISPOSE_CLASS1:
  386. popl %edi
  387. end; *)
  388. {$endif ndef FPC_SYSTEM_HAS_FPC_DISPOSE_CLASS}
  389. {$ifndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT}
  390. procedure int_check_object(vmt : pointer);[public,alias:'FPC_CHECK_OBJECT'];
  391. type
  392. pvmt = ^tvmt;
  393. tvmt = packed record
  394. size,msize : longint;
  395. parent : pointer;
  396. end;
  397. begin
  398. if (vmt=nil) or
  399. (pvmt(vmt)^.size=0) or
  400. (pvmt(vmt)^.size+pvmt(vmt)^.msize<>0) then
  401. RunError(210);
  402. end;
  403. {$endif ndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT}
  404. { checks for a correct vmt pointer }
  405. { deeper check to see if the current object is }
  406. { really related to the true }
  407. {$ifndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT_EXT}
  408. procedure int_check_object_ext(vmt, expvmt : pointer);[public,alias:'FPC_CHECK_OBJECT_EXT'];
  409. type
  410. pvmt = ^tvmt;
  411. tvmt = packed record
  412. size,msize : longint;
  413. parent : pointer;
  414. end;
  415. begin
  416. if (vmt=nil) or
  417. (pvmt(vmt)^.size=0) or
  418. (pvmt(vmt)^.size+pvmt(vmt)^.msize<>0) then
  419. RunError(210);
  420. while assigned(vmt) do
  421. if vmt=expvmt then
  422. exit
  423. else
  424. vmt:=pvmt(vmt)^.parent;
  425. RunError(220);
  426. end;
  427. {$endif ndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT_EXT}
  428. {****************************************************************************
  429. String
  430. ****************************************************************************}
  431. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COPY}
  432. procedure int_strcopy(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_COPY'];
  433. var
  434. slen : byte;
  435. begin
  436. if dstr=nil then
  437. exit;
  438. if sstr=nil then
  439. begin
  440. if dstr<>nil then
  441. pstring(dstr)^[0]:=#0;
  442. exit;
  443. end;
  444. slen:=length(pstring(sstr)^);
  445. if slen<len then
  446. len:=slen;
  447. { don't forget the length character }
  448. if len <> 0 then
  449. move(sstr^,dstr^,len+1);
  450. pstring(dstr)^[0]:=chr(len);
  451. end;
  452. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COPY}
  453. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
  454. procedure int_strconcat(s1,s2:pointer);[public,alias:'FPC_SHORTSTR_CONCAT'];
  455. var
  456. s1l, s2l : byte;
  457. begin
  458. if (s1=nil) or (s2=nil) then
  459. exit;
  460. s1l:=length(pstring(s1)^);
  461. s2l:=length(pstring(s2)^);
  462. if s1l+s2l>255 then
  463. s1l:=255-s2l;
  464. move(pstring(s1)^[1],pstring(s2)^[s2l+1],s1l);
  465. pstring(s2)^[0]:=chr(s1l+s2l);
  466. end;
  467. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
  468. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
  469. function int_strcmp(dstr,sstr:pointer) : longint;[public,alias:'FPC_SHORTSTR_COMPARE'];
  470. var
  471. s1,s2,max,i : byte;
  472. d : longint;
  473. begin
  474. s1:=length(pstring(dstr)^);
  475. s2:=length(pstring(sstr)^);
  476. if s1<s2 then
  477. max:=s1
  478. else
  479. max:=s2;
  480. for i:=1 to max do
  481. begin
  482. d:=byte(pstring(dstr)^[i])-byte(pstring(sstr)^[i]);
  483. if d>0 then
  484. exit(1)
  485. else if d<0 then
  486. exit(-1);
  487. end;
  488. if s1>s2 then
  489. exit(1)
  490. else if s1<s2 then
  491. exit(-1)
  492. else
  493. exit(0);
  494. end;
  495. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
  496. {$ifndef FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
  497. function strpas(p:pchar):shortstring;[public,alias:'FPC_PCHAR_TO_SHORTSTR'];
  498. var
  499. l : longint;
  500. s: shortstring;
  501. begin
  502. if p=nil then
  503. l:=0
  504. else
  505. l:=strlen(p);
  506. if l>255 then
  507. l:=255;
  508. if l>0 then
  509. move(p^,s[1],l);
  510. s[0]:=chr(l);
  511. strpas := s;
  512. end;
  513. {$endif ndef FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
  514. {$ifndef FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
  515. function strchararray(p:pchar; l : longint):shortstring;[public,alias:'FPC_CHARARRAY_TO_SHORTSTR'];
  516. var
  517. s: shortstring;
  518. begin
  519. if l>=256 then
  520. l:=255
  521. else if l<0 then
  522. l:=0;
  523. move(p^,s[1],l);
  524. s[0]:=chr(l);
  525. strchararray := s;
  526. end;
  527. {$endif ndef FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
  528. {$ifopt r+}
  529. {$define rangeon}
  530. {$r-}
  531. {$endif}
  532. {$ifndef FPC_SYSTEM_HAS_FPC_STR_TO_CHARARRAY}
  533. procedure str_to_chararray(strtyp, arraysize: longint; src,dest: pchar);[public,alias:'FPC_STR_TO_CHARARRAY'];
  534. type
  535. plongint = ^longint;
  536. var
  537. len: longint;
  538. begin
  539. case strtyp of
  540. { shortstring }
  541. 0:
  542. begin
  543. len := byte(src[0]);
  544. inc(src);
  545. end;
  546. { ansistring}
  547. 1: len := length(ansistring(pointer(src)));
  548. { longstring }
  549. 2:;
  550. { widestring }
  551. 3:;
  552. end;
  553. if len > arraysize then
  554. len := arraysize;
  555. { make sure we don't dereference src if it can be nil (JM) }
  556. if len > 0 then
  557. move(src^,dest^,len);
  558. fillchar(dest[len],arraysize-len,0);
  559. end;
  560. {$endif FPC_SYSTEM_HAS_FPC_STR_TO_CHARARRAY}
  561. {$ifdef rangeon}
  562. {$r+}
  563. {undef rangeon}
  564. {$endif rangeon}
  565. {$ifndef FPC_SYSTEM_HAS_STRLEN}
  566. function strlen(p:pchar):longint;
  567. var i : longint;
  568. begin
  569. i:=0;
  570. while p[i]<>#0 do inc(i);
  571. exit(i);
  572. end;
  573. {$endif ndef FPC_SYSTEM_HAS_STRLEN}
  574. {****************************************************************************
  575. Caller/StackFrame Helpers
  576. ****************************************************************************}
  577. {$ifndef FPC_SYSTEM_HAS_GET_FRAME}
  578. {$error Get_frame must be defined for each processor }
  579. {$endif ndef FPC_SYSTEM_HAS_GET_FRAME}
  580. {$ifndef FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  581. {$error Get_caller_addr must be defined for each processor }
  582. {$endif ndef FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  583. {$ifndef FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  584. {$error Get_caller_frame must be defined for each processor }
  585. {$endif ndef FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  586. {****************************************************************************
  587. Math
  588. ****************************************************************************}
  589. {$ifndef FPC_SYSTEM_HAS_ABS_LONGINT}
  590. function abs(l:longint):longint;[internconst:in_const_abs];
  591. begin
  592. if l<0 then
  593. abs:=-l
  594. else
  595. abs:=l;
  596. end;
  597. {$endif ndef FPC_SYSTEM_HAS_ABS_LONGINT}
  598. {$ifndef FPC_SYSTEM_HAS_ODD_LONGINT}
  599. function odd(l:longint):boolean;
  600. begin
  601. odd:=boolean(l and 1);
  602. end;
  603. {$endif ndef FPC_SYSTEM_HAS_ODD_LONGINT}
  604. {$ifndef FPC_SYSTEM_HAS_ODD_CARDINAL}
  605. function odd(l:cardinal):boolean;
  606. begin
  607. odd:=boolean(l and 1);
  608. end;
  609. {$endif ndef FPC_SYSTEM_HAS_ODD_CARDINAL}
  610. {$ifndef FPC_SYSTEM_HAS_ODD_INT64}
  611. function odd(l:int64):boolean;[internconst:in_const_odd];
  612. begin
  613. odd:=boolean(longint(l) and 1);
  614. end;
  615. {$endif ndef FPC_SYSTEM_HAS_ODD_INT64}
  616. {$ifndef FPC_SYSTEM_HAS_ODD_QWORD}
  617. function odd(l:qword):boolean;
  618. begin
  619. odd:=boolean(longint(l) and 1);
  620. end;
  621. {$endif ndef FPC_SYSTEM_HAS_ODD_QWORD}
  622. {$ifndef FPC_SYSTEM_HAS_SQR_LONGINT}
  623. function sqr(l:longint):longint;[internconst:in_const_sqr];
  624. begin
  625. sqr:=l*l;
  626. end;
  627. {$endif ndef FPC_SYSTEM_HAS_SQR_LONGINT}
  628. {$ifndef FPC_SYSTEM_HAS_SPTR}
  629. {$error Sptr must be defined for each processor }
  630. {$endif ndef FPC_SYSTEM_HAS_SPTR}
  631. {****************************************************************************
  632. Str()
  633. ****************************************************************************}
  634. {$ifndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
  635. procedure int_str(l : longint;var s : string);
  636. var
  637. value: longint;
  638. negative: boolean;
  639. begin
  640. negative := false;
  641. s:='';
  642. { Workaround: }
  643. if l=$80000000 then
  644. begin
  645. s:='-2147483648';
  646. exit;
  647. end;
  648. { handle case where l = 0 }
  649. if l = 0 then
  650. begin
  651. s:='0';
  652. exit;
  653. end;
  654. If l < 0 then
  655. begin
  656. negative := true;
  657. value:=abs(l);
  658. end
  659. else
  660. value:=l;
  661. { handle non-zero case }
  662. while value>0 do
  663. begin
  664. s:=char((value mod 10)+ord('0'))+s;
  665. value := value div 10;
  666. end;
  667. if negative then
  668. s := '-' + s;
  669. end;
  670. {$endif ndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
  671. {$ifndef FPC_SYSTEM_HAS_INT_STR_CARDINAL}
  672. procedure int_str(l : cardinal;var s : string);
  673. begin
  674. s:='';
  675. if l = 0 then
  676. begin
  677. s := '0';
  678. exit;
  679. end;
  680. while l>0 do
  681. begin
  682. s:=char(ord('0')+(l mod 10))+s;
  683. l:=l div 10;
  684. end;
  685. end;
  686. {$endif ndef FPC_SYSTEM_HAS_INT_STR_CARDINAL}
  687. {****************************************************************************
  688. Bounds Check
  689. ****************************************************************************}
  690. {$ifndef NOBOUNDCHECK}
  691. {$ifndef FPC_SYSTEM_HAS_FPC_BOUNDCHECK}
  692. procedure int_boundcheck(l : longint; range : pointer);[public,alias: 'FPC_BOUNDCHECK'];
  693. type
  694. prange = ^trange;
  695. trange = packed record
  696. min,max : longint;
  697. end;
  698. begin
  699. if (l < prange(range)^.min) or
  700. (l > prange(range)^.max) then
  701. HandleError(201);
  702. end;
  703. {$endif ndef FPC_SYSTEM_HAS_FPC_BOUNDCHECK}
  704. {$endif NOBOUNDCHECK}
  705. {
  706. $Log$
  707. Revision 1.12 2001-05-18 22:59:59 peter
  708. * merged fixes branch fixes
  709. Revision 1.11 2001/05/16 17:44:25 jonas
  710. + odd() for cardinal, int64 and qword (merged)
  711. Revision 1.10 2001/05/09 19:57:07 peter
  712. *** empty log message ***
  713. Revision 1.9 2001/04/21 12:16:28 peter
  714. * int_str cardinal fix (merged)
  715. Revision 1.8 2001/04/13 18:06:28 peter
  716. * removed rtllite define
  717. Revision 1.7 2001/03/05 17:10:40 jonas
  718. * changed typecast in FPC_STR_TO_CHARARRAY so that no temp ansistring is
  719. generated anymore (merged)
  720. Revision 1.6 2001/03/03 12:41:22 jonas
  721. * simplified and optimized range checking code, FPC_BOUNDCHECK is no longer necessary
  722. Revision 1.5 2000/10/01 13:17:35 michael
  723. + Merged from fixbranch
  724. Revision 1.4 2000/08/09 11:29:01 jonas
  725. Revision 1.1.2.2 2000/10/01 13:14:50 michael
  726. + Corrected and (hopefully) improved compare0
  727. Revision 1.1.2.1 2000/08/09 11:21:32 jonas
  728. + FPC_STR_TO_CHARARRAY routine necessary for string -> chararray
  729. conversions fix (merged fropm fixes branch)
  730. Revision 1.3 2000/07/14 10:33:10 michael
  731. + Conditionals fixed
  732. Revision 1.2 2000/07/13 11:33:43 michael
  733. + removed logs
  734. }