home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-m68k / math-emu.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  6.3 KB  |  301 lines

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