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

VxWorks

开发平台:

C/C++

  1. /* Copyright 1991-1992 Wind River Systems, Inc. */
  2. .data
  3. .globl _copyright_wind_river
  4. .long _copyright_wind_river
  5. /*
  6. modification history
  7. --------------------
  8. 01f,04jun96,ms   fixed SPR 6583 - tracing during fpp emulation trashes a0
  9. 01e,23aug92,jcf  changed bxxx to jxx.
  10. 01d,26may92,rrr  the tree shuffle
  11. 01c,17dec91,kdl  added changes from Motorola "skeleton.sa" v3.2:
  12.  don't do fsave unless frame format id is 40.
  13. 01b,04dec91,kdl  fixed register saving in __x_fpsp_ill_inst.
  14. 01a,12aug91,jcf  adapted from Motorola version 2.1.
  15. */
  16. /*
  17. DESCRIPTION
  18. skeleton.s 3.1 12/10/90,  2.1 Motorola 040 Floating Point Software Package
  19. The exception handler entry points for the FPSP are as follows:
  20.     ill_inst -> __x_fpsp_ill_inst
  21.     fline -> __x_fpsp_fline
  22.     bsun -> __x_fpsp_bsun
  23.     inex -> __x_fpsp_inex
  24.     dz -> __x_fpsp_dz
  25.     unfl -> __x_fpsp_unfl
  26.     operr -> __x_fpsp_operr
  27.     ovfl -> __x_fpsp_ovfl
  28.     snan -> __x_fpsp_snan
  29.     unsupp -> __x_fpsp_unsupp
  30. If the FPSP determines that the exception is one that must be handled by
  31. the operating system then there will be a return from the package by a 'jmp
  32. real_xxxx' where xxxx corresponds to an exception outlined above.  At that
  33. point the machine state will be identical to the state before the FPSP was
  34. entered.  In particular, whatever condition that caused the exception will
  35. still be pending when the FPSP package returns.  This will enable system
  36. specific code, contained in excALib()/excLib() to handle the exception.
  37. If the exception was completely handled by the package, then the return
  38. will be via a 'jmp fpsp_done'.  Unless there is OS specific work to be done
  39. (such as handling a context switch or interrupt) the user program can be
  40. resumed via 'rte'.
  41. In the following skeleton code, some typical 'real_xxxx' handling code is
  42. shown.  This code may need to be moved to an appropriate place in the
  43. target system, or rewritten.
  44. Copyright (C) Motorola, Inc. 1990
  45. All Rights Reserved
  46. THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
  47. The copyright notice above does not evidence any
  48. actual or intended publication of such source code.
  49. Original VxWorks implementation by Jim Foris, GE Medical Systems.
  50. NOMANUAL
  51. */
  52. #include "fpsp040E.h"
  53. /* imports */
  54. .globl _excStub
  55. .globl __x_b1238_fix
  56. .globl __x_do_func
  57. .globl __x_gen_except
  58. .globl __x_get_op
  59. .globl __x_sto_res
  60. /* globals */
  61. .globl __x_real_bsun /* called from __x_fpsp_bsun for OS handling */
  62. .globl __x_real_dz /* called from __x_fpsp_dz for OS handling */
  63. .globl __x_real_operr /* called from __x_fpsp_operr for OS handling */
  64. .globl __x_real_ovfl /* called from __x_fpsp_ovfl for OS handling */
  65. .globl __x_real_snan /* called from __x_fpsp_snan for OS handling */
  66. .globl __x_real_trace /* called from __x_fpsp_trace for OS handling */
  67. .globl __x_real_unfl /* called from __x_fpsp_unfl for OS handling */
  68. .globl __x_real_unsupp /* called from __x_fpsp_unsupp for OS handling*/
  69. .globl __x_real_inex /* called from __x_fpsp_inex for OS handling */
  70. .globl __x_fpsp_dz /* divide by zero exception handler */
  71. .globl __x_fpsp_inex /* inexact exception handler */
  72. .globl __x_fpsp_fline /* fline exception handler */
  73. .globl __x_fpsp_ill_inst  /* illegal instruction exception handler */
  74. .globl __x_fpsp_fmt_error /* called if format not supported */
  75. .globl __x_fpsp_done /* called from handlers to return to user */
  76. .globl __x_mem_read /* utility routine to read memory */
  77. .globl __x_mem_write /* utility routine to write memory */
  78. .text
  79. /*******************************************************************************
  80. *
  81. * BSUN exception
  82. *
  83. * This sample handler simply clears the nan bit in the FPSR.
  84. */
  85. __x_real_bsun:
  86. link a6,#-192
  87. fsave a7@-
  88. bclr #E1,a6@(E_BYTE) /* bsun is always an E1 exception */
  89. fmovel FPSR,a7@-
  90. bclr #nan_bit,a7@
  91. fmovel a7@+,FPSR
  92. frestore a7@+
  93. unlk a6
  94. jmp _excStub /* start VxWorks exception handling */
  95. /*******************************************************************************
  96. *
  97. * Divide by Zero exception
  98. *
  99. */
  100. __x_fpsp_dz:
  101. __x_real_dz:
  102. link a6,#-192
  103. fsave a7@-
  104. bclr #E1,a6@(E_BYTE)
  105. frestore a7@+
  106. unlk a6
  107. jmp _excStub /* start VxWorks exception handling */
  108. /*******************************************************************************
  109. *
  110. * Operand Error exception
  111. */
  112. __x_real_operr:
  113. link a6,#-192
  114. fsave a7@-
  115. bclr #E1,a6@(E_BYTE) /* operr is always an E1 exception */
  116. frestore a7@+
  117. unlk a6
  118. jmp _excStub /* start VxWorks exception handling */
  119. /*******************************************************************************
  120. *
  121. * Overflow exception
  122. */
  123. __x_real_ovfl:
  124. link a6,#-192
  125. fsave a7@-
  126. bclr #E3,a6@(E_BYTE) /* clear and test E3 flag */
  127. jne  ovfl_done
  128. bclr #E1,a6@(E_BYTE)
  129. ovfl_done:
  130. frestore a7@+
  131. unlk a6
  132. jmp _excStub /* start VxWorks exception handling */
  133. /*******************************************************************************
  134. *
  135. * Signalling NAN exception
  136. */
  137. __x_real_snan:
  138. link a6,#-192
  139. fsave a7@-
  140. bclr #E1,a6@(E_BYTE) /* snan is always an E1 exception */
  141. frestore a7@+
  142. unlk a6
  143. jmp _excStub /* start VxWorks exception handling */
  144. /*******************************************************************************
  145. *
  146. * Trace Exception
  147. */
  148. __x_real_trace:
  149. movel a0, sp@- /* save a0 to the stack */
  150. movec vbr,a0 /* compute IV_TRACE vector address */
  151. movel a0@(0x24),a0
  152. movel a0, sp@- /* and push it on the stack */
  153. movel sp@(0x4), a0 /* restore a0 */
  154. rtd #4 /* jump to trace vector */
  155. /*******************************************************************************
  156. *
  157. * Underflow exception
  158. */
  159. __x_real_unfl:
  160. link a6,#-192
  161. fsave a7@-
  162. bclr #E3,a6@(E_BYTE) /* clear and test E3 flag */
  163. jne  unfl_done
  164. bclr #E1,a6@(E_BYTE)
  165. unfl_done:
  166. frestore a7@+
  167. unlk a6
  168. jmp _excStub /* start VxWorks exception handling */
  169. /*******************************************************************************
  170. *
  171. * Unsupported data type exception
  172. */
  173. __x_real_unsupp:
  174. link a6,#-192
  175. fsave a7@-
  176. bclr #E1,a6@(E_BYTE) /* unsupp is always an E1 exception */
  177. frestore a7@+
  178. unlk a6
  179. jmp _excStub /* start VxWorks exception handling */
  180. /*******************************************************************************
  181. *
  182. * Inexact exception
  183. *
  184. * All inexact exceptions are real, but the 'real' handler
  185. * will probably want to clear the pending exception.
  186. * The provided code will clear the E3 exception (if pending),
  187. * otherwise clear the E1 exception.  The frestore is not really
  188. * necessary for E1 exceptions.
  189. *
  190. * Code following the 'inex' label is to handle bug #1232.  In this
  191. * bug, if an E1 snan, ovfl, or unfl occured, and the process was
  192. * swapped out before taking the exception, the exception taken on
  193. * return was inex, rather than the correct exception.  The snan, ovfl,
  194. * and unfl exception to be taken must not have been enabled.  The
  195. * fix is to check for E1, and the existence of one of snan, ovfl,
  196. * or unfl bits set in the fpsr.  If any of these are set, branch
  197. * to the appropriate  handler for the exception in the fpsr.  Note
  198. * that this fix is only for d43b parts, and is skipped if the
  199. * version number is not 0x40.
  200. */
  201. __x_fpsp_inex:
  202. link a6,#-LOCAL_SIZE
  203. fsave a7@-
  204. cmpib #VER_40,a7@ | test version number
  205. jne  not_fmt40
  206. fmovel fpsr,a7@-
  207. btst #E1,a6@(E_BYTE) | test for E1 set
  208. jeq  not_b1232
  209. btst #__x_snan_bit,a7@(2) | test for snan
  210. beq __x_inex_ckofl
  211. addl #4,sp
  212. frestore a7@+
  213. unlk a6
  214. jra __x_fpsp_snan
  215. __x_inex_ckofl:
  216. btst #__x_ovfl_bit,a7@(2) | test for ovfl
  217. jeq __x_inex_ckufl
  218. addl #4,sp
  219. frestore a7@+
  220. unlk a6
  221. jra __x_fpsp_ovfl
  222. __x_inex_ckufl:
  223. btst #__x_unfl_bit,a7@(2) | test for unfl
  224. jeq not_b1232
  225. addl #4,sp
  226. frestore a7@+
  227. unlk a6
  228. jra __x_fpsp_unfl
  229. |
  230. | We do not have the bug 1232 case.  Clean up the stack and call
  231. | __x_real_inex.
  232. |
  233. not_b1232:
  234. addl #4,sp
  235. frestore a7@+
  236. unlk a6
  237. __x_real_inex:
  238. link a6,#-LOCAL_SIZE
  239. fsave a7@-
  240. not_fmt40:
  241. bclr #E3,a6@(E_BYTE) | clear and test E3 flag
  242. jeq  __x_inex_cke1
  243. |
  244. | Clear dirty bit on dest resister in the frame before branching
  245. | to __x_b1238_fix.
  246. |
  247. moveml d0/d1,a6@(USER_DA)
  248. bfextu a6@(CMDREG1B){#6:#3},d0 | get dest reg no
  249. bclr d0,a6@(FPR_DIRTY_BITS) | clr dest dirty bit
  250. bsrl __x_b1238_fix | test for bug1238 case
  251. moveml a6@(USER_DA),d0/d1
  252. jra  __x_inex_done
  253. __x_inex_cke1:
  254. bclr #E1,a6@(E_BYTE)
  255. __x_inex_done:
  256. frestore a7@+
  257. unlk a6
  258. jmp _excStub /* start VxWorks exception handling */
  259. /*******************************************************************************
  260. *
  261. * fpsp_ill_inst - illegal instruction handler (from Mot. FPSP Version 1.0)
  262. *
  263. * ERRATA E34 fix: F-line illegal instruction through vector 4
  264. */
  265. __x_fpsp_ill_inst:
  266. movl a0,a7@- | save a0
  267. movl a7@(6),a0 | copy PC into a0
  268. cmpw #0xffff,a0@ | check if it was really a F-line
  269. jeq  fpsp_ill1 | skip if true
  270. movl a7@+,a0 | else, restore a0
  271. jmp _excStub | and jump into common vxWorks handler*
  272. fpsp_ill1: | really a F-line exception
  273. movl a7@+,a0 | so restore a0
  274. jra  __x_fpsp_fline | and jump into F-line handler
  275. /*******************************************************************************
  276. *
  277. * fpsp_fline --- FPSP handler for fline exception (x_flinesa 3.3 1/10/91)
  278. *
  279. * A 'real' F-line exception is one that the FPSP isn't supposed to
  280. * handle. E.g. an instruction with a co-processor ID that is not 1.
  281. * First determine if the exception is one of the unimplemented floating point
  282. * instructions.  If so, let fpsp_unimp handle it.  Next, determine if the
  283. * instruction is an fmovecr with a non-zero <ea> field.  If so, handle here
  284. * and return.  Otherwise, it must be a real F-line exception.
  285. */
  286. __x_fpsp_fline:
  287. /* Check for unimplemented vector first.  Use EXC_VEC-4 because
  288.  * the equate is valid only after a 'link a6' has pushed one more
  289.  * .long onto the stack.
  290.  */
  291. cmpw #UNIMP_VEC,a7@(EXC_VEC-4)
  292. jeq  __x_fpsp_unimp
  293. | fmovecr with non-zero <ea> handling here
  294. subl #4,a7 | 4 accounts for 2-word difference
  295. | between six word frame (unimp) and
  296. | four word frame
  297. link a6,#-LOCAL_SIZE
  298. fsave a7@-
  299. moveml d0-d1/a0-a1,a6@(USER_DA)
  300. moveal a6@(EXC_PC+4),a0 | get address of __x_fline instruction
  301. lea a6@(L_SCR1),a1 | use L_SCR1 as scratch
  302. movel #4,d0
  303. addl #4,a6 | to offset the subl #4,a7 above so that
  304. | a6 can point correctly to the stack frame
  305. | before branching to __x_mem_read
  306. bsrl __x_mem_read
  307. subl #4,a6
  308. movel a6@(L_SCR1),d0 | d0 contains the __x_fline and command word
  309. bfextu d0{#4:#3},d1 | extract coprocessor id
  310. cmpib #1,d1 | check if cpid=1
  311. jne not_mvcr | exit if not
  312. bfextu d0{#16:#6},d1
  313. cmpib #0x17,d1 | check if it is an FMOVECR encoding
  314. jne not_mvcr
  315. | if an FMOVECR instruction, fix stack
  316. | and go to FPSP_UNIMP
  317. fix_stack:
  318. cmpib #VER_40,a7@ | test for orig unimp frame
  319. jne  ck_rev
  320. subl #UNIMP_40_SIZE-4,a7 | emulate an orig fsave
  321. moveb #VER_40,a7@
  322. moveb #UNIMP_40_SIZE-4,a7@(1)
  323. clrw a7@(2)
  324. jra  fix_con
  325. ck_rev:
  326. cmpib #VER_41,a7@ | test for rev unimp frame
  327. jne  __x_fpsp_fmt_error | if not 0x40 or 0x41, exit with error
  328. subl #UNIMP_41_SIZE-4,a7  | emulate a rev fsave
  329. moveb #VER_41,a7@
  330. moveb #UNIMP_41_SIZE-4,a7@(1)
  331. clrw a7@(2)
  332. fix_con:
  333. movew a6@(EXC_SR+4),a6@(EXC_SR) | move stacked sr to new position
  334. movel a6@(EXC_PC+4),a6@(EXC_PC) | move stacked pc to new position
  335. fmovel a6@(EXC_PC),fpi  | point fpi to __x_fline inst
  336. movel #4,d1
  337. addl d1,a6@(EXC_PC) | increment stacked pc val to next inst
  338. movew #0x202c,a6@(EXC_VEC)  | reformat vector to unimp
  339. clrl a6@(EXC_EA) | clear the EXC_EA field
  340. movew d0,a6@(CMDREG1B)  | move the lower word into CMDREG1B
  341. clrl a6@(E_BYTE)
  342. bset #UFLAG,a6@(T_BYTE)
  343. moveml a6@(USER_DA),d0-d1/a0-a1 | restore data registers
  344. jra  __x_uni_2
  345. not_mvcr:
  346. moveml a6@(USER_DA),d0-d1/a0-a1 | restore data registers
  347. frestore a7@+
  348. unlk a6
  349. addl #4,a7
  350. __x_real_fline:
  351. jmp _excStub /* start VxWorks exception handling */
  352. /*******************************************************************************
  353. *
  354. * fpsp_unimp --- FPSP handler for unimp inst exception (x_unimpsa 3.2 4/26/91)
  355. *
  356. * Invoked when the user program encounters a floating-point op-code that
  357. * hardware does not support.  Trap vector# 11 (See table 8-1 MC68030 User's
  358. * Manual).
  359. *
  360. * Note: An fsave for an unimplemented inst. will create a short
  361. * fsave stack.
  362. *
  363. *  Input: 1. Six word stack frame for unimplemented inst, four word
  364. *            for illegal. (See table 8-7 MC68030 User's Manual).
  365. *         2. Unimp (short) fsave state frame created here by fsave
  366. *            instruction.
  367. */
  368. __x_fpsp_unimp:
  369. link a6,#-LOCAL_SIZE
  370. fsave a7@-
  371. __x_uni_2:
  372. moveml d0-d1/a0-a1,a6@(USER_DA)
  373. fmovemx fp0-fp3,a6@(USER_FP0)
  374. fmoveml fpcr/fpsr/fpi,a6@(USER_FPCR)
  375. moveb a7@,d0 | test for valid version num
  376. andib #0xf0,d0 | test for 0x4x
  377. cmpib #VER_4,d0 | must be 0x4x or exit
  378. jne  __x_fpsp_fmt_error
  379. /* Temporary D25B Fix - The following lines are used to ensure that the FPSR
  380.  * exception byte and condition codes are clear before proceeding
  381.  */
  382. movel a6@(USER_FPSR),d0
  383. andl #0xFF,d0 | clear all but accrued exceptions
  384. movel d0,a6@(USER_FPSR)
  385. fmovel #0,FPSR  | clear all user bits
  386. fmovel #0,fpcr | clear all user exceptions for FPSP
  387. clrb a6@(UFLG_TMP) | clr flag for __x_unsupp data
  388. bsrl __x_get_op | go get operand(s)
  389. clrb a6@(STORE_FLG)
  390. bsrl __x_do_func | do the function
  391. fsave a7@- | capture possible exc state
  392. tstb a6@(STORE_FLG)
  393. jne  no_store | if STORE_FLG is set, no __x_store
  394. bsrl __x_sto_res | store the result in user space
  395. no_store:
  396. jra  __x_gen_except | post any exceptions and return
  397. /*******************************************************************************
  398. *
  399. * __x_fpsp_fmt_error --- exit point for frame format error
  400. *
  401. * The fpu stack frame does not match the frames existing
  402. * or planned at the time of this writing.  The fpsp is
  403. * unable to handle frame sizes not in the following
  404. * version:size pairs:
  405. *
  406. * {4060, 4160} - busy frame
  407. * {4028, 4130} - unimp frame
  408. * {4000, 4100} - idle frame
  409. *
  410. * This entry point simply holds an f-line illegal value.
  411. * Replace this with a call to your kernel panic code or
  412. * code to handle future revisions of the fpu.
  413. */
  414. __x_fpsp_fmt_error:
  415. .long 0xf27f0000 | f-line illegal
  416. /*******************************************************************************
  417. *
  418. * __x_fpsp_done --- FPSP exit point
  419. *
  420. * The exception has been handled by the package and we are ready
  421. * to return to user mode, but there may be OS specific code
  422. * to execute before we do.  If there is, do it now.
  423. */
  424. __x_fpsp_done:
  425. rte
  426. /*******************************************************************************
  427. *
  428. * __x_mem_write --- write to user or supervisor address space
  429. *
  430. * Writes to memory while in supervisor mode.  For systems with MMU this must
  431. * be rewritten to utilize a 'moves' instruction.
  432. *
  433. * Input:
  434. *     a0 - supervisor source address
  435. *     a1 - user destination address
  436. *     d0 - number of bytes to write (maximum count is 12)
  437. */
  438. __x_mem_write:
  439. movb a0@+,a1@+
  440. subql #1,d0
  441. jne  __x_mem_write
  442. rts
  443. /*******************************************************************************
  444. *
  445. * __x_mem_read --- read from user or supervisor address space
  446. *
  447. * Reads from memory while in supervisor mode.  For systems with MMU this must
  448. * be rewritten to utilize a 'moves' instruction.
  449. *
  450. * The FPSP calls mem_read to read the original F-line instruction in order
  451. * to extract the data register number when the 'Dn' addressing mode is
  452. * used.
  453. *
  454. * Input:
  455. *     a0 - user source address
  456. *     a1 - supervisor destination address
  457. *     d0 - number of bytes to read (maximum count is 12)
  458. */
  459. __x_mem_read:
  460. movb a0@+,a1@+
  461. subql #1,d0
  462. jne  __x_mem_read
  463. rts
  464. #if 0
  465. /*******************************************************************************
  466. *
  467. * excFppEmulate - emulate subset of MC68881/MC68882 unimplemented instructions
  468. *
  469. * This routine emulates the MC68881/MC68882 instructions that the GNU toolchain
  470. * generates.  Namely, fmovecr and fintrz.  The notion is that complete
  471. * emulation of the MC68881/MC68882 is only required in situations where
  472. * part of the application is a floating point assembly package.
  473. * For everyone else (the majority?) it is 32K of dead weight.  So we use
  474. * a hook to connect the rest of the support.
  475. */
  476. __x_excFppEmulate:
  477. clrb a6@(CU_ONLY)
  478. /* Check for fmovecr.  It does not follow the format of fp gen unimplemented
  479.  * instructions.  The test is on the upper 6 bits if they are 0x17, the inst
  480.  * is fmovecr.  Call entry smovcr directly.
  481.  */
  482. bfextu a6@(CMDREG1B){#0:#6},d0 | get opclass and src fields
  483. cmpil #0x17,d0 | if op class and size fields are 0x17,
  484. jne  not_fmovecr
  485. jmp smovcr | fmovecr, jmp directly to emulation
  486. not_fmovecr:
  487. st a6@(STORE_FLG) | return ERROR for now
  488. rts
  489. #endif