generic.inc 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by the Free Pascal development team.
  4. Processor independent implementation for the system unit
  5. (adapted for intel i386.inc file)
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {****************************************************************************
  13. Primitives
  14. ****************************************************************************}
  15. type
  16. pstring = ^shortstring;
  17. {$ifndef FPC_SYSTEM_HAS_MOVE}
  18. procedure Move(const source;var dest;count:SizeInt);[public, alias: 'FPC_MOVE'];
  19. type
  20. bytearray = array [0..high(sizeint)-1] of byte;
  21. var
  22. i:longint;
  23. begin
  24. if count <= 0 then exit;
  25. Dec(count);
  26. if @source<@dest then
  27. begin
  28. for i:=count downto 0 do
  29. bytearray(dest)[i]:=bytearray(source)[i];
  30. end
  31. else
  32. begin
  33. for i:=0 to count do
  34. bytearray(dest)[i]:=bytearray(source)[i];
  35. end;
  36. end;
  37. {$endif not FPC_SYSTEM_HAS_MOVE}
  38. {$ifndef FPC_SYSTEM_HAS_FILLCHAR}
  39. Procedure FillChar(var x;count:SizeInt;value:byte);
  40. type
  41. longintarray = array [0..high(sizeint) div 4-1] of longint;
  42. bytearray = array [0..high(sizeint)-1] of byte;
  43. var
  44. i,v : longint;
  45. begin
  46. if count <= 0 then exit;
  47. v := 0;
  48. { aligned? }
  49. if (PtrUInt(@x) mod sizeof(PtrUInt))<>0 then
  50. begin
  51. for i:=0 to count-1 do
  52. bytearray(x)[i]:=value;
  53. end
  54. else
  55. begin
  56. v:=(value shl 8) or (value and $FF);
  57. v:=(v shl 16) or (v and $ffff);
  58. for i:=0 to (count div 4)-1 do
  59. longintarray(x)[i]:=v;
  60. for i:=(count div 4)*4 to count-1 do
  61. bytearray(x)[i]:=value;
  62. end;
  63. end;
  64. {$endif FPC_SYSTEM_HAS_FILLCHAR}
  65. {$ifndef INTERNALMOVEFILLCHAR}
  66. {$ifndef FPC_SYSTEM_HAS_FILLBYTE}
  67. procedure FillByte (var x;count : SizeInt;value : byte );
  68. begin
  69. FillChar (X,Count,CHR(VALUE));
  70. end;
  71. {$endif not FPC_SYSTEM_HAS_FILLBYTE}
  72. {$endif INTERNALMOVEFILLCHAR}
  73. {$ifndef FPC_SYSTEM_HAS_FILLWORD}
  74. procedure fillword(var x;count : SizeInt;value : word);
  75. type
  76. longintarray = array [0..high(sizeint) div 4-1] of longint;
  77. wordarray = array [0..high(sizeint) div 2-1] of word;
  78. var
  79. i,v : longint;
  80. begin
  81. if Count <= 0 then exit;
  82. { aligned? }
  83. if (PtrUInt(@x) mod sizeof(PtrUInt))<>0 then
  84. begin
  85. for i:=0 to count-1 do
  86. wordarray(x)[i]:=value;
  87. end
  88. else
  89. begin
  90. v:=value*$10000+value;
  91. for i:=0 to (count div 2) -1 do
  92. longintarray(x)[i]:=v;
  93. for i:=(count div 2)*2 to count-1 do
  94. wordarray(x)[i]:=value;
  95. end;
  96. end;
  97. {$endif not FPC_SYSTEM_HAS_FILLWORD}
  98. {$ifndef FPC_SYSTEM_HAS_FILLDWORD}
  99. procedure FillDWord(var x;count : SizeInt;value : DWord);
  100. type
  101. longintarray = array [0..high(sizeint) div 4-1] of longint;
  102. begin
  103. if count <= 0 then exit;
  104. while Count<>0 do
  105. begin
  106. { range checking must be disabled here }
  107. longintarray(x)[count-1]:=longint(value);
  108. Dec(count);
  109. end;
  110. end;
  111. {$endif FPC_SYSTEM_HAS_FILLDWORD}
  112. {$ifndef FPC_SYSTEM_HAS_INDEXCHAR}
  113. function IndexChar(Const buf;len:SizeInt;b:char):SizeInt;
  114. begin
  115. IndexChar:=IndexByte(Buf,Len,byte(B));
  116. end;
  117. {$endif not FPC_SYSTEM_HAS_INDEXCHAR}
  118. {$ifndef FPC_SYSTEM_HAS_INDEXBYTE}
  119. function IndexByte(Const buf;len:SizeInt;b:byte):SizeInt;
  120. type
  121. bytearray = array [0..high(sizeint)-1] of byte;
  122. var
  123. I : longint;
  124. begin
  125. I:=0;
  126. { simulate assembler implementations behaviour, which is expected }
  127. { fpc_pchar_to_ansistr in astrings.inc }
  128. if (len < 0) then
  129. len := high(longint);
  130. while (I<Len) and (bytearray(buf)[I]<>b) do
  131. inc(I);
  132. if (i=Len) then
  133. i:=-1; {Can't use 0, since it is a possible value}
  134. IndexByte:=I;
  135. end;
  136. {$endif not FPC_SYSTEM_HAS_INDEXBYTE}
  137. {$ifndef FPC_SYSTEM_HAS_INDEXWORD}
  138. function Indexword(Const buf;len:SizeInt;b:word):SizeInt;
  139. type
  140. wordarray = array [0..high(sizeint) div 2-1] of word;
  141. var
  142. I : longint;
  143. begin
  144. I:=0;
  145. if (len < 0) then
  146. len := high(longint);
  147. while (I<Len) and (wordarray(buf)[I]<>b) do
  148. inc(I);
  149. if (i=Len) then
  150. i:=-1; {Can't use 0, since it is a possible value for index}
  151. Indexword:=I;
  152. end;
  153. {$endif not FPC_SYSTEM_HAS_INDEXWORD}
  154. {$ifndef FPC_SYSTEM_HAS_INDEXDWORD}
  155. function IndexDWord(Const buf;len:SizeInt;b:DWord):SizeInt;
  156. type
  157. dwordarray = array [0..high(sizeint) div 4-1] of dword;
  158. var
  159. I : longint;
  160. begin
  161. I:=0;
  162. if (len < 0) then
  163. len := high(longint);
  164. while (I<Len) and (dwordarray(buf)[I]<>b) do
  165. inc(I);
  166. if (i=Len) then
  167. i:=-1; {Can't use 0, since it is a possible value for index}
  168. IndexDWord:=I;
  169. end;
  170. {$endif not FPC_SYSTEM_HAS_INDEXDWORD}
  171. {$ifndef FPC_SYSTEM_HAS_COMPARECHAR}
  172. function CompareChar(Const buf1,buf2;len:SizeInt):SizeInt;
  173. begin
  174. CompareChar:=CompareByte(buf1,buf2,len);
  175. end;
  176. {$endif not FPC_SYSTEM_HAS_COMPARECHAR}
  177. {$ifndef FPC_SYSTEM_HAS_COMPAREBYTE}
  178. function CompareByte(Const buf1,buf2;len:SizeInt):SizeInt;
  179. type
  180. bytearray = array [0..high(sizeint)-1] of byte;
  181. var
  182. I : longint;
  183. begin
  184. I:=0;
  185. if (Len<>0) and (@Buf1<>@Buf2) then
  186. begin
  187. while (bytearray(Buf1)[I]=bytearray(Buf2)[I]) and (I<Len) do
  188. inc(I);
  189. if I=Len then {No difference}
  190. I:=0
  191. else
  192. begin
  193. I:=bytearray(Buf1)[I]-bytearray(Buf2)[I];
  194. if I>0 then
  195. I:=1
  196. else
  197. if I<0 then
  198. I:=-1;
  199. end;
  200. end;
  201. CompareByte:=I;
  202. end;
  203. {$endif not FPC_SYSTEM_HAS_COMPAREBYTE}
  204. {$ifndef FPC_SYSTEM_HAS_COMPAREWORD}
  205. function CompareWord(Const buf1,buf2;len:SizeInt):SizeInt;
  206. type
  207. wordarray = array [0..high(sizeint) div 2-1] of word;
  208. var
  209. I : longint;
  210. begin
  211. I:=0;
  212. if (Len<>0) and (@Buf1<>@Buf2) then
  213. begin
  214. while (wordarray(Buf1)[I]=wordarray(Buf2)[I]) and (I<Len) do
  215. inc(I);
  216. if I=Len then {No difference}
  217. I:=0
  218. else
  219. begin
  220. I:=wordarray(Buf1)[I]-wordarray(Buf2)[I];
  221. if I>0 then
  222. I:=1
  223. else
  224. if I<0 then
  225. I:=-1;
  226. end;
  227. end;
  228. CompareWord:=I;
  229. end;
  230. {$endif not FPC_SYSTEM_HAS_COMPAREWORD}
  231. {$ifndef FPC_SYSTEM_HAS_COMPAREDWORD}
  232. function CompareDWord(Const buf1,buf2;len:SizeInt):SizeInt;
  233. type
  234. longintarray = array [0..high(sizeint) div 4-1] of longint;
  235. var
  236. I : longint;
  237. begin
  238. I:=0;
  239. if (Len<>0) and (@Buf1<>@Buf2) then
  240. begin
  241. while (longintarray(Buf1)[I]=longintarray(Buf2)[I]) and (I<Len) do
  242. inc(I);
  243. if I=Len then {No difference}
  244. I:=0
  245. else
  246. begin
  247. I:=longintarray(Buf1)[I]-longintarray(Buf2)[I];
  248. if I>0 then
  249. I:=1
  250. else
  251. if I<0 then
  252. I:=-1;
  253. end;
  254. end;
  255. CompareDWord:=I;
  256. end;
  257. {$endif ndef FPC_SYSTEM_HAS_COMPAREDWORD}
  258. {$ifndef FPC_SYSTEM_HAS_MOVECHAR0}
  259. procedure MoveChar0(Const buf1;var buf2;len:SizeInt);
  260. var
  261. I : longint;
  262. begin
  263. if Len = 0 then exit;
  264. I:=IndexByte(Buf1,Len,0);
  265. if I<>-1 then
  266. Move(Buf1,Buf2,I)
  267. else
  268. Move(Buf1,Buf2,len);
  269. end;
  270. {$endif ndef FPC_SYSTEM_HAS_MOVECHAR0}
  271. {$ifndef FPC_SYSTEM_HAS_INDEXCHAR0}
  272. function IndexChar0(Const buf;len:SizeInt;b:Char):SizeInt;
  273. var
  274. I : longint;
  275. begin
  276. if Len<>0 then
  277. begin
  278. I:=IndexByte(Buf,Len,0);
  279. If (I=-1) then
  280. I:=Len;
  281. IndexChar0:=IndexByte(Buf,I,byte(b));
  282. end
  283. else
  284. IndexChar0:=0;
  285. end;
  286. {$endif ndef FPC_SYSTEM_HAS_INDEXCHAR0}
  287. {$ifndef FPC_SYSTEM_HAS_COMPARECHAR0}
  288. function CompareChar0(Const buf1,buf2;len:SizeInt):SizeInt;
  289. type
  290. bytearray = array [0..high(sizeint)-1] of byte;
  291. var
  292. i : longint;
  293. begin
  294. I:=0;
  295. if (Len<>0) and (@Buf1<>@Buf2) then
  296. begin
  297. while (I<Len) And
  298. ((Pbyte(@Buf1)[i]<>0) and (PByte(@buf2)[i]<>0)) and
  299. (pbyte(@Buf1)[I]=pbyte(@Buf2)[I]) do
  300. inc(I);
  301. if (I=Len) or
  302. (PByte(@Buf1)[i]=0) or
  303. (PByte(@buf2)[I]=0) then {No difference or 0 reached }
  304. I:=0
  305. else
  306. begin
  307. I:=bytearray(Buf1)[I]-bytearray(Buf2)[I];
  308. if I>0 then
  309. I:=1
  310. else
  311. if I<0 then
  312. I:=-1;
  313. end;
  314. end;
  315. CompareChar0:=I;
  316. end;
  317. {$endif not FPC_SYSTEM_HAS_COMPARECHAR0}
  318. {****************************************************************************
  319. Object Helpers
  320. ****************************************************************************}
  321. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_CONSTRUCTOR}
  322. { Note: _vmt will be reset to -1 when memory is allocated,
  323. this is needed for fpc_help_fail }
  324. function fpc_help_constructor(_self:pointer;var _vmt:pointer;_vmt_pos:cardinal):pointer;[public,alias:'FPC_HELP_CONSTRUCTOR'];compilerproc;
  325. type
  326. ppointer = ^pointer;
  327. pvmt = ^tvmt;
  328. tvmt=packed record
  329. size,msize:ptrint;
  330. parent:pointer;
  331. end;
  332. var
  333. vmtcopy : pointer;
  334. begin
  335. { Inherited call? }
  336. if _vmt=nil then
  337. begin
  338. fpc_help_constructor:=_self;
  339. exit;
  340. end;
  341. vmtcopy:=_vmt;
  342. if (_self=nil) and
  343. (pvmt(_vmt)^.size>0) then
  344. begin
  345. getmem(_self,pvmt(_vmt)^.size);
  346. { reset vmt needed for fail }
  347. _vmt:=pointer(-1);
  348. end;
  349. if _self<>nil then
  350. begin
  351. fillchar(_self^,pvmt(vmtcopy)^.size,#0);
  352. ppointer(_self+_vmt_pos)^:=vmtcopy;
  353. end;
  354. fpc_help_constructor:=_self;
  355. end;
  356. {$endif FPC_SYSTEM_HAS_FPC_HELP_CONSTRUCTOR}
  357. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_DESTRUCTOR}
  358. { Note: _self will not be reset, the compiler has to generate the reset }
  359. procedure fpc_help_destructor(_self,_vmt:pointer;vmt_pos:cardinal);[public,alias:'FPC_HELP_DESTRUCTOR']; compilerproc;
  360. type
  361. ppointer = ^pointer;
  362. pvmt = ^tvmt;
  363. tvmt = packed record
  364. size,msize : ptrint;
  365. parent : pointer;
  366. end;
  367. begin
  368. { already released? }
  369. if (_self=nil) or
  370. (_vmt=nil) or
  371. (ppointer(_self+vmt_pos)^=nil) then
  372. exit;
  373. if (pvmt(ppointer(_self+vmt_pos)^)^.size=0) or
  374. (pvmt(ppointer(_self+vmt_pos)^)^.size+pvmt(ppointer(_self+vmt_pos)^)^.msize<>0) then
  375. RunError(210);
  376. { reset vmt to nil for protection }
  377. ppointer(_self+vmt_pos)^:=nil;
  378. freemem(_self);
  379. end;
  380. {$endif FPC_SYSTEM_HAS_FPC_HELP_DESTRUCTOR}
  381. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_FAIL}
  382. { Note: _self will not be reset, the compiler has to generate the reset }
  383. procedure fpc_help_fail(_self:pointer;var _vmt:pointer;vmt_pos:cardinal);[public,alias:'FPC_HELP_FAIL'];compilerproc;
  384. type
  385. ppointer = ^pointer;
  386. pvmt = ^tvmt;
  387. tvmt = packed record
  388. size,msize : ptrint;
  389. parent : pointer;
  390. end;
  391. begin
  392. if (_self=nil) or (_vmt=nil) then
  393. exit;
  394. { vmt=-1 when memory was allocated }
  395. if ptrint(_vmt)=-1 then
  396. begin
  397. if (_self=nil) or (ppointer(_self+vmt_pos)^=nil) then
  398. HandleError(210)
  399. else
  400. begin
  401. ppointer(_self+vmt_pos)^:=nil;
  402. freemem(_self);
  403. { reset _vmt to nil so it will not be freed a
  404. second time }
  405. _vmt:=nil;
  406. end;
  407. end
  408. else
  409. ppointer(_self+vmt_pos)^:=nil;
  410. end;
  411. {$endif FPC_SYSTEM_HAS_FPC_HELP_FAIL}
  412. {$ifndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT}
  413. procedure fpc_check_object(_vmt : pointer); [public,alias:'FPC_CHECK_OBJECT']; compilerproc;
  414. type
  415. pvmt = ^tvmt;
  416. tvmt = packed record
  417. size,msize : ptrint;
  418. parent : pointer;
  419. end;
  420. begin
  421. if (_vmt=nil) or
  422. (pvmt(_vmt)^.size=0) or
  423. (pvmt(_vmt)^.size+pvmt(_vmt)^.msize<>0) then
  424. RunError(210);
  425. end;
  426. {$endif ndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT}
  427. {$ifndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT_EXT}
  428. { checks for a correct vmt pointer }
  429. { deeper check to see if the current object is }
  430. { really related to the true }
  431. procedure fpc_check_object_ext(vmt, expvmt : pointer); [public,alias:'FPC_CHECK_OBJECT_EXT']; compilerproc;
  432. type
  433. pvmt = ^tvmt;
  434. tvmt = packed record
  435. size,msize : ptrint;
  436. parent : pointer;
  437. end;
  438. begin
  439. if (vmt=nil) or
  440. (pvmt(vmt)^.size=0) or
  441. (pvmt(vmt)^.size+pvmt(vmt)^.msize<>0) then
  442. RunError(210);
  443. while assigned(vmt) do
  444. if vmt=expvmt then
  445. exit
  446. else
  447. vmt:=pvmt(vmt)^.parent;
  448. RunError(219);
  449. end;
  450. {$endif not FPC_SYSTEM_HAS_FPC_CHECK_OBJECT_EXT}
  451. {****************************************************************************
  452. String
  453. ****************************************************************************}
  454. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_ASSIGN}
  455. function fpc_shortstr_to_shortstr(len:longint;const sstr:shortstring): shortstring;[public,alias:'FPC_SHORTSTR_TO_SHORTSTR']; compilerproc;
  456. var
  457. slen : byte;
  458. begin
  459. slen:=length(sstr);
  460. if slen<len then
  461. len:=slen;
  462. move(sstr[0],result[0],len+1);
  463. if slen>len then
  464. result[0]:=chr(len);
  465. end;
  466. procedure fpc_shortstr_assign(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_ASSIGN']; {$ifdef HAS_COMPILER_PROC} compilerproc; {$endif}
  467. var
  468. slen : byte;
  469. type
  470. pstring = ^string;
  471. begin
  472. slen:=length(pstring(sstr)^);
  473. if slen<len then
  474. len:=slen;
  475. move(sstr^,dstr^,len+1);
  476. if slen>len then
  477. pchar(dstr)^:=chr(len);
  478. end;
  479. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_ASSIGN}
  480. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
  481. function fpc_shortstr_concat(const s1,s2:shortstring): shortstring;[public,alias:'FPC_SHORTSTR_CONCAT']; compilerproc;
  482. var
  483. s1l, s2l : byte;
  484. begin
  485. s1l:=length(s1);
  486. s2l:=length(s2);
  487. if s1l+s2l>255 then
  488. s2l:=255-s1l;
  489. move(s1[1],fpc_shortstr_concat[1],s1l);
  490. move(s2[1],fpc_shortstr_concat[s1l+1],s2l);
  491. fpc_shortstr_concat[0]:=chr(s1l+s2l);
  492. end;
  493. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
  494. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_APPEND_SHORTSTR}
  495. procedure fpc_shortstr_append_shortstr(var s1:shortstring;const s2:shortstring);compilerproc;
  496. [public,alias:'FPC_SHORTSTR_APPEND_SHORTSTR'];
  497. var
  498. s1l, s2l : byte;
  499. begin
  500. s1l:=length(s1);
  501. s2l:=length(s2);
  502. if s1l+s2l>high(s1) then
  503. s2l:=high(s1)-s1l;
  504. move(s2[1],s1[s1l+1],s2l);
  505. s1[0]:=chr(s1l+s2l);
  506. end;
  507. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_APPEND_SHORTSTR}
  508. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
  509. function fpc_shortstr_compare(const left,right:shortstring) : longint;[public,alias:'FPC_SHORTSTR_COMPARE']; compilerproc;
  510. var
  511. s1,s2,max,i : byte;
  512. d : longint;
  513. begin
  514. s1:=length(left);
  515. s2:=length(right);
  516. if s1<s2 then
  517. max:=s1
  518. else
  519. max:=s2;
  520. for i:=1 to max do
  521. begin
  522. d:=byte(left[i])-byte(right[i]);
  523. if d>0 then
  524. exit(1)
  525. else if d<0 then
  526. exit(-1);
  527. end;
  528. if s1>s2 then
  529. exit(1)
  530. else if s1<s2 then
  531. exit(-1)
  532. else
  533. exit(0);
  534. end;
  535. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
  536. {$ifndef FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
  537. function fpc_pchar_to_shortstr(p:pchar):shortstring;[public,alias:'FPC_PCHAR_TO_SHORTSTR']; compilerproc;
  538. var
  539. l : longint;
  540. s: shortstring;
  541. begin
  542. if p=nil then
  543. l:=0
  544. else
  545. l:=strlen(p);
  546. if l>255 then
  547. l:=255;
  548. if l>0 then
  549. move(p^,s[1],l);
  550. s[0]:=chr(l);
  551. fpc_pchar_to_shortstr := s;
  552. end;
  553. {$endif ndef FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
  554. {$ifndef FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
  555. function fpc_chararray_to_shortstr(const arr: array of char; zerobased: boolean = true):shortstring;[public,alias:'FPC_CHARARRAY_TO_SHORTSTR']; compilerproc;
  556. var
  557. l: longint;
  558. index: longint;
  559. len: byte;
  560. begin
  561. l := high(arr)+1;
  562. if l>=256 then
  563. l:=255
  564. else if l<0 then
  565. l:=0;
  566. if (zerobased) then
  567. begin
  568. index:=IndexByte(arr[0],l,0);
  569. if (index < 0) then
  570. len := l
  571. else
  572. len := index;
  573. end
  574. else
  575. len := l;
  576. move(arr[0],fpc_chararray_to_shortstr[1],len);
  577. fpc_chararray_to_shortstr[0]:=chr(len);
  578. end;
  579. {$endif ndef FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
  580. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_TO_CHARARRAY}
  581. { inside the compiler, the resulttype is modified to that of the actual }
  582. { chararray we're converting to (JM) }
  583. function fpc_shortstr_to_chararray(arraysize: longint; const src: ShortString): fpc_big_chararray;[public,alias: 'FPC_SHORTSTR_TO_CHARARRAY']; compilerproc;
  584. var
  585. len: longint;
  586. begin
  587. len := length(src);
  588. if len > arraysize then
  589. len := arraysize;
  590. { make sure we don't access char 1 if length is 0 (JM) }
  591. if len > 0 then
  592. move(src[1],fpc_shortstr_to_chararray[0],len);
  593. fillchar(fpc_shortstr_to_chararray[len],arraysize-len,0);
  594. end;
  595. {$endif FPC_SYSTEM_HAS_FPC_SHORTSTR_TO_CHARARRAY}
  596. {$ifndef FPC_SYSTEM_HAS_FPC_PCHAR_LENGTH}
  597. function fpc_pchar_length(p:pchar):longint;[public,alias:'FPC_PCHAR_LENGTH']; compilerproc;
  598. var i : longint;
  599. begin
  600. i:=0;
  601. while p[i]<>#0 do inc(i);
  602. exit(i);
  603. end;
  604. {$endif ndef FPC_SYSTEM_HAS_FPC_PCHAR_LENGTH}
  605. {$ifndef FPC_SYSTEM_HAS_FPC_PWIDECHAR_LENGTH}
  606. function fpc_pwidechar_length(p:pwidechar):longint;[public,alias:'FPC_PWIDECHAR_LENGTH']; compilerproc;
  607. var i : longint;
  608. begin
  609. i:=0;
  610. while p[i]<>#0 do inc(i);
  611. exit(i);
  612. end;
  613. {$endif ndef FPC_SYSTEM_HAS_FPC_PWIDECHAR_LENGTH}
  614. {****************************************************************************
  615. Caller/StackFrame Helpers
  616. ****************************************************************************}
  617. {$ifndef FPC_SYSTEM_HAS_GET_FRAME}
  618. {_$error Get_frame must be defined for each processor }
  619. {$endif ndef FPC_SYSTEM_HAS_GET_FRAME}
  620. {$ifndef FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  621. {_$error Get_caller_addr must be defined for each processor }
  622. {$endif ndef FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  623. {$ifndef FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  624. {_$error Get_caller_frame must be defined for each processor }
  625. {$endif ndef FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  626. {****************************************************************************
  627. Math
  628. ****************************************************************************}
  629. {****************************************************************************
  630. Software longint/dword division
  631. ****************************************************************************}
  632. {$ifdef FPC_INCLUDE_SOFTWARE_MOD_DIV}
  633. function count_leading_zeros_32bit(l : longint) : longint;
  634. var
  635. i : longint;
  636. begin
  637. for i:=0 to 31 do
  638. begin
  639. if (l and (longint($80000000) shr i))<>0 then
  640. begin
  641. result:=i;
  642. exit;
  643. end;
  644. end;
  645. result:=i;
  646. end;
  647. {$ifndef FPC_SYSTEM_HAS_DIV_DWORD}
  648. function fpc_div_dword(n,z : dword) : dword; [public,alias: 'FPC_DIV_DWORD']; compilerproc;
  649. var
  650. shift,lzz,lzn : longint;
  651. begin
  652. result:=0;
  653. if n=0 then
  654. HandleErrorFrame(200,get_frame);
  655. lzz:=count_leading_zeros_32bit(z);
  656. lzn:=count_leading_zeros_32bit(n);
  657. { if the denominator contains less zeros
  658. then the numerator
  659. the d is greater than the n }
  660. if lzn<lzz then
  661. exit;
  662. shift:=lzn-lzz;
  663. n:=n shl shift;
  664. repeat
  665. if z>=n then
  666. begin
  667. z:=z-n;
  668. result:=result+dword(1 shl shift);
  669. end;
  670. dec(shift);
  671. n:=n shr 1;
  672. until shift<0;
  673. end;
  674. {$endif FPC_SYSTEM_HAS_DIV_DWORD}
  675. {$ifndef FPC_SYSTEM_HAS_MOD_DWORD}
  676. function fpc_mod_dword(n,z : dword) : dword; [public,alias: 'FPC_MOD_DWORD']; compilerproc;
  677. var
  678. shift,lzz,lzn : longint;
  679. begin
  680. result:=0;
  681. if n=0 then
  682. HandleErrorFrame(200,get_frame);
  683. lzz:=count_leading_zeros_32bit(z);
  684. lzn:=count_leading_zeros_32bit(n);
  685. { if the denominator contains less zeros
  686. then the numerator
  687. the d is greater than the n }
  688. if lzn<lzz then
  689. begin
  690. result:=z;
  691. exit;
  692. end;
  693. shift:=lzn-lzz;
  694. n:=n shl shift;
  695. repeat
  696. if z>=n then
  697. z:=z-n;
  698. dec(shift);
  699. n:=n shr 1;
  700. until shift<0;
  701. result:=z;
  702. end;
  703. {$endif FPC_SYSTEM_HAS_MOD_DWORD}
  704. {$ifndef FPC_SYSTEM_HAS_DIV_LONGINT}
  705. function fpc_div_longint(n,z : longint) : longint; [public,alias: 'FPC_DIV_LONGINT']; compilerproc;
  706. var
  707. sign : boolean;
  708. d1,d2 : dword;
  709. begin
  710. if n=0 then
  711. HandleErrorFrame(200,get_frame);
  712. sign:=false;
  713. if z<0 then
  714. begin
  715. sign:=not(sign);
  716. d1:=dword(-z);
  717. end
  718. else
  719. d1:=z;
  720. if n<0 then
  721. begin
  722. sign:=not(sign);
  723. d2:=dword(-n);
  724. end
  725. else
  726. d2:=n;
  727. { the div is coded by the compiler as call to divdword }
  728. if sign then
  729. result:=-(d1 div d2)
  730. else
  731. result:=d1 div d2;
  732. end;
  733. {$endif FPC_SYSTEM_HAS_DIV_LONGINT}
  734. {$ifndef FPC_SYSTEM_HAS_MOD_LONGINT}
  735. function fpc_mod_longint(n,z : longint) : longint; [public,alias: 'FPC_MOD_LONGINT']; compilerproc;
  736. var
  737. signed : boolean;
  738. r,nq,zq : dword;
  739. begin
  740. if n=0 then
  741. HandleErrorFrame(200,get_frame);
  742. nq:=abs(n);
  743. if z<0 then
  744. begin
  745. zq:=dword(-z);
  746. signed:=true;
  747. end
  748. else
  749. begin
  750. zq:=z;
  751. signed:=false;
  752. end;
  753. r:=zq mod nq;
  754. if signed then
  755. result:=-longint(r)
  756. else
  757. result:=r;
  758. end;
  759. {$endif FPC_SYSTEM_HAS_MOD_LONGINT}
  760. {$endif FPC_INCLUDE_SOFTWARE_MOD_DIV}
  761. {****************************************************************************}
  762. {$ifndef FPC_SYSTEM_HAS_ABS_LONGINT}
  763. function abs(l:longint):longint;{$ifdef SYSTEMINLINE}inline;{$endif}
  764. begin
  765. if l<0 then
  766. abs:=-l
  767. else
  768. abs:=l;
  769. end;
  770. {$endif not FPC_SYSTEM_HAS_ABS_LONGINT}
  771. {$ifndef FPC_SYSTEM_HAS_ODD_LONGINT}
  772. function odd(l:longint):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  773. begin
  774. odd:=boolean(l and 1);
  775. end;
  776. {$endif ndef FPC_SYSTEM_HAS_ODD_LONGINT}
  777. {$ifndef FPC_SYSTEM_HAS_ODD_LONGWORD}
  778. function odd(l:longword):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  779. begin
  780. odd:=boolean(l and 1);
  781. end;
  782. {$endif ndef FPC_SYSTEM_HAS_ODD_LONGWORD}
  783. {$ifndef FPC_SYSTEM_HAS_ODD_INT64}
  784. function odd(l:int64):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  785. begin
  786. odd:=boolean(longint(l) and 1);
  787. end;
  788. {$endif ndef FPC_SYSTEM_HAS_ODD_INT64}
  789. {$ifndef FPC_SYSTEM_HAS_ODD_QWORD}
  790. function odd(l:qword):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  791. begin
  792. odd:=boolean(longint(l) and 1);
  793. end;
  794. {$endif ndef FPC_SYSTEM_HAS_ODD_QWORD}
  795. {$ifndef FPC_SYSTEM_HAS_SQR_LONGINT}
  796. function sqr(l:longint):longint;{$ifdef SYSTEMINLINE}inline;{$endif}
  797. begin
  798. sqr:=l*l;
  799. end;
  800. {$endif ndef FPC_SYSTEM_HAS_SQR_LONGINT}
  801. {$ifndef FPC_SYSTEM_HAS_ABS_INT64}
  802. function abs(l: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
  803. begin
  804. if l < 0 then
  805. abs := -l
  806. else
  807. abs := l;
  808. end;
  809. {$endif ndef FPC_SYSTEM_HAS_ABS_INT64}
  810. {$ifndef FPC_SYSTEM_HAS_SQR_INT64}
  811. function sqr(l: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
  812. begin
  813. sqr := l*l;
  814. end;
  815. {$endif ndef FPC_SYSTEM_HAS_SQR_INT64}
  816. {$ifndef FPC_SYSTEM_HAS_SQR_QWORD}
  817. function sqr(l: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  818. begin
  819. sqr := l*l;
  820. end;
  821. {$endif ndef FPC_SYSTEM_HAS_SQR_INT64}
  822. {$ifndef FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
  823. function declocked(var l:longint):boolean;
  824. begin
  825. Dec(l);
  826. declocked:=(l=0);
  827. end;
  828. {$endif FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
  829. {$ifndef FPC_SYSTEM_HAS_DECLOCKED_INT64}
  830. function declocked(var l:int64):boolean;
  831. begin
  832. Dec(l);
  833. declocked:=(l=0);
  834. end;
  835. {$endif FPC_SYSTEM_HAS_DECLOCKED_INT64}
  836. {$ifndef FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  837. procedure inclocked(var l:longint);
  838. begin
  839. Inc(l);
  840. end;
  841. {$endif FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  842. {$ifndef FPC_SYSTEM_HAS_INCLOCKED_INT64}
  843. procedure inclocked(var l:int64);
  844. begin
  845. Inc(l);
  846. end;
  847. {$endif FPC_SYSTEM_HAS_INCLOCKED_INT64}
  848. {$ifndef FPC_SYSTEM_HAS_SPTR}
  849. {_$error Sptr must be defined for each processor }
  850. {$endif ndef FPC_SYSTEM_HAS_SPTR}
  851. function align(addr : PtrInt;alignment : PtrInt) : PtrInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  852. begin
  853. if addr mod alignment<>0 then
  854. result:=addr+(alignment-(addr mod alignment))
  855. else
  856. result:=addr;
  857. end;
  858. function align(addr : Pointer;alignment : PtrInt) : Pointer;{$ifdef SYSTEMINLINE}inline;{$endif}
  859. begin
  860. if PtrInt(addr) mod alignment<>0 then
  861. result:=pointer(addr+(alignment-(PtrInt(addr) mod alignment)))
  862. else
  863. result:=addr;
  864. end;
  865. {****************************************************************************
  866. Str()
  867. ****************************************************************************}
  868. {$ifndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
  869. procedure int_str(l:longint;out s:string);
  870. var
  871. m,m1 : longword;
  872. pc,pc2 : pchar;
  873. hs : string[32];
  874. begin
  875. pc2:=@s[1];
  876. if (l<0) then
  877. begin
  878. pc2^:='-';
  879. inc(pc2);
  880. m:=longword(-l);
  881. end
  882. else
  883. m:=longword(l);
  884. pc:=@hs[0];
  885. repeat
  886. inc(pc);
  887. m1:=m div 10;
  888. pc^:=char(m-(m1*10)+byte('0'));
  889. m:=m1;
  890. until m=0;
  891. while (pc>pchar(@hs[0])) do
  892. begin
  893. pc2^:=pc^;
  894. dec(pc);
  895. inc(pc2);
  896. end;
  897. s[0]:=char(pc2-pchar(@s[1]));
  898. end;
  899. {$endif ndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
  900. {$ifndef FPC_SYSTEM_HAS_INT_STR_LONGWORD}
  901. procedure int_str(l:longword;out s:string);
  902. var
  903. m1 : longword;
  904. pc,pc2 : pchar;
  905. hs : string[32];
  906. begin
  907. pc2:=@s[1];
  908. pc:=@hs[0];
  909. repeat
  910. inc(pc);
  911. m1:=l div 10;
  912. pc^:=char(l-(m1*10)+byte('0'));
  913. l:=m1;
  914. until l=0;
  915. while (pc>pchar(@hs[0])) do
  916. begin
  917. pc2^:=pc^;
  918. dec(pc);
  919. inc(pc2);
  920. end;
  921. s[0]:=char(pc2-pchar(@s[1]));
  922. end;
  923. {$endif ndef FPC_SYSTEM_HAS_INT_STR_LONGWORD}
  924. {$ifndef FPC_SYSTEM_HAS_INT_STR_INT64}
  925. procedure int_str(l:int64;out s:string);
  926. var
  927. m,m1 : qword;
  928. pc,pc2 : pchar;
  929. hs : string[64];
  930. begin
  931. pc2:=@s[1];
  932. if (l<0) then
  933. begin
  934. pc2^:='-';
  935. inc(pc2);
  936. m:=qword(-l);
  937. end
  938. else
  939. m:=qword(l);
  940. pc:=@hs[0];
  941. repeat
  942. inc(pc);
  943. m1:=m div 10;
  944. pc^:=char(m-(m1*10)+byte('0'));
  945. m:=m1;
  946. until m=0;
  947. while (pc>pchar(@hs[0])) do
  948. begin
  949. pc2^:=pc^;
  950. dec(pc);
  951. inc(pc2);
  952. end;
  953. s[0]:=char(pc2-pchar(@s[1]));
  954. end;
  955. {$endif ndef FPC_SYSTEM_HAS_INT_STR_INT64}
  956. {$ifndef FPC_SYSTEM_HAS_INT_STR_QWORD}
  957. procedure int_str(l:qword;out s:string);
  958. var
  959. m1 : qword;
  960. pc,pc2 : pchar;
  961. hs : string[64];
  962. begin
  963. pc2:=@s[1];
  964. pc:=@hs[0];
  965. repeat
  966. inc(pc);
  967. m1:=l div 10;
  968. pc^:=char(l-(m1*10)+byte('0'));
  969. l:=m1;
  970. until l=0;
  971. while (pc>pchar(@hs[0])) do
  972. begin
  973. pc2^:=pc^;
  974. dec(pc);
  975. inc(pc2);
  976. end;
  977. s[0]:=char(pc2-pchar(@s[1]));
  978. end;
  979. {$endif ndef FPC_SYSTEM_HAS_INT_STR_QWORD}
  980. {$ifndef FPC_SYSTEM_HAS_SYSRESETFPU}
  981. procedure SysResetFpu;{$ifdef SYSTEMINLINE}inline;{$endif}
  982. begin
  983. { nothing todo }
  984. end;
  985. {$endif FPC_SYSTEM_HAS_SYSRESETFPU}