generic.inc 18 KB

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