fppArchLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:14k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* fppArchLib.c - architecture-dependent floating-point coprocessor support */
  2. /* Copyright 1984-2002 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01j,05jun02,wsl  remove reference to SPARC and i960
  7. 01i,28mar02,hdn  updated x86 specific sections
  8. 01h,20nov01,hdn  updated x86 specific sections
  9. 01g,13nov01,hbh  Updated for simulators.
  10. 01f,29oct01,zl   added SH-specific documentation
  11. 01e,27feb97,jpd  added ARM-specific documentation.
  12. 01d,25nov95,jdi  removed 29k stuff.
  13. 01c,31jan95,rhp  update for MIPS R4000, AM29K, i386/i486.
  14.             jdi  changed 80960 to i960.
  15. 01b,20jan93,jdi  documentation cleanup.
  16. 01a,23sep92,jdi  written, based on fppALib.s and fppArchLib.c for
  17.  mc68k, sparc, i960, mips.
  18. */
  19. /*
  20. DESCRIPTION
  21. This library contains architecture-dependent routines to support the 
  22. floating-point coprocessor.  The routines fppSave() and fppRestore() save
  23. and restore all the task floating-point context information.  The routine
  24. fppProbe() checks for the presence of the floating-point coprocessor.  The
  25. routines fppTaskRegsSet() and fppTaskRegsGet() inspect and set coprocessor
  26. registers on a per-task basis.
  27. With the exception of fppProbe(), the higher-level facilities in dbgLib
  28. and usrLib should be used instead of these routines.  For information about
  29. architecture-independent access mechanisms, see the manual entry for fppLib.
  30. INITIALIZATION
  31. To activate floating-point support, fppInit() must be called before any
  32. tasks using the coprocessor are spawned.  This is done by the root task,
  33. usrRoot(), in usrConfig.c.  See the manual entry for fppLib.
  34. NOTE X86:
  35. There are two kind of floating-point contexts and set of routines for 
  36. each kind.  One is 108 bytes for older FPU (i80387, i80487, Pentium) 
  37. and older MMX technology and fppSave(), fppRestore(), fppRegsToCtx(), 
  38. and fppCtxToRegs() are used to save and restore the context, convert to 
  39. or from the FPPREG_SET.
  40. The other is 512 bytes for newer FPU, newer MMX technology and streaming 
  41. SIMD technology (PentiumII, III, 4) and fppXsave(), fppXrestore(), 
  42. fppXregsToCtx(), and fppXctxToRegs() are used to save and restore 
  43. the context, convert to or from the FPPREG_SET.  
  44. Which to use is automatically detected by checking CPUID information in 
  45. fppArchInit().  And fppTaskRegsSet() and fppTaskRegsGet() access the 
  46. appropriate floating-point context.  The bit interrogated for the 
  47. automatic detection is the "Fast Save and Restore" feature flag.
  48. NOTE X86 INITIALIZATION:
  49. To activate floating-point support, fppInit() must be called before any
  50. tasks using the coprocessor are spawned.  If INCLUDE_FLOATING_POINT is
  51. defined in configAll.h, this is done by the root task, usrRoot(), in
  52. usrConfig.c.
  53. NOTE X86 VX FP TASK OPTION: 
  54. Saving and restoring floating-point registers adds to the context switch
  55. time of a task.
  56. Therefore, floating-point registers are f2notfP saved and restored for 
  57. f2everyfP task.  Only those tasks spawned with the task option VX_FP_TASK
  58. will have floating-point state, MMX technology state, and streaming SIMD 
  59. state saved and restored.  
  60. f3NOTE:fP  If a task does any floating-point operations, MMX operations,
  61. and streaming SIMD operation, it must be spawned with VX_FP_TASK.
  62. It is deadly to execute any floating-point operations in a task spawned 
  63. without VX_FP_TASK option, and very difficult to find.  To detect that
  64. illegal/unintentional/accidental floating-point operations, a new API and
  65. mechanism is added.  The mechanism is to enable or disable the FPU by 
  66. toggling the TS flag in the CR0 in the new task switch hook routine -
  67. fppArchSwitchHook() - respecting the VX_FP_TASK option.  If VX_FP_TASK
  68. option is not set in the switching-in task, the FPU is disabled.  Thus
  69. the device-not-available exception will be raised if that task does any 
  70. floating-point operations.  This mechanism is disabled in the default.
  71. To enable, call the enabler - fppArchSwitchHookEnable() - with a 
  72. parameter TRUE(1).  A parameter FALSE(0) disables the mechanism.
  73. NOTE X86 MIXING MMX AND FPU INSTRUCTIONS:
  74. A task with VX_FP_TASK option saves and restores the FPU and MMX state
  75. when performing a context switch.  Therefore, the application does not
  76. have to save or restore the FPU and MMX state if the FPU and MMX 
  77. instructions are not mixed within a task.  Because the MMX registers
  78. are aliased to the FPU registers, care must be taken when making
  79. transitions between FPU instructions and MMX instructions to prevent
  80. the loss of data in the FPU and MMX registers and to prevent incoherent
  81. or unexpected result.  When mixing MMX and FPU instructions within a 
  82. task, follow these guidelines from Intel:
  83.     - Keep the code in separate modules, procedures, or routines.
  84.     - Do not rely on register contents across transitions between FPU
  85.       and MMX code modules.
  86.     - When transitioning between MMX code and FPU code, save the MMX
  87.       register state (if it will be needed in the future) and execute
  88.       an EMMS instruction to empty the MMX state.
  89.     - When transitioning between FPU and MMX code, save the FPU state,
  90.       if it will be needed in the future.
  91. NOTE X86 MIXING SSE SSE2 FPU AND MMX INSTRUCTIONS:
  92. The XMM registers and the FPU/MMX registers represent separate 
  93. execution environments, which has certain ramifications when executing
  94. SSE, SSE2, MMX and FPU instructions in the same task context:
  95.     - Those SSE and SSE2 instruction that operate only on the XMM 
  96.       registers (such as the packed and scalar floating-point
  97.       instructions and the 128-bit SIMD integer instructions) can be
  98.       executed in the same instruction stream with 64-bit SIMD integer
  99.       or FPU instructions without any restrictions.  For example, an
  100.       application can perform the majority of its floating-point 
  101.       computations in the XMM registers, using the packed and scalar
  102.       floating-point instructions, and at the same time use the FPU
  103.       to perform trigonometric and other transcendental computations.
  104.       Likewise, an application can perform packed 64-bit and 128-bit
  105.       SIMD integer operations can be executed together without
  106.       restrictions.
  107.     - Those SSE and SSE2 instructions that operate on MMX registers
  108.       (such as the CVTPS2PI, CVTTPS2PI, CVTPI2PS, CVTPD2PI, CVTTPD2PI,
  109.       CVTPI2PD, MOVDQ2Q, MOVQ2DQ, PADDQ, and PSUBQ instructions) can
  110.       also be executed in the same instruction stream as 64-bit SIMD
  111.       integer or FPU instructions, however, here they subject to the
  112.       restrictions on the simultaneous use of MMX and FPU instructions,
  113.       which mentioned in the previous paragraph.
  114. NOTE X86 INTERRUPT LEVEL:
  115. Floating-point registers are f2notfP saved and restored for interrupt
  116. service routines connected with intConnect().  However, if necessary,
  117. an interrupt service routine can save and restore floating-point registers
  118. by calling routines in fppALib.  See the manual entry for intConnect() for
  119. more information.
  120. NOTE X86 EXCEPTIONS:
  121. There are six FPU exceptions that can send an exception to the CPU.  They 
  122. are controlled by Exception Mask bits of the Control Word register.  VxWorks 
  123. disables them in the default configuration.  They 
  124. are:
  125.     - Precision
  126.     - Overflow
  127.     - Underflow
  128.     - Division by zero
  129.     - Denormalized operand
  130.     - Invalid Operation
  131. NOTE ARM
  132. This architecture does not currently support floating-point coprocessors.
  133. INCLUDE FILES: fppLib.h
  134. SEE ALSO: fppLib, intConnect(),
  135. .nf
  136. .IR "Motorola MC68881/882 Floating-Point Coprocessor User's Manual" ,
  137. .IR "Intel 387 DX User's Manual" ,
  138. .IR "Intel Architecture Software Developer's Manual" ,
  139. .IR "Hitachi SH7750 Hardware Manual" ,
  140. .fi
  141. Gerry Kane and Joe Heinrich:
  142. .I "MIPS RISC Architecture Manual"
  143. */
  144. /*******************************************************************************
  145. *
  146. * fppSave - save the floating-point coprocessor context
  147. *
  148. * This routine saves the floating-point coprocessor context.
  149. * The context saved is:
  150. *
  151. * &`MC680x0':
  152. * - registers `fpcr', `fpsr', and `fpiar'
  153. * - registers `f0' - `f7'
  154. * - internal state frame (if NULL, the other registers are not saved.)
  155. *
  156. * "&`SPARC':
  157. * " - registers `fsr' and `fpq'
  158. * " - registers `f0' - `f31'
  159. * "
  160. * "&`i960':
  161. * " - registers `fp0' - `fp3'
  162. * "
  163. * &`MIPS':
  164. * - register `fpcsr'
  165. * - registers `fp0' - `fp31'
  166. *
  167. * &`SH-4':
  168. * - registers `fpcsr' and `fpul'
  169. * - registers `fr0' - `fr15'
  170. * - registers `xf0' - `xf15'
  171. *
  172. * &`x86':
  173. *       108 byte old context with fsave and frstor instruction
  174. *       - control word, status word, tag word, 
  175. *       - instruction pointer,
  176. *       - instruction pointer selector,
  177. *       - last FP instruction op code,
  178. *       - data pointer,
  179. *       - data pointer selector,
  180. *       - registers `st/mm0' - `st/mm7' (10 bytes * 8)
  181. *       512 byte new context with fxsave and fxrstor instruction
  182. *       - control word, status word, tag word, 
  183. *       - last FP instruction op code,
  184. *       - instruction pointer,
  185. *       - instruction pointer selector,
  186. *       - data pointer,
  187. *       - data pointer selector,
  188. *       - registers `st/mm0' - `st/mm7' (10 bytes * 8)
  189. *       - registers `xmm0' - `xmm7' (16 bytes * 8)
  190. *
  191. * &`ARM':
  192. *       - currently, on this architecture, this routine does nothing.
  193. *
  194. * &`SimSolaris':
  195. * - register `fsr'
  196. * - registers `f0' - `f31'
  197. *
  198. * &`SimNT':
  199. * - this routine does nothing on Windows simulator. Floating point
  200. *   registers are saved by Windows.
  201. *
  202. * RETURNS: N/A
  203. *
  204. * SEE ALSO: fppRestore()
  205. */
  206. void fppSave
  207.     (
  208.     FP_CONTEXT *  pFpContext /* where to save context */
  209.     )
  210.     {
  211.     ...
  212.     }
  213. /*******************************************************************************
  214. *
  215. * fppRestore - restore the floating-point coprocessor context
  216. *
  217. * This routine restores the floating-point coprocessor context.
  218. * The context restored is:
  219. *
  220. * &`MC680x0':
  221. * - registers `fpcr', `fpsr', and `fpiar'
  222. * - registers `f0' - `f7'
  223. * - internal state frame (if NULL, the other registers are not saved.)
  224. *
  225. * "&`SPARC':
  226. * " - registers `fsr' and `fpq'
  227. * " - registers `f0' - `f31'
  228. * "
  229. * "&`i960':
  230. * " - registers `fp0' - `fp3'
  231. * "
  232. * &`MIPS':
  233. * - register `fpcsr'
  234. * - registers `fp0' - `fp31'
  235. *
  236. * &`SH-4':
  237. * - registers `fpcsr' and `fpul'
  238. * - registers `fr0' - `fr15'
  239. * - registers `xf0' - `xf15'
  240. *
  241. * &`x86':
  242. *       108 byte old context with fsave and frstor instruction
  243. *       - control word, status word, tag word, 
  244. *       - instruction pointer,
  245. *       - instruction pointer selector,
  246. *       - last FP instruction op code,
  247. *       - data pointer,
  248. *       - data pointer selector,
  249. *       - registers `st/mm0' - `st/mm7' (10 bytes * 8)
  250. *       512 byte new context with fxsave and fxrstor instruction
  251. *       - control word, status word, tag word, 
  252. *       - last FP instruction op code,
  253. *       - instruction pointer,
  254. *       - instruction pointer selector,
  255. *       - data pointer,
  256. *       - data pointer selector,
  257. *       - registers `st/mm0' - `st/mm7' (10 bytes * 8)
  258. *       - registers `xmm0' - `xmm7' (16 bytes * 8)
  259. *
  260. * &`ARM':
  261. *       - currently, on this architecture, this routine does nothing.
  262. *
  263. * &`SimSolaris':
  264. * - register `fsr'
  265. * - registers `f0' - `f31'
  266. *
  267. * &`SimNT':
  268. * - this routine does nothing on Windows simulator. 
  269. *
  270. * RETURNS: N/A
  271. *
  272. * SEE ALSO: fppSave()
  273. */
  274. void fppRestore
  275.     (
  276.     FP_CONTEXT *  pFpContext /* where to restore context from */
  277.     )
  278.     {
  279.     ...
  280.     }
  281. /*******************************************************************************
  282. *
  283. * fppProbe - probe for the presence of a floating-point coprocessor
  284. *
  285. * This routine determines whether there is a
  286. * floating-point coprocessor in the system.
  287. *
  288. * The implementation of this routine is architecture-dependent:
  289. *
  290. * .IP "`MC680x0', `x86', `SH-4':"
  291. * This routine sets the illegal coprocessor opcode trap vector and executes
  292. * a coprocessor instruction.  If the instruction causes an exception,
  293. * fppProbe() returns ERROR.  Note that this routine saves and restores
  294. * the illegal coprocessor opcode trap vector that was there prior to this
  295. * call.
  296. *
  297. * The probe is only performed the first time this routine is called.
  298. * The result is stored in a static and returned on subsequent
  299. * calls without actually probing.
  300. *
  301. * ".IP `i960':
  302. * "This routine merely indicates whether VxWorks was compiled with
  303. * "the flag `-DCPU=I960KB'.
  304. * "
  305. * .IP `MIPS':
  306. * This routine simply reads the R-Series status register and reports
  307. * the bit that indicates whether coprocessor 1 is usable.  This bit
  308. * must be correctly initialized in the BSP.
  309. *
  310. * .IP `ARM':
  311. * This routine currently returns ERROR to indicate no floating-point 
  312. * coprocessor support.
  313. * .IP "`SimNT', `SimSolaris':"
  314. * This routine currently returns OK.
  315. *
  316. * INTERNAL
  317. * The STAR board will always have an on-board floating-point unit.
  318. * What about others?
  319. *
  320. * RETURNS:
  321. * OK, or ERROR if there is no floating-point coprocessor.
  322. */
  323. STATUS fppProbe (void)
  324.     {
  325.     ...
  326.     }
  327. /*******************************************************************************
  328. *
  329. * fppTaskRegsGet - get the floating-point registers from a task TCB
  330. *
  331. * This routine copies a task's floating-point registers and/or status
  332. * registers to the locations whose pointers are passed as
  333. * parameters.  The floating-point registers are copied into
  334. * an array containing all the registers.
  335. *
  336. * NOTE
  337. * This routine only works well if <task> is not the calling task.
  338. * If a task tries to discover its own registers, the values will be stale
  339. * (that is, left over from the last task switch).
  340. *
  341. * RETURNS: OK, or ERROR if there is no floating-point
  342. * support or there is an invalid state.
  343. *
  344. * SEE ALSO: fppTaskRegsSet()
  345. */
  346. STATUS fppTaskRegsGet
  347.     (
  348.     int  task,        /* task to get info about */
  349.     FPREG_SET *  pFpRegSet /* ptr to floating-point register set */
  350.     )
  351.     {
  352.     ...
  353.     }
  354. /*******************************************************************************
  355. *
  356. * fppTaskRegsSet - set the floating-point registers of a task
  357. *
  358. * This routine loads the specified values into the TCB of a specified task.
  359. * The register values are copied from the array at <pFpRegSet>.
  360. *
  361. * RETURNS: OK, or ERROR if there is no floating-point
  362. * support or there is an invalid state.
  363. *
  364. * SEE ALSO: fppTaskRegsGet()
  365. */
  366. STATUS fppTaskRegsSet
  367.     (
  368.     int  task,          /* task to set registers for */
  369.     FPREG_SET *  pFpRegSet /* ptr to floating-point register set */
  370.     )
  371.     {
  372.     ...
  373.     }