i386.inc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 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. Move / Fill
  16. ****************************************************************************}
  17. {$define FPC_SYSTEM_HAS_MOVE}
  18. procedure Move(var source;var dest;count:longint);
  19. begin
  20. asm
  21. movl dest,%edi
  22. movl source,%esi
  23. movl %edi,%eax
  24. movl count,%ebx
  25. { Check for back or forward }
  26. sub %esi,%eax
  27. jz .LMoveEnd { Do nothing when source=dest }
  28. jc .LFMove { Do forward, dest<source }
  29. cmp %ebx,%eax
  30. jb .LBMove { Dest is in range of move, do backward }
  31. { Forward Copy }
  32. .LFMove:
  33. cld
  34. cmpl $15,%ebx
  35. jl .LFMove1
  36. movl %edi,%ecx { Align on 32bits }
  37. negl %ecx
  38. andl $3,%ecx
  39. subl %ecx,%ebx
  40. rep
  41. movsb
  42. movl %ebx,%ecx
  43. andl $3,%ebx
  44. shrl $2,%ecx
  45. rep
  46. movsl
  47. .LFMove1:
  48. movl %ebx,%ecx
  49. rep
  50. movsb
  51. jmp .LMoveEnd
  52. { Backward Copy }
  53. .LBMove:
  54. std
  55. addl %ebx,%esi
  56. addl %ebx,%edi
  57. movl %edi,%ecx
  58. decl %esi
  59. decl %edi
  60. cmpl $15,%ebx
  61. jl .LBMove1
  62. negl %ecx { Align on 32bits }
  63. andl $3,%ecx
  64. subl %ecx,%ebx
  65. rep
  66. movsb
  67. movl %ebx,%ecx
  68. andl $3,%ebx
  69. shrl $2,%ecx
  70. subl $3,%esi
  71. subl $3,%edi
  72. rep
  73. movsl
  74. addl $3,%esi
  75. addl $3,%edi
  76. .LBMove1:
  77. movl %ebx,%ecx
  78. rep
  79. movsb
  80. cld
  81. .LMoveEnd:
  82. end;
  83. end;
  84. {$define FPC_SYSTEM_HAS_FILLCHAR}
  85. Procedure FillChar(var x;count:longint;value:byte);
  86. begin
  87. asm
  88. cld
  89. movl x,%edi
  90. { movl value,%eax Only lower 8 bits will be used }
  91. movb value,%al
  92. movl count,%ecx
  93. cmpl $7,%ecx
  94. jl .LFill1
  95. movb %al,%ah
  96. movl %eax,%ebx
  97. shll $16,%eax
  98. movl %ecx,%edx
  99. movw %bx,%ax
  100. movl %edi,%ecx { Align on 32bits }
  101. negl %ecx
  102. andl $3,%ecx
  103. subl %ecx,%edx
  104. rep
  105. stosb
  106. movl %edx,%ecx
  107. andl $3,%edx
  108. shrl $2,%ecx
  109. rep
  110. stosl
  111. movl %edx,%ecx
  112. .LFill1:
  113. rep
  114. stosb
  115. end;
  116. end;
  117. {$define FPC_SYSTEM_HAS_FILLWORD}
  118. procedure fillword(var x;count : longint;value : word);
  119. begin
  120. asm
  121. movl 8(%ebp),%edi
  122. movl 12(%ebp),%ecx
  123. movl 16(%ebp),%eax
  124. movl %eax,%edx
  125. shll $16,%eax
  126. movw %dx,%ax
  127. movl %ecx,%edx
  128. shrl $1,%ecx
  129. cld
  130. rep
  131. stosl
  132. movl %edx,%ecx
  133. andl $1,%ecx
  134. rep
  135. stosw
  136. end ['EAX','ECX','EDX','EDI'];
  137. end;
  138. {****************************************************************************
  139. Object Helpers
  140. ****************************************************************************}
  141. {$define FPC_SYSTEM_HAS_FPC_HELP_CONSTRUCTOR}
  142. procedure int_help_constructor;assembler; [public,alias:'FPC_HELP_CONSTRUCTOR'];
  143. asm
  144. { Entry without preamble, since we need the ESP of the constructor
  145. Stack (relative to %ebp):
  146. 12 Self
  147. 8 VMT-Address
  148. 4 main programm-Addr
  149. 0 %ebp
  150. edi contains the vmt position
  151. }
  152. { eax isn't touched anywhere, so it doesn't have to reloaded }
  153. movl 8(%ebp),%eax
  154. { initialise self ? }
  155. orl %esi,%esi
  156. jne .LHC_4
  157. { get memory, but save register first temporary variable }
  158. subl $4,%esp
  159. movl %esp,%esi
  160. { Save Register}
  161. pushal
  162. { Memory size }
  163. pushl (%eax)
  164. pushl %esi
  165. call GetMem
  166. popal
  167. { Memory position to %esi }
  168. movl (%esi),%esi
  169. addl $4,%esp
  170. { If no memory available : fail() }
  171. orl %esi,%esi
  172. jz .LHC_5
  173. { init self for the constructor }
  174. movl %esi,12(%ebp)
  175. .LHC_4:
  176. { is there a VMT address ? }
  177. orl %eax,%eax
  178. jnz .LHC_7
  179. { In case the constructor doesn't do anything, the Zero-Flag }
  180. { can't be put, because this calls Fail() }
  181. incl %eax
  182. ret
  183. .LHC_7:
  184. { set zero inside the object }
  185. pushal
  186. cld
  187. movl (%eax),%ecx
  188. movl %esi,%edi
  189. xorl %eax,%eax
  190. shrl $1,%ecx
  191. jnc .LHCFill1
  192. stosb
  193. .LHCFill1:
  194. shrl $1,%ecx
  195. jnc .LHCFill2
  196. stosw
  197. .LHCFill2:
  198. rep
  199. stosl
  200. popal
  201. { set the VMT address for the new created object }
  202. { the offset is in %edi since the calling and has not been changed !! }
  203. movl %eax,(%esi,%edi,1)
  204. orl %eax,%eax
  205. .LHC_5:
  206. end;
  207. {$define FPC_SYSTEM_HAS_FPC_HELP_DESTRUCTOR}
  208. procedure int_help_destructor;assembler;[public,alias:'FPC_HELP_DESTRUCTOR'];
  209. asm
  210. { Stack (relative to %ebp):
  211. 12 Self
  212. 8 VMT-Address
  213. 4 Main program-Addr
  214. 0 %ebp
  215. edi contains the vmt position
  216. }
  217. pushal
  218. { Should the object be resolved ? }
  219. movl 8(%ebp),%eax
  220. orl %eax,%eax
  221. jz .LHD_3
  222. { Yes, get size from SELF! }
  223. movl 12(%ebp),%eax
  224. { get VMT-pointer (from Self) to %ebx }
  225. { the offset is in %edi since the calling and has not been changed !! }
  226. movl (%eax,%edi,1),%ebx
  227. { I think for precaution }
  228. { that we should clear the VMT here }
  229. movl $0,(%eax,%edi,1)
  230. { temporary Variable }
  231. subl $4,%esp
  232. movl %esp,%edi
  233. { And put size on the Stack }
  234. pushl (%ebx)
  235. { SELF }
  236. movl %eax,(%edi)
  237. pushl %edi
  238. call FreeMem
  239. addl $4,%esp
  240. .LHD_3:
  241. popal
  242. end;
  243. {$ifndef NEWATT}
  244. {$asmmode DIRECT}
  245. {$endif}
  246. {$define FPC_SYSTEM_HAS_FPC_NEW_CLASS}
  247. procedure int_new_class;assembler;[public,alias:'FPC_NEW_CLASS'];
  248. asm
  249. { to be sure in the future, we save also edit }
  250. pushl %edi
  251. { create class ? }
  252. movl 8(%ebp),%edi
  253. { if we test eax later without calling newinstance }
  254. { it must have a value <>0 }
  255. movl $1,%eax
  256. orl %edi,%edi
  257. jz .LNEW_CLASS1
  258. { save registers !! }
  259. pushl %ebx
  260. pushl %ecx
  261. pushl %edx
  262. { esi contains the vmt }
  263. pushl %esi
  264. { call newinstance (class method!) }
  265. call *16(%esi)
  266. popl %edx
  267. popl %ecx
  268. popl %ebx
  269. { newinstance returns a pointer to the new created }
  270. { instance in eax }
  271. { load esi and insert self }
  272. movl %eax,%esi
  273. .LNEW_CLASS1:
  274. movl %esi,8(%ebp)
  275. orl %eax,%eax
  276. popl %edi
  277. end;
  278. {$define FPC_SYSTEM_HAS_FPC_DISPOSE_CLASS}
  279. procedure int_dispose_class;assembler;[public,alias:'FPC_DISPOSE_CLASS'];
  280. asm
  281. { to be sure in the future, we save also edit }
  282. pushl %edi
  283. { destroy class ? }
  284. movl 12(%ebp),%edi
  285. orl %edi,%edi
  286. jz .LDISPOSE_CLASS1
  287. { no inherited call }
  288. movl (%esi),%edi
  289. { save registers !! }
  290. pushl %eax
  291. pushl %ebx
  292. pushl %ecx
  293. pushl %edx
  294. { push self }
  295. pushl %esi
  296. { call freeinstance }
  297. call *20(%edi)
  298. popl %edx
  299. popl %ecx
  300. popl %ebx
  301. popl %eax
  302. .LDISPOSE_CLASS1:
  303. popl %edi
  304. end;
  305. {$ifndef NEWATT}
  306. {$asmmode att}
  307. {$endif}
  308. { checks for a correct vmt pointer }
  309. {$define FPC_SYSTEM_HAS_FPC_CHECK_OBJECT}
  310. {$ifdef SYSTEMDEBUG}
  311. { we want the stack for debugging !! PM }
  312. procedure int_check_object(obj : pointer);[public,alias:'FPC_CHECK_OBJECT'];
  313. begin
  314. {$else not SYSTEMDEBUG}
  315. procedure int_check_object;assembler;[public,alias:'FPC_CHECK_OBJECT'];
  316. {$endif not SYSTEMDEBUG}
  317. asm
  318. pushl %edi
  319. {$ifdef SYSTEMDEBUG}
  320. movl obj,%edi
  321. {$else not SYSTEMDEBUG}
  322. movl 8(%esp),%edi
  323. {$endif not SYSTEMDEBUG}
  324. pushl %eax
  325. { Here we must check if the VMT pointer is nil before }
  326. { accessing it... }
  327. orl %edi,%edi
  328. jz .Lco_re
  329. movl (%edi),%eax
  330. addl 4(%edi),%eax
  331. jz .Lco_ok
  332. .Lco_re:
  333. pushl $210
  334. call HandleError
  335. .Lco_ok:
  336. popl %eax
  337. popl %edi
  338. { the adress is pushed : it needs to be removed from stack !! PM }
  339. {$ifdef SYSTEMDEBUG}
  340. end;{ of asm }
  341. end;
  342. {$else SYSTEMDEBUG}
  343. ret $4
  344. end;
  345. {$endif not SYSTEMDEBUG}
  346. {$ifdef FPC_TESTOBJEXT}
  347. { checks for a correct vmt pointer }
  348. { deeper check to see if the current object is }
  349. { really related to the true }
  350. {$define FPC_SYSTEM_HAS_FPC_CHECK_OBJECT_EXT}
  351. procedure int_check_object_ext;assembler;[public,alias:'FPC_CHECK_OBJECT_EXT'];
  352. asm
  353. pushl %ebp
  354. movl %esp,%ebp
  355. pushl %edi
  356. movl 8(%ebp),%edi
  357. pushl %ebx
  358. movl 12(%ebp),%ebx
  359. pushl %eax
  360. { Here we must check if the VMT pointer is nil before }
  361. { accessing it... }
  362. .Lcoext_obj:
  363. orl %edi,%edi
  364. jz .Lcoext_re
  365. movl (%edi),%eax
  366. addl 4(%edi),%eax
  367. jnz .Lcoext_re
  368. cmpl %edi,%ebx
  369. je .Lcoext_ok
  370. .Lcoext_vmt:
  371. movl 8(%edi),%eax
  372. cmpl %ebx,%eax
  373. je .Lcoext_ok
  374. movl %eax,%edi
  375. jmp .Lcoext_obj
  376. .Lcoext_re:
  377. pushl $220
  378. call HandleError
  379. .Lcoext_ok:
  380. popl %eax
  381. popl %ebx
  382. popl %edi
  383. { the adress and vmt were pushed : it needs to be removed from stack !! PM }
  384. popl %ebp
  385. ret $8
  386. end;
  387. {$endif FPC_TESTOBJEXT}
  388. {****************************************************************************
  389. String
  390. ****************************************************************************}
  391. {$define FPC_SYSTEM_HAS_FPC_SHORTSTR_COPY}
  392. procedure int_strcopy(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_COPY'];
  393. {
  394. this procedure must save all modified registers except EDI and ESI !!!
  395. }
  396. begin
  397. asm
  398. pushl %eax
  399. pushl %ecx
  400. cld
  401. movl 16(%ebp),%edi
  402. movl 12(%ebp),%esi
  403. xorl %eax,%eax
  404. movl 8(%ebp),%ecx
  405. lodsb
  406. cmpl %ecx,%eax
  407. jbe .LStrCopy1
  408. movl %ecx,%eax
  409. .LStrCopy1:
  410. stosb
  411. cmpl $7,%eax
  412. jl .LStrCopy2
  413. movl %edi,%ecx { Align on 32bits }
  414. negl %ecx
  415. andl $3,%ecx
  416. subl %ecx,%eax
  417. rep
  418. movsb
  419. movl %eax,%ecx
  420. andl $3,%eax
  421. shrl $2,%ecx
  422. rep
  423. movsl
  424. .LStrCopy2:
  425. movl %eax,%ecx
  426. rep
  427. movsb
  428. popl %ecx
  429. popl %eax
  430. end ['ESI','EDI'];
  431. end;
  432. {$define FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
  433. procedure int_strconcat(s1,s2:pointer);[public,alias:'FPC_SHORTSTR_CONCAT'];
  434. begin
  435. asm
  436. xorl %ecx,%ecx
  437. movl 12(%ebp),%edi
  438. movl 8(%ebp),%esi
  439. movl %edi,%ebx
  440. movb (%edi),%cl
  441. lea 1(%edi,%ecx),%edi
  442. negl %ecx
  443. xor %eax,%eax
  444. addl $0xff,%ecx
  445. lodsb
  446. cmpl %ecx,%eax
  447. jbe .LStrConcat1
  448. movl %ecx,%eax
  449. .LStrConcat1:
  450. addb %al,(%ebx)
  451. cmpl $7,%eax
  452. jl .LStrConcat2
  453. movl %edi,%ecx { Align on 32bits }
  454. negl %ecx
  455. andl $3,%ecx
  456. subl %ecx,%eax
  457. rep
  458. movsb
  459. movl %eax,%ecx
  460. andl $3,%eax
  461. shrl $2,%ecx
  462. rep
  463. movsl
  464. .LStrConcat2:
  465. movl %eax,%ecx
  466. rep
  467. movsb
  468. end ['EBX','ECX','EAX','ESI','EDI'];
  469. end;
  470. {$define FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
  471. procedure int_strcmp(dstr,sstr:pointer);[public,alias:'FPC_SHORTSTR_COMPARE'];
  472. begin
  473. asm
  474. cld
  475. xorl %ebx,%ebx
  476. xorl %eax,%eax
  477. movl 12(%ebp),%esi
  478. movl 8(%ebp),%edi
  479. movb (%esi),%al
  480. movb (%edi),%bl
  481. movl %eax,%edx
  482. incl %esi
  483. incl %edi
  484. cmpl %ebx,%eax
  485. jbe .LStrCmp1
  486. movl %ebx,%eax
  487. .LStrCmp1:
  488. cmpl $7,%eax
  489. jl .LStrCmp2
  490. movl %edi,%ecx { Align on 32bits }
  491. negl %ecx
  492. andl $3,%ecx
  493. subl %ecx,%eax
  494. orl %ecx,%ecx
  495. rep
  496. cmpsb
  497. jne .LStrCmp3
  498. movl %eax,%ecx
  499. andl $3,%eax
  500. shrl $2,%ecx
  501. orl %ecx,%ecx
  502. rep
  503. cmpsl
  504. je .LStrCmp2
  505. movl $4,%eax
  506. sub %eax,%esi
  507. sub %eax,%edi
  508. .LStrCmp2:
  509. movl %eax,%ecx
  510. orl %eax,%eax
  511. rep
  512. cmpsb
  513. jne .LStrCmp3
  514. cmp %ebx,%edx
  515. .LStrCmp3:
  516. end ['EDX','ECX','EBX','EAX','ESI','EDI'];
  517. end;
  518. {$define FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
  519. function strpas(p:pchar):string;[public,alias:'FPC_PCHAR_TO_SHORTSTR'];
  520. begin
  521. {$ifndef NEWATT}
  522. { remove warning }
  523. strpas:='';
  524. {$endif}
  525. asm
  526. cld
  527. movl p,%edi
  528. movl $0xff,%ecx
  529. orl %edi,%edi
  530. jnz .LStrPasNotNil
  531. decl %ecx
  532. jmp .LStrPasNil
  533. .LStrPasNotNil:
  534. xorl %eax,%eax
  535. movl %edi,%esi
  536. repne
  537. scasb
  538. .LStrPasNil:
  539. movl %ecx,%eax
  540. {$ifdef NEWATT}
  541. movl __RESULT,%edi
  542. {$else}
  543. movl 8(%ebp),%edi
  544. {$endif}
  545. notb %al
  546. decl %eax
  547. stosb
  548. cmpl $7,%eax
  549. jl .LStrPas2
  550. movl %edi,%ecx { Align on 32bits }
  551. negl %ecx
  552. andl $3,%ecx
  553. subl %ecx,%eax
  554. rep
  555. movsb
  556. movl %eax,%ecx
  557. andl $3,%eax
  558. shrl $2,%ecx
  559. rep
  560. movsl
  561. .LStrPas2:
  562. movl %eax,%ecx
  563. rep
  564. movsb
  565. end ['ECX','EAX','ESI','EDI'];
  566. end;
  567. {$define FPC_SYSTEM_HAS_STRLEN}
  568. function strlen(p:pchar):longint;assembler;
  569. asm
  570. movl p,%edi
  571. movl $0xffffffff,%ecx
  572. xorl %eax,%eax
  573. cld
  574. repne
  575. scasb
  576. movl $0xfffffffe,%eax
  577. subl %ecx,%eax
  578. end ['EDI','ECX','EAX'];
  579. {****************************************************************************
  580. Caller/StackFrame Helpers
  581. ****************************************************************************}
  582. {$define FPC_SYSTEM_HAS_GET_FRAME}
  583. function get_frame:longint;assembler;
  584. asm
  585. movl %ebp,%eax
  586. end ['EAX'];
  587. {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  588. function get_caller_addr(framebp:longint):longint;assembler;
  589. asm
  590. movl framebp,%eax
  591. orl %eax,%eax
  592. jz .Lg_a_null
  593. movl 4(%eax),%eax
  594. .Lg_a_null:
  595. end ['EAX'];
  596. {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  597. function get_caller_frame(framebp:longint):longint;assembler;
  598. asm
  599. movl framebp,%eax
  600. orl %eax,%eax
  601. jz .Lgnf_null
  602. movl (%eax),%eax
  603. .Lgnf_null:
  604. end ['EAX'];
  605. {****************************************************************************
  606. Math
  607. ****************************************************************************}
  608. {$define FPC_SYSTEM_HAS_ABS_LONGINT}
  609. function abs(l:longint):longint;assembler;[internconst:in_const_abs];
  610. asm
  611. movl l,%eax
  612. orl %eax,%eax
  613. jns .LMABS1
  614. negl %eax
  615. .LMABS1:
  616. end ['EAX'];
  617. {$define FPC_SYSTEM_HAS_ODD_LONGINT}
  618. function odd(l:longint):boolean;assembler;[internconst:in_const_odd];
  619. asm
  620. movl l,%eax
  621. andl $1,%eax
  622. setnz %al
  623. end ['EAX'];
  624. {$define FPC_SYSTEM_HAS_SQR_LONGINT}
  625. function sqr(l:longint):longint;assembler;[internconst:in_const_sqr];
  626. asm
  627. mov l,%eax
  628. imull %eax,%eax
  629. end ['EAX'];
  630. {$define FPC_SYSTEM_HAS_SPTR}
  631. Function Sptr : Longint;assembler;
  632. asm
  633. movl %esp,%eax
  634. end;
  635. {****************************************************************************
  636. Str()
  637. ****************************************************************************}
  638. {$define FPC_SYSTEM_HAS_INT_STR_LONGINT}
  639. procedure int_str(l : longint;var s : string);
  640. var
  641. buffer : array[0..11] of byte;
  642. begin
  643. { Workaround: }
  644. if l=$80000000 then
  645. begin
  646. s:='-2147483648';
  647. exit;
  648. end;
  649. asm
  650. movl l,%eax // load Integer
  651. movl s,%edi // Load String address
  652. xorl %ecx,%ecx // String length=0
  653. xorl %ebx,%ebx // Buffer length=0
  654. movl $0x0a,%esi // load 10 as dividing constant.
  655. orl %eax,%eax // Sign ?
  656. jns .LM2
  657. neg %eax
  658. movb $0x2d,1(%edi) // put '-' in String
  659. incl %ecx
  660. .LM2:
  661. cltd
  662. idivl %esi
  663. addb $0x30,%dl // convert Rest to ASCII.
  664. movb %dl,-12(%ebp,%ebx)
  665. incl %ebx
  666. cmpl $0,%eax
  667. jnz .LM2
  668. { copy String }
  669. .LM3:
  670. movb -13(%ebp,%ebx),%al // -13 because EBX is decreased only later
  671. movb %al,1(%edi,%ecx)
  672. incl %ecx
  673. decl %ebx
  674. jnz .LM3
  675. movb %cl,(%edi) // Copy String length
  676. end;
  677. end;
  678. {$define FPC_SYSTEM_HAS_INT_STR_CARDINAL}
  679. procedure int_str(c : cardinal;var s : string);
  680. var
  681. buffer : array[0..14] of byte;
  682. begin
  683. asm
  684. movl c,%eax // load CARDINAL
  685. movl s,%edi // Load String address
  686. xorl %ecx,%ecx // String length=0
  687. xorl %ebx,%ebx // Buffer length=0
  688. movl $0x0a,%esi // load 10 as dividing constant.
  689. .LM4:
  690. xorl %edx,%edx
  691. divl %esi
  692. addb $0x30,%dl // convert Rest to ASCII.
  693. movb %dl,-12(%ebp,%ebx)
  694. incl %ebx
  695. cmpl $0,%eax
  696. jnz .LM4
  697. { now copy the string }
  698. .LM5:
  699. movb -13(%ebp,%ebx),%al // -13 because EBX is decreased only later
  700. movb %al,1(%edi,%ecx)
  701. incl %ecx
  702. decl %ebx
  703. jnz .LM5
  704. movb %cl,(%edi) // Copy String length
  705. end;
  706. end;
  707. {****************************************************************************
  708. Bounds Check
  709. ****************************************************************************}
  710. {$define FPC_SYSTEM_HAS_FPC_BOUNDCHECK}
  711. {$ifdef SYSTEMDEBUG}
  712. { we want the stack for debugging !! PM }
  713. procedure int_boundcheck;[public,alias: 'FPC_BOUNDCHECK'];
  714. begin
  715. {$else not SYSTEMDEBUG}
  716. procedure int_boundcheck;assembler;[public,alias: 'FPC_BOUNDCHECK'];
  717. {$endif not SYSTEMDEBUG}
  718. {
  719. called with:
  720. %ecx - value
  721. %edi - pointer to the ranges
  722. }
  723. asm
  724. cmpl (%edi),%ecx
  725. jl .Lbc_err
  726. cmpl 4(%edi),%ecx
  727. jle .Lbc_ok
  728. .Lbc_err:
  729. pushl $201
  730. call HandleError
  731. .Lbc_ok:
  732. end;
  733. {$ifdef SYSTEMDEBUG}
  734. end;
  735. {$endif def SYSTEMDEBUG}
  736. {****************************************************************************
  737. IoCheck
  738. ****************************************************************************}
  739. {$define FPC_SYSTEM_HAS_FPC_IOCHECK}
  740. procedure int_iocheck(addr : longint);[public,alias:'FPC_IOCHECK'];
  741. var
  742. l : longint;
  743. begin
  744. asm
  745. pushal
  746. end;
  747. if InOutRes<>0 then
  748. begin
  749. l:=InOutRes;
  750. InOutRes:=0;
  751. HandleErrorFrame(l,get_frame);
  752. end;
  753. asm
  754. popal
  755. end;
  756. end;
  757. {
  758. $Log$
  759. Revision 1.47.2.2 1999-07-09 16:25:31 michael
  760. + Florians Fix from main branch
  761. Revision 1.47.2.1 1999/07/04 12:29:22 peter
  762. * fix from main branch
  763. Revision 1.48 1999/07/03 09:03:47 florian
  764. * int_new_class returned with zero flag=1, if at the entrance eax was zero
  765. and newinstance wasn't called, fixed
  766. Revision 1.47 1999/05/31 22:03:37 pierre
  767. * added $define FPC_SYSTEM_HAS_... for use with generic.inc
  768. Revision 1.46 1999/05/31 12:49:19 peter
  769. * smaller sptr function
  770. Revision 1.45 1999/04/22 10:52:40 peter
  771. * nil check for strpas
  772. Revision 1.44 1999/04/19 06:13:28 florian
  773. * the class helper routines doesn't store the registers properly,
  774. fixed
  775. Revision 1.43 1999/04/08 11:30:57 peter
  776. * removed warnings
  777. Revision 1.42 1999/04/07 16:21:10 pierre
  778. + no assembler if systemdebug defined
  779. Revision 1.41 1999/03/01 15:40:55 peter
  780. * use external names
  781. * removed all direct assembler modes
  782. Revision 1.40 1999/02/22 13:23:22 pierre
  783. * VMT field zeroed at destructor forgot offset !!
  784. Revision 1.39 1999/02/05 12:26:25 pierre
  785. + code for FPC_TESTOBJEXT conditionnal
  786. Revision 1.38 1999/02/02 11:04:27 florian
  787. * class destructor helper routine for the new calling copnventions fixed
  788. Revision 1.37 1998/12/21 14:28:20 pierre
  789. * HandleError -> HandleErrorFrame to avoid problem in
  790. assembler code in i386.inc
  791. (call to overloaded function in assembler block !)
  792. Revision 1.36 1998/12/18 17:21:32 peter
  793. * fixed io-error handling
  794. Revision 1.35 1998/12/15 22:42:53 peter
  795. * removed temp symbols
  796. Revision 1.34 1998/11/30 15:27:28 pierre
  797. * vmt address pushed for CHECK_OBJECT was not removed from stack
  798. Revision 1.33 1998/11/28 14:09:49 peter
  799. * NOATTCDQ define
  800. Revision 1.32 1998/11/26 23:15:08 jonas
  801. * changed cdq to cltd in AT&T assembler block
  802. Revision 1.31 1998/11/26 21:33:58 peter
  803. + FPC_BOUNDCHECK
  804. Revision 1.30 1998/11/17 00:41:08 peter
  805. * renamed string functions
  806. Revision 1.29 1998/10/19 08:49:16 pierre
  807. * removed old code forgotten about vmtoffset
  808. Revision 1.28 1998/10/16 13:37:46 pierre
  809. * added code for vmt_offset in destructors
  810. Revision 1.27 1998/10/16 08:53:50 peter
  811. * fill_object in constructor changed to 'inline' code to overcome
  812. pushw/pushl problem
  813. Revision 1.26 1998/10/15 11:35:02 pierre
  814. + first step of variable vmt offset
  815. offset is stored in R_EDI (R_D0)
  816. if objectvmtoffset is defined
  817. Revision 1.25 1998/09/28 11:02:34 peter
  818. * added some more $ifdef FPCNAMES
  819. Revision 1.24 1998/09/28 10:23:43 florian
  820. * FPC_NEW_CLASS optimized: addl $0,%eax => orl %eax,%eax
  821. Revision 1.23 1998/09/28 08:40:47 michael
  822. + Bugreport from Gertjan Schouten
  823. Revision 1.22 1998/09/22 15:32:00 peter
  824. + fpc_pchar_to_str alias for strpas
  825. Revision 1.21 1998/09/14 10:48:08 peter
  826. * FPC_ names
  827. * Heap manager is now system independent
  828. Revision 1.20 1998/09/11 17:38:48 pierre
  829. merge for fixes branch
  830. Revision 1.19.2.1 1998/09/11 17:37:24 pierre
  831. * correction respective to stricter as v2.9.1 syntax
  832. Revision 1.19 1998/09/01 17:36:17 peter
  833. + internconst
  834. Revision 1.18 1998/08/11 00:04:47 peter
  835. * $ifdef ver0_99_5 updates
  836. Revision 1.17 1998/07/30 13:26:20 michael
  837. + Added support for ErrorProc variable. All internal functions are required
  838. to call HandleError instead of runerror from now on.
  839. This is necessary for exception support.
  840. Revision 1.16 1998/07/02 12:55:04 carl
  841. * Put back DoError, DO NOT TOUCH!
  842. Revision 1.15 1998/07/02 12:19:32 carl
  843. + IO-Error and Overflow now print address in hex
  844. Revision 1.14 1998/07/01 15:29:58 peter
  845. * better readln/writeln
  846. Revision 1.13 1998/06/26 08:20:57 daniel
  847. - Doerror removed.
  848. Revision 1.12 1998/05/31 14:15:47 peter
  849. * force to use ATT or direct parsing
  850. Revision 1.11 1998/05/30 14:30:21 peter
  851. * force att reading
  852. Revision 1.10 1998/05/25 10:40:49 peter
  853. * remake3 works again on tflily
  854. Revision 1.5 1998/04/29 13:28:19 peter
  855. * some cleanup and i386_att usage
  856. Revision 1.4 1998/04/10 15:41:54 florian
  857. + some small comments added
  858. Revision 1.3 1998/04/10 15:25:23 michael
  859. - Removed so-called better random function
  860. Revision 1.2 1998/04/08 07:53:31 michael
  861. + Changed Random() function. Moved from system to processor dependent files (from Pedro Gimeno)
  862. }