generic.inc 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617
  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:=longint(bytearray(Buf1)[I])-longint(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:=longint(wordarray(Buf1)[I])-longint(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. cardinalarray = array [0..high(sizeint) div 4-1] of cardinal;
  235. var
  236. I : int64;
  237. begin
  238. I:=0;
  239. if (Len<>0) and (@Buf1<>@Buf2) then
  240. begin
  241. while (cardinalarray(Buf1)[I]=cardinalarray(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:=int64(cardinalarray(Buf1)[I])-int64(cardinalarray(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:=longint(bytearray(Buf1)[I])-longint(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. {$ifdef FPC_HAS_FEATURE_OBJECTS}
  322. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_CONSTRUCTOR}
  323. { Note: _vmt will be reset to -1 when memory is allocated,
  324. this is needed for fpc_help_fail }
  325. function fpc_help_constructor(_self:pointer;var _vmt:pointer;_vmt_pos:cardinal):pointer;[public,alias:'FPC_HELP_CONSTRUCTOR'];compilerproc;
  326. type
  327. ppointer = ^pointer;
  328. pvmt = ^tvmt;
  329. tvmt=packed record
  330. size,msize:ptruint;
  331. parent:pointer;
  332. end;
  333. var
  334. vmtcopy : pointer;
  335. begin
  336. { Inherited call? }
  337. if _vmt=nil then
  338. begin
  339. fpc_help_constructor:=_self;
  340. exit;
  341. end;
  342. vmtcopy:=_vmt;
  343. if (_self=nil) and
  344. (pvmt(_vmt)^.size>0) then
  345. begin
  346. getmem(_self,pvmt(_vmt)^.size);
  347. { reset vmt needed for fail }
  348. _vmt:=pointer(-1);
  349. end;
  350. if _self<>nil then
  351. begin
  352. fillchar(_self^,pvmt(vmtcopy)^.size,#0);
  353. ppointer(_self+_vmt_pos)^:=vmtcopy;
  354. end;
  355. fpc_help_constructor:=_self;
  356. end;
  357. {$endif FPC_SYSTEM_HAS_FPC_HELP_CONSTRUCTOR}
  358. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_DESTRUCTOR}
  359. { Note: _self will not be reset, the compiler has to generate the reset }
  360. procedure fpc_help_destructor(_self,_vmt:pointer;vmt_pos:cardinal);[public,alias:'FPC_HELP_DESTRUCTOR']; compilerproc;
  361. type
  362. ppointer = ^pointer;
  363. pvmt = ^tvmt;
  364. tvmt = packed record
  365. size,msize : ptruint;
  366. parent : pointer;
  367. end;
  368. begin
  369. { already released? }
  370. if (_self=nil) or
  371. (_vmt=nil) or
  372. (ppointer(_self+vmt_pos)^=nil) then
  373. exit;
  374. if (pvmt(ppointer(_self+vmt_pos)^)^.size=0) or
  375. (pvmt(ppointer(_self+vmt_pos)^)^.size+pvmt(ppointer(_self+vmt_pos)^)^.msize<>0) then
  376. RunError(210);
  377. { reset vmt to nil for protection }
  378. ppointer(_self+vmt_pos)^:=nil;
  379. freemem(_self);
  380. end;
  381. {$endif FPC_SYSTEM_HAS_FPC_HELP_DESTRUCTOR}
  382. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_FAIL}
  383. { Note: _self will not be reset, the compiler has to generate the reset }
  384. procedure fpc_help_fail(_self:pointer;var _vmt:pointer;vmt_pos:cardinal);[public,alias:'FPC_HELP_FAIL'];compilerproc;
  385. begin
  386. if (_self=nil) or (_vmt=nil) then
  387. exit;
  388. { vmt=$ffffffff when memory was allocated }
  389. if ptruint(_vmt)=high(ptruint) then
  390. begin
  391. if (_self=nil) or (ppointer(_self+vmt_pos)^=nil) then
  392. HandleError(210)
  393. else
  394. begin
  395. ppointer(_self+vmt_pos)^:=nil;
  396. freemem(_self);
  397. { reset _vmt to nil so it will not be freed a
  398. second time }
  399. _vmt:=nil;
  400. end;
  401. end
  402. else
  403. ppointer(_self+vmt_pos)^:=nil;
  404. end;
  405. {$endif FPC_SYSTEM_HAS_FPC_HELP_FAIL}
  406. {$ifndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT}
  407. procedure fpc_check_object(_vmt : pointer); [public,alias:'FPC_CHECK_OBJECT']; compilerproc;
  408. type
  409. pvmt = ^tvmt;
  410. tvmt = packed record
  411. size,msize : ptruint;
  412. parent : pointer;
  413. end;
  414. begin
  415. if (_vmt=nil) or
  416. (pvmt(_vmt)^.size=0) or
  417. (pvmt(_vmt)^.size+pvmt(_vmt)^.msize<>0) then
  418. RunError(210);
  419. end;
  420. {$endif ndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT}
  421. {$ifndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT_EXT}
  422. { checks for a correct vmt pointer }
  423. { deeper check to see if the current object is }
  424. { really related to the true }
  425. procedure fpc_check_object_ext(vmt, expvmt : pointer); [public,alias:'FPC_CHECK_OBJECT_EXT']; compilerproc;
  426. type
  427. pvmt = ^tvmt;
  428. tvmt = packed record
  429. size,msize : ptruint;
  430. parent : pointer;
  431. end;
  432. begin
  433. if (vmt=nil) or
  434. (pvmt(vmt)^.size=0) or
  435. (pvmt(vmt)^.size+pvmt(vmt)^.msize<>0) then
  436. RunError(210);
  437. while assigned(vmt) do
  438. if vmt=expvmt then
  439. exit
  440. else
  441. vmt:=pvmt(vmt)^.parent;
  442. RunError(219);
  443. end;
  444. {$endif not FPC_SYSTEM_HAS_FPC_CHECK_OBJECT_EXT}
  445. {$endif FPC_HAS_FEATURE_OBJECTS}
  446. {****************************************************************************
  447. String
  448. ****************************************************************************}
  449. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_ASSIGN}
  450. function fpc_shortstr_to_shortstr(len:longint;const sstr:shortstring): shortstring;[public,alias:'FPC_SHORTSTR_TO_SHORTSTR']; compilerproc;
  451. var
  452. slen : byte;
  453. begin
  454. slen:=length(sstr);
  455. if slen<len then
  456. len:=slen;
  457. move(sstr[0],result[0],len+1);
  458. if slen>len then
  459. result[0]:=chr(len);
  460. end;
  461. procedure fpc_shortstr_assign(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_ASSIGN']; {$ifdef HAS_COMPILER_PROC} compilerproc; {$endif}
  462. var
  463. slen : byte;
  464. type
  465. pstring = ^string;
  466. begin
  467. slen:=length(pstring(sstr)^);
  468. if slen<len then
  469. len:=slen;
  470. move(sstr^,dstr^,len+1);
  471. if slen>len then
  472. pchar(dstr)^:=chr(len);
  473. end;
  474. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_ASSIGN}
  475. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
  476. {$ifndef STR_CONCAT_PROCS}
  477. function fpc_shortstr_concat(const s1,s2:shortstring): shortstring;[public,alias:'FPC_SHORTSTR_CONCAT']; compilerproc;
  478. var
  479. s1l, s2l : byte;
  480. begin
  481. s1l:=length(s1);
  482. s2l:=length(s2);
  483. if s1l+s2l>255 then
  484. s2l:=255-s1l;
  485. move(s1[1],fpc_shortstr_concat[1],s1l);
  486. move(s2[1],fpc_shortstr_concat[s1l+1],s2l);
  487. fpc_shortstr_concat[0]:=chr(s1l+s2l);
  488. end;
  489. {$else STR_CONCAT_PROCS}
  490. procedure fpc_shortstr_concat(var dests:shortstring;const s1,s2:shortstring);compilerproc;
  491. var
  492. s1l, s2l : longint;
  493. begin
  494. s1l:=length(s1);
  495. s2l:=length(s2);
  496. if s1l+s2l>high(dests) then
  497. s2l:=high(dests)-s1l;
  498. if @dests=@s1 then
  499. move(s2[1],dests[s1l+1],s2l)
  500. else
  501. if @dests=@s2 then
  502. begin
  503. move(dests[1],dests[s1l+1],s2l);
  504. move(s1[1],dests[1],s1l);
  505. end
  506. else
  507. begin
  508. move(s1[1],dests[1],s1l);
  509. move(s2[1],dests[s1l+1],s2l);
  510. end;
  511. dests[0]:=chr(s1l+s2l);
  512. end;
  513. procedure fpc_shortstr_concat_multi(var dests:shortstring;const sarr:array of pshortstring);compilerproc;
  514. var
  515. s2l : byte;
  516. LowStart,i,
  517. Len : longint;
  518. pc : pchar;
  519. needtemp : boolean;
  520. tmpstr : shortstring;
  521. p,pdest : pshortstring;
  522. begin
  523. if high(sarr)=0 then
  524. begin
  525. DestS:='';
  526. exit;
  527. end;
  528. lowstart:=low(sarr);
  529. if Pointer(@DestS)=Pointer(sarr[lowstart]) then
  530. inc(lowstart);
  531. { Check for another reuse, then we can't use
  532. the append optimization and need to use a temp }
  533. needtemp:=false;
  534. for i:=lowstart to high(sarr) do
  535. begin
  536. if Pointer(@DestS)=Pointer(sarr[i]) then
  537. begin
  538. needtemp:=true;
  539. break;
  540. end;
  541. end;
  542. if needtemp then
  543. begin
  544. lowstart:=low(sarr);
  545. tmpstr:='';
  546. pdest:=@tmpstr
  547. end
  548. else
  549. begin
  550. { Start with empty DestS if we start with concatting
  551. the first array element }
  552. if lowstart=low(sarr) then
  553. DestS:='';
  554. pdest:=@DestS;
  555. end;
  556. { Concat all strings, except the string we already
  557. copied in DestS }
  558. Len:=length(pdest^);
  559. pc:=@pdest^[1+Length(pdest^)];
  560. for i:=lowstart to high(sarr) do
  561. begin
  562. p:=sarr[i];
  563. if assigned(p) then
  564. begin
  565. s2l:=length(p^);
  566. if Len+s2l>high(dests) then
  567. s2l:=high(dests)-Len;
  568. Move(p^[1],pc^,s2l);
  569. inc(pc,s2l);
  570. inc(Len,s2l);
  571. end;
  572. end;
  573. pdest^[0]:=Chr(Len);
  574. if needtemp then
  575. DestS:=TmpStr;
  576. end;
  577. {$endif STR_CONCAT_PROCS}
  578. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
  579. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_APPEND_SHORTSTR}
  580. procedure fpc_shortstr_append_shortstr(var s1:shortstring;const s2:shortstring);compilerproc;
  581. [public,alias:'FPC_SHORTSTR_APPEND_SHORTSTR'];
  582. var
  583. s1l, s2l : integer;
  584. begin
  585. s1l:=length(s1);
  586. s2l:=length(s2);
  587. if s1l+s2l>high(s1) then
  588. s2l:=high(s1)-s1l;
  589. move(s2[1],s1[s1l+1],s2l);
  590. s1[0]:=chr(s1l+s2l);
  591. end;
  592. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_APPEND_SHORTSTR}
  593. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
  594. function fpc_shortstr_compare(const left,right:shortstring) : longint;[public,alias:'FPC_SHORTSTR_COMPARE']; compilerproc;
  595. var
  596. s1,s2,max,i : byte;
  597. d : longint;
  598. begin
  599. s1:=length(left);
  600. s2:=length(right);
  601. if s1<s2 then
  602. max:=s1
  603. else
  604. max:=s2;
  605. for i:=1 to max do
  606. begin
  607. d:=byte(left[i])-byte(right[i]);
  608. if d>0 then
  609. exit(1)
  610. else if d<0 then
  611. exit(-1);
  612. end;
  613. if s1>s2 then
  614. exit(1)
  615. else if s1<s2 then
  616. exit(-1)
  617. else
  618. exit(0);
  619. end;
  620. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
  621. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE_EQUAL}
  622. function fpc_shortstr_compare_equal(const left,right:shortstring): longint; [public,alias:'FPC_SHORTSTR_COMPARE_EQUAL']; compilerproc;
  623. begin
  624. Result := longint(left[0]) - longint(right[0]);
  625. if Result = 0 then
  626. Result := CompareByte(left[1],right[1], longint(left[0]));
  627. end;
  628. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE_EQUAL}
  629. {$ifndef FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
  630. function fpc_pchar_to_shortstr(p:pchar):shortstring;[public,alias:'FPC_PCHAR_TO_SHORTSTR']; compilerproc;
  631. var
  632. l : longint;
  633. s: shortstring;
  634. begin
  635. if p=nil then
  636. l:=0
  637. else
  638. l:=strlen(p);
  639. if l>255 then
  640. l:=255;
  641. if l>0 then
  642. move(p^,s[1],l);
  643. s[0]:=chr(l);
  644. fpc_pchar_to_shortstr := s;
  645. end;
  646. {$endif ndef FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
  647. {$ifndef FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
  648. function fpc_chararray_to_shortstr(const arr: array of char; zerobased: boolean = true):shortstring;[public,alias:'FPC_CHARARRAY_TO_SHORTSTR']; compilerproc;
  649. var
  650. l: longint;
  651. index: longint;
  652. len: byte;
  653. begin
  654. l := high(arr)+1;
  655. if l>=256 then
  656. l:=255
  657. else if l<0 then
  658. l:=0;
  659. if (zerobased) then
  660. begin
  661. index:=IndexByte(arr[0],l,0);
  662. if (index < 0) then
  663. len := l
  664. else
  665. len := index;
  666. end
  667. else
  668. len := l;
  669. move(arr[0],fpc_chararray_to_shortstr[1],len);
  670. fpc_chararray_to_shortstr[0]:=chr(len);
  671. end;
  672. {$endif ndef FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
  673. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_TO_CHARARRAY}
  674. {$ifndef FPC_STRTOCHARARRAYPROC}
  675. { inside the compiler, the resulttype is modified to that of the actual }
  676. { chararray we're converting to (JM) }
  677. function fpc_shortstr_to_chararray(arraysize: longint; const src: ShortString): fpc_big_chararray;[public,alias: 'FPC_SHORTSTR_TO_CHARARRAY']; compilerproc;
  678. var
  679. len: longint;
  680. begin
  681. len := length(src);
  682. if len > arraysize then
  683. len := arraysize;
  684. {$r-}
  685. { make sure we don't access char 1 if length is 0 (JM) }
  686. if len > 0 then
  687. move(src[1],fpc_shortstr_to_chararray[0],len);
  688. fillchar(fpc_shortstr_to_chararray[len],arraysize-len,0);
  689. {$ifdef RangeCheckWasOn}
  690. {$r+}
  691. {$endif}
  692. end;
  693. {$else ndef FPC_STRTOCHARARRAYPROC}
  694. procedure fpc_shortstr_to_chararray(out res: array of char; const src: ShortString); compilerproc;
  695. var
  696. len: longint;
  697. begin
  698. len := length(src);
  699. if len > length(res) then
  700. len := length(res);
  701. {$r-}
  702. { make sure we don't access char 1 if length is 0 (JM) }
  703. if len > 0 then
  704. move(src[1],res[0],len);
  705. fillchar(res[len],length(res)-len,0);
  706. {$ifdef RangeCheckWasOn}
  707. {$r+}
  708. {$endif}
  709. end;
  710. {$endif ndef FPC_STRTOCHARARRAYPROC}
  711. {$endif FPC_SYSTEM_HAS_FPC_SHORTSTR_TO_CHARARRAY}
  712. {$ifndef FPC_SYSTEM_HAS_FPC_PCHAR_LENGTH}
  713. function fpc_pchar_length(p:pchar):longint;[public,alias:'FPC_PCHAR_LENGTH']; compilerproc;
  714. var i : longint;
  715. begin
  716. i:=0;
  717. while p[i]<>#0 do inc(i);
  718. exit(i);
  719. end;
  720. {$endif ndef FPC_SYSTEM_HAS_FPC_PCHAR_LENGTH}
  721. {$ifndef FPC_SYSTEM_HAS_FPC_PWIDECHAR_LENGTH}
  722. function fpc_pwidechar_length(p:pwidechar):longint;[public,alias:'FPC_PWIDECHAR_LENGTH']; compilerproc;
  723. var i : longint;
  724. begin
  725. i:=0;
  726. while p[i]<>#0 do inc(i);
  727. exit(i);
  728. end;
  729. {$endif ndef FPC_SYSTEM_HAS_FPC_PWIDECHAR_LENGTH}
  730. {****************************************************************************
  731. Caller/StackFrame Helpers
  732. ****************************************************************************}
  733. {$ifndef FPC_SYSTEM_HAS_GET_FRAME}
  734. {_$error Get_frame must be defined for each processor }
  735. {$endif ndef FPC_SYSTEM_HAS_GET_FRAME}
  736. {$ifndef FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  737. {_$error Get_caller_addr must be defined for each processor }
  738. {$endif ndef FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  739. {$ifndef FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  740. {_$error Get_caller_frame must be defined for each processor }
  741. {$endif ndef FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  742. {****************************************************************************
  743. Math
  744. ****************************************************************************}
  745. {****************************************************************************
  746. Software longint/dword division
  747. ****************************************************************************}
  748. {$ifdef FPC_INCLUDE_SOFTWARE_MOD_DIV}
  749. function count_leading_zeros_32bit(l : longint) : longint;
  750. var
  751. i : longint;
  752. begin
  753. for i:=0 to 31 do
  754. begin
  755. if (l and (longint($80000000) shr i))<>0 then
  756. begin
  757. result:=i;
  758. exit;
  759. end;
  760. end;
  761. result:=i;
  762. end;
  763. {$ifndef FPC_SYSTEM_HAS_DIV_DWORD}
  764. function fpc_div_dword(n,z : dword) : dword; [public,alias: 'FPC_DIV_DWORD']; compilerproc;
  765. var
  766. shift,lzz,lzn : longint;
  767. begin
  768. result:=0;
  769. if n=0 then
  770. HandleErrorFrame(200,get_frame);
  771. lzz:=count_leading_zeros_32bit(z);
  772. lzn:=count_leading_zeros_32bit(n);
  773. { if the denominator contains less zeros
  774. then the numerator
  775. the d is greater than the n }
  776. if lzn<lzz then
  777. exit;
  778. shift:=lzn-lzz;
  779. n:=n shl shift;
  780. repeat
  781. if z>=n then
  782. begin
  783. z:=z-n;
  784. result:=result+dword(1 shl shift);
  785. end;
  786. dec(shift);
  787. n:=n shr 1;
  788. until shift<0;
  789. end;
  790. {$endif FPC_SYSTEM_HAS_DIV_DWORD}
  791. {$ifndef FPC_SYSTEM_HAS_MOD_DWORD}
  792. function fpc_mod_dword(n,z : dword) : dword; [public,alias: 'FPC_MOD_DWORD']; compilerproc;
  793. var
  794. shift,lzz,lzn : longint;
  795. begin
  796. result:=0;
  797. if n=0 then
  798. HandleErrorFrame(200,get_frame);
  799. lzz:=count_leading_zeros_32bit(z);
  800. lzn:=count_leading_zeros_32bit(n);
  801. { if the denominator contains less zeros
  802. then the numerator
  803. the d is greater than the n }
  804. if lzn<lzz then
  805. begin
  806. result:=z;
  807. exit;
  808. end;
  809. shift:=lzn-lzz;
  810. n:=n shl shift;
  811. repeat
  812. if z>=n then
  813. z:=z-n;
  814. dec(shift);
  815. n:=n shr 1;
  816. until shift<0;
  817. result:=z;
  818. end;
  819. {$endif FPC_SYSTEM_HAS_MOD_DWORD}
  820. {$ifndef FPC_SYSTEM_HAS_DIV_LONGINT}
  821. function fpc_div_longint(n,z : longint) : longint; [public,alias: 'FPC_DIV_LONGINT']; compilerproc;
  822. var
  823. sign : boolean;
  824. d1,d2 : dword;
  825. begin
  826. if n=0 then
  827. HandleErrorFrame(200,get_frame);
  828. sign:=false;
  829. if z<0 then
  830. begin
  831. sign:=not(sign);
  832. d1:=dword(-z);
  833. end
  834. else
  835. d1:=z;
  836. if n<0 then
  837. begin
  838. sign:=not(sign);
  839. d2:=dword(-n);
  840. end
  841. else
  842. d2:=n;
  843. { the div is coded by the compiler as call to divdword }
  844. if sign then
  845. result:=-(d1 div d2)
  846. else
  847. result:=d1 div d2;
  848. end;
  849. {$endif FPC_SYSTEM_HAS_DIV_LONGINT}
  850. {$ifndef FPC_SYSTEM_HAS_MOD_LONGINT}
  851. function fpc_mod_longint(n,z : longint) : longint; [public,alias: 'FPC_MOD_LONGINT']; compilerproc;
  852. var
  853. signed : boolean;
  854. r,nq,zq : dword;
  855. begin
  856. if n=0 then
  857. HandleErrorFrame(200,get_frame);
  858. nq:=abs(n);
  859. if z<0 then
  860. begin
  861. zq:=dword(-z);
  862. signed:=true;
  863. end
  864. else
  865. begin
  866. zq:=z;
  867. signed:=false;
  868. end;
  869. r:=zq mod nq;
  870. if signed then
  871. result:=-longint(r)
  872. else
  873. result:=r;
  874. end;
  875. {$endif FPC_SYSTEM_HAS_MOD_LONGINT}
  876. {$endif FPC_INCLUDE_SOFTWARE_MOD_DIV}
  877. {****************************************************************************}
  878. {$ifndef FPC_SYSTEM_HAS_ABS_LONGINT}
  879. function abs(l:longint):longint;{$ifdef SYSTEMINLINE}inline;{$endif}
  880. begin
  881. if l<0 then
  882. abs:=-l
  883. else
  884. abs:=l;
  885. end;
  886. {$endif not FPC_SYSTEM_HAS_ABS_LONGINT}
  887. {$ifndef FPC_SYSTEM_HAS_ODD_LONGINT}
  888. function odd(l:longint):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  889. begin
  890. odd:=boolean(l and 1);
  891. end;
  892. {$endif ndef FPC_SYSTEM_HAS_ODD_LONGINT}
  893. {$ifndef FPC_SYSTEM_HAS_ODD_LONGWORD}
  894. function odd(l:longword):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  895. begin
  896. odd:=boolean(l and 1);
  897. end;
  898. {$endif ndef FPC_SYSTEM_HAS_ODD_LONGWORD}
  899. {$ifndef FPC_SYSTEM_HAS_ODD_INT64}
  900. function odd(l:int64):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  901. begin
  902. odd:=boolean(longint(l) and 1);
  903. end;
  904. {$endif ndef FPC_SYSTEM_HAS_ODD_INT64}
  905. {$ifndef FPC_SYSTEM_HAS_ODD_QWORD}
  906. function odd(l:qword):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  907. begin
  908. odd:=boolean(longint(l) and 1);
  909. end;
  910. {$endif ndef FPC_SYSTEM_HAS_ODD_QWORD}
  911. {$ifndef FPC_SYSTEM_HAS_SQR_LONGINT}
  912. function sqr(l:longint):longint;{$ifdef SYSTEMINLINE}inline;{$endif}
  913. begin
  914. sqr:=l*l;
  915. end;
  916. {$endif ndef FPC_SYSTEM_HAS_SQR_LONGINT}
  917. {$ifndef FPC_SYSTEM_HAS_ABS_INT64}
  918. function abs(l: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
  919. begin
  920. if l < 0 then
  921. abs := -l
  922. else
  923. abs := l;
  924. end;
  925. {$endif ndef FPC_SYSTEM_HAS_ABS_INT64}
  926. {$ifndef FPC_SYSTEM_HAS_SQR_INT64}
  927. function sqr(l: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
  928. begin
  929. sqr := l*l;
  930. end;
  931. {$endif ndef FPC_SYSTEM_HAS_SQR_INT64}
  932. {$ifndef FPC_SYSTEM_HAS_SQR_QWORD}
  933. function sqr(l: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  934. begin
  935. sqr := l*l;
  936. end;
  937. {$endif ndef FPC_SYSTEM_HAS_SQR_INT64}
  938. {$ifndef FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
  939. function declocked(var l:longint):boolean;
  940. begin
  941. Dec(l);
  942. declocked:=(l=0);
  943. end;
  944. {$endif FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
  945. {$ifndef FPC_SYSTEM_HAS_DECLOCKED_INT64}
  946. function declocked(var l:int64):boolean;
  947. begin
  948. Dec(l);
  949. declocked:=(l=0);
  950. end;
  951. {$endif FPC_SYSTEM_HAS_DECLOCKED_INT64}
  952. {$ifndef FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  953. procedure inclocked(var l:longint);
  954. begin
  955. Inc(l);
  956. end;
  957. {$endif FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  958. {$ifndef FPC_SYSTEM_HAS_INCLOCKED_INT64}
  959. procedure inclocked(var l:int64);
  960. begin
  961. Inc(l);
  962. end;
  963. {$endif FPC_SYSTEM_HAS_INCLOCKED_INT64}
  964. {$ifndef FPC_SYSTEM_HAS_SPTR}
  965. {_$error Sptr must be defined for each processor }
  966. {$endif ndef FPC_SYSTEM_HAS_SPTR}
  967. function align(addr : PtrUInt;alignment : PtrUInt) : PtrUInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  968. begin
  969. if addr mod alignment<>0 then
  970. result:=addr+(alignment-(addr mod alignment))
  971. else
  972. result:=addr;
  973. end;
  974. function align(addr : Pointer;alignment : PtrUInt) : Pointer;{$ifdef SYSTEMINLINE}inline;{$endif}
  975. begin
  976. if PtrUInt(addr) mod alignment<>0 then
  977. result:=pointer(addr+(alignment-(PtrUInt(addr) mod alignment)))
  978. else
  979. result:=addr;
  980. end;
  981. {****************************************************************************
  982. Str()
  983. ****************************************************************************}
  984. {$ifndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
  985. procedure int_str(l:longint;out s:string);
  986. var
  987. m,m1 : longword;
  988. pc,pc2 : pchar;
  989. hs : string[32];
  990. b : longint;
  991. begin
  992. pc2:=@s[1];
  993. if (l<0) then
  994. begin
  995. b:=1;
  996. pc2^:='-';
  997. inc(pc2);
  998. m:=longword(-l);
  999. end
  1000. else
  1001. begin
  1002. b:=0;
  1003. m:=longword(l);
  1004. end;
  1005. pc:=@hs[0];
  1006. repeat
  1007. inc(pc);
  1008. m1:=m div 10;
  1009. pc^:=char(m-(m1*10)+byte('0'));
  1010. m:=m1;
  1011. until m=0;
  1012. while (pc>pchar(@hs[0])) and
  1013. (b<high(s)) do
  1014. begin
  1015. pc2^:=pc^;
  1016. dec(pc);
  1017. inc(pc2);
  1018. inc(b);
  1019. end;
  1020. s[0]:=chr(b);
  1021. end;
  1022. {$endif ndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
  1023. {$ifndef FPC_SYSTEM_HAS_INT_STR_LONGWORD}
  1024. procedure int_str(l:longword;out s:string);
  1025. var
  1026. m1 : longword;
  1027. b: longint;
  1028. pc,pc2 : pchar;
  1029. hs : string[32];
  1030. begin
  1031. pc2:=@s[1];
  1032. pc:=@hs[0];
  1033. repeat
  1034. inc(pc);
  1035. m1:=l div 10;
  1036. pc^:=char(l-(m1*10)+byte('0'));
  1037. l:=m1;
  1038. until l=0;
  1039. b:=0;
  1040. while (pc>pchar(@hs[0])) and
  1041. (b<high(s)) do
  1042. begin
  1043. pc2^:=pc^;
  1044. dec(pc);
  1045. inc(pc2);
  1046. inc(b);
  1047. end;
  1048. s[0]:=chr(b);
  1049. end;
  1050. {$endif ndef FPC_SYSTEM_HAS_INT_STR_LONGWORD}
  1051. {$ifndef FPC_SYSTEM_HAS_INT_STR_INT64}
  1052. procedure int_str(l:int64;out s:string);
  1053. var
  1054. m,m1 : qword;
  1055. pc,pc2 : pchar;
  1056. b: longint;
  1057. hs : string[64];
  1058. begin
  1059. pc2:=@s[1];
  1060. if (l<0) then
  1061. begin
  1062. b:=1;
  1063. pc2^:='-';
  1064. inc(pc2);
  1065. m:=qword(-l);
  1066. end
  1067. else
  1068. begin
  1069. b:=0;
  1070. m:=qword(l);
  1071. end;
  1072. pc:=@hs[0];
  1073. repeat
  1074. inc(pc);
  1075. m1:=m div 10;
  1076. pc^:=char(m-(m1*10)+byte('0'));
  1077. m:=m1;
  1078. until m=0;
  1079. while (pc>pchar(@hs[0])) and
  1080. (b < high(s)) do
  1081. begin
  1082. pc2^:=pc^;
  1083. dec(pc);
  1084. inc(pc2);
  1085. inc(b);
  1086. end;
  1087. s[0]:=chr(b);
  1088. end;
  1089. {$endif ndef FPC_SYSTEM_HAS_INT_STR_INT64}
  1090. {$ifndef FPC_SYSTEM_HAS_INT_STR_QWORD}
  1091. procedure int_str(l:qword;out s:string);
  1092. var
  1093. m1 : qword;
  1094. pc,pc2 : pchar;
  1095. b: longint;
  1096. hs : string[64];
  1097. begin
  1098. pc2:=@s[1];
  1099. pc:=@hs[0];
  1100. repeat
  1101. inc(pc);
  1102. m1:=l div 10;
  1103. pc^:=char(l-(m1*10)+byte('0'));
  1104. l:=m1;
  1105. until l=0;
  1106. b:=0;
  1107. while (pc>pchar(@hs[0])) and
  1108. (b<high(s)) do
  1109. begin
  1110. pc2^:=pc^;
  1111. dec(pc);
  1112. inc(pc2);
  1113. inc(b);
  1114. end;
  1115. s[0]:=chr(b);
  1116. end;
  1117. {$endif ndef FPC_SYSTEM_HAS_INT_STR_QWORD}
  1118. {$ifndef FPC_SYSTEM_HAS_SYSRESETFPU}
  1119. procedure SysResetFpu;{$ifdef SYSTEMINLINE}inline;{$endif}
  1120. begin
  1121. softfloat_exception_flags:=0;
  1122. softfloat_exception_mask:=float_flag_underflow or float_flag_inexact or float_flag_denormal;
  1123. end;
  1124. {$endif FPC_SYSTEM_HAS_SYSRESETFPU}
  1125. {$ifndef FPC_SYSTEM_HAS_SWAPENDIAN}
  1126. function SwapEndian(const AValue: SmallInt): SmallInt;
  1127. begin
  1128. Result := (AValue shr 8) or (AValue shl 8);
  1129. end;
  1130. function SwapEndian(const AValue: Word): Word;
  1131. begin
  1132. Result := (AValue shr 8) or (AValue shl 8);
  1133. end;
  1134. function SwapEndian(const AValue: LongInt): LongInt;
  1135. begin
  1136. Result := (AValue shl 24)
  1137. or ((AValue and $0000FF00) shl 8)
  1138. or ((AValue and $00FF0000) shr 8)
  1139. or (AValue shr 24);
  1140. end;
  1141. function SwapEndian(const AValue: DWord): DWord;
  1142. begin
  1143. Result := (AValue shl 24)
  1144. or ((AValue and $0000FF00) shl 8)
  1145. or ((AValue and $00FF0000) shr 8)
  1146. or (AValue shr 24);
  1147. end;
  1148. function SwapEndian(const AValue: Int64): Int64;
  1149. begin
  1150. Result := (AValue shl 56)
  1151. or ((AValue and $000000000000FF00) shl 40)
  1152. or ((AValue and $0000000000FF0000) shl 24)
  1153. or ((AValue and $00000000FF000000) shl 8)
  1154. or ((AValue and $000000FF00000000) shr 8)
  1155. or ((AValue and $0000FF0000000000) shr 24)
  1156. or ((AValue and $00FF000000000000) shr 40)
  1157. or (AValue shr 56);
  1158. end;
  1159. function SwapEndian(const AValue: QWord): QWord;
  1160. begin
  1161. Result := (AValue shl 56)
  1162. or ((AValue and $000000000000FF00) shl 40)
  1163. or ((AValue and $0000000000FF0000) shl 24)
  1164. or ((AValue and $00000000FF000000) shl 8)
  1165. or ((AValue and $000000FF00000000) shr 8)
  1166. or ((AValue and $0000FF0000000000) shr 24)
  1167. or ((AValue and $00FF000000000000) shr 40)
  1168. or (AValue shr 56);
  1169. end;
  1170. {$endif FPC_SYSTEM_HAS_SWAPENDIAN}
  1171. function BEtoN(const AValue: SmallInt): SmallInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1172. begin
  1173. {$IFDEF ENDIAN_BIG}
  1174. Result := AValue;
  1175. {$ELSE}
  1176. Result := SwapEndian(AValue);
  1177. {$ENDIF}
  1178. end;
  1179. function BEtoN(const AValue: Word): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
  1180. begin
  1181. {$IFDEF ENDIAN_BIG}
  1182. Result := AValue;
  1183. {$ELSE}
  1184. Result := SwapEndian(AValue);
  1185. {$ENDIF}
  1186. end;
  1187. function BEtoN(const AValue: LongInt): LongInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1188. begin
  1189. {$IFDEF ENDIAN_BIG}
  1190. Result := AValue;
  1191. {$ELSE}
  1192. Result := SwapEndian(AValue);
  1193. {$ENDIF}
  1194. end;
  1195. function BEtoN(const AValue: DWord): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1196. begin
  1197. {$IFDEF ENDIAN_BIG}
  1198. Result := AValue;
  1199. {$ELSE}
  1200. Result := SwapEndian(AValue);
  1201. {$ENDIF}
  1202. end;
  1203. function BEtoN(const AValue: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
  1204. begin
  1205. {$IFDEF ENDIAN_BIG}
  1206. Result := AValue;
  1207. {$ELSE}
  1208. Result := SwapEndian(AValue);
  1209. {$ENDIF}
  1210. end;
  1211. function BEtoN(const AValue: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1212. begin
  1213. {$IFDEF ENDIAN_BIG}
  1214. Result := AValue;
  1215. {$ELSE}
  1216. Result := SwapEndian(AValue);
  1217. {$ENDIF}
  1218. end;
  1219. function LEtoN(const AValue: SmallInt): SmallInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1220. begin
  1221. {$IFDEF ENDIAN_LITTLE}
  1222. Result := AValue;
  1223. {$ELSE}
  1224. Result := SwapEndian(AValue);
  1225. {$ENDIF}
  1226. end;
  1227. function LEtoN(const AValue: Word): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
  1228. begin
  1229. {$IFDEF ENDIAN_LITTLE}
  1230. Result := AValue;
  1231. {$ELSE}
  1232. Result := SwapEndian(AValue);
  1233. {$ENDIF}
  1234. end;
  1235. function LEtoN(const AValue: LongInt): LongInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1236. begin
  1237. {$IFDEF ENDIAN_LITTLE}
  1238. Result := AValue;
  1239. {$ELSE}
  1240. Result := SwapEndian(AValue);
  1241. {$ENDIF}
  1242. end;
  1243. function LEtoN(const AValue: DWord): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1244. begin
  1245. {$IFDEF ENDIAN_LITTLE}
  1246. Result := AValue;
  1247. {$ELSE}
  1248. Result := SwapEndian(AValue);
  1249. {$ENDIF}
  1250. end;
  1251. function LEtoN(const AValue: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
  1252. begin
  1253. {$IFDEF ENDIAN_LITTLE}
  1254. Result := AValue;
  1255. {$ELSE}
  1256. Result := SwapEndian(AValue);
  1257. {$ENDIF}
  1258. end;
  1259. function LEtoN(const AValue: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1260. begin
  1261. {$IFDEF ENDIAN_LITTLE}
  1262. Result := AValue;
  1263. {$ELSE}
  1264. Result := SwapEndian(AValue);
  1265. {$ENDIF}
  1266. end;
  1267. function NtoBE(const AValue: SmallInt): SmallInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1268. begin
  1269. {$IFDEF ENDIAN_BIG}
  1270. Result := AValue;
  1271. {$ELSE}
  1272. Result := SwapEndian(AValue);
  1273. {$ENDIF}
  1274. end;
  1275. function NtoBE(const AValue: Word): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
  1276. begin
  1277. {$IFDEF ENDIAN_BIG}
  1278. Result := AValue;
  1279. {$ELSE}
  1280. Result := SwapEndian(AValue);
  1281. {$ENDIF}
  1282. end;
  1283. function NtoBE(const AValue: LongInt): LongInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1284. begin
  1285. {$IFDEF ENDIAN_BIG}
  1286. Result := AValue;
  1287. {$ELSE}
  1288. Result := SwapEndian(AValue);
  1289. {$ENDIF}
  1290. end;
  1291. function NtoBE(const AValue: DWord): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1292. begin
  1293. {$IFDEF ENDIAN_BIG}
  1294. Result := AValue;
  1295. {$ELSE}
  1296. Result := SwapEndian(AValue);
  1297. {$ENDIF}
  1298. end;
  1299. function NtoBE(const AValue: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
  1300. begin
  1301. {$IFDEF ENDIAN_BIG}
  1302. Result := AValue;
  1303. {$ELSE}
  1304. Result := SwapEndian(AValue);
  1305. {$ENDIF}
  1306. end;
  1307. function NtoBE(const AValue: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1308. begin
  1309. {$IFDEF ENDIAN_BIG}
  1310. Result := AValue;
  1311. {$ELSE}
  1312. Result := SwapEndian(AValue);
  1313. {$ENDIF}
  1314. end;
  1315. function NtoLE(const AValue: SmallInt): SmallInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1316. begin
  1317. {$IFDEF ENDIAN_LITTLE}
  1318. Result := AValue;
  1319. {$ELSE}
  1320. Result := SwapEndian(AValue);
  1321. {$ENDIF}
  1322. end;
  1323. function NtoLE(const AValue: Word): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
  1324. begin
  1325. {$IFDEF ENDIAN_LITTLE}
  1326. Result := AValue;
  1327. {$ELSE}
  1328. Result := SwapEndian(AValue);
  1329. {$ENDIF}
  1330. end;
  1331. function NtoLE(const AValue: LongInt): LongInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1332. begin
  1333. {$IFDEF ENDIAN_LITTLE}
  1334. Result := AValue;
  1335. {$ELSE}
  1336. Result := SwapEndian(AValue);
  1337. {$ENDIF}
  1338. end;
  1339. function NtoLE(const AValue: DWord): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1340. begin
  1341. {$IFDEF ENDIAN_LITTLE}
  1342. Result := AValue;
  1343. {$ELSE}
  1344. Result := SwapEndian(AValue);
  1345. {$ENDIF}
  1346. end;
  1347. function NtoLE(const AValue: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
  1348. begin
  1349. {$IFDEF ENDIAN_LITTLE}
  1350. Result := AValue;
  1351. {$ELSE}
  1352. Result := SwapEndian(AValue);
  1353. {$ENDIF}
  1354. end;
  1355. function NtoLE(const AValue: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1356. begin
  1357. {$IFDEF ENDIAN_LITTLE}
  1358. Result := AValue;
  1359. {$ELSE}
  1360. Result := SwapEndian(AValue);
  1361. {$ENDIF}
  1362. end;
  1363. {$ifndef FPC_SYSTEM_HAS_MEM_BARRIER}
  1364. procedure ReadBarrier;{$ifdef SYSTEMINLINE}inline;{$endif}
  1365. begin
  1366. end;
  1367. procedure ReadDependencyBarrier;{$ifdef SYSTEMINLINE}inline;{$endif}
  1368. begin
  1369. end;
  1370. procedure ReadWriteBarrier;{$ifdef SYSTEMINLINE}inline;{$endif}
  1371. begin
  1372. end;
  1373. procedure WriteBarrier;{$ifdef SYSTEMINLINE}inline;{$endif}
  1374. begin
  1375. end;
  1376. {$endif}