i386.inc 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by the Free Pascal development team.
  5. Processor dependent implementation for the system unit for
  6. intel i386+
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. {$asmmode ATT}
  14. {****************************************************************************
  15. Primitives
  16. ****************************************************************************}
  17. function geteipasebx : pointer;assembler;[public,alias:'FPC_GETEIPINEBX'];
  18. asm
  19. movl (%esp),%ebx
  20. ret
  21. end;
  22. {$define FPC_SYSTEM_HAS_MOVE}
  23. procedure Move(const source;var dest;count:longint);assembler;
  24. var
  25. saveesi,saveedi : longint;
  26. asm
  27. movl %edi,saveedi
  28. movl %esi,saveesi
  29. movl dest,%edi
  30. movl source,%esi
  31. movl %edi,%eax
  32. movl count,%edx
  33. { check for zero or negative count }
  34. cmpl $0,%edx
  35. jle .LMoveEnd
  36. { Check for back or forward }
  37. sub %esi,%eax
  38. jz .LMoveEnd { Do nothing when source=dest }
  39. jc .LFMove { Do forward, dest<source }
  40. cmp %edx,%eax
  41. jb .LBMove { Dest is in range of move, do backward }
  42. { Forward Copy }
  43. .LFMove:
  44. cld
  45. cmpl $15,%edx
  46. jl .LFMove1
  47. movl %edi,%ecx { Align on 32bits }
  48. negl %ecx
  49. andl $3,%ecx
  50. subl %ecx,%edx
  51. rep
  52. movsb
  53. movl %edx,%ecx
  54. andl $3,%edx
  55. shrl $2,%ecx
  56. rep
  57. movsl
  58. .LFMove1:
  59. movl %edx,%ecx
  60. rep
  61. movsb
  62. jmp .LMoveEnd
  63. { Backward Copy }
  64. .LBMove:
  65. std
  66. addl %edx,%esi
  67. addl %edx,%edi
  68. movl %edi,%ecx
  69. decl %esi
  70. decl %edi
  71. cmpl $15,%edx
  72. jl .LBMove1
  73. negl %ecx { Align on 32bits }
  74. andl $3,%ecx
  75. subl %ecx,%edx
  76. rep
  77. movsb
  78. movl %edx,%ecx
  79. andl $3,%edx
  80. shrl $2,%ecx
  81. subl $3,%esi
  82. subl $3,%edi
  83. rep
  84. movsl
  85. addl $3,%esi
  86. addl $3,%edi
  87. .LBMove1:
  88. movl %edx,%ecx
  89. rep
  90. movsb
  91. cld
  92. .LMoveEnd:
  93. movl saveedi,%edi
  94. movl saveesi,%esi
  95. end;
  96. {$define FPC_SYSTEM_HAS_FILLCHAR}
  97. Procedure FillChar(var x;count:longint;value:byte);assembler;
  98. var
  99. saveedi : longint;
  100. asm
  101. movl %edi,saveedi
  102. cld
  103. movl x,%edi
  104. movb value,%al
  105. movl count,%ecx
  106. { check for zero or negative count }
  107. cmpl $0,%ecx
  108. jle .LFillEnd
  109. cmpl $7,%ecx
  110. jl .LFill1
  111. movb %al,%ah
  112. movl %eax,%edx
  113. shll $16,%eax
  114. movw %dx,%ax
  115. movl %ecx,%edx
  116. movl %edi,%ecx { Align on 32bits }
  117. negl %ecx
  118. andl $3,%ecx
  119. subl %ecx,%edx
  120. rep
  121. stosb
  122. movl %edx,%ecx
  123. andl $3,%edx
  124. shrl $2,%ecx
  125. rep
  126. stosl
  127. movl %edx,%ecx
  128. .LFill1:
  129. rep
  130. stosb
  131. .LFillEnd:
  132. movl saveedi,%edi
  133. end;
  134. {$define FPC_SYSTEM_HAS_FILLWORD}
  135. procedure fillword(var x;count : longint;value : word);assembler;
  136. var
  137. saveedi : longint;
  138. asm
  139. movl %edi,saveedi
  140. movl x,%edi
  141. movl count,%ecx
  142. { check for zero or negative count }
  143. cmpl $0,%ecx
  144. jle .LFillWordEnd
  145. movzwl value,%eax
  146. movl %eax,%edx
  147. shll $16,%eax
  148. orl %edx,%eax
  149. movl %ecx,%edx
  150. shrl $1,%ecx
  151. cld
  152. rep
  153. stosl
  154. movl %edx,%ecx
  155. andl $1,%ecx
  156. rep
  157. stosw
  158. .LFillWordEnd:
  159. movl saveedi,%edi
  160. end;
  161. {$define FPC_SYSTEM_HAS_FILLDWORD}
  162. procedure filldword(var x;count : longint;value : dword);assembler;
  163. var
  164. saveedi : longint;
  165. asm
  166. movl %edi,saveedi
  167. movl x,%edi
  168. movl count,%ecx
  169. { check for zero or negative count }
  170. cmpl $0,%ecx
  171. jle .LFillDWordEnd
  172. movl value,%eax
  173. cld
  174. rep
  175. stosl
  176. .LFillDWordEnd:
  177. movl saveedi,%edi
  178. end;
  179. {$define FPC_SYSTEM_HAS_INDEXBYTE}
  180. function IndexByte(Const buf;len:longint;b:byte):longint; assembler;
  181. var
  182. saveedi : longint;
  183. asm
  184. movl %edi,saveedi
  185. xorl %eax,%eax
  186. movl Len,%ecx // Load len
  187. movl Buf,%edi // Load String
  188. testl %ecx,%ecx
  189. jz .Lready
  190. cld
  191. movl %ecx,%edx // Copy for easy manipulation
  192. movb b,%al
  193. repne
  194. scasb
  195. jne .Lcharposnotfound
  196. incl %ecx
  197. subl %ecx,%edx
  198. movl %edx,%eax
  199. jmp .Lready
  200. .Lcharposnotfound:
  201. movl $-1,%eax
  202. .Lready:
  203. movl saveedi,%edi
  204. end;
  205. {$define FPC_SYSTEM_HAS_INDEXWORD}
  206. function Indexword(Const buf;len:longint;b:word):longint; assembler;
  207. var
  208. saveedi : longint;
  209. asm
  210. movl %edi,saveedi
  211. xorl %eax,%eax
  212. movl Len,%ecx // Load len
  213. movl Buf,%edi // Load String
  214. testl %ecx,%ecx
  215. jz .Lready
  216. cld
  217. movl %ecx,%edx // Copy for easy manipulation
  218. movw b,%ax
  219. repne
  220. scasw
  221. jne .Lcharposnotfound
  222. incl %ecx
  223. subl %ecx,%edx
  224. movl %edx,%eax
  225. jmp .Lready
  226. .Lcharposnotfound:
  227. movl $-1,%eax
  228. .Lready:
  229. movl saveedi,%edi
  230. end;
  231. {$define FPC_SYSTEM_HAS_INDEXDWORD}
  232. function IndexDWord(Const buf;len:longint;b:DWord):longint; assembler;
  233. var
  234. saveedi : longint;
  235. asm
  236. movl %edi,saveedi
  237. xorl %eax,%eax
  238. movl Len,%ecx // Load len
  239. movl Buf,%edi // Load String
  240. testl %ecx,%ecx
  241. jz .Lready
  242. cld
  243. movl %ecx,%edx // Copy for easy manipulation
  244. movl b,%eax
  245. repne
  246. scasl
  247. jne .Lcharposnotfound
  248. incl %ecx
  249. subl %ecx,%edx
  250. movl %edx,%eax
  251. jmp .Lready
  252. .Lcharposnotfound:
  253. movl $-1,%eax
  254. .Lready:
  255. movl saveedi,%edi
  256. end;
  257. {$define FPC_SYSTEM_HAS_COMPAREBYTE}
  258. function CompareByte(Const buf1,buf2;len:longint):longint; assembler;
  259. var
  260. saveesi,saveedi : longint;
  261. asm
  262. movl %edi,saveedi
  263. movl %esi,saveesi
  264. cld
  265. movl len,%eax
  266. movl buf2,%esi { Load params}
  267. movl buf1,%edi
  268. testl %eax,%eax {We address -1(%esi), so we have to deal with len=0}
  269. je .LCmpbyteExit
  270. cmpl $7,%eax {<7 not worth aligning and go through all trouble}
  271. jl .LCmpbyte2
  272. movl %edi,%ecx { Align on 32bits }
  273. negl %ecx { calc bytes to align (%edi and 3) xor 3= -%edi and 3}
  274. andl $3,%ecx
  275. subl %ecx,%eax { Subtract from number of bytes to go}
  276. orl %ecx,%ecx
  277. rep
  278. cmpsb {The actual 32-bit Aligning}
  279. jne .LCmpbyte3
  280. movl %eax,%ecx {bytes to do, divide by 4}
  281. andl $3,%eax {remainder}
  282. shrl $2,%ecx {The actual division}
  283. orl %ecx,%ecx {Sets zero flag if ecx=0 -> no cmp}
  284. rep
  285. cmpsl
  286. je .LCmpbyte2 { All equal? then to the left over bytes}
  287. movl $4,%eax { Not equal. Rescan the last 4 bytes bytewise}
  288. subl %eax,%esi
  289. subl %eax,%edi
  290. .LCmpbyte2:
  291. movl %eax,%ecx {bytes still to (re)scan}
  292. orl %eax,%eax {prevent disaster in case %eax=0}
  293. rep
  294. cmpsb
  295. .LCmpbyte3:
  296. movzbl -1(%esi),%ecx
  297. movzbl -1(%edi),%eax // Compare failing (or equal) position
  298. subl %ecx,%eax
  299. .LCmpbyteExit:
  300. movl saveedi,%edi
  301. movl saveesi,%esi
  302. end;
  303. {$define FPC_SYSTEM_HAS_COMPAREWORD}
  304. function CompareWord(Const buf1,buf2;len:longint):longint; assembler;
  305. var
  306. saveesi,saveedi,saveebx : longint;
  307. asm
  308. movl %edi,saveedi
  309. movl %esi,saveesi
  310. movl %ebx,saveebx
  311. cld
  312. movl len,%eax
  313. movl buf2,%esi { Load params}
  314. movl buf1,%edi
  315. testl %eax,%eax {We address -2(%esi), so we have to deal with len=0}
  316. je .LCmpwordExit
  317. cmpl $5,%eax {<5 (3 bytes align + 4 bytes cmpsl = 4 words}
  318. jl .LCmpword2 { not worth aligning and go through all trouble}
  319. movl (%edi),%ebx // Compare alignment bytes.
  320. cmpl (%esi),%ebx
  321. jne .LCmpword2 // Aligning will go wrong already. Max 2 words will be scanned Branch NOW
  322. shll $1,%eax {Convert word count to bytes}
  323. movl %edi,%edx { Align comparing is already done, so simply add}
  324. negl %edx { calc bytes to align -%edi and 3}
  325. andl $3,%edx
  326. addl %edx,%esi { Skip max 3 bytes alignment}
  327. addl %edx,%edi
  328. subl %edx,%eax { Subtract from number of bytes to go}
  329. movl %eax,%ecx { Make copy of bytes to go}
  330. andl $3,%eax { Calc remainder (mod 4) }
  331. andl $1,%edx { %edx is 1 if array not 2-aligned, 0 otherwise}
  332. shrl $2,%ecx { divide bytes to go by 4, DWords to go}
  333. orl %ecx,%ecx { Sets zero flag if ecx=0 -> no cmp}
  334. rep { Compare entire DWords}
  335. cmpsl
  336. je .LCmpword2a { All equal? then to the left over bytes}
  337. movl $4,%eax { Not equal. Rescan the last 4 bytes bytewise}
  338. subl %eax,%esi { Go back one DWord}
  339. subl %eax,%edi
  340. incl %eax {if not odd then this does nothing, else it makes
  341. sure that adding %edx increases from 2 to 3 words}
  342. .LCmpword2a:
  343. subl %edx,%esi { Subtract alignment}
  344. subl %edx,%edi
  345. addl %edx,%eax
  346. shrl $1,%eax
  347. .LCmpword2:
  348. movl %eax,%ecx {words still to (re)scan}
  349. orl %eax,%eax {prevent disaster in case %eax=0}
  350. rep
  351. cmpsw
  352. .LCmpword3:
  353. movzwl -2(%esi),%ecx
  354. movzwl -2(%edi),%eax // Compare failing (or equal) position
  355. subl %ecx,%eax // calculate end result.
  356. .LCmpwordExit:
  357. movl saveedi,%edi
  358. movl saveesi,%esi
  359. movl saveebx,%ebx
  360. end;
  361. {$define FPC_SYSTEM_HAS_COMPAREDWORD}
  362. function CompareDWord(Const buf1,buf2;len:longint):longint; assembler;
  363. var
  364. saveesi,saveedi,saveebx : longint;
  365. asm
  366. movl %edi,saveedi
  367. movl %esi,saveesi
  368. movl %ebx,saveebx
  369. cld
  370. movl len,%eax
  371. movl buf2,%esi { Load params}
  372. movl buf1,%edi
  373. testl %eax,%eax {We address -2(%esi), so we have to deal with len=0}
  374. je .LCmpDwordExit
  375. cmpl $3,%eax {<3 (3 bytes align + 4 bytes cmpsl) = 2 DWords}
  376. jl .LCmpDword2 { not worth aligning and go through all trouble}
  377. movl (%edi),%ebx // Compare alignment bytes.
  378. cmpl (%esi),%ebx
  379. jne .LCmpDword2 // Aligning will go wrong already. Max 2 words will be scanned Branch NOW
  380. shll $2,%eax {Convert word count to bytes}
  381. movl %edi,%edx { Align comparing is already done, so simply add}
  382. negl %edx { calc bytes to align -%edi and 3}
  383. andl $3,%edx
  384. addl %edx,%esi { Skip max 3 bytes alignment}
  385. addl %edx,%edi
  386. subl %edx,%eax { Subtract from number of bytes to go}
  387. movl %eax,%ecx { Make copy of bytes to go}
  388. andl $3,%eax { Calc remainder (mod 4) }
  389. shrl $2,%ecx { divide bytes to go by 4, DWords to go}
  390. orl %ecx,%ecx { Sets zero flag if ecx=0 -> no cmp}
  391. rep { Compare entire DWords}
  392. cmpsl
  393. je .LCmpDword2a { All equal? then to the left over bytes}
  394. movl $4,%eax { Not equal. Rescan the last 4 bytes bytewise}
  395. subl %eax,%esi { Go back one DWord}
  396. subl %eax,%edi
  397. addl $3,%eax {if align<>0 this causes repcount to be 2}
  398. .LCmpDword2a:
  399. subl %edx,%esi { Subtract alignment}
  400. subl %edx,%edi
  401. addl %edx,%eax
  402. shrl $2,%eax
  403. .LCmpDword2:
  404. movl %eax,%ecx {words still to (re)scan}
  405. orl %eax,%eax {prevent disaster in case %eax=0}
  406. rep
  407. cmpsl
  408. .LCmpDword3:
  409. movzwl -4(%esi),%ecx
  410. movzwl -4(%edi),%eax // Compare failing (or equal) position
  411. subl %ecx,%eax // calculate end result.
  412. .LCmpDwordExit:
  413. movl saveedi,%edi
  414. movl saveesi,%esi
  415. movl saveebx,%ebx
  416. end;
  417. {$define FPC_SYSTEM_HAS_INDEXCHAR0}
  418. function IndexChar0(Const buf;len:longint;b:Char):longint; assembler;
  419. var
  420. saveesi,saveebx : longint;
  421. asm
  422. movl %esi,saveesi
  423. movl %ebx,saveebx
  424. // Can't use scasb, or will have to do it twice, think this
  425. // is faster for small "len"
  426. movl Buf,%esi // Load address
  427. movl len,%edx // load maximal searchdistance
  428. movzbl b,%ebx // Load searchpattern
  429. testl %edx,%edx
  430. je .LFound
  431. xorl %ecx,%ecx // zero index in Buf
  432. xorl %eax,%eax // To make DWord compares possible
  433. .LLoop:
  434. movb (%esi),%al // Load byte
  435. cmpb %al,%bl
  436. je .LFound // byte the same?
  437. incl %ecx
  438. incl %esi
  439. cmpl %edx,%ecx // Maximal distance reached?
  440. je .LNotFound
  441. testl %eax,%eax // Nullchar = end of search?
  442. jne .LLoop
  443. .LNotFound:
  444. movl $-1,%ecx // Not found return -1
  445. .LFound:
  446. movl %ecx,%eax
  447. movl saveesi,%esi
  448. movl saveebx,%ebx
  449. end;
  450. {****************************************************************************
  451. Object Helpers
  452. ****************************************************************************}
  453. {$ifndef HAS_GENERICCONSTRUCTOR}
  454. {$define FPC_SYSTEM_HAS_FPC_HELP_CONSTRUCTOR}
  455. procedure fpc_help_constructor; assembler; [public,alias:'FPC_HELP_CONSTRUCTOR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  456. asm
  457. { Entry without preamble, since we need the ESP of the constructor
  458. Stack (relative to %ebp):
  459. 12 Self
  460. 8 VMT-Address
  461. 4 main programm-Addr
  462. 0 %ebp
  463. edi contains the vmt position
  464. }
  465. { eax isn't touched anywhere, so it doesn't have to reloaded }
  466. movl 8(%ebp),%eax
  467. { initialise self ? }
  468. orl %esi,%esi
  469. jne .LHC_4
  470. { get memory, but save register first temporary variable }
  471. subl $4,%esp
  472. movl %esp,%esi
  473. { Save Register}
  474. pushal
  475. {$ifdef valuegetmem}
  476. { esi can be destroyed in fpc_getmem!!! (JM) }
  477. pushl %esi
  478. {$endif valuegetmem}
  479. { Memory size }
  480. pushl (%eax)
  481. {$ifdef valuegetmem}
  482. call fpc_getmem
  483. popl %esi
  484. movl %eax,(%esi)
  485. {$else valuegetmem}
  486. pushl %esi
  487. call AsmGetMem
  488. {$endif valuegetmem}
  489. movl $-1,8(%ebp)
  490. popal
  491. { Avoid 80386DX bug }
  492. nop
  493. { Memory position to %esi }
  494. movl (%esi),%esi
  495. addl $4,%esp
  496. { If no memory available : fail() }
  497. orl %esi,%esi
  498. jz .LHC_5
  499. { init self for the constructor }
  500. movl %esi,12(%ebp)
  501. { jmp not necessary anymore because next instruction is disabled (JM)
  502. jmp .LHC_6 }
  503. { Why was the VMT reset to zero here ????
  504. I need it fail to know if I should
  505. zero the VMT field in static objects PM }
  506. .LHC_4:
  507. { movl $0,8(%ebp) }
  508. .LHC_6:
  509. { is there a VMT address ? }
  510. orl %eax,%eax
  511. jnz .LHC_7
  512. { In case the constructor doesn't do anything, the Zero-Flag }
  513. { can't be put, because this calls Fail() }
  514. incl %eax
  515. ret
  516. .LHC_7:
  517. { set zero inside the object }
  518. pushal
  519. cld
  520. movl (%eax),%ecx
  521. movl %esi,%edi
  522. movl %ecx,%ebx
  523. xorl %eax,%eax
  524. shrl $2,%ecx
  525. andl $3,%ebx
  526. rep
  527. stosl
  528. movl %ebx,%ecx
  529. rep
  530. stosb
  531. popal
  532. { avoid the 80386DX bug }
  533. nop
  534. { set the VMT address for the new created object }
  535. { the offset is in %edi since the calling and has not been changed !! }
  536. movl %eax,(%esi,%edi,1)
  537. testl %eax,%eax
  538. .LHC_5:
  539. end;
  540. {$define FPC_SYSTEM_HAS_FPC_HELP_FAIL}
  541. procedure fpc_help_fail;assembler;[public,alias:'FPC_HELP_FAIL']; {$ifdef hascompilerproc} compilerproc; {$endif}
  542. { should be called with a object that needs to be
  543. freed if VMT field is at -1
  544. %edi contains VMT offset in object again }
  545. asm
  546. testl %esi,%esi
  547. je .LHF_1
  548. cmpl $-1,8(%ebp)
  549. je .LHF_2
  550. { reset vmt field to zero for static instances }
  551. cmpl $0,8(%ebp)
  552. je .LHF_3
  553. { main constructor, we can zero the VMT field now }
  554. movl $0,(%esi,%edi,1)
  555. .LHF_3:
  556. { we zero esi to indicate failure }
  557. xorl %esi,%esi
  558. jmp .LHF_1
  559. .LHF_2:
  560. { get vmt address in eax }
  561. movl (%esi,%edi,1),%eax
  562. movl %esi,12(%ebp)
  563. { push object position }
  564. {$ifdef valuefreemem}
  565. pushl %esi
  566. call fpc_freemem
  567. {$else valuefreemem}
  568. leal 12(%ebp),%eax
  569. pushl %eax
  570. call AsmFreeMem
  571. {$endif valuefreemem}
  572. { set both object places to zero }
  573. xorl %esi,%esi
  574. movl %esi,12(%ebp)
  575. .LHF_1:
  576. end;
  577. {$define FPC_SYSTEM_HAS_FPC_HELP_DESTRUCTOR}
  578. procedure fpc_help_destructor;assembler;[public,alias:'FPC_HELP_DESTRUCTOR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  579. asm
  580. { Stack (relative to %ebp):
  581. 12 Self
  582. 8 VMT-Address
  583. 4 Main program-Addr
  584. 0 %ebp
  585. edi contains the vmt position
  586. }
  587. pushal
  588. { Should the object be resolved ? }
  589. movl 8(%ebp),%eax
  590. orl %eax,%eax
  591. jz .LHD_3
  592. { Yes, get size from SELF! }
  593. movl 12(%ebp),%eax
  594. { get VMT-pointer (from Self) to %ebx }
  595. { the offset is in %edi since the calling and has not been changed !! }
  596. movl (%eax,%edi,1),%ebx
  597. { I think for precaution }
  598. { that we should clear the VMT here }
  599. movl $0,(%eax,%edi,1)
  600. {$ifdef valuefreemem}
  601. { Freemem }
  602. pushl %eax
  603. call fpc_freemem
  604. {$else valuefreemem}
  605. { temporary Variable }
  606. subl $4,%esp
  607. movl %esp,%edi
  608. { SELF }
  609. movl %eax,(%edi)
  610. pushl %edi
  611. call AsmFreeMem
  612. addl $4,%esp
  613. {$endif valuefreemem}
  614. .LHD_3:
  615. popal
  616. { avoid the 80386DX bug }
  617. nop
  618. end;
  619. {$define FPC_SYSTEM_HAS_FPC_NEW_CLASS}
  620. procedure fpc_new_class;assembler;[public,alias:'FPC_NEW_CLASS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  621. asm
  622. { to be sure in the future, we save also edit }
  623. pushl %edi
  624. { create class ? }
  625. movl 8(%ebp),%edi
  626. { if we test eax later without calling newinstance }
  627. { it must have a value <>0 }
  628. movl $1,%eax
  629. testl %edi,%edi
  630. jz .LNEW_CLASS1
  631. { save registers !! }
  632. pushl %ebx
  633. pushl %ecx
  634. pushl %edx
  635. { esi contains the vmt }
  636. pushl %esi
  637. { call newinstance (class method!) }
  638. call *52{vmtNewInstance}(%esi)
  639. popl %edx
  640. popl %ecx
  641. popl %ebx
  642. { newinstance returns a pointer to the new created }
  643. { instance in eax }
  644. { load esi and insert self }
  645. movl %eax,%esi
  646. .LNEW_CLASS1:
  647. movl %esi,8(%ebp)
  648. testl %eax,%eax
  649. popl %edi
  650. end;
  651. { Internal alias that can be reference from asm code }
  652. procedure int_dispose_class;external name 'FPC_DISPOSE_CLASS';
  653. {$define FPC_SYSTEM_HAS_FPC_DISPOSE_CLASS}
  654. procedure fpc_dispose_class;assembler;[public,alias:'FPC_DISPOSE_CLASS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  655. asm
  656. { to be sure in the future, we save also edit }
  657. pushl %edi
  658. { destroy class ? }
  659. movl 12(%ebp),%edi
  660. testl %edi,%edi
  661. jz .LDISPOSE_CLASS1
  662. { no inherited call }
  663. movl (%esi),%edi
  664. { save registers !! }
  665. pushl %eax
  666. pushl %ebx
  667. pushl %ecx
  668. pushl %edx
  669. { push self }
  670. pushl %esi
  671. { call freeinstance }
  672. call *56{vmtFreeInstance}(%edi)
  673. popl %edx
  674. popl %ecx
  675. popl %ebx
  676. popl %eax
  677. .LDISPOSE_CLASS1:
  678. popl %edi
  679. end;
  680. {$define FPC_SYSTEM_HAS_FPC_HELP_FAIL_CLASS}
  681. procedure fpc_help_fail_class;assembler;[public,alias:'FPC_HELP_FAIL_CLASS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  682. { a non zero class must allways be disposed
  683. VMT is allways at pos 0 }
  684. asm
  685. testl %esi,%esi
  686. je .LHFC_1
  687. { can't use the compilerproc version as that will generate a
  688. reference instead of a symbol }
  689. call int_dispose_class
  690. { set both object places to zero }
  691. xorl %esi,%esi
  692. movl %esi,8(%ebp)
  693. .LHFC_1:
  694. end;
  695. {$define FPC_SYSTEM_HAS_FPC_CHECK_OBJECT}
  696. { we want the stack for debugging !! PM }
  697. procedure fpc_check_object(obj : pointer);[public,alias:'FPC_CHECK_OBJECT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  698. begin
  699. asm
  700. pushl %edi
  701. movl obj,%edi
  702. pushl %eax
  703. { Here we must check if the VMT pointer is nil before }
  704. { accessing it... }
  705. testl %edi,%edi
  706. jz .Lco_re
  707. movl (%edi),%eax
  708. addl 4(%edi),%eax
  709. jz .Lco_ok
  710. .Lco_re:
  711. pushl $210
  712. call HandleError
  713. .Lco_ok:
  714. popl %eax
  715. popl %edi
  716. { the adress is pushed : it needs to be removed from stack !! PM }
  717. end;{ of asm }
  718. end;
  719. {$define FPC_SYSTEM_HAS_FPC_CHECK_OBJECT_EXT}
  720. procedure fpc_check_object_ext;assembler;[public,alias:'FPC_CHECK_OBJECT_EXT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  721. { checks for a correct vmt pointer }
  722. { deeper check to see if the current object is }
  723. { really related to the true }
  724. asm
  725. pushl %ebp
  726. movl %esp,%ebp
  727. pushl %edi
  728. movl 8(%ebp),%edi
  729. pushl %ebx
  730. movl 12(%ebp),%ebx
  731. pushl %eax
  732. { Here we must check if the VMT pointer is nil before }
  733. { accessing it... }
  734. .Lcoext_obj:
  735. testl %edi,%edi
  736. jz .Lcoext_re
  737. movl (%edi),%eax
  738. addl 4(%edi),%eax
  739. jnz .Lcoext_re
  740. cmpl %edi,%ebx
  741. je .Lcoext_ok
  742. .Lcoext_vmt:
  743. movl 8(%edi),%eax
  744. cmpl %ebx,%eax
  745. je .Lcoext_ok
  746. movl %eax,%edi
  747. jmp .Lcoext_obj
  748. .Lcoext_re:
  749. pushl $219
  750. call HandleError
  751. .Lcoext_ok:
  752. popl %eax
  753. popl %ebx
  754. popl %edi
  755. { the adress and vmt were pushed : it needs to be removed from stack !! PM }
  756. popl %ebp
  757. ret $8
  758. end;
  759. {$endif HAS_GENERICCONSTRUCTOR}
  760. {****************************************************************************
  761. String
  762. ****************************************************************************}
  763. {$define FPC_SYSTEM_HAS_FPC_SHORTSTR_ASSIGN}
  764. function fpc_shortstr_to_shortstr(len:longint; const sstr: shortstring): shortstring; [public,alias: 'FPC_SHORTSTR_TO_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  765. begin
  766. asm
  767. cld
  768. movl __RESULT,%edi
  769. movl sstr,%esi
  770. xorl %eax,%eax
  771. movl len,%ecx
  772. lodsb
  773. cmpl %ecx,%eax
  774. jbe .LStrCopy1
  775. movl %ecx,%eax
  776. .LStrCopy1:
  777. stosb
  778. cmpl $7,%eax
  779. jl .LStrCopy2
  780. movl %edi,%ecx { Align on 32bits }
  781. negl %ecx
  782. andl $3,%ecx
  783. subl %ecx,%eax
  784. rep
  785. movsb
  786. movl %eax,%ecx
  787. andl $3,%eax
  788. shrl $2,%ecx
  789. rep
  790. movsl
  791. .LStrCopy2:
  792. movl %eax,%ecx
  793. rep
  794. movsb
  795. end ['ESI','EDI','EAX','ECX'];
  796. end;
  797. {$ifdef interncopy}
  798. procedure fpc_shortstr_assign(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_ASSIGN'];
  799. {$else}
  800. procedure fpc_shortstr_copy(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_COPY'];
  801. {$endif}
  802. begin
  803. asm
  804. pushl %eax
  805. pushl %ecx
  806. cld
  807. movl dstr,%edi
  808. movl sstr,%esi
  809. xorl %eax,%eax
  810. movl len,%ecx
  811. lodsb
  812. cmpl %ecx,%eax
  813. jbe .LStrCopy1
  814. movl %ecx,%eax
  815. .LStrCopy1:
  816. stosb
  817. cmpl $7,%eax
  818. jl .LStrCopy2
  819. movl %edi,%ecx { Align on 32bits }
  820. negl %ecx
  821. andl $3,%ecx
  822. subl %ecx,%eax
  823. rep
  824. movsb
  825. movl %eax,%ecx
  826. andl $3,%eax
  827. shrl $2,%ecx
  828. rep
  829. movsl
  830. .LStrCopy2:
  831. movl %eax,%ecx
  832. rep
  833. movsb
  834. popl %ecx
  835. popl %eax
  836. end ['ESI','EDI'];
  837. end;
  838. {$define FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
  839. function fpc_shortstr_concat(const s1,s2:shortstring):shortstring;{$ifdef hascompilerproc}compilerproc;{$endif}
  840. begin
  841. asm
  842. movl __RESULT,%edi
  843. movl %edi,%ebx
  844. movl s1,%esi { first string }
  845. lodsb
  846. andl $0x0ff,%eax
  847. stosb
  848. cmpl $7,%eax
  849. jl .LStrConcat1
  850. movl %edi,%ecx { Align on 32bits }
  851. negl %ecx
  852. andl $3,%ecx
  853. subl %ecx,%eax
  854. rep
  855. movsb
  856. movl %eax,%ecx
  857. andl $3,%eax
  858. shrl $2,%ecx
  859. rep
  860. movsl
  861. .LStrConcat1:
  862. movl %eax,%ecx
  863. rep
  864. movsb
  865. movl s2,%esi { second string }
  866. movzbl (%ebx),%ecx
  867. negl %ecx
  868. addl $0x0ff,%ecx
  869. lodsb
  870. cmpl %ecx,%eax
  871. jbe .LStrConcat2
  872. movl %ecx,%eax
  873. .LStrConcat2:
  874. addb %al,(%ebx)
  875. cmpl $7,%eax
  876. jl .LStrConcat3
  877. movl %edi,%ecx { Align on 32bits }
  878. negl %ecx
  879. andl $3,%ecx
  880. subl %ecx,%eax
  881. rep
  882. movsb
  883. movl %eax,%ecx
  884. andl $3,%eax
  885. shrl $2,%ecx
  886. rep
  887. movsl
  888. .LStrConcat3:
  889. movl %eax,%ecx
  890. rep
  891. movsb
  892. end ['EBX','ECX','EAX','ESI','EDI'];
  893. end;
  894. {$define FPC_SYSTEM_HAS_FPC_SHORTSTR_APPEND_SHORTSTR}
  895. {$ifdef hascompilerproc}
  896. procedure fpc_shortstr_append_shortstr(var s1:shortstring;const s2:shortstring);compilerproc;
  897. [public,alias:'FPC_SHORTSTR_APPEND_SHORTSTR'];
  898. begin
  899. asm
  900. movl s1,%edi
  901. movl s2,%esi
  902. movl %edi,%ebx
  903. movzbl (%edi),%ecx
  904. movl __HIGH(s1),%eax
  905. lea 1(%edi,%ecx),%edi
  906. negl %ecx
  907. addl %eax,%ecx
  908. // no need to zero eax, high(s1) <= 255
  909. lodsb
  910. cmpl %ecx,%eax
  911. jbe .LStrConcat1
  912. movl %ecx,%eax
  913. .LStrConcat1:
  914. addb %al,(%ebx)
  915. cmpl $7,%eax
  916. jl .LStrConcat2
  917. movl %edi,%ecx { Align on 32bits }
  918. negl %ecx
  919. andl $3,%ecx
  920. subl %ecx,%eax
  921. rep
  922. movsb
  923. movl %eax,%ecx
  924. andl $3,%eax
  925. shrl $2,%ecx
  926. rep
  927. movsl
  928. .LStrConcat2:
  929. movl %eax,%ecx
  930. rep
  931. movsb
  932. end ['EBX','ECX','EAX','ESI','EDI'];
  933. end;
  934. {$else hascompilerproc}
  935. procedure fpc_shortstr_concat_int(const s1,s2:shortstring);[public,alias:'FPC_SHORTSTR_CONCAT'];
  936. begin
  937. asm
  938. movl s1,%esi
  939. movl s2,%edi
  940. movl %edi,%ebx
  941. movzbl (%edi),%ecx
  942. xor %eax,%eax
  943. lea 1(%edi,%ecx),%edi
  944. negl %ecx
  945. addl $0x0ff,%ecx
  946. lodsb
  947. cmpl %ecx,%eax
  948. jbe .LStrConcat1
  949. movl %ecx,%eax
  950. .LStrConcat1:
  951. addb %al,(%ebx)
  952. cmpl $7,%eax
  953. jl .LStrConcat2
  954. movl %edi,%ecx { Align on 32bits }
  955. negl %ecx
  956. andl $3,%ecx
  957. subl %ecx,%eax
  958. rep
  959. movsb
  960. movl %eax,%ecx
  961. andl $3,%eax
  962. shrl $2,%ecx
  963. rep
  964. movsl
  965. .LStrConcat2:
  966. movl %eax,%ecx
  967. rep
  968. movsb
  969. end ['EBX','ECX','EAX','ESI','EDI'];
  970. end;
  971. {$endif hascompilerproc}
  972. {$define FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
  973. function fpc_shortstr_compare(const left,right:shortstring): longint; [public,alias:'FPC_SHORTSTR_COMPARE']; {$ifdef hascompilerproc} compilerproc; {$endif}
  974. begin
  975. asm
  976. cld
  977. xorl %ebx,%ebx
  978. xorl %eax,%eax
  979. movl right,%esi
  980. movl left,%edi
  981. movb (%esi),%al
  982. movb (%edi),%bl
  983. movl %eax,%edx
  984. incl %esi
  985. incl %edi
  986. cmpl %ebx,%eax
  987. jbe .LStrCmp1
  988. movl %ebx,%eax
  989. .LStrCmp1:
  990. cmpl $7,%eax
  991. jl .LStrCmp2
  992. movl %edi,%ecx { Align on 32bits }
  993. negl %ecx
  994. andl $3,%ecx
  995. subl %ecx,%eax
  996. orl %ecx,%ecx
  997. rep
  998. cmpsb
  999. jne .LStrCmp3
  1000. movl %eax,%ecx
  1001. andl $3,%eax
  1002. shrl $2,%ecx
  1003. orl %ecx,%ecx
  1004. rep
  1005. cmpsl
  1006. je .LStrCmp2
  1007. movl $4,%eax
  1008. sub %eax,%esi
  1009. sub %eax,%edi
  1010. .LStrCmp2:
  1011. movl %eax,%ecx
  1012. orl %eax,%eax
  1013. rep
  1014. cmpsb
  1015. jne .LStrCmp3
  1016. cmp %ebx,%edx
  1017. .LStrCmp3:
  1018. end ['EDX','ECX','EBX','EAX','ESI','EDI'];
  1019. end;
  1020. {$define FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
  1021. function fpc_pchar_to_shortstr(p:pchar):shortstring;[public,alias:'FPC_PCHAR_TO_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  1022. {$include strpas.inc}
  1023. {$define FPC_SYSTEM_HAS_FPC_PCHAR_LENGTH}
  1024. function fpc_pchar_length(p:pchar):longint;assembler;[public,alias:'FPC_PCHAR_LENGTH']; {$ifdef hascompilerproc} compilerproc; {$endif}
  1025. {$include strlen.inc}
  1026. {$define FPC_SYSTEM_HAS_GET_FRAME}
  1027. function get_frame:pointer;assembler;{$ifdef SYSTEMINLINE}inline;{$endif}
  1028. asm
  1029. movl %ebp,%eax
  1030. end ['EAX'];
  1031. {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  1032. function get_caller_addr(framebp:pointer):pointer;assembler;{$ifdef SYSTEMINLINE}inline;{$endif}
  1033. asm
  1034. movl framebp,%eax
  1035. orl %eax,%eax
  1036. jz .Lg_a_null
  1037. movl 4(%eax),%eax
  1038. .Lg_a_null:
  1039. end ['EAX'];
  1040. {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  1041. function get_caller_frame(framebp:pointer):pointer;assembler;{$ifdef SYSTEMINLINE}inline;{$endif}
  1042. asm
  1043. movl framebp,%eax
  1044. orl %eax,%eax
  1045. jz .Lgnf_null
  1046. movl (%eax),%eax
  1047. .Lgnf_null:
  1048. end ['EAX'];
  1049. {****************************************************************************
  1050. Math
  1051. ****************************************************************************}
  1052. {$define FPC_SYSTEM_HAS_ABS_LONGINT}
  1053. function abs(l:longint):longint; assembler;{$ifdef SYSTEMINLINE}inline;{$endif}[internconst:in_const_abs];
  1054. asm
  1055. movl l,%eax
  1056. cltd
  1057. xorl %edx,%eax
  1058. subl %edx,%eax
  1059. end ['EAX','EDX'];
  1060. {$define FPC_SYSTEM_HAS_ODD_LONGINT}
  1061. function odd(l:longint):boolean;assembler;{$ifdef SYSTEMINLINE}inline;{$endif}[internconst:in_const_odd];
  1062. asm
  1063. movl l,%eax
  1064. andl $1,%eax
  1065. setnz %al
  1066. end ['EAX'];
  1067. {$define FPC_SYSTEM_HAS_SQR_LONGINT}
  1068. function sqr(l:longint):longint;assembler;{$ifdef SYSTEMINLINE}inline;{$endif}[internconst:in_const_sqr];
  1069. asm
  1070. mov l,%eax
  1071. imull %eax,%eax
  1072. end ['EAX'];
  1073. {$define FPC_SYSTEM_HAS_SPTR}
  1074. Function Sptr : Pointer;assembler;{$ifdef SYSTEMINLINE}inline;{$endif}
  1075. asm
  1076. movl %esp,%eax
  1077. end;
  1078. {****************************************************************************
  1079. Str()
  1080. ****************************************************************************}
  1081. {$define FPC_SYSTEM_HAS_INT_STR_LONGINT}
  1082. procedure int_str(l : longint;var s : string);
  1083. var
  1084. buffer : array[0..15] of byte;
  1085. isneg : byte;
  1086. begin
  1087. { Workaround: }
  1088. if l=longint($80000000) then
  1089. begin
  1090. s:='-2147483648';
  1091. exit;
  1092. end;
  1093. asm
  1094. movl l,%eax // load Integer
  1095. xorl %ecx,%ecx // String length=0
  1096. leal buffer,%ebx
  1097. movl $0x0a,%esi // load 10 as dividing constant.
  1098. movb $0,isneg
  1099. orl %eax,%eax // Sign ?
  1100. jns .LM2
  1101. movb $1,isneg
  1102. negl %eax
  1103. .LM2:
  1104. cltd
  1105. idivl %esi
  1106. addb $0x30,%dl // convert Rest to ASCII.
  1107. movb %dl,(%ebx)
  1108. incl %ecx
  1109. incl %ebx
  1110. cmpl $0,%eax
  1111. jnz .LM2
  1112. { now copy the string }
  1113. movl s,%edi // Load String address
  1114. cmpb $0,isneg
  1115. je .LM3
  1116. movb $0x2d,(%ebx)
  1117. incl %ecx
  1118. incl %ebx
  1119. .LM3:
  1120. movb %cl,(%edi) // Copy String length
  1121. incl %edi
  1122. .LM4:
  1123. decl %ebx
  1124. movb (%ebx),%al
  1125. stosb
  1126. decl %ecx
  1127. jnz .LM4
  1128. end ['eax','ecx','edx','ebx','esi','edi'];
  1129. end;
  1130. {$define FPC_SYSTEM_HAS_INT_STR_LONGWORD}
  1131. procedure int_str(c : longword;var s : string);
  1132. var
  1133. buffer : array[0..15] of byte;
  1134. begin
  1135. asm
  1136. movl c,%eax // load CARDINAL
  1137. xorl %ecx,%ecx // String length=0
  1138. leal buffer,%ebx
  1139. movl $0x0a,%esi // load 10 as dividing constant.
  1140. .LM4:
  1141. xorl %edx,%edx
  1142. divl %esi
  1143. addb $0x30,%dl // convert Rest to ASCII.
  1144. movb %dl,(%ebx)
  1145. incl %ecx
  1146. incl %ebx
  1147. cmpl $0,%eax
  1148. jnz .LM4
  1149. { now copy the string }
  1150. movl s,%edi // Load String address
  1151. movb %cl,(%edi) // Copy String length
  1152. incl %edi
  1153. .LM5:
  1154. decl %ebx
  1155. movb (%ebx),%al
  1156. stosb
  1157. decl %ecx
  1158. jnz .LM5
  1159. end ['eax','ecx','edx','ebx','esi','edi'];
  1160. end;
  1161. {****************************************************************************
  1162. Bounds Check
  1163. ****************************************************************************}
  1164. {$ifndef NOBOUNDCHECK}
  1165. procedure int_boundcheck;assembler;[public,alias: 'FPC_BOUNDCHECK'];
  1166. var dummy_to_force_stackframe_generation_for_trace: Longint;
  1167. {
  1168. called with:
  1169. %ecx - value
  1170. %edi - pointer to the ranges
  1171. }
  1172. asm
  1173. cmpl (%edi),%ecx
  1174. jl .Lbc_err
  1175. cmpl 4(%edi),%ecx
  1176. jle .Lbc_ok
  1177. .Lbc_err:
  1178. pushl %ebp
  1179. pushl $201
  1180. call HandleErrorFrame
  1181. .Lbc_ok:
  1182. end;
  1183. {$endif NOBOUNDCHECK}
  1184. { do a thread save inc/dec }
  1185. {$define FPC_SYSTEM_HAS_DECLOCKED}
  1186. function declocked(var l : longint) : boolean;assembler;
  1187. asm
  1188. movl l,%eax
  1189. { this check should be done because a lock takes a lot }
  1190. { of time! }
  1191. cmpb $0,IsMultithread
  1192. jz .Ldeclockednolock
  1193. lock
  1194. decl (%eax)
  1195. jmp .Ldeclockedend
  1196. .Ldeclockednolock:
  1197. decl (%eax);
  1198. .Ldeclockedend:
  1199. setzb %al
  1200. end;
  1201. {$define FPC_SYSTEM_HAS_INCLOCKED}
  1202. procedure inclocked(var l : longint);assembler;
  1203. asm
  1204. movl l,%eax
  1205. { this check should be done because a lock takes a lot }
  1206. { of time! }
  1207. cmpb $0,IsMultithread
  1208. jz .Linclockednolock
  1209. lock
  1210. incl (%eax)
  1211. jmp .Linclockedend
  1212. .Linclockednolock:
  1213. incl (%eax)
  1214. .Linclockedend:
  1215. end;
  1216. {****************************************************************************
  1217. FPU
  1218. ****************************************************************************}
  1219. const
  1220. fpucw : word = $1332;
  1221. { Internal constants for use in system unit }
  1222. FPU_Invalid = 1;
  1223. FPU_Denormal = 2;
  1224. FPU_DivisionByZero = 4;
  1225. FPU_Overflow = 8;
  1226. FPU_Underflow = $10;
  1227. FPU_StackUnderflow = $20;
  1228. FPU_StackOverflow = $40;
  1229. FPU_ExceptionMask = $ff;
  1230. {$define FPC_SYSTEM_HAS_SYSRESETFPU}
  1231. Procedure SysResetFPU;assembler;{$ifdef SYSTEMINLINE}inline;{$endif}
  1232. asm
  1233. fninit
  1234. fldcw fpucw
  1235. end;
  1236. {
  1237. $Log$
  1238. Revision 1.52 2003-11-03 09:42:27 marco
  1239. * Peter's Cardinal<->Longint fixes patch
  1240. Revision 1.51 2003/10/27 09:16:57 marco
  1241. * fix from peter i386.inc to circumvent ebx destroying
  1242. Revision 1.50 2003/10/23 17:01:27 peter
  1243. * save edi,ebx,esi in int_str
  1244. Revision 1.49 2003/10/16 21:28:40 peter
  1245. * use __HIGH()
  1246. Revision 1.48 2003/10/14 00:57:48 florian
  1247. + some code for PIC support added
  1248. Revision 1.47 2003/09/14 11:34:13 peter
  1249. * moved int64 asm code to int64p.inc
  1250. * save ebx,esi
  1251. Revision 1.46 2003/09/08 18:21:37 peter
  1252. * save edi,esi,ebx
  1253. Revision 1.45 2003/06/01 14:50:17 jonas
  1254. * fpc_shortstr_append_shortstr has to use high(s1) instead of 255 as
  1255. maxlen
  1256. + ppc version of fpc_shortstr_append_shortstr
  1257. Revision 1.44 2003/05/26 21:18:13 peter
  1258. * FPC_SHORTSTR_APPEND_SHORTSTR public added
  1259. Revision 1.43 2003/05/26 19:36:46 peter
  1260. * fpc_shortstr_concat is now the same for all targets
  1261. * fpc_shortstr_append_shortstr added for optimized code generation
  1262. Revision 1.42 2003/05/16 22:40:11 florian
  1263. * fixed generic shortstr_compare
  1264. Revision 1.41 2003/03/26 00:19:10 peter
  1265. * ifdef HAS_GENERICCONSTRUCTOR
  1266. Revision 1.40 2003/03/17 14:30:11 peter
  1267. * changed address parameter/return values to pointer instead
  1268. of longint
  1269. Revision 1.39 2003/02/18 17:56:06 jonas
  1270. - removed buggy i386-specific FPC_CHARARRAY_TO_SHORTSTR
  1271. * fixed generic FPC_CHARARRAY_TO_SHORTSTR (web bug 2382)
  1272. * fixed some potential range errors in indexchar/word/dword
  1273. Revision 1.38 2003/01/06 23:03:13 mazen
  1274. + defining FPC_SYSTEM_HAS_DECLOCKED and FPC_SYSTEM_HAS_INCLOCKED to avoid
  1275. compilation error on generic.inc
  1276. Revision 1.37 2003/01/03 17:14:54 peter
  1277. * fix possible overflow when array len > 255 when converting to
  1278. shortstring
  1279. Revision 1.36 2002/12/15 22:32:25 peter
  1280. * fixed return value when len=0 for indexchar,indexword
  1281. Revision 1.35 2002/10/20 11:50:57 carl
  1282. * avoid crashes with negative len counts on fills/moves
  1283. Revision 1.34 2002/10/15 19:24:47 carl
  1284. * Replace 220 -> 219
  1285. Revision 1.33 2002/10/14 19:39:16 peter
  1286. * threads unit added for thread support
  1287. Revision 1.32 2002/10/05 14:20:16 peter
  1288. * fpc_pchar_length compilerproc and strlen alias
  1289. Revision 1.31 2002/10/02 18:21:51 peter
  1290. * Copy() changed to internal function calling compilerprocs
  1291. * FPC_SHORTSTR_COPY renamed to FPC_SHORTSTR_ASSIGN because of the
  1292. new copy functions
  1293. Revision 1.30 2002/09/07 21:33:35 carl
  1294. - removed unused defines
  1295. Revision 1.29 2002/09/07 16:01:19 peter
  1296. * old logs removed and tabs fixed
  1297. Revision 1.28 2002/09/03 15:43:36 peter
  1298. * add alias for fpc_dispose_class so it can be called from
  1299. fpc_help_fail_class
  1300. Revision 1.27 2002/08/19 19:34:02 peter
  1301. * SYSTEMINLINE define that will add inline directives for small
  1302. functions and wrappers. This will be defined automaticly when
  1303. the compiler defines the HASINLINE directive
  1304. Revision 1.26 2002/07/26 15:45:33 florian
  1305. * changed multi threading define: it's MT instead of MTRTL
  1306. Revision 1.25 2002/07/06 20:31:59 carl
  1307. + added TEST_GENERIC to test generic version
  1308. Revision 1.24 2002/06/16 08:21:26 carl
  1309. + TEST_GENERIC to test generic versions of code
  1310. Revision 1.23 2002/06/09 12:54:37 jonas
  1311. * fixed memory corruption bug in fpc_help_constructor
  1312. Revision 1.22 2002/04/21 18:56:59 peter
  1313. * fpc_freemem and fpc_getmem compilerproc
  1314. Revision 1.21 2002/04/01 14:23:17 carl
  1315. - no need for runerror 203, already fixed!
  1316. Revision 1.20 2002/03/30 14:52:04 carl
  1317. * cause runtime error 203 on failed class creation
  1318. }