generic.inc 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997
  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. var
  20. aligncount : sizeint;
  21. pdest,psrc,pend : pbyte;
  22. begin
  23. if (@dest=@source) or (count<=0) then
  24. exit;
  25. if (@dest<@source) or (@source+count<@dest) then
  26. begin
  27. { Forward Move }
  28. psrc:=@source;
  29. pdest:=@dest;
  30. if (Count>4*sizeof(ptruint)-11)
  31. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  32. and ((PtrUInt(pdest) and (sizeof(PtrUInt)-1))=(PtrUInt(psrc) and (sizeof(PtrUInt)-1)))
  33. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  34. then
  35. begin
  36. { Align on native pointer size }
  37. aligncount:=(PtrUInt(pdest) and (sizeof(PtrUInt)-1));
  38. dec(count,aligncount);
  39. pend:=psrc+aligncount;
  40. while psrc<pend do
  41. begin
  42. pdest^:=psrc^;
  43. inc(pdest);
  44. inc(psrc);
  45. end;
  46. { use sizeuint typecast to force shr optimization }
  47. pptruint(pend):=pptruint(psrc)+(sizeuint(count) div sizeof(ptruint));
  48. while psrc<pend do
  49. begin
  50. pptruint(pdest)^:=pptruint(psrc)^;
  51. inc(pptruint(pdest));
  52. inc(pptruint(psrc));
  53. end;
  54. count:=count and (sizeof(PtrUInt)-1);
  55. end;
  56. pend:=psrc+count;
  57. while psrc<pend do
  58. begin
  59. pdest^:=psrc^;
  60. inc(pdest);
  61. inc(psrc);
  62. end;
  63. end
  64. else
  65. begin
  66. { Backward Move }
  67. psrc:=@source+count;
  68. pdest:=@dest+count;
  69. if (Count>4*sizeof(ptruint)-11)
  70. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  71. and ((PtrUInt(pdest) and (sizeof(PtrUInt)-1))=(PtrUInt(psrc) and (sizeof(PtrUInt)-1)))
  72. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  73. then
  74. begin
  75. { Align on native pointer size }
  76. aligncount:=(PtrUInt(pdest) and (sizeof(PtrUInt)-1));
  77. dec(count,aligncount);
  78. pend:=psrc-aligncount;
  79. while psrc>pend do
  80. begin
  81. dec(pdest);
  82. dec(psrc);
  83. pdest^:=psrc^;
  84. end;
  85. { use sizeuint typecast to force shr optimization }
  86. pptruint(pend):=pptruint(psrc)-(sizeuint(count) div sizeof(ptruint));
  87. while psrc>pend do
  88. begin
  89. dec(pptruint(pdest));
  90. dec(pptruint(psrc));
  91. pptruint(pdest)^:=pptruint(psrc)^;
  92. end;
  93. count:=count and (sizeof(PtrUInt)-1);
  94. end;
  95. pend:=psrc-count;
  96. while psrc>pend do
  97. begin
  98. dec(pdest);
  99. dec(psrc);
  100. pdest^:=psrc^;
  101. end;
  102. end;
  103. end;
  104. {$endif not FPC_SYSTEM_HAS_MOVE}
  105. {$ifndef FPC_SYSTEM_HAS_FILLCHAR}
  106. Procedure FillChar(var x;count:SizeInt;value:byte);
  107. var
  108. aligncount : sizeint;
  109. pdest,pend : pbyte;
  110. v : ptruint;
  111. begin
  112. if count <= 0 then
  113. exit;
  114. pdest:=@x;
  115. if Count>4*sizeof(ptruint)-1 then
  116. begin
  117. v:=(value shl 8) or value;
  118. v:=(v shl 16) or v;
  119. if sizeof(ptruint)=8 then
  120. v:=(v shl 32) or v;
  121. { Align on native pointer size }
  122. aligncount:=(PtrUInt(pdest) and (sizeof(PtrUInt)-1));
  123. dec(count,aligncount);
  124. pend:=pdest+aligncount;
  125. while pdest<pend do
  126. begin
  127. pdest^:=value;
  128. inc(pdest);
  129. end;
  130. { use sizeuint typecast to force shr optimization }
  131. pptruint(pend):=pptruint(pdest)+(sizeuint(count) div sizeof(ptruint));
  132. while pdest<pend do
  133. begin
  134. pptruint(pdest)^:=v;
  135. inc(pptruint(pdest));
  136. end;
  137. count:=count and (sizeof(ptruint)-1);
  138. end;
  139. pend:=pdest+count;
  140. while pdest<pend do
  141. begin
  142. pdest^:=value;
  143. inc(pdest);
  144. end;
  145. end;
  146. {$endif FPC_SYSTEM_HAS_FILLCHAR}
  147. {$ifndef FPC_SYSTEM_HAS_FILLWORD}
  148. procedure fillword(var x;count : SizeInt;value : word);
  149. var
  150. aligncount : sizeint;
  151. pdest,pend : pword;
  152. v : ptruint;
  153. begin
  154. if count <= 0 then
  155. exit;
  156. pdest:=@x;
  157. if Count>4*sizeof(ptruint)-1 then
  158. begin
  159. v:=(value shl 16) or value;
  160. if sizeof(ptruint)=8 then
  161. v:=(v shl 32) or v;
  162. { Align on native pointer size }
  163. aligncount:=(PtrUInt(pdest) and (sizeof(PtrUInt)-1)) shr 1;
  164. dec(count,aligncount);
  165. pend:=pdest+aligncount;
  166. while pdest<pend do
  167. begin
  168. pdest^:=value;
  169. inc(pdest);
  170. end;
  171. { use sizeuint typecast to force shr optimization }
  172. pptruint(pend):=pptruint(pdest)+((sizeuint(count)*2) div sizeof(ptruint));
  173. while pdest<pend do
  174. begin
  175. pptruint(pdest)^:=v;
  176. inc(pptruint(pdest));
  177. end;
  178. count:=((count*2) and (sizeof(ptruint)-1)) shr 1;
  179. end;
  180. pend:=pdest+count;
  181. while pdest<pend do
  182. begin
  183. pdest^:=value;
  184. inc(pdest);
  185. end;
  186. end;
  187. {$endif not FPC_SYSTEM_HAS_FILLWORD}
  188. {$ifndef FPC_SYSTEM_HAS_FILLDWORD}
  189. procedure filldword(var x;count : SizeInt;value : dword);
  190. var
  191. aligncount : sizeint;
  192. pdest,pend : pdword;
  193. v : ptruint;
  194. begin
  195. if count <= 0 then
  196. exit;
  197. pdest:=@x;
  198. if Count>4*sizeof(ptruint)-1 then
  199. begin
  200. v:=value;
  201. if sizeof(ptruint)=8 then
  202. v:=(v shl 32) or v;
  203. { Align on native pointer size }
  204. aligncount:=(PtrUInt(pdest) and (sizeof(PtrUInt)-1)) shr 2;
  205. dec(count,aligncount);
  206. pend:=pdest+aligncount;
  207. while pdest<pend do
  208. begin
  209. pdest^:=value;
  210. inc(pdest);
  211. end;
  212. { use sizeuint typecast to force shr optimization }
  213. pptruint(pend):=pptruint(pdest)+((sizeuint(count)*4) div sizeof(ptruint));
  214. while pdest<pend do
  215. begin
  216. pptruint(pdest)^:=v;
  217. inc(pptruint(pdest));
  218. end;
  219. count:=((count*4) and (sizeof(ptruint)-1)) shr 2;
  220. end;
  221. pend:=pdest+count;
  222. while pdest<pend do
  223. begin
  224. pdest^:=value;
  225. inc(pdest);
  226. end;
  227. end;
  228. {$endif FPC_SYSTEM_HAS_FILLDWORD}
  229. {$ifndef FPC_SYSTEM_HAS_INDEXBYTE}
  230. function IndexByte(Const buf;len:SizeInt;b:byte):SizeInt;
  231. var
  232. psrc,pend : pbyte;
  233. begin
  234. psrc:=@buf;
  235. { simulate assembler implementations behaviour, which is expected }
  236. { fpc_pchar_to_ansistr in astrings.inc }
  237. if (len < 0) or
  238. (psrc+len < psrc) then
  239. pend:=pbyte(high(PtrUInt)-sizeof(byte))
  240. else
  241. pend:=psrc+len;
  242. while (psrc<pend) do
  243. begin
  244. if psrc^=b then
  245. begin
  246. result:=psrc-pbyte(@buf);
  247. exit;
  248. end;
  249. inc(psrc);
  250. end;
  251. result:=-1;
  252. end;
  253. {$endif not FPC_SYSTEM_HAS_INDEXBYTE}
  254. {$ifndef FPC_SYSTEM_HAS_INDEXWORD}
  255. function Indexword(Const buf;len:SizeInt;b:word):SizeInt;
  256. var
  257. psrc,pend : pword;
  258. begin
  259. psrc:=@buf;
  260. { simulate assembler implementations behaviour, which is expected }
  261. { fpc_pchar_to_ansistr in astrings.inc }
  262. if (len < 0) or
  263. { is this ever true? }
  264. (len > high(PtrInt)) or
  265. (psrc+len < psrc) then
  266. pend:=pword(high(PtrUInt)-sizeof(word))
  267. else
  268. pend:=psrc+len;
  269. while psrc<pend do
  270. begin
  271. if psrc^=b then
  272. begin
  273. result:=psrc-pword(@buf);
  274. exit;
  275. end;
  276. inc(psrc);
  277. end;
  278. result:=-1;
  279. end;
  280. {$endif not FPC_SYSTEM_HAS_INDEXWORD}
  281. {$ifndef FPC_SYSTEM_HAS_INDEXDWORD}
  282. function IndexDWord(Const buf;len:SizeInt;b:DWord):SizeInt;
  283. var
  284. psrc,pend : pdword;
  285. begin
  286. psrc:=@buf;
  287. { simulate assembler implementations behaviour, which is expected }
  288. { fpc_pchar_to_ansistr in astrings.inc }
  289. if (len < 0) or
  290. (len > high(PtrInt) div 2) or
  291. (psrc+len < psrc) then
  292. pend:=pdword(high(PtrUInt)-sizeof(dword))
  293. else
  294. pend:=psrc+len;
  295. while psrc<pend do
  296. begin
  297. if psrc^=b then
  298. begin
  299. result:=psrc-pdword(@buf);
  300. exit;
  301. end;
  302. inc(psrc);
  303. end;
  304. result:=-1;
  305. end;
  306. {$endif not FPC_SYSTEM_HAS_INDEXDWORD}
  307. {$ifndef FPC_SYSTEM_HAS_COMPAREBYTE}
  308. function CompareByte(Const buf1,buf2;len:SizeInt):SizeInt;
  309. var
  310. aligncount : sizeint;
  311. psrc,pdest,pend : pbyte;
  312. b : ptrint;
  313. begin
  314. b:=0;
  315. psrc:=@buf1;
  316. pdest:=@buf2;
  317. if (len>4*sizeof(ptruint)-1)
  318. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  319. and ((PtrUInt(pdest) and (sizeof(PtrUInt)-1))=(PtrUInt(psrc) and (sizeof(PtrUInt)-1)))
  320. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  321. then
  322. begin
  323. { Align on native pointer size }
  324. aligncount:=(sizeof(PtrUInt)-(PtrUInt(pdest) and (sizeof(PtrUInt)-1))) and (sizeof(PtrUInt)-1);
  325. dec(len,aligncount);
  326. pend:=psrc+aligncount;
  327. while psrc<pend do
  328. begin
  329. b:=(ptrint(psrc^)-ptrint(pdest^));
  330. if b<>0 then
  331. begin
  332. if b<0 then
  333. exit(-1)
  334. else
  335. exit(1);
  336. end;
  337. inc(pdest);
  338. inc(psrc);
  339. end;
  340. { use sizeuint typecast to force shr optimization }
  341. pptruint(pend):=pptruint(psrc)+(sizeuint(len) div sizeof(ptruint));
  342. len:=len and (sizeof(PtrUInt)-1);
  343. while psrc<pend do
  344. begin
  345. b:=(pptrint(psrc)^-pptrint(pdest)^);
  346. if b<>0 then
  347. begin
  348. len:=sizeof(ptruint);
  349. break;
  350. end;
  351. inc(pptruint(pdest));
  352. inc(pptruint(psrc));
  353. end;
  354. end;
  355. if (psrc+len >= psrc) then
  356. pend:=psrc+len
  357. else
  358. pend:=pbyte(high(ptruint)-1);
  359. while psrc<pend do
  360. begin
  361. b:=(ptrint(psrc^)-ptrint(pdest^));
  362. if b<>0 then
  363. begin
  364. if b<0 then
  365. exit(-1)
  366. else
  367. exit(1);
  368. end;
  369. inc(pdest);
  370. inc(psrc);
  371. end;
  372. result:=0;
  373. end;
  374. {$endif not FPC_SYSTEM_HAS_COMPAREBYTE}
  375. {$ifndef FPC_SYSTEM_HAS_COMPAREWORD}
  376. function CompareWord(Const buf1,buf2;len:SizeInt):SizeInt;
  377. var
  378. aligncount : sizeint;
  379. psrc,pdest,pend : pword;
  380. b : ptrint;
  381. begin
  382. b:=0;
  383. psrc:=@buf1;
  384. pdest:=@buf2;
  385. if (len>4*sizeof(ptruint)-1)
  386. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  387. and ((PtrUInt(pdest) and (sizeof(PtrUInt)-1))=(PtrUInt(psrc) and (sizeof(PtrUInt)-1)))
  388. and (((PtrUInt(pdest) and 1) or (PtrUInt(psrc) and 1))=0)
  389. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  390. then
  391. begin
  392. { Align on native pointer size }
  393. aligncount:=((sizeof(PtrUInt)-(PtrUInt(pdest) and (sizeof(PtrUInt)-1))) and (sizeof(PtrUInt)-1)) shr 1;
  394. dec(len,aligncount);
  395. pend:=psrc+aligncount;
  396. while psrc<pend do
  397. begin
  398. b:=(ptrint(psrc^)-ptrint(pdest^));
  399. if b<>0 then
  400. begin
  401. if b<0 then
  402. exit(-1)
  403. else
  404. exit(1);
  405. end;
  406. inc(pdest);
  407. inc(psrc);
  408. end;
  409. { use sizeuint typecast to force shr optimization }
  410. pptruint(pend):=pptruint(psrc)+(sizeuint(len)*2 div sizeof(ptruint));
  411. len:=((len*2) and (sizeof(PtrUInt)-1)) shr 1;
  412. while psrc<pend do
  413. begin
  414. b:=(pptrint(psrc)^-pptrint(pdest)^);
  415. if b<>0 then
  416. begin
  417. len:=sizeof(ptruint) shr 1;
  418. break;
  419. end;
  420. inc(pptruint(pdest));
  421. inc(pptruint(psrc));
  422. end;
  423. end;
  424. if (len <= high(ptruint) div 2) and
  425. (psrc+len >= psrc) then
  426. pend:=psrc+len
  427. else
  428. pend:=pword(high(ptruint)-2);
  429. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  430. if ((PtrUInt(pdest) and 1) or (PtrUInt(psrc) and 1))<>0 then
  431. while psrc<pend do
  432. begin
  433. b:=(ptrint(unaligned(psrc^))-ptrint(unaligned(pdest^)));
  434. if b<>0 then
  435. begin
  436. if b<0 then
  437. exit(-1)
  438. else
  439. exit(1);
  440. end;
  441. inc(pdest);
  442. inc(psrc);
  443. end
  444. else
  445. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  446. while psrc<pend do
  447. begin
  448. b:=(ptrint(psrc^)-ptrint(pdest^));
  449. if b<>0 then
  450. begin
  451. if b<0 then
  452. exit(-1)
  453. else
  454. exit(1);
  455. end;
  456. inc(pdest);
  457. inc(psrc);
  458. end;
  459. result:=0;
  460. end;
  461. {$endif not FPC_SYSTEM_HAS_COMPAREWORD}
  462. {$ifndef FPC_SYSTEM_HAS_COMPAREDWORD}
  463. function CompareDWord(Const buf1,buf2;len:SizeInt):SizeInt;
  464. var
  465. aligncount : sizeint;
  466. psrc,pdest,pend : pdword;
  467. b : ptruint;
  468. begin
  469. b:=0;
  470. psrc:=@buf1;
  471. pdest:=@buf2;
  472. if (len>4*sizeof(ptruint)-11)
  473. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  474. and (((PtrUInt(pdest) and 3) or (PtrUInt(psrc) and 3))=0)
  475. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  476. then
  477. begin
  478. { Align on native pointer size }
  479. aligncount:=((sizeof(PtrUInt)-(PtrUInt(pdest) and (sizeof(PtrUInt)-1))) and (sizeof(PtrUInt)-1)) shr 2;
  480. dec(len,aligncount);
  481. pend:=psrc+aligncount;
  482. while psrc<pend do
  483. begin
  484. b:=(ptrint(psrc^)-ptrint(pdest^));
  485. if b<>0 then
  486. begin
  487. if b<0 then
  488. exit(-1)
  489. else
  490. exit(1);
  491. end;
  492. inc(pdest);
  493. inc(psrc);
  494. end;
  495. { use sizeuint typecast to force shr optimization }
  496. pptruint(pend):=pptruint(psrc)+(sizeuint(len)*4 div sizeof(ptruint));
  497. len:=((len*4) and (sizeof(PtrUInt)-1)) shr 2;
  498. while psrc<pend do
  499. begin
  500. b:=(pptrint(psrc)^-pptrint(pdest)^);
  501. if b<>0 then
  502. begin
  503. len:=sizeof(ptruint) shr 2;
  504. break;
  505. end;
  506. inc(pptruint(pdest));
  507. inc(pptruint(psrc));
  508. end;
  509. end;
  510. if (len <= high(ptruint) div 4) and
  511. (psrc+len >= psrc) then
  512. pend:=psrc+len
  513. else
  514. pend:=pdword(high(ptruint)-4);
  515. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  516. if ((PtrUInt(pdest) and 3) or (PtrUInt(psrc) and 3))<>0 then
  517. while psrc<pend do
  518. begin
  519. b:=(ptruint(unaligned(psrc^))-ptruint(unaligned(pdest^)));
  520. if b<>0 then
  521. begin
  522. if b<0 then
  523. exit(-1)
  524. else
  525. exit(1);
  526. end;
  527. inc(pdest);
  528. inc(psrc);
  529. end
  530. else
  531. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  532. while psrc<pend do
  533. begin
  534. b:=(ptruint(psrc^)-ptruint(pdest^));
  535. if b<>0 then
  536. begin
  537. if b<0 then
  538. exit(-1)
  539. else
  540. exit(1);
  541. end;
  542. inc(pdest);
  543. inc(psrc);
  544. end;
  545. result:=0;
  546. end;
  547. {$endif ndef FPC_SYSTEM_HAS_COMPAREDWORD}
  548. {$ifndef FPC_SYSTEM_HAS_MOVECHAR0}
  549. procedure MoveChar0(Const buf1;var buf2;len:SizeInt);
  550. var
  551. I : SizeInt;
  552. begin
  553. if Len = 0 then
  554. exit;
  555. I:=IndexByte(Buf1,Len,0);
  556. if I<>-1 then
  557. Move(Buf1,Buf2,I)
  558. else
  559. Move(Buf1,Buf2,len);
  560. end;
  561. {$endif ndef FPC_SYSTEM_HAS_MOVECHAR0}
  562. {$ifndef FPC_SYSTEM_HAS_INDEXCHAR0}
  563. function IndexChar0(Const buf;len:SizeInt;b:Char):SizeInt;
  564. var
  565. psrc,pend : pbyte;
  566. begin
  567. psrc:=@buf;
  568. { simulate assembler implementations behaviour, which is expected }
  569. { fpc_pchar_to_ansistr in astrings.inc }
  570. if (len < 0) then
  571. pend:=pbyte(high(PtrUInt)-sizeof(byte))
  572. else
  573. pend:=psrc+len;
  574. while (psrc<pend) and (psrc^<>0) do
  575. begin
  576. if (psrc^=byte(b)) then
  577. begin
  578. result:=psrc-pbyte(@buf);
  579. exit;
  580. end;
  581. inc(psrc);
  582. end;
  583. result:=-1;
  584. end;
  585. {$endif ndef FPC_SYSTEM_HAS_INDEXCHAR0}
  586. {$ifndef FPC_SYSTEM_HAS_COMPARECHAR0}
  587. function CompareChar0(Const buf1,buf2;len:SizeInt):SizeInt;
  588. var
  589. aligncount : sizeint;
  590. psrc,pdest,pend : pbyte;
  591. b : ptrint;
  592. begin
  593. b:=0;
  594. psrc:=@buf1;
  595. pdest:=@buf2;
  596. pend:=psrc+len;
  597. while psrc<pend do
  598. begin
  599. b:=(ptrint(psrc^)-ptrint(pdest^));
  600. if (b<>0) or (psrc^=0) or (pdest^=0) then
  601. begin
  602. if b<0 then
  603. exit(-1)
  604. else
  605. exit(1);
  606. end;
  607. inc(pdest);
  608. inc(psrc);
  609. end;
  610. result:=0;
  611. end;
  612. {$endif not FPC_SYSTEM_HAS_COMPARECHAR0}
  613. {****************************************************************************
  614. Object Helpers
  615. ****************************************************************************}
  616. {$ifdef FPC_HAS_FEATURE_OBJECTS}
  617. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_CONSTRUCTOR}
  618. { Note: _vmt will be reset to -1 when memory is allocated,
  619. this is needed for fpc_help_fail }
  620. function fpc_help_constructor(_self:pointer;var _vmt:pointer;_vmt_pos:cardinal):pointer;[public,alias:'FPC_HELP_CONSTRUCTOR'];compilerproc;
  621. type
  622. ppointer = ^pointer;
  623. pvmt = ^tvmt;
  624. tvmt=packed record
  625. size,msize:ptruint;
  626. parent:pointer;
  627. end;
  628. var
  629. vmtcopy : pointer;
  630. begin
  631. { Inherited call? }
  632. if _vmt=nil then
  633. begin
  634. fpc_help_constructor:=_self;
  635. exit;
  636. end;
  637. vmtcopy:=_vmt;
  638. if (_self=nil) and
  639. (pvmt(_vmt)^.size>0) then
  640. begin
  641. getmem(_self,pvmt(_vmt)^.size);
  642. { reset vmt needed for fail }
  643. _vmt:=pointer(-1);
  644. end;
  645. if _self<>nil then
  646. begin
  647. fillchar(_self^,pvmt(vmtcopy)^.size,#0);
  648. ppointer(_self+_vmt_pos)^:=vmtcopy;
  649. end;
  650. fpc_help_constructor:=_self;
  651. end;
  652. {$endif FPC_SYSTEM_HAS_FPC_HELP_CONSTRUCTOR}
  653. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_DESTRUCTOR}
  654. { Note: _self will not be reset, the compiler has to generate the reset }
  655. procedure fpc_help_destructor(_self,_vmt:pointer;vmt_pos:cardinal);[public,alias:'FPC_HELP_DESTRUCTOR']; compilerproc;
  656. type
  657. ppointer = ^pointer;
  658. pvmt = ^tvmt;
  659. tvmt = packed record
  660. size,msize : ptruint;
  661. parent : pointer;
  662. end;
  663. begin
  664. { already released? }
  665. if (_self=nil) or
  666. (_vmt=nil) or
  667. (ppointer(_self+vmt_pos)^=nil) then
  668. exit;
  669. if (pvmt(ppointer(_self+vmt_pos)^)^.size=0) or
  670. (pvmt(ppointer(_self+vmt_pos)^)^.size+pvmt(ppointer(_self+vmt_pos)^)^.msize<>0) then
  671. RunError(210);
  672. { reset vmt to nil for protection }
  673. ppointer(_self+vmt_pos)^:=nil;
  674. freemem(_self);
  675. end;
  676. {$endif FPC_SYSTEM_HAS_FPC_HELP_DESTRUCTOR}
  677. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_FAIL}
  678. { Note: _self will not be reset, the compiler has to generate the reset }
  679. procedure fpc_help_fail(_self:pointer;var _vmt:pointer;vmt_pos:cardinal);[public,alias:'FPC_HELP_FAIL'];compilerproc;
  680. begin
  681. if (_self=nil) or (_vmt=nil) then
  682. exit;
  683. { vmt=$ffffffff when memory was allocated }
  684. if ptruint(_vmt)=high(ptruint) then
  685. begin
  686. if (_self=nil) or (ppointer(_self+vmt_pos)^=nil) then
  687. HandleError(210)
  688. else
  689. begin
  690. ppointer(_self+vmt_pos)^:=nil;
  691. freemem(_self);
  692. { reset _vmt to nil so it will not be freed a
  693. second time }
  694. _vmt:=nil;
  695. end;
  696. end
  697. else
  698. ppointer(_self+vmt_pos)^:=nil;
  699. end;
  700. {$endif FPC_SYSTEM_HAS_FPC_HELP_FAIL}
  701. {$ifndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT}
  702. procedure fpc_check_object(_vmt : pointer); [public,alias:'FPC_CHECK_OBJECT']; compilerproc;
  703. type
  704. pvmt = ^tvmt;
  705. tvmt = packed record
  706. size,msize : ptruint;
  707. parent : pointer;
  708. end;
  709. begin
  710. if (_vmt=nil) or
  711. (pvmt(_vmt)^.size=0) or
  712. (pvmt(_vmt)^.size+pvmt(_vmt)^.msize<>0) then
  713. RunError(210);
  714. end;
  715. {$endif ndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT}
  716. {$ifndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT_EXT}
  717. { checks for a correct vmt pointer }
  718. { deeper check to see if the current object is }
  719. { really related to the true }
  720. procedure fpc_check_object_ext(vmt, expvmt : pointer); [public,alias:'FPC_CHECK_OBJECT_EXT']; compilerproc;
  721. type
  722. pvmt = ^tvmt;
  723. tvmt = packed record
  724. size,msize : ptruint;
  725. parent : pointer;
  726. end;
  727. begin
  728. if (vmt=nil) or
  729. (pvmt(vmt)^.size=0) or
  730. (pvmt(vmt)^.size+pvmt(vmt)^.msize<>0) then
  731. RunError(210);
  732. while assigned(vmt) do
  733. if vmt=expvmt then
  734. exit
  735. else
  736. vmt:=pvmt(vmt)^.parent;
  737. RunError(219);
  738. end;
  739. {$endif not FPC_SYSTEM_HAS_FPC_CHECK_OBJECT_EXT}
  740. {$endif FPC_HAS_FEATURE_OBJECTS}
  741. {****************************************************************************
  742. String
  743. ****************************************************************************}
  744. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_ASSIGN}
  745. {$ifndef FPC_STRTOSHORTSTRINGPROC}
  746. function fpc_shortstr_to_shortstr(len:longint;const sstr:shortstring): shortstring;[public,alias:'FPC_SHORTSTR_TO_SHORTSTR']; compilerproc;
  747. var
  748. slen : byte;
  749. begin
  750. slen:=length(sstr);
  751. if slen<len then
  752. len:=slen;
  753. move(sstr[0],result[0],len+1);
  754. if slen>len then
  755. result[0]:=chr(len);
  756. end;
  757. {$else FPC_STRTOSHORTSTRINGPROC}
  758. procedure fpc_shortstr_to_shortstr(out res:shortstring; const sstr: shortstring);[public,alias:'FPC_SHORTSTR_TO_SHORTSTR']; compilerproc;
  759. var
  760. slen : byte;
  761. begin
  762. slen:=length(sstr);
  763. if slen>high(res) then
  764. slen:=high(res);
  765. move(sstr[0],res[0],slen+1);
  766. res[0]:=chr(slen);
  767. end;
  768. {$endif FPC_STRTOSHORTSTRINGPROC}
  769. procedure fpc_shortstr_assign(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_ASSIGN']; {$ifdef HAS_COMPILER_PROC} compilerproc; {$endif}
  770. var
  771. slen : byte;
  772. type
  773. pstring = ^string;
  774. begin
  775. slen:=length(pstring(sstr)^);
  776. if slen<len then
  777. len:=slen;
  778. move(sstr^,dstr^,len+1);
  779. if slen>len then
  780. pchar(dstr)^:=chr(len);
  781. end;
  782. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_ASSIGN}
  783. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
  784. {$ifndef STR_CONCAT_PROCS}
  785. function fpc_shortstr_concat(const s1,s2:shortstring): shortstring;[public,alias:'FPC_SHORTSTR_CONCAT']; compilerproc;
  786. var
  787. s1l, s2l : byte;
  788. begin
  789. s1l:=length(s1);
  790. s2l:=length(s2);
  791. if s1l+s2l>255 then
  792. s2l:=255-s1l;
  793. move(s1[1],fpc_shortstr_concat[1],s1l);
  794. move(s2[1],fpc_shortstr_concat[s1l+1],s2l);
  795. fpc_shortstr_concat[0]:=chr(s1l+s2l);
  796. end;
  797. {$else STR_CONCAT_PROCS}
  798. procedure fpc_shortstr_concat(var dests:shortstring;const s1,s2:shortstring);compilerproc;
  799. var
  800. s1l, s2l : longint;
  801. begin
  802. s1l:=length(s1);
  803. s2l:=length(s2);
  804. if s1l+s2l>high(dests) then
  805. s2l:=high(dests)-s1l;
  806. if @dests=@s1 then
  807. move(s2[1],dests[s1l+1],s2l)
  808. else
  809. if @dests=@s2 then
  810. begin
  811. move(dests[1],dests[s1l+1],s2l);
  812. move(s1[1],dests[1],s1l);
  813. end
  814. else
  815. begin
  816. move(s1[1],dests[1],s1l);
  817. move(s2[1],dests[s1l+1],s2l);
  818. end;
  819. dests[0]:=chr(s1l+s2l);
  820. end;
  821. procedure fpc_shortstr_concat_multi(var dests:shortstring;const sarr:array of pshortstring);compilerproc;
  822. var
  823. s2l : byte;
  824. LowStart,i,
  825. Len : longint;
  826. pc : pchar;
  827. needtemp : boolean;
  828. tmpstr : shortstring;
  829. p,pdest : pshortstring;
  830. begin
  831. if high(sarr)=0 then
  832. begin
  833. DestS:='';
  834. exit;
  835. end;
  836. lowstart:=low(sarr);
  837. if Pointer(@DestS)=Pointer(sarr[lowstart]) then
  838. inc(lowstart);
  839. { Check for another reuse, then we can't use
  840. the append optimization and need to use a temp }
  841. needtemp:=false;
  842. for i:=lowstart to high(sarr) do
  843. begin
  844. if Pointer(@DestS)=Pointer(sarr[i]) then
  845. begin
  846. needtemp:=true;
  847. break;
  848. end;
  849. end;
  850. if needtemp then
  851. begin
  852. lowstart:=low(sarr);
  853. tmpstr:='';
  854. pdest:=@tmpstr
  855. end
  856. else
  857. begin
  858. { Start with empty DestS if we start with concatting
  859. the first array element }
  860. if lowstart=low(sarr) then
  861. DestS:='';
  862. pdest:=@DestS;
  863. end;
  864. { Concat all strings, except the string we already
  865. copied in DestS }
  866. Len:=length(pdest^);
  867. pc:=@pdest^[1+Length(pdest^)];
  868. for i:=lowstart to high(sarr) do
  869. begin
  870. p:=sarr[i];
  871. if assigned(p) then
  872. begin
  873. s2l:=length(p^);
  874. if Len+s2l>high(dests) then
  875. s2l:=high(dests)-Len;
  876. Move(p^[1],pc^,s2l);
  877. inc(pc,s2l);
  878. inc(Len,s2l);
  879. end;
  880. end;
  881. pdest^[0]:=Chr(Len);
  882. if needtemp then
  883. DestS:=TmpStr;
  884. end;
  885. {$endif STR_CONCAT_PROCS}
  886. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
  887. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_APPEND_SHORTSTR}
  888. procedure fpc_shortstr_append_shortstr(var s1:shortstring;const s2:shortstring);compilerproc;
  889. [public,alias:'FPC_SHORTSTR_APPEND_SHORTSTR'];
  890. var
  891. s1l, s2l : integer;
  892. begin
  893. s1l:=length(s1);
  894. s2l:=length(s2);
  895. if s1l+s2l>high(s1) then
  896. s2l:=high(s1)-s1l;
  897. move(s2[1],s1[s1l+1],s2l);
  898. s1[0]:=chr(s1l+s2l);
  899. end;
  900. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_APPEND_SHORTSTR}
  901. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
  902. function fpc_shortstr_compare(const left,right:shortstring) : longint;[public,alias:'FPC_SHORTSTR_COMPARE']; compilerproc;
  903. var
  904. s1,s2,max,i : byte;
  905. d : longint;
  906. begin
  907. s1:=length(left);
  908. s2:=length(right);
  909. if s1<s2 then
  910. max:=s1
  911. else
  912. max:=s2;
  913. for i:=1 to max do
  914. begin
  915. d:=byte(left[i])-byte(right[i]);
  916. if d>0 then
  917. exit(1)
  918. else if d<0 then
  919. exit(-1);
  920. end;
  921. if s1>s2 then
  922. exit(1)
  923. else if s1<s2 then
  924. exit(-1)
  925. else
  926. exit(0);
  927. end;
  928. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
  929. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE_EQUAL}
  930. function fpc_shortstr_compare_equal(const left,right:shortstring): longint; [public,alias:'FPC_SHORTSTR_COMPARE_EQUAL']; compilerproc;
  931. begin
  932. Result := longint(left[0]) - longint(right[0]);
  933. if Result = 0 then
  934. Result := CompareByte(left[1],right[1], longint(left[0]));
  935. end;
  936. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE_EQUAL}
  937. {$ifndef FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
  938. {$ifndef FPC_STRTOSHORTSTRINGPROC}
  939. function fpc_pchar_to_shortstr(p:pchar):shortstring;[public,alias:'FPC_PCHAR_TO_SHORTSTR']; compilerproc;
  940. var
  941. l : longint;
  942. s: shortstring;
  943. begin
  944. if p=nil then
  945. l:=0
  946. else
  947. l:=strlen(p);
  948. if l>255 then
  949. l:=255;
  950. if l>0 then
  951. move(p^,s[1],l);
  952. s[0]:=chr(l);
  953. fpc_pchar_to_shortstr := s;
  954. end;
  955. {$else FPC_STRTOSHORTSTRINGPROC}
  956. procedure fpc_pchar_to_shortstr(out res : shortstring;p:pchar);[public,alias:'FPC_PCHAR_TO_SHORTSTR']; compilerproc;
  957. var
  958. l : longint;
  959. s: shortstring;
  960. begin
  961. if p=nil then
  962. l:=0
  963. else
  964. l:=strlen(p);
  965. if l>high(res) then
  966. l:=high(res);
  967. if l>0 then
  968. move(p^,s[1],l);
  969. s[0]:=chr(l);
  970. res:=s;
  971. end;
  972. {$endif FPC_STRTOSHORTSTRINGPROC}
  973. {$endif ndef FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
  974. {$ifndef FPC_STRTOSHORTSTRINGPROC}
  975. { also define alias which can be used inside the system unit }
  976. function fpc_pchar_to_shortstr(p:pchar):shortstring;[external name 'FPC_PCHAR_TO_SHORTSTR'];
  977. {$else FPC_STRTOSHORTSTRINGPROC}
  978. { also define alias which can be used inside the system unit }
  979. procedure fpc_pchar_to_shortstr(out res : shortstring;p:pchar);[external name 'FPC_PCHAR_TO_SHORTSTR'];
  980. {$endif FPC_STRTOSHORTSTRINGPROC}
  981. function strpas(p:pchar):shortstring;{$ifdef SYSTEMINLINE}inline;{$endif}
  982. begin
  983. {$ifndef FPC_STRTOSHORTSTRINGPROC}
  984. result:=fpc_pchar_to_shortstr(p);
  985. {$else FPC_STRTOSHORTSTRINGPROC}
  986. fpc_pchar_to_shortstr(result,p);
  987. {$endif FPC_STRTOSHORTSTRINGPROC}
  988. end;
  989. {$ifndef FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
  990. {$ifndef FPC_STRTOSHORTSTRINGPROC}
  991. function fpc_chararray_to_shortstr(const arr: array of char; zerobased: boolean = true):shortstring;[public,alias:'FPC_CHARARRAY_TO_SHORTSTR']; compilerproc;
  992. var
  993. l: longint;
  994. index: longint;
  995. len: byte;
  996. begin
  997. l := high(arr)+1;
  998. if l>=256 then
  999. l:=255
  1000. else if l<0 then
  1001. l:=0;
  1002. if (zerobased) then
  1003. begin
  1004. index:=IndexByte(arr[0],l,0);
  1005. if (index < 0) then
  1006. len := l
  1007. else
  1008. len := index;
  1009. end
  1010. else
  1011. len := l;
  1012. move(arr[0],fpc_chararray_to_shortstr[1],len);
  1013. fpc_chararray_to_shortstr[0]:=chr(len);
  1014. end;
  1015. {$else FPC_STRTOSHORTSTRINGPROC}
  1016. procedure fpc_chararray_to_shortstr(out res : shortstring;const arr: array of char; zerobased: boolean = true);[public,alias:'FPC_CHARARRAY_TO_SHORTSTR']; compilerproc;
  1017. var
  1018. l: longint;
  1019. index: longint;
  1020. len: byte;
  1021. begin
  1022. l:=high(arr)+1;
  1023. if l>=high(res)+1 then
  1024. l:=high(res)
  1025. else if l<0 then
  1026. l:=0;
  1027. if zerobased then
  1028. begin
  1029. index:=IndexByte(arr[0],l,0);
  1030. if index<0 then
  1031. len:=l
  1032. else
  1033. len:=index;
  1034. end
  1035. else
  1036. len:=l;
  1037. move(arr[0],res[1],len);
  1038. res[0]:=chr(len);
  1039. end;
  1040. {$endif FPC_STRTOSHORTSTRINGPROC}
  1041. {$endif ndef FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
  1042. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_TO_CHARARRAY}
  1043. {$ifndef FPC_STRTOCHARARRAYPROC}
  1044. { inside the compiler, the resulttype is modified to that of the actual }
  1045. { chararray we're converting to (JM) }
  1046. function fpc_shortstr_to_chararray(arraysize: longint; const src: ShortString): fpc_big_chararray;[public,alias: 'FPC_SHORTSTR_TO_CHARARRAY']; compilerproc;
  1047. var
  1048. len: longint;
  1049. begin
  1050. len := length(src);
  1051. if len > arraysize then
  1052. len := arraysize;
  1053. {$r-}
  1054. { make sure we don't access char 1 if length is 0 (JM) }
  1055. if len > 0 then
  1056. move(src[1],fpc_shortstr_to_chararray[0],len);
  1057. fillchar(fpc_shortstr_to_chararray[len],arraysize-len,0);
  1058. {$ifdef RangeCheckWasOn}
  1059. {$r+}
  1060. {$endif}
  1061. end;
  1062. {$else ndef FPC_STRTOCHARARRAYPROC}
  1063. procedure fpc_shortstr_to_chararray(out res: array of char; const src: ShortString); compilerproc;
  1064. var
  1065. len: longint;
  1066. begin
  1067. len := length(src);
  1068. if len > length(res) then
  1069. len := length(res);
  1070. {$r-}
  1071. { make sure we don't access char 1 if length is 0 (JM) }
  1072. if len > 0 then
  1073. move(src[1],res[0],len);
  1074. fillchar(res[len],length(res)-len,0);
  1075. {$ifdef RangeCheckWasOn}
  1076. {$r+}
  1077. {$endif}
  1078. end;
  1079. {$endif ndef FPC_STRTOCHARARRAYPROC}
  1080. {$endif FPC_SYSTEM_HAS_FPC_SHORTSTR_TO_CHARARRAY}
  1081. {$ifndef FPC_SYSTEM_HAS_FPC_PCHAR_LENGTH}
  1082. function fpc_pchar_length(p:pchar):longint;[public,alias:'FPC_PCHAR_LENGTH']; compilerproc;
  1083. var i : longint;
  1084. begin
  1085. i:=0;
  1086. while p[i]<>#0 do inc(i);
  1087. exit(i);
  1088. end;
  1089. {$endif ndef FPC_SYSTEM_HAS_FPC_PCHAR_LENGTH}
  1090. {$ifndef FPC_SYSTEM_HAS_FPC_PWIDECHAR_LENGTH}
  1091. function fpc_pwidechar_length(p:pwidechar):longint;[public,alias:'FPC_PWIDECHAR_LENGTH']; compilerproc;
  1092. var i : longint;
  1093. begin
  1094. i:=0;
  1095. while p[i]<>#0 do inc(i);
  1096. exit(i);
  1097. end;
  1098. {$endif ndef FPC_SYSTEM_HAS_FPC_PWIDECHAR_LENGTH}
  1099. {****************************************************************************
  1100. Caller/StackFrame Helpers
  1101. ****************************************************************************}
  1102. {$ifndef FPC_SYSTEM_HAS_GET_FRAME}
  1103. {_$error Get_frame must be defined for each processor }
  1104. {$endif ndef FPC_SYSTEM_HAS_GET_FRAME}
  1105. {$ifndef FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  1106. {_$error Get_caller_addr must be defined for each processor }
  1107. {$endif ndef FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  1108. {$ifndef FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  1109. {_$error Get_caller_frame must be defined for each processor }
  1110. {$endif ndef FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  1111. {****************************************************************************
  1112. Math
  1113. ****************************************************************************}
  1114. {****************************************************************************
  1115. Software longint/dword division
  1116. ****************************************************************************}
  1117. {$ifdef FPC_INCLUDE_SOFTWARE_MOD_DIV}
  1118. function count_leading_zeros_32bit(l : longint) : longint;
  1119. var
  1120. i : longint;
  1121. begin
  1122. for i:=0 to 31 do
  1123. begin
  1124. if (l and (longint($80000000) shr i))<>0 then
  1125. begin
  1126. result:=i;
  1127. exit;
  1128. end;
  1129. end;
  1130. result:=i;
  1131. end;
  1132. {$ifndef FPC_SYSTEM_HAS_DIV_DWORD}
  1133. function fpc_div_dword(n,z : dword) : dword; [public,alias: 'FPC_DIV_DWORD']; compilerproc;
  1134. var
  1135. shift,lzz,lzn : longint;
  1136. begin
  1137. result:=0;
  1138. if n=0 then
  1139. HandleErrorFrame(200,get_frame);
  1140. lzz:=count_leading_zeros_32bit(z);
  1141. lzn:=count_leading_zeros_32bit(n);
  1142. { if the denominator contains less zeros
  1143. then the numerator
  1144. the d is greater than the n }
  1145. if lzn<lzz then
  1146. exit;
  1147. shift:=lzn-lzz;
  1148. n:=n shl shift;
  1149. repeat
  1150. if z>=n then
  1151. begin
  1152. z:=z-n;
  1153. result:=result+dword(1 shl shift);
  1154. end;
  1155. dec(shift);
  1156. n:=n shr 1;
  1157. until shift<0;
  1158. end;
  1159. {$endif FPC_SYSTEM_HAS_DIV_DWORD}
  1160. {$ifndef FPC_SYSTEM_HAS_MOD_DWORD}
  1161. function fpc_mod_dword(n,z : dword) : dword; [public,alias: 'FPC_MOD_DWORD']; compilerproc;
  1162. var
  1163. shift,lzz,lzn : longint;
  1164. begin
  1165. result:=0;
  1166. if n=0 then
  1167. HandleErrorFrame(200,get_frame);
  1168. lzz:=count_leading_zeros_32bit(z);
  1169. lzn:=count_leading_zeros_32bit(n);
  1170. { if the denominator contains less zeros
  1171. then the numerator
  1172. the d is greater than the n }
  1173. if lzn<lzz then
  1174. begin
  1175. result:=z;
  1176. exit;
  1177. end;
  1178. shift:=lzn-lzz;
  1179. n:=n shl shift;
  1180. repeat
  1181. if z>=n then
  1182. z:=z-n;
  1183. dec(shift);
  1184. n:=n shr 1;
  1185. until shift<0;
  1186. result:=z;
  1187. end;
  1188. {$endif FPC_SYSTEM_HAS_MOD_DWORD}
  1189. {$ifndef FPC_SYSTEM_HAS_DIV_LONGINT}
  1190. function fpc_div_longint(n,z : longint) : longint; [public,alias: 'FPC_DIV_LONGINT']; compilerproc;
  1191. var
  1192. sign : boolean;
  1193. d1,d2 : dword;
  1194. begin
  1195. if n=0 then
  1196. HandleErrorFrame(200,get_frame);
  1197. sign:=false;
  1198. if z<0 then
  1199. begin
  1200. sign:=not(sign);
  1201. d1:=dword(-z);
  1202. end
  1203. else
  1204. d1:=z;
  1205. if n<0 then
  1206. begin
  1207. sign:=not(sign);
  1208. d2:=dword(-n);
  1209. end
  1210. else
  1211. d2:=n;
  1212. { the div is coded by the compiler as call to divdword }
  1213. if sign then
  1214. result:=-(d1 div d2)
  1215. else
  1216. result:=d1 div d2;
  1217. end;
  1218. {$endif FPC_SYSTEM_HAS_DIV_LONGINT}
  1219. {$ifndef FPC_SYSTEM_HAS_MOD_LONGINT}
  1220. function fpc_mod_longint(n,z : longint) : longint; [public,alias: 'FPC_MOD_LONGINT']; compilerproc;
  1221. var
  1222. signed : boolean;
  1223. r,nq,zq : dword;
  1224. begin
  1225. if n=0 then
  1226. HandleErrorFrame(200,get_frame);
  1227. nq:=abs(n);
  1228. if z<0 then
  1229. begin
  1230. zq:=dword(-z);
  1231. signed:=true;
  1232. end
  1233. else
  1234. begin
  1235. zq:=z;
  1236. signed:=false;
  1237. end;
  1238. r:=zq mod nq;
  1239. if signed then
  1240. result:=-longint(r)
  1241. else
  1242. result:=r;
  1243. end;
  1244. {$endif FPC_SYSTEM_HAS_MOD_LONGINT}
  1245. {$endif FPC_INCLUDE_SOFTWARE_MOD_DIV}
  1246. {****************************************************************************}
  1247. {$ifndef FPC_SYSTEM_HAS_ABS_LONGINT}
  1248. function abs(l:longint):longint;{$ifdef SYSTEMINLINE}inline;{$endif}
  1249. begin
  1250. if l<0 then
  1251. abs:=-l
  1252. else
  1253. abs:=l;
  1254. end;
  1255. {$endif not FPC_SYSTEM_HAS_ABS_LONGINT}
  1256. {$ifndef FPC_SYSTEM_HAS_ODD_LONGINT}
  1257. function odd(l:longint):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  1258. begin
  1259. odd:=boolean(l and 1);
  1260. end;
  1261. {$endif ndef FPC_SYSTEM_HAS_ODD_LONGINT}
  1262. {$ifndef FPC_SYSTEM_HAS_ODD_LONGWORD}
  1263. function odd(l:longword):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  1264. begin
  1265. odd:=boolean(l and 1);
  1266. end;
  1267. {$endif ndef FPC_SYSTEM_HAS_ODD_LONGWORD}
  1268. {$ifndef FPC_SYSTEM_HAS_ODD_INT64}
  1269. function odd(l:int64):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  1270. begin
  1271. odd:=boolean(longint(l) and 1);
  1272. end;
  1273. {$endif ndef FPC_SYSTEM_HAS_ODD_INT64}
  1274. {$ifndef FPC_SYSTEM_HAS_ODD_QWORD}
  1275. function odd(l:qword):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  1276. begin
  1277. odd:=boolean(longint(l) and 1);
  1278. end;
  1279. {$endif ndef FPC_SYSTEM_HAS_ODD_QWORD}
  1280. {$ifndef FPC_SYSTEM_HAS_SQR_LONGINT}
  1281. function sqr(l:longint):longint;{$ifdef SYSTEMINLINE}inline;{$endif}
  1282. begin
  1283. sqr:=l*l;
  1284. end;
  1285. {$endif ndef FPC_SYSTEM_HAS_SQR_LONGINT}
  1286. {$ifndef FPC_SYSTEM_HAS_ABS_INT64}
  1287. function abs(l: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
  1288. begin
  1289. if l < 0 then
  1290. abs := -l
  1291. else
  1292. abs := l;
  1293. end;
  1294. {$endif ndef FPC_SYSTEM_HAS_ABS_INT64}
  1295. {$ifndef FPC_SYSTEM_HAS_SQR_INT64}
  1296. function sqr(l: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
  1297. begin
  1298. sqr := l*l;
  1299. end;
  1300. {$endif ndef FPC_SYSTEM_HAS_SQR_INT64}
  1301. {$ifndef FPC_SYSTEM_HAS_SQR_QWORD}
  1302. function sqr(l: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1303. begin
  1304. sqr := l*l;
  1305. end;
  1306. {$endif ndef FPC_SYSTEM_HAS_SQR_INT64}
  1307. {$ifndef FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
  1308. function declocked(var l:longint):boolean;
  1309. begin
  1310. Dec(l);
  1311. declocked:=(l=0);
  1312. end;
  1313. {$endif FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
  1314. {$ifndef FPC_SYSTEM_HAS_DECLOCKED_INT64}
  1315. function declocked(var l:int64):boolean;
  1316. begin
  1317. Dec(l);
  1318. declocked:=(l=0);
  1319. end;
  1320. {$endif FPC_SYSTEM_HAS_DECLOCKED_INT64}
  1321. {$ifndef FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  1322. procedure inclocked(var l:longint);
  1323. begin
  1324. Inc(l);
  1325. end;
  1326. {$endif FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  1327. {$ifndef FPC_SYSTEM_HAS_INCLOCKED_INT64}
  1328. procedure inclocked(var l:int64);
  1329. begin
  1330. Inc(l);
  1331. end;
  1332. {$endif FPC_SYSTEM_HAS_INCLOCKED_INT64}
  1333. {$ifndef FPC_SYSTEM_HAS_SPTR}
  1334. {_$error Sptr must be defined for each processor }
  1335. {$endif ndef FPC_SYSTEM_HAS_SPTR}
  1336. function align(addr : PtrUInt;alignment : PtrUInt) : PtrUInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1337. begin
  1338. if addr mod alignment<>0 then
  1339. result:=addr+(alignment-(addr mod alignment))
  1340. else
  1341. result:=addr;
  1342. end;
  1343. function align(addr : Pointer;alignment : PtrUInt) : Pointer;{$ifdef SYSTEMINLINE}inline;{$endif}
  1344. begin
  1345. if PtrUInt(addr) mod alignment<>0 then
  1346. result:=pointer(addr+(alignment-(PtrUInt(addr) mod alignment)))
  1347. else
  1348. result:=addr;
  1349. end;
  1350. {****************************************************************************
  1351. Str()
  1352. ****************************************************************************}
  1353. {$ifndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
  1354. procedure int_str(l:longint;out s:string);
  1355. var
  1356. m,m1 : longword;
  1357. pc,pc2 : pchar;
  1358. hs : string[32];
  1359. b : longint;
  1360. begin
  1361. pc2:=@s[1];
  1362. if (l<0) then
  1363. begin
  1364. b:=1;
  1365. pc2^:='-';
  1366. inc(pc2);
  1367. m:=longword(-l);
  1368. end
  1369. else
  1370. begin
  1371. b:=0;
  1372. m:=longword(l);
  1373. end;
  1374. pc:=@hs[0];
  1375. repeat
  1376. inc(pc);
  1377. m1:=m div 10;
  1378. pc^:=char(m-(m1*10)+byte('0'));
  1379. m:=m1;
  1380. until m=0;
  1381. while (pc>pchar(@hs[0])) and
  1382. (b<high(s)) do
  1383. begin
  1384. pc2^:=pc^;
  1385. dec(pc);
  1386. inc(pc2);
  1387. inc(b);
  1388. end;
  1389. s[0]:=chr(b);
  1390. end;
  1391. {$endif ndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
  1392. {$ifndef FPC_SYSTEM_HAS_INT_STR_LONGWORD}
  1393. procedure int_str(l:longword;out s:string);
  1394. var
  1395. m1 : longword;
  1396. b: longint;
  1397. pc,pc2 : pchar;
  1398. hs : string[32];
  1399. begin
  1400. pc2:=@s[1];
  1401. pc:=@hs[0];
  1402. repeat
  1403. inc(pc);
  1404. m1:=l div 10;
  1405. pc^:=char(l-(m1*10)+byte('0'));
  1406. l:=m1;
  1407. until l=0;
  1408. b:=0;
  1409. while (pc>pchar(@hs[0])) and
  1410. (b<high(s)) do
  1411. begin
  1412. pc2^:=pc^;
  1413. dec(pc);
  1414. inc(pc2);
  1415. inc(b);
  1416. end;
  1417. s[0]:=chr(b);
  1418. end;
  1419. {$endif ndef FPC_SYSTEM_HAS_INT_STR_LONGWORD}
  1420. {$ifndef FPC_SYSTEM_HAS_INT_STR_INT64}
  1421. procedure int_str(l:int64;out s:string);
  1422. var
  1423. m,m1 : qword;
  1424. pc,pc2 : pchar;
  1425. b: longint;
  1426. hs : string[64];
  1427. begin
  1428. pc2:=@s[1];
  1429. if (l<0) then
  1430. begin
  1431. b:=1;
  1432. pc2^:='-';
  1433. inc(pc2);
  1434. m:=qword(-l);
  1435. end
  1436. else
  1437. begin
  1438. b:=0;
  1439. m:=qword(l);
  1440. end;
  1441. pc:=@hs[0];
  1442. repeat
  1443. inc(pc);
  1444. m1:=m div 10;
  1445. pc^:=char(m-(m1*10)+byte('0'));
  1446. m:=m1;
  1447. until m=0;
  1448. while (pc>pchar(@hs[0])) and
  1449. (b < high(s)) do
  1450. begin
  1451. pc2^:=pc^;
  1452. dec(pc);
  1453. inc(pc2);
  1454. inc(b);
  1455. end;
  1456. s[0]:=chr(b);
  1457. end;
  1458. {$endif ndef FPC_SYSTEM_HAS_INT_STR_INT64}
  1459. {$ifndef FPC_SYSTEM_HAS_INT_STR_QWORD}
  1460. procedure int_str(l:qword;out s:string);
  1461. var
  1462. m1 : qword;
  1463. pc,pc2 : pchar;
  1464. b: longint;
  1465. hs : string[64];
  1466. begin
  1467. pc2:=@s[1];
  1468. pc:=@hs[0];
  1469. repeat
  1470. inc(pc);
  1471. m1:=l div 10;
  1472. pc^:=char(l-(m1*10)+byte('0'));
  1473. l:=m1;
  1474. until l=0;
  1475. b:=0;
  1476. while (pc>pchar(@hs[0])) and
  1477. (b<high(s)) do
  1478. begin
  1479. pc2^:=pc^;
  1480. dec(pc);
  1481. inc(pc2);
  1482. inc(b);
  1483. end;
  1484. s[0]:=chr(b);
  1485. end;
  1486. {$endif ndef FPC_SYSTEM_HAS_INT_STR_QWORD}
  1487. {$ifndef FPC_SYSTEM_HAS_SYSRESETFPU}
  1488. procedure SysResetFpu;{$ifdef SYSTEMINLINE}inline;{$endif}
  1489. begin
  1490. softfloat_exception_flags:=0;
  1491. end;
  1492. {$endif FPC_SYSTEM_HAS_SYSRESETFPU}
  1493. {$ifndef FPC_SYSTEM_HAS_SYSINITFPU}
  1494. procedure SysInitFpu;{$ifdef SYSTEMINLINE}inline;{$endif}
  1495. begin
  1496. softfloat_exception_mask:=float_flag_underflow or float_flag_inexact or float_flag_denormal;
  1497. end;
  1498. {$endif FPC_SYSTEM_HAS_SYSINITFPU}
  1499. {$ifndef FPC_SYSTEM_HAS_SWAPENDIAN}
  1500. function SwapEndian(const AValue: SmallInt): SmallInt;
  1501. begin
  1502. Result := (AValue shr 8) or (AValue shl 8);
  1503. end;
  1504. function SwapEndian(const AValue: Word): Word;
  1505. begin
  1506. Result := (AValue shr 8) or (AValue shl 8);
  1507. end;
  1508. function SwapEndian(const AValue: LongInt): LongInt;
  1509. begin
  1510. Result := (AValue shl 24)
  1511. or ((AValue and $0000FF00) shl 8)
  1512. or ((AValue and $00FF0000) shr 8)
  1513. or (AValue shr 24);
  1514. end;
  1515. function SwapEndian(const AValue: DWord): DWord;
  1516. begin
  1517. Result := (AValue shl 24)
  1518. or ((AValue and $0000FF00) shl 8)
  1519. or ((AValue and $00FF0000) shr 8)
  1520. or (AValue shr 24);
  1521. end;
  1522. function SwapEndian(const AValue: Int64): Int64;
  1523. begin
  1524. Result := (AValue shl 56)
  1525. or ((AValue and $000000000000FF00) shl 40)
  1526. or ((AValue and $0000000000FF0000) shl 24)
  1527. or ((AValue and $00000000FF000000) shl 8)
  1528. or ((AValue and $000000FF00000000) shr 8)
  1529. or ((AValue and $0000FF0000000000) shr 24)
  1530. or ((AValue and $00FF000000000000) shr 40)
  1531. or (AValue shr 56);
  1532. end;
  1533. function SwapEndian(const AValue: QWord): QWord;
  1534. begin
  1535. Result := (AValue shl 56)
  1536. or ((AValue and $000000000000FF00) shl 40)
  1537. or ((AValue and $0000000000FF0000) shl 24)
  1538. or ((AValue and $00000000FF000000) shl 8)
  1539. or ((AValue and $000000FF00000000) shr 8)
  1540. or ((AValue and $0000FF0000000000) shr 24)
  1541. or ((AValue and $00FF000000000000) shr 40)
  1542. or (AValue shr 56);
  1543. end;
  1544. {$endif FPC_SYSTEM_HAS_SWAPENDIAN}
  1545. function BEtoN(const AValue: SmallInt): SmallInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1546. begin
  1547. {$IFDEF ENDIAN_BIG}
  1548. Result := AValue;
  1549. {$ELSE}
  1550. Result := SwapEndian(AValue);
  1551. {$ENDIF}
  1552. end;
  1553. function BEtoN(const AValue: Word): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
  1554. begin
  1555. {$IFDEF ENDIAN_BIG}
  1556. Result := AValue;
  1557. {$ELSE}
  1558. Result := SwapEndian(AValue);
  1559. {$ENDIF}
  1560. end;
  1561. function BEtoN(const AValue: LongInt): LongInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1562. begin
  1563. {$IFDEF ENDIAN_BIG}
  1564. Result := AValue;
  1565. {$ELSE}
  1566. Result := SwapEndian(AValue);
  1567. {$ENDIF}
  1568. end;
  1569. function BEtoN(const AValue: DWord): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1570. begin
  1571. {$IFDEF ENDIAN_BIG}
  1572. Result := AValue;
  1573. {$ELSE}
  1574. Result := SwapEndian(AValue);
  1575. {$ENDIF}
  1576. end;
  1577. function BEtoN(const AValue: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
  1578. begin
  1579. {$IFDEF ENDIAN_BIG}
  1580. Result := AValue;
  1581. {$ELSE}
  1582. Result := SwapEndian(AValue);
  1583. {$ENDIF}
  1584. end;
  1585. function BEtoN(const AValue: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1586. begin
  1587. {$IFDEF ENDIAN_BIG}
  1588. Result := AValue;
  1589. {$ELSE}
  1590. Result := SwapEndian(AValue);
  1591. {$ENDIF}
  1592. end;
  1593. function LEtoN(const AValue: SmallInt): SmallInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1594. begin
  1595. {$IFDEF ENDIAN_LITTLE}
  1596. Result := AValue;
  1597. {$ELSE}
  1598. Result := SwapEndian(AValue);
  1599. {$ENDIF}
  1600. end;
  1601. function LEtoN(const AValue: Word): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
  1602. begin
  1603. {$IFDEF ENDIAN_LITTLE}
  1604. Result := AValue;
  1605. {$ELSE}
  1606. Result := SwapEndian(AValue);
  1607. {$ENDIF}
  1608. end;
  1609. function LEtoN(const AValue: LongInt): LongInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1610. begin
  1611. {$IFDEF ENDIAN_LITTLE}
  1612. Result := AValue;
  1613. {$ELSE}
  1614. Result := SwapEndian(AValue);
  1615. {$ENDIF}
  1616. end;
  1617. function LEtoN(const AValue: DWord): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1618. begin
  1619. {$IFDEF ENDIAN_LITTLE}
  1620. Result := AValue;
  1621. {$ELSE}
  1622. Result := SwapEndian(AValue);
  1623. {$ENDIF}
  1624. end;
  1625. function LEtoN(const AValue: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
  1626. begin
  1627. {$IFDEF ENDIAN_LITTLE}
  1628. Result := AValue;
  1629. {$ELSE}
  1630. Result := SwapEndian(AValue);
  1631. {$ENDIF}
  1632. end;
  1633. function LEtoN(const AValue: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1634. begin
  1635. {$IFDEF ENDIAN_LITTLE}
  1636. Result := AValue;
  1637. {$ELSE}
  1638. Result := SwapEndian(AValue);
  1639. {$ENDIF}
  1640. end;
  1641. function NtoBE(const AValue: SmallInt): SmallInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1642. begin
  1643. {$IFDEF ENDIAN_BIG}
  1644. Result := AValue;
  1645. {$ELSE}
  1646. Result := SwapEndian(AValue);
  1647. {$ENDIF}
  1648. end;
  1649. function NtoBE(const AValue: Word): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
  1650. begin
  1651. {$IFDEF ENDIAN_BIG}
  1652. Result := AValue;
  1653. {$ELSE}
  1654. Result := SwapEndian(AValue);
  1655. {$ENDIF}
  1656. end;
  1657. function NtoBE(const AValue: LongInt): LongInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1658. begin
  1659. {$IFDEF ENDIAN_BIG}
  1660. Result := AValue;
  1661. {$ELSE}
  1662. Result := SwapEndian(AValue);
  1663. {$ENDIF}
  1664. end;
  1665. function NtoBE(const AValue: DWord): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1666. begin
  1667. {$IFDEF ENDIAN_BIG}
  1668. Result := AValue;
  1669. {$ELSE}
  1670. Result := SwapEndian(AValue);
  1671. {$ENDIF}
  1672. end;
  1673. function NtoBE(const AValue: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
  1674. begin
  1675. {$IFDEF ENDIAN_BIG}
  1676. Result := AValue;
  1677. {$ELSE}
  1678. Result := SwapEndian(AValue);
  1679. {$ENDIF}
  1680. end;
  1681. function NtoBE(const AValue: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1682. begin
  1683. {$IFDEF ENDIAN_BIG}
  1684. Result := AValue;
  1685. {$ELSE}
  1686. Result := SwapEndian(AValue);
  1687. {$ENDIF}
  1688. end;
  1689. function NtoLE(const AValue: SmallInt): SmallInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1690. begin
  1691. {$IFDEF ENDIAN_LITTLE}
  1692. Result := AValue;
  1693. {$ELSE}
  1694. Result := SwapEndian(AValue);
  1695. {$ENDIF}
  1696. end;
  1697. function NtoLE(const AValue: Word): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
  1698. begin
  1699. {$IFDEF ENDIAN_LITTLE}
  1700. Result := AValue;
  1701. {$ELSE}
  1702. Result := SwapEndian(AValue);
  1703. {$ENDIF}
  1704. end;
  1705. function NtoLE(const AValue: LongInt): LongInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1706. begin
  1707. {$IFDEF ENDIAN_LITTLE}
  1708. Result := AValue;
  1709. {$ELSE}
  1710. Result := SwapEndian(AValue);
  1711. {$ENDIF}
  1712. end;
  1713. function NtoLE(const AValue: DWord): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1714. begin
  1715. {$IFDEF ENDIAN_LITTLE}
  1716. Result := AValue;
  1717. {$ELSE}
  1718. Result := SwapEndian(AValue);
  1719. {$ENDIF}
  1720. end;
  1721. function NtoLE(const AValue: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
  1722. begin
  1723. {$IFDEF ENDIAN_LITTLE}
  1724. Result := AValue;
  1725. {$ELSE}
  1726. Result := SwapEndian(AValue);
  1727. {$ENDIF}
  1728. end;
  1729. function NtoLE(const AValue: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
  1730. begin
  1731. {$IFDEF ENDIAN_LITTLE}
  1732. Result := AValue;
  1733. {$ELSE}
  1734. Result := SwapEndian(AValue);
  1735. {$ENDIF}
  1736. end;
  1737. {$ifndef FPC_SYSTEM_HAS_MEM_BARRIER}
  1738. procedure ReadBarrier;{$ifdef SYSTEMINLINE}inline;{$endif}
  1739. begin
  1740. end;
  1741. procedure ReadDependencyBarrier;{$ifdef SYSTEMINLINE}inline;{$endif}
  1742. begin
  1743. end;
  1744. procedure ReadWriteBarrier;{$ifdef SYSTEMINLINE}inline;{$endif}
  1745. begin
  1746. end;
  1747. procedure WriteBarrier;{$ifdef SYSTEMINLINE}inline;{$endif}
  1748. begin
  1749. end;
  1750. {$endif}