i8086.inc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2013 by the Free Pascal development team.
  4. Processor dependent implementation for the system unit for
  5. intel i8086+
  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. procedure fpc_cpuinit;
  13. begin
  14. end;
  15. {$ifndef FPC_SYSTEM_HAS_FILLCHAR}
  16. {$define FPC_SYSTEM_HAS_FILLCHAR}
  17. procedure FillChar(var x;count:SizeInt;value:byte);assembler;nostackframe;
  18. asm
  19. mov bx, sp
  20. mov cx, ss:[bx + 4 + extra_param_offset] // count
  21. or cx, cx
  22. jle @@Done
  23. {$ifdef FPC_X86_DATA_NEAR}
  24. mov di, ss:[bx + 6 + extra_param_offset] // @x
  25. mov ax, ds
  26. mov es, ax
  27. {$else FPC_X86_DATA_NEAR}
  28. les di, ss:[bx + 6 + extra_param_offset] // @x
  29. {$endif FPC_X86_DATA_NEAR}
  30. mov al, ss:[bx + 2 + extra_param_offset] // value
  31. mov ah, al
  32. shr cx, 1
  33. {$ifdef FPC_ENABLED_CLD}
  34. cld
  35. {$endif FPC_ENABLED_CLD}
  36. rep stosw
  37. adc cx, cx
  38. rep stosb
  39. @@Done:
  40. end;
  41. {$endif FPC_SYSTEM_HAS_FILLCHAR}
  42. {$ifndef FPC_SYSTEM_HAS_FILLWORD}
  43. {$define FPC_SYSTEM_HAS_FILLWORD}
  44. procedure FillWord(var x;count : SizeInt;value : word);assembler;nostackframe;
  45. asm
  46. mov bx, sp
  47. mov cx, ss:[bx + 4 + extra_param_offset] // count
  48. or cx, cx
  49. jle @@Done
  50. {$ifdef FPC_X86_DATA_NEAR}
  51. mov di, ss:[bx + 6 + extra_param_offset] // @x
  52. mov ax, ds
  53. mov es, ax
  54. {$else FPC_X86_DATA_NEAR}
  55. les di, ss:[bx + 6 + extra_param_offset] // @x
  56. {$endif FPC_X86_DATA_NEAR}
  57. mov ax, ss:[bx + 2 + extra_param_offset] // value
  58. {$ifdef FPC_ENABLED_CLD}
  59. cld
  60. {$endif FPC_ENABLED_CLD}
  61. rep stosw
  62. @@Done:
  63. end;
  64. {$endif FPC_SYSTEM_HAS_FILLWORD}
  65. {$ifndef FPC_SYSTEM_HAS_MOVE}
  66. {$define FPC_SYSTEM_HAS_MOVE}
  67. procedure Move(const source;var dest;count:SizeInt);[public, alias: 'FPC_MOVE'];assembler;nostackframe;
  68. asm
  69. mov bx, sp
  70. mov cx, ss:[bx + 2 + extra_param_offset] // count
  71. or cx, cx
  72. jle @@Done
  73. mov ax, ds // for far data models, backup ds; for near data models, use to initialize es
  74. {$ifdef FPC_X86_DATA_NEAR}
  75. mov es, ax
  76. mov si, ss:[bx + 6 + extra_param_offset] // @source
  77. mov di, ss:[bx + 4 + extra_param_offset] // @dest
  78. {$else FPC_X86_DATA_NEAR}
  79. lds si, ss:[bx + 8 + extra_param_offset] // @source
  80. les di, ss:[bx + 4 + extra_param_offset] // @dest
  81. {$endif FPC_X86_DATA_NEAR}
  82. cmp si, di
  83. jb @@BackwardsMove
  84. {$ifdef FPC_ENABLED_CLD}
  85. cld
  86. {$endif FPC_ENABLED_CLD}
  87. shr cx, 1
  88. rep movsw
  89. adc cx, cx
  90. rep movsb
  91. jmp @@AfterMove // todo, add mov ds,ax & ret here for performance reasons
  92. @@BackwardsMove:
  93. std
  94. add si, cx
  95. add di, cx
  96. dec si
  97. dec di
  98. rep movsb // todo: movsw
  99. cld
  100. @@AfterMove:
  101. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  102. mov ds, ax
  103. {$endif}
  104. @@Done:
  105. end;
  106. {$endif FPC_SYSTEM_HAS_MOVE}
  107. {$define FPC_SYSTEM_HAS_SPTR}
  108. Function Sptr : Pointer;assembler;nostackframe;
  109. asm
  110. mov ax, sp
  111. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  112. mov dx, ss
  113. {$endif}
  114. end;
  115. {$define FPC_SYSTEM_HAS_PTR}
  116. function Ptr(sel,off: Word):farpointer;{$ifdef SYSTEMINLINE}inline;{$endif}assembler;nostackframe;
  117. asm
  118. mov si, sp
  119. mov ax, ss:[si + 2 + extra_param_offset] // off
  120. mov dx, ss:[si + 4 + extra_param_offset] // sel
  121. end;
  122. {$define FPC_SYSTEM_HAS_CSEG}
  123. function CSeg: Word;{$ifdef SYSTEMINLINE}inline;{$endif}assembler;nostackframe;
  124. asm
  125. mov ax, cs
  126. end;
  127. {$define FPC_SYSTEM_HAS_DSEG}
  128. function DSeg: Word;{$ifdef SYSTEMINLINE}inline;{$endif}assembler;nostackframe;
  129. asm
  130. mov ax, ds
  131. end;
  132. {$define FPC_SYSTEM_HAS_SSEG}
  133. function SSeg: Word;{$ifdef SYSTEMINLINE}inline;{$endif}assembler;nostackframe;
  134. asm
  135. mov ax, ss
  136. end;
  137. {$IFNDEF INTERNAL_BACKTRACE}
  138. {$define FPC_SYSTEM_HAS_GET_FRAME}
  139. function get_frame:pointer;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
  140. asm
  141. mov ax, bp
  142. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  143. mov dx, ss
  144. {$endif}
  145. end;
  146. {$ENDIF not INTERNAL_BACKTRACE}
  147. {$define FPC_SYSTEM_HAS_GET_PC_ADDR}
  148. Function Get_pc_addr : CodePointer;assembler;nostackframe;
  149. asm
  150. mov bx, sp
  151. mov ax, ss:[bx]
  152. {$ifdef FPC_X86_CODE_FAR}
  153. mov dx, ss:[bx+2]
  154. {$endif FPC_X86_CODE_FAR}
  155. end;
  156. {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  157. function get_caller_addr(framebp:pointer;addr:codepointer=nil):codepointer;nostackframe;assembler;
  158. asm
  159. mov si, sp
  160. {$ifdef FPC_X86_CODE_FAR}
  161. xor dx, dx
  162. {$endif FPC_X86_CODE_FAR}
  163. mov ax, ss:[si + 4 + extra_param_offset + extra_param_offset] // framebp
  164. or ax, ax
  165. jz @@Lg_a_null
  166. xchg ax, bx // 1 byte shorter than a mov
  167. mov ax, [bx+2]
  168. {$ifdef FPC_X86_CODE_FAR}
  169. mov dx, [bx+4]
  170. {$endif FPC_X86_CODE_FAR}
  171. @@Lg_a_null:
  172. end;
  173. {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  174. function get_caller_frame(framebp:pointer;addr:codepointer=nil):pointer;nostackframe;assembler;
  175. asm
  176. mov si, sp
  177. mov ax, ss:[si + 4 + extra_param_offset + extra_param_offset] // framebp
  178. or ax, ax
  179. jz @@Lgnf_null
  180. xchg ax, si // 1 byte shorter than a mov
  181. lodsw
  182. @@Lgnf_null:
  183. end;
  184. {TODO: use smallint?}
  185. function InterLockedDecrement (var Target: longint) : longint;nostackframe;assembler;
  186. asm
  187. mov si, sp
  188. {$ifdef FPC_X86_DATA_NEAR}
  189. mov bx, ss:[si + 2 + extra_param_offset] // Target
  190. {$else FPC_X86_DATA_NEAR}
  191. mov cx, ds
  192. lds bx, ss:[si + 2 + extra_param_offset] // Target
  193. {$endif FPC_X86_DATA_NEAR}
  194. pushf
  195. cli
  196. sub word [bx], 1
  197. sbb word [bx+2], 0
  198. mov ax, [bx]
  199. mov dx, [bx+2]
  200. popf
  201. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  202. mov ds, cx
  203. {$endif}
  204. end;
  205. {TODO: use smallint?}
  206. function InterLockedIncrement (var Target: longint) : longint;nostackframe;assembler;
  207. asm
  208. mov si, sp
  209. {$ifdef FPC_X86_DATA_NEAR}
  210. mov bx, ss:[si + 2 + extra_param_offset] // Target
  211. {$else FPC_X86_DATA_NEAR}
  212. mov cx, ds
  213. lds bx, ss:[si + 2 + extra_param_offset] // Target
  214. {$endif FPC_X86_DATA_NEAR}
  215. pushf
  216. cli
  217. add word [bx], 1
  218. adc word [bx+2], 0
  219. mov ax, [bx]
  220. mov dx, [bx+2]
  221. popf
  222. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  223. mov ds, cx
  224. {$endif}
  225. end;
  226. {TODO: use smallint?}
  227. function InterLockedExchange (var Target: longint;Source : longint) : longint;nostackframe;assembler;
  228. asm
  229. mov si, sp
  230. {$ifdef FPC_X86_DATA_NEAR}
  231. mov bx, ss:[si + 6 + extra_param_offset] // Target
  232. {$else FPC_X86_DATA_NEAR}
  233. mov cx, ds
  234. lds bx, ss:[si + 6 + extra_param_offset] // Target
  235. {$endif FPC_X86_DATA_NEAR}
  236. mov ax, ss:[si + 2 + extra_param_offset] // Lo(Source)
  237. mov dx, ss:[si + 4 + extra_param_offset] // Hi(Source)
  238. pushf
  239. cli
  240. xchg word [bx], ax
  241. xchg word [bx+2], dx
  242. popf
  243. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  244. mov ds, cx
  245. {$endif}
  246. end;
  247. {TODO: use smallint?}
  248. function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint;nostackframe;assembler;
  249. asm
  250. mov si, sp
  251. {$ifdef FPC_X86_DATA_NEAR}
  252. mov bx, ss:[si + 6 + extra_param_offset] // Target
  253. {$else FPC_X86_DATA_NEAR}
  254. mov cx, ds
  255. lds bx, ss:[si + 6 + extra_param_offset] // Target
  256. {$endif FPC_X86_DATA_NEAR}
  257. mov di, ss:[si + 2 + extra_param_offset] // Lo(Source)
  258. mov si, ss:[si + 4 + extra_param_offset] // Hi(Source)
  259. pushf
  260. cli
  261. mov ax, [bx]
  262. mov dx, [bx+2]
  263. add word [bx], di
  264. adc word [bx+2], si
  265. popf
  266. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  267. mov ds, cx
  268. {$endif}
  269. end;
  270. {TODO: use smallint?}
  271. function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;assembler;
  272. asm
  273. {$ifdef FPC_X86_DATA_NEAR}
  274. mov bx, [Target] // Target
  275. {$else FPC_X86_DATA_NEAR}
  276. mov cx, ds
  277. lds bx, [Target] // Target
  278. {$endif FPC_X86_DATA_NEAR}
  279. mov di, [Comperand]
  280. mov si, [Comperand+2]
  281. pushf
  282. cli
  283. mov ax, [bx]
  284. mov dx, [bx+2]
  285. cmp ax, di
  286. jne @@not_equal
  287. cmp dx, si
  288. jne @@not_equal
  289. mov di, [NewValue]
  290. mov si, [NewValue+2]
  291. mov [bx], di
  292. mov [bx+2], si
  293. @@not_equal:
  294. popf
  295. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  296. mov ds, cx
  297. {$endif}
  298. end;
  299. {****************************************************************************
  300. BSR/BSF
  301. ****************************************************************************}
  302. const
  303. bsr8bit: array [Byte] of Byte = (
  304. $ff,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  305. 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  306. 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  307. 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  308. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  309. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  310. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  311. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
  312. );
  313. bsf8bit: array [Byte] of Byte = (
  314. $ff,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  315. 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  316. 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  317. 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  318. 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  319. 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  320. 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  321. 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
  322. );
  323. {$define FPC_SYSTEM_HAS_BSR_BYTE}
  324. function BsrByte(const AValue: Byte): Byte;
  325. begin
  326. BsrByte := bsr8bit[AValue];
  327. end;
  328. {$define FPC_SYSTEM_HAS_BSF_BYTE}
  329. function BsfByte(const AValue: Byte): Byte;
  330. begin
  331. BsfByte := bsf8bit[AValue];
  332. end;
  333. {$define FPC_SYSTEM_HAS_BSR_WORD}
  334. function BsrWord(const AValue: Word): Byte; assembler;
  335. asm
  336. lea bx, bsr8bit
  337. xor cl, cl
  338. mov ax, word [AValue]
  339. test ah, ah
  340. jz @@0
  341. mov cl, 8
  342. mov al, ah
  343. @@0: xlatb
  344. add al, cl
  345. end;
  346. {$define FPC_SYSTEM_HAS_BSF_WORD}
  347. function BsfWord(const AValue: Word): Byte; assembler;
  348. asm
  349. lea bx, bsf8bit
  350. xor cl, cl
  351. mov ax, word [AValue]
  352. test al, al
  353. jnz @@0
  354. or al, ah
  355. jz @@0
  356. add cl, 8
  357. @@0: xlatb
  358. add al, cl
  359. end;
  360. {$define FPC_SYSTEM_HAS_BSR_DWORD}
  361. function BsrDword(const AValue: DWord): Byte; assembler;
  362. asm
  363. lea bx, bsr8bit
  364. mov cl, 16
  365. mov ax, word [AValue+2]
  366. test ax, ax
  367. jnz @@0
  368. xor cl, cl
  369. mov ax, word [AValue]
  370. @@0: test ah, ah
  371. jz @@1
  372. add cl, 8
  373. mov al, ah
  374. @@1: xlatb
  375. add al, cl
  376. end;
  377. {$define FPC_SYSTEM_HAS_BSF_DWORD}
  378. function BsfDword(const AValue: DWord): Byte; assembler;
  379. asm
  380. lea bx, bsf8bit
  381. xor cl, cl
  382. mov ax, word [AValue]
  383. test ax, ax
  384. jnz @@0
  385. or ax, word [AValue+2]
  386. jz @@1
  387. mov cl, 16
  388. @@0: test al, al
  389. jnz @@1
  390. add cl, 8
  391. mov al, ah
  392. @@1: xlatb
  393. add al, cl
  394. end;
  395. {$define FPC_SYSTEM_HAS_BSR_QWORD}
  396. function BsrQword(const AValue: QWord): Byte; assembler;
  397. asm
  398. lea bx, bsr8bit
  399. mov cl, 48
  400. mov ax, word [AValue+6]
  401. test ax, ax
  402. jnz @@0
  403. mov cl, 32
  404. or ax, word [AValue+4]
  405. jnz @@0
  406. mov cl, 16
  407. or ax, word [AValue+2]
  408. jnz @@0
  409. xor cl, cl
  410. mov ax, word [AValue]
  411. @@0: test ah, ah
  412. jz @@1
  413. add cl, 8
  414. mov al, ah
  415. @@1: xlatb
  416. add al, cl
  417. end;
  418. {$define FPC_SYSTEM_HAS_BSF_QWORD}
  419. function BsfQword(const AValue: QWord): Byte; assembler;
  420. asm
  421. lea bx, bsf8bit
  422. xor cl, cl
  423. mov ax, word [AValue]
  424. test ax, ax
  425. jnz @@0
  426. mov cl, 16
  427. or ax, word [AValue+2]
  428. jnz @@0
  429. mov cl, 32
  430. or ax, word [AValue+4]
  431. jnz @@0
  432. xor cl, cl
  433. or ax, word [AValue+6]
  434. jz @@1
  435. mov cl, 48
  436. @@0: test al, al
  437. jnz @@1
  438. add cl, 8
  439. mov al, ah
  440. @@1: xlatb
  441. add al, cl
  442. end;
  443. {****************************************************************************
  444. HexStr
  445. ****************************************************************************}
  446. {$define FPC_HAS_HEXSTR_POINTER_SHORTSTR}
  447. function HexStr(Val: NearPointer): ShortString;
  448. begin
  449. HexStr:=HexStr(Word(Val),4);
  450. end;
  451. function HexStr(Val: FarPointer): ShortString;
  452. type
  453. TFarPointerRec = record
  454. Offset, Segment: Word;
  455. end;
  456. begin
  457. HexStr:=HexStr(TFarPointerRec(Val).Segment,4)+':'+HexStr(TFarPointerRec(Val).Offset,4);
  458. end;
  459. {****************************************************************************
  460. FPU
  461. ****************************************************************************}
  462. const
  463. { Internal constants for use in system unit }
  464. FPU_Invalid = 1;
  465. FPU_Denormal = 2;
  466. FPU_DivisionByZero = 4;
  467. FPU_Overflow = 8;
  468. FPU_Underflow = $10;
  469. FPU_StackUnderflow = $20;
  470. FPU_StackOverflow = $40;
  471. FPU_ExceptionMask = $ff;
  472. { use Default8087CW instead
  473. fpucw : word = $1300 or FPU_StackUnderflow or FPU_Underflow or FPU_Denormal;
  474. }
  475. { Detects the FPU and initializes the Test8087 variable (and Default8087CW):
  476. 0 = NO FPU
  477. 1 = 8087
  478. 2 = 80287
  479. 3 = 80387+ }
  480. procedure DetectFPU;
  481. var
  482. localfpucw: word;
  483. begin
  484. asm
  485. xor bx, bx { initialization, 0=NO FPU }
  486. { FPU presence detection }
  487. fninit
  488. mov byte [localfpucw + 1], 0
  489. nop
  490. fnstcw localfpucw
  491. cmp byte [localfpucw + 1], 3
  492. jne @@Done { No FPU? }
  493. inc bx
  494. { FPU found; now test if it's a 8087 }
  495. and byte [localfpucw], $7F { clear the interrupt enable mask (IEM) }
  496. fldcw localfpucw
  497. fdisi { try to set the interrupt enable mask }
  498. fstcw localfpucw
  499. test byte [localfpucw], $80 { IEM set? }
  500. jnz @@Done { if yes, we have an 8087 }
  501. inc bx
  502. { we have a 287+; now test if it's a 80287 }
  503. finit
  504. fld1
  505. fldz
  506. fdiv { calculate 1/0 }
  507. fld st { copy the value }
  508. fchs { change the sign }
  509. fcompp { compare. if the FPU distinguishes +inf from -inf, it's a 387+ }
  510. fstsw localfpucw
  511. mov ah, byte [localfpucw + 1]
  512. sahf
  513. je @@Done
  514. inc bx { 387+ }
  515. @@Done:
  516. mov Test8087, bl
  517. end ['AX','BX'];
  518. if Test8087<=2 then
  519. Default8087CW:=$1330
  520. else
  521. Default8087CW:=$1332;
  522. end;
  523. {$define FPC_SYSTEM_HAS_SYSINITFPU}
  524. Procedure SysInitFPU;
  525. var
  526. { these locals are so we don't have to hack pic code in the assembler }
  527. localfpucw: word;
  528. begin
  529. localfpucw:=Default8087CW;
  530. asm
  531. fninit
  532. fldcw localfpucw
  533. fwait
  534. end;
  535. end;
  536. {$define FPC_SYSTEM_HAS_SYSRESETFPU}
  537. Procedure SysResetFPU;
  538. var
  539. { these locals are so we don't have to hack pic code in the assembler }
  540. localfpucw: word;
  541. begin
  542. localfpucw:=Default8087CW;
  543. asm
  544. fninit
  545. fwait
  546. fldcw localfpucw
  547. end;
  548. end;
  549. {$I int32p.inc}