fp_movem.S 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /*
  2. * fp_movem.S
  3. *
  4. * Copyright Roman Zippel, 1997. All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, and the entire permission notice in its entirety,
  11. * including the disclaimer of warranties.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. The name of the author may not be used to endorse or promote
  16. * products derived from this software without specific prior
  17. * written permission.
  18. *
  19. * ALTERNATIVELY, this product may be distributed under the terms of
  20. * the GNU General Public License, in which case the provisions of the GPL are
  21. * required INSTEAD OF the above restrictions. (This clause is
  22. * necessary due to a potential bad interaction between the GPL and
  23. * the restrictions contained in a BSD-style copyright.)
  24. *
  25. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  26. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  27. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  28. * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  29. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  31. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  33. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  34. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  35. * OF THE POSSIBILITY OF SUCH DAMAGE.
  36. */
  37. #include "fp_emu.h"
  38. #include "fp_decode.h"
  39. | set flags for decode macros for fmovem
  40. do_fmovem=1
  41. .globl fp_fmovem_fp, fp_fmovem_cr
  42. | %d1 contains the mask and count of the register list
  43. | for other register usage see fp_decode.h
  44. fp_fmovem_fp:
  45. printf PDECODE,"fmovem.x "
  46. | get register list and count them
  47. btst #11,%d2
  48. jne 1f
  49. bfextu %d2{#24,#8},%d0 | static register list
  50. jra 2f
  51. 1: bfextu %d2{#25,#3},%d0 | dynamic register list
  52. jsr fp_get_data_reg
  53. 2: move.l %d0,%d1
  54. swap %d1
  55. jra 2f
  56. 1: addq.w #1,%d1 | count the # of registers in
  57. 2: lsr.b #1,%d0 | register list and keep it in %d1
  58. jcs 1b
  59. jne 2b
  60. printf PDECODE,"#%08x",1,%d1
  61. #ifdef FPU_EMU_DEBUG
  62. btst #12,%d2
  63. jne 1f
  64. printf PDECODE,"-" | decremental move
  65. jra 2f
  66. 1: printf PDECODE,"+" | incremental move
  67. 2: btst #13,%d2
  68. jeq 1f
  69. printf PDECODE,"->" | fpu -> cpu
  70. jra 2f
  71. 1: printf PDECODE,"<-" | fpu <- cpu
  72. 2:
  73. #endif
  74. | decode address mode
  75. fp_decode_addr_mode
  76. .long fp_ill, fp_ill
  77. .long fpr_indirect, fpr_postinc
  78. .long fpr_predecr, fpr_disp16
  79. .long fpr_extmode0, fpr_extmode1
  80. | addressing mode: address register indirect
  81. fpr_indirect:
  82. fp_mode_addr_indirect
  83. jra fpr_do_movem
  84. | addressing mode: address register indirect with postincrement
  85. fpr_postinc:
  86. fp_mode_addr_indirect_postinc
  87. jra fpr_do_movem
  88. fpr_predecr:
  89. fp_mode_addr_indirect_predec
  90. jra fpr_do_movem
  91. | addressing mode: address register/programm counter indirect
  92. | with 16bit displacement
  93. fpr_disp16:
  94. fp_mode_addr_indirect_disp16
  95. jra fpr_do_movem
  96. fpr_extmode0:
  97. fp_mode_addr_indirect_extmode0
  98. jra fpr_do_movem
  99. fpr_extmode1:
  100. fp_decode_addr_reg
  101. jmp ([0f:w,%pc,%d0*4])
  102. .align 4
  103. 0:
  104. .long fpr_absolute_short, fpr_absolute_long
  105. .long fpr_disp16, fpr_extmode0
  106. .long fp_ill, fp_ill
  107. .long fp_ill, fp_ill
  108. fpr_absolute_short:
  109. fp_mode_abs_short
  110. jra fpr_do_movem
  111. fpr_absolute_long:
  112. fp_mode_abs_long
  113. | jra fpr_do_movem
  114. fpr_do_movem:
  115. swap %d1 | get fpu register list
  116. lea (FPD_FPREG,FPDATA),%a1
  117. moveq #12,%d0
  118. btst #12,%d2
  119. jne 1f
  120. lea (-12,%a1,%d0*8),%a1
  121. neg.l %d0
  122. 1: btst #13,%d2
  123. jne 4f
  124. | move register from memory into fpu
  125. jra 3f
  126. 1: printf PMOVEM,"(%p>%p)",2,%a0,%a1
  127. getuser.l (%a0)+,%d2,fp_err_ua1,%a0
  128. lsr.l #8,%d2
  129. lsr.l #7,%d2
  130. lsr.w #1,%d2
  131. move.l %d2,(%a1)+
  132. getuser.l (%a0)+,%d2,fp_err_ua1,%a0
  133. move.l %d2,(%a1)+
  134. getuser.l (%a0),%d2,fp_err_ua1,%a0
  135. move.l %d2,(%a1)
  136. subq.l #8,%a0
  137. subq.l #8,%a1
  138. add.l %d0,%a0
  139. 2: add.l %d0,%a1
  140. 3: lsl.b #1,%d1
  141. jcs 1b
  142. jne 2b
  143. jra 5f
  144. | move register from fpu into memory
  145. 1: printf PMOVEM,"(%p>%p)",2,%a1,%a0
  146. move.l (%a1)+,%d2
  147. lsl.w #1,%d2
  148. lsl.l #7,%d2
  149. lsl.l #8,%d2
  150. putuser.l %d2,(%a0)+,fp_err_ua1,%a0
  151. move.l (%a1)+,%d2
  152. putuser.l %d2,(%a0)+,fp_err_ua1,%a0
  153. move.l (%a1),%d2
  154. putuser.l %d2,(%a0),fp_err_ua1,%a0
  155. subq.l #8,%a1
  156. subq.l #8,%a0
  157. add.l %d0,%a0
  158. 2: add.l %d0,%a1
  159. 4: lsl.b #1,%d1
  160. jcs 1b
  161. jne 2b
  162. 5:
  163. printf PDECODE,"\n"
  164. #if 0
  165. lea (FPD_FPREG,FPDATA),%a0
  166. printf PMOVEM,"fp:"
  167. printx PMOVEM,%a0@(0)
  168. printx PMOVEM,%a0@(12)
  169. printf PMOVEM,"\n "
  170. printx PMOVEM,%a0@(24)
  171. printx PMOVEM,%a0@(36)
  172. printf PMOVEM,"\n "
  173. printx PMOVEM,%a0@(48)
  174. printx PMOVEM,%a0@(60)
  175. printf PMOVEM,"\n "
  176. printx PMOVEM,%a0@(72)
  177. printx PMOVEM,%a0@(84)
  178. printf PMOVEM,"\n"
  179. #endif
  180. jra fp_end
  181. | set flags for decode macros for fmovem control register
  182. do_fmovem=1
  183. do_fmovem_cr=1
  184. fp_fmovem_cr:
  185. printf PDECODE,"fmovem.cr "
  186. | get register list and count them
  187. bfextu %d2{#19,#3},%d0
  188. move.l %d0,%d1
  189. swap %d1
  190. jra 2f
  191. 1: addq.w #1,%d1
  192. 2: lsr.l #1,%d0
  193. jcs 1b
  194. jne 2b
  195. printf PDECODE,"#%08x",1,%d1
  196. #ifdef FPU_EMU_DEBUG
  197. btst #13,%d2
  198. jeq 1f
  199. printf PDECODE,"->" | fpu -> cpu
  200. jra 2f
  201. 1: printf PDECODE,"<-" | fpu <- cpu
  202. 2:
  203. #endif
  204. | decode address mode
  205. fp_decode_addr_mode
  206. .long fpc_data, fpc_addr
  207. .long fpc_indirect, fpc_postinc
  208. .long fpc_predecr, fpc_disp16
  209. .long fpc_extmode0, fpc_extmode1
  210. fpc_data:
  211. fp_mode_data_direct
  212. move.w %d0,%d1
  213. bfffo %d2{#19,#3},%d0
  214. sub.w #19,%d0
  215. lea (FPD_FPCR,FPDATA,%d0.w*4),%a1
  216. btst #13,%d2
  217. jne 1f
  218. move.w %d1,%d0
  219. jsr fp_get_data_reg
  220. move.l %d0,(%a1)
  221. jra fpc_movem_fin
  222. 1: move.l (%a1),%d0
  223. jsr fp_put_data_reg
  224. jra fpc_movem_fin
  225. fpc_addr:
  226. fp_decode_addr_reg
  227. printf PDECODE,"a%d",1,%d0
  228. btst #13,%d2
  229. jne 1f
  230. jsr fp_get_addr_reg
  231. move.l %a0,(FPD_FPIAR,FPDATA)
  232. jra fpc_movem_fin
  233. 1: move.l (FPD_FPIAR,FPDATA),%a0
  234. jsr fp_put_addr_reg
  235. jra fpc_movem_fin
  236. fpc_indirect:
  237. fp_mode_addr_indirect
  238. jra fpc_do_movem
  239. fpc_postinc:
  240. fp_mode_addr_indirect_postinc
  241. jra fpc_do_movem
  242. fpc_predecr:
  243. fp_mode_addr_indirect_predec
  244. jra fpc_do_movem
  245. fpc_disp16:
  246. fp_mode_addr_indirect_disp16
  247. jra fpc_do_movem
  248. fpc_extmode0:
  249. fp_mode_addr_indirect_extmode0
  250. jra fpc_do_movem
  251. fpc_extmode1:
  252. fp_decode_addr_reg
  253. jmp ([0f:w,%pc,%d0*4])
  254. .align 4
  255. 0:
  256. .long fpc_absolute_short, fpc_absolute_long
  257. .long fpc_disp16, fpc_extmode0
  258. .long fpc_immediate, fp_ill
  259. .long fp_ill, fp_ill
  260. fpc_absolute_short:
  261. fp_mode_abs_short
  262. jra fpc_do_movem
  263. fpc_absolute_long:
  264. fp_mode_abs_long
  265. jra fpc_do_movem
  266. fpc_immediate:
  267. fp_get_pc %a0
  268. lea (%a0,%d1.w*4),%a1
  269. fp_put_pc %a1
  270. printf PDECODE,"#imm"
  271. | jra fpc_do_movem
  272. #if 0
  273. swap %d1
  274. lsl.l #5,%d1
  275. lea (FPD_FPCR,FPDATA),%a0
  276. jra 3f
  277. 1: move.l %d0,(%a0)
  278. 2: addq.l #4,%a0
  279. 3: lsl.b #1,%d1
  280. jcs 1b
  281. jne 2b
  282. jra fpc_movem_fin
  283. #endif
  284. fpc_do_movem:
  285. swap %d1 | get fpu register list
  286. lsl.l #5,%d1
  287. lea (FPD_FPCR,FPDATA),%a1
  288. 1: btst #13,%d2
  289. jne 4f
  290. | move register from memory into fpu
  291. jra 3f
  292. 1: printf PMOVEM,"(%p>%p)",2,%a0,%a1
  293. getuser.l (%a0)+,%d0,fp_err_ua1,%a0
  294. move.l %d0,(%a1)
  295. 2: addq.l #4,%a1
  296. 3: lsl.b #1,%d1
  297. jcs 1b
  298. jne 2b
  299. jra fpc_movem_fin
  300. | move register from fpu into memory
  301. 1: printf PMOVEM,"(%p>%p)",2,%a1,%a0
  302. move.l (%a1),%d0
  303. putuser.l %d0,(%a0)+,fp_err_ua1,%a0
  304. 2: addq.l #4,%a1
  305. 4: lsl.b #1,%d1
  306. jcs 1b
  307. jne 2b
  308. fpc_movem_fin:
  309. and.l #0x0000fff0,(FPD_FPCR,FPDATA)
  310. and.l #0x0ffffff8,(FPD_FPSR,FPDATA)
  311. move.l (FPD_FPCR,FPDATA),%d0
  312. lsr.l #4,%d0
  313. moveq #3,%d1
  314. and.l %d0,%d1
  315. move.w %d1,(FPD_RND,FPDATA)
  316. lsr.l #2,%d0
  317. moveq #3,%d1
  318. and.l %d0,%d1
  319. move.w %d1,(FPD_PREC,FPDATA)
  320. printf PDECODE,"\n"
  321. #if 0
  322. printf PMOVEM,"fpcr : %08x\n",1,FPDATA@(FPD_FPCR)
  323. printf PMOVEM,"fpsr : %08x\n",1,FPDATA@(FPD_FPSR)
  324. printf PMOVEM,"fpiar: %08x\n",1,FPDATA@(FPD_FPIAR)
  325. clr.l %d0
  326. move.w (FPD_PREC,FPDATA),%d0
  327. printf PMOVEM,"prec : %04x\n",1,%d0
  328. move.w (FPD_RND,FPDATA),%d0
  329. printf PMOVEM,"rnd : %04x\n",1,%d0
  330. #endif
  331. jra fp_end