math-emu.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. #ifndef _ASM_M68K_SETUP_H
  2. #define _ASM_M68K_SETUP_H
  3. #include <asm/setup.h>
  4. #include <linux/linkage.h>
  5. /* Status Register bits */
  6. /* accrued exception bits */
  7. #define FPSR_AEXC_INEX 3
  8. #define FPSR_AEXC_DZ 4
  9. #define FPSR_AEXC_UNFL 5
  10. #define FPSR_AEXC_OVFL 6
  11. #define FPSR_AEXC_IOP 7
  12. /* exception status bits */
  13. #define FPSR_EXC_INEX1 8
  14. #define FPSR_EXC_INEX2 9
  15. #define FPSR_EXC_DZ 10
  16. #define FPSR_EXC_UNFL 11
  17. #define FPSR_EXC_OVFL 12
  18. #define FPSR_EXC_OPERR 13
  19. #define FPSR_EXC_SNAN 14
  20. #define FPSR_EXC_BSUN 15
  21. /* quotient byte, assumes big-endian, of course */
  22. #define FPSR_QUOTIENT(fpsr) (*((signed char *) &(fpsr) + 1))
  23. /* condition code bits */
  24. #define FPSR_CC_NAN 24
  25. #define FPSR_CC_INF 25
  26. #define FPSR_CC_Z 26
  27. #define FPSR_CC_NEG 27
  28. /* Control register bits */
  29. /* rounding mode */
  30. #define FPCR_ROUND_RN 0 /* round to nearest/even */
  31. #define FPCR_ROUND_RZ 1 /* round to zero */
  32. #define FPCR_ROUND_RM 2 /* minus infinity */
  33. #define FPCR_ROUND_RP 3 /* plus infinity */
  34. /* rounding precision */
  35. #define FPCR_PRECISION_X 0 /* long double */
  36. #define FPCR_PRECISION_S 1 /* double */
  37. #define FPCR_PRECISION_D 2 /* float */
  38. /* Flags to select the debugging output */
  39. #define PDECODE 0
  40. #define PEXECUTE 1
  41. #define PCONV 2
  42. #define PNORM 3
  43. #define PREGISTER 4
  44. #define PINSTR 5
  45. #define PUNIMPL 6
  46. #define PMOVEM 7
  47. #define PMDECODE (1<<PDECODE)
  48. #define PMEXECUTE (1<<PEXECUTE)
  49. #define PMCONV (1<<PCONV)
  50. #define PMNORM (1<<PNORM)
  51. #define PMREGISTER (1<<PREGISTER)
  52. #define PMINSTR (1<<PINSTR)
  53. #define PMUNIMPL (1<<PUNIMPL)
  54. #define PMMOVEM (1<<PMOVEM)
  55. #ifndef __ASSEMBLY__
  56. #include <linux/kernel.h>
  57. #include <linux/sched.h>
  58. union fp_mant64 {
  59. unsigned long long m64;
  60. unsigned long m32[2];
  61. };
  62. union fp_mant128 {
  63. unsigned long long m64[2];
  64. unsigned long m32[4];
  65. };
  66. /* internal representation of extended fp numbers */
  67. struct fp_ext {
  68. unsigned char lowmant;
  69. unsigned char sign;
  70. unsigned short exp;
  71. union fp_mant64 mant;
  72. };
  73. /* C representation of FPU registers */
  74. /* NOTE: if you change this, you have to change the assembler offsets
  75.    below and the size in <asm/fpu.h>, too */
  76. struct fp_data {
  77. struct fp_ext fpreg[8];
  78. unsigned int fpcr;
  79. unsigned int fpsr;
  80. unsigned int fpiar;
  81. unsigned short prec;
  82. unsigned short rnd;
  83. struct fp_ext temp[2];
  84. };
  85. #if FPU_EMU_DEBUG
  86. extern unsigned int fp_debugprint;
  87. #define dprint(bit, fmt, args...) ({
  88. if (fp_debugprint & (1 << (bit)))
  89. printk(fmt, ## args);
  90. })
  91. #else
  92. #define dprint(bit, fmt, args...)
  93. #endif
  94. #define uprint(str) ({
  95. static int __count = 3;
  96. if (__count > 0) {
  97. printk("You just hit an unimplemented "
  98.        "fpu instruction (%s)n", str);
  99. printk("Please report this to ....n");
  100. __count--;
  101. }
  102. })
  103. #define FPDATA ((struct fp_data *)current->thread.fp)
  104. #else /* __ASSEMBLY__ */
  105. #define FPDATA %a2
  106. /* offsets from the base register to the floating point data in the task struct */
  107. #define FPD_FPREG (TASK_THREAD+THREAD_FPREG+0)
  108. #define FPD_FPCR (TASK_THREAD+THREAD_FPREG+96)
  109. #define FPD_FPSR (TASK_THREAD+THREAD_FPREG+100)
  110. #define FPD_FPIAR (TASK_THREAD+THREAD_FPREG+104)
  111. #define FPD_PREC (TASK_THREAD+THREAD_FPREG+108)
  112. #define FPD_RND (TASK_THREAD+THREAD_FPREG+110)
  113. #define FPD_TEMPFP1 (TASK_THREAD+THREAD_FPREG+112)
  114. #define FPD_TEMPFP2 (TASK_THREAD+THREAD_FPREG+124)
  115. #define FPD_SIZEOF (TASK_THREAD+THREAD_FPREG+136)
  116. /* offsets on the stack to access saved registers,
  117.  * these are only used during instruction decoding
  118.  * where we always know how deep we're on the stack.
  119.  */
  120. #define FPS_DO (PT_D0)
  121. #define FPS_D1 (PT_D1)
  122. #define FPS_D2 (PT_D2)
  123. #define FPS_A0 (PT_A0)
  124. #define FPS_A1 (PT_A1)
  125. #define FPS_A2 (PT_A2)
  126. #define FPS_SR (PT_SR)
  127. #define FPS_PC (PT_PC)
  128. #define FPS_EA (PT_PC+6)
  129. #define FPS_PC2 (PT_PC+10)
  130. .macro fp_get_fp_reg
  131. lea (FPD_FPREG,FPDATA,%d0.w*4),%a0
  132. lea (%a0,%d0.w*8),%a0
  133. .endm
  134. /* Macros used to get/put the current program counter.
  135.  * 020/030 use a different stack frame then 040/060, for the
  136.  * 040/060 the return pc points already to the next location,
  137.  * so this only needs to be modified for jump instructions.
  138.  */
  139. .macro fp_get_pc dest
  140. move.l (FPS_PC+4,%sp),dest
  141. .endm
  142. .macro fp_put_pc src,jump=0
  143. move.l src,(FPS_PC+4,%sp)
  144. .endm
  145. .macro fp_get_instr_data f,s,dest,label
  146. getuser f,%sp@(FPS_PC+4)@(0),dest,label,%sp@(FPS_PC+4)
  147. addq.l #s,%sp@(FPS_PC+4)
  148. .endm
  149. .macro fp_get_instr_word dest,label,addr
  150. fp_get_instr_data w,2,dest,label,addr
  151. .endm
  152. .macro fp_get_instr_long dest,label,addr
  153. fp_get_instr_data l,4,dest,label,addr
  154. .endm
  155. /* These macros are used to read from/write to user space
  156.  * on error we jump to the fixup section, load the fault
  157.  * address into %a0 and jump to the exit.
  158.  * (derived from <asm/uaccess.h>)
  159.  */
  160. .macro getuser size,src,dest,label,addr
  161. | printf ,"[size<%08x]",1,addr
  162. .Lu1@: movessize src,dest
  163. .section .fixup,"ax"
  164. .even
  165. .Lu2@: move.l addr,%a0
  166. jra label
  167. .previous
  168. .section __ex_table,"a"
  169. .align 4
  170. .long .Lu1@,.Lu2@
  171. .previous
  172. .endm
  173. .macro putuser size,src,dest,label,addr
  174. | printf ,"[size>%08x]",1,addr
  175. .Lu1@: movessize src,dest
  176. .Lu2@:
  177. .section .fixup,"ax"
  178. .even
  179. .Lu3@: move.l addr,%a0
  180. jra label
  181. .previous
  182. .section __ex_table,"a"
  183. .align 4
  184. .long .Lu1@,.Lu3@
  185. .long .Lu2@,.Lu3@
  186. .previous
  187. .endm
  188. .macro movestack nr,arg1,arg2,arg3,arg4,arg5
  189. .if nr
  190. movestack (nr-1),arg2,arg3,arg4,arg5
  191. move.l arg1,-(%sp)
  192. .endif
  193. .endm
  194. .macro printf bit=-1,string,nr=0,arg1,arg2,arg3,arg4,arg5
  195. #ifdef FPU_EMU_DEBUG
  196. .data
  197. .Lpdata@:
  198. .string "string"
  199. .previous
  200. movem.l %d0/%d1/%a0/%a1,-(%sp)
  201. .if bit+1
  202. #if 0
  203. moveq #bit,%d0
  204. andw #7,%d0
  205. btst %d0,fp_debugprint+((31-bit)/8)
  206. #else
  207. btst #bit,fp_debugprint+((31-bit)/8)
  208. #endif
  209. jeq .Lpskip@
  210. .endif
  211. movestack nr,arg1,arg2,arg3,arg4,arg5
  212. pea .Lpdata@
  213. jsr printk
  214. lea ((nr+1)*4,%sp),%sp
  215. .Lpskip@:
  216. movem.l (%sp)+,%d0/%d1/%a0/%a1
  217. #endif
  218. .endm
  219. .macro printx bit,fp
  220. #ifdef FPU_EMU_DEBUG
  221. movem.l %d0/%a0,-(%sp)
  222. lea fp,%a0
  223. #if 0
  224. moveq #'+',%d0
  225. tst.w (%a0)
  226. jeq .Lx1@
  227. moveq #'-',%d0
  228. .Lx1@: printf bit," %c",1,%d0
  229. move.l (4,%a0),%d0
  230. bclr #31,%d0
  231. jne .Lx2@
  232. printf bit,"0."
  233. jra .Lx3@
  234. .Lx2@: printf bit,"1."
  235. .Lx3@: printf bit,"%08x%08x",2,%d0,%a0@(8)
  236. move.w (2,%a0),%d0
  237. ext.l %d0
  238. printf bit,"E%04x",1,%d0
  239. #else
  240. printf bit," %08x%08x%08x",3,%a0@,%a0@(4),%a0@(8)
  241. #endif
  242. movem.l (%sp)+,%d0/%a0
  243. #endif
  244. .endm
  245. .macro debug instr,args
  246. #ifdef FPU_EMU_DEBUG
  247. instr args
  248. #endif
  249. .endm
  250. #endif /* __ASSEMBLY__ */
  251. #endif /* _ASM_M68K_SETUP_H */