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 /* work around binutils idiocy */ 230 old_gas=-1 231 .irp gas_ident.x .x 232 old_gas=old_gas+1 233 .endr 234 .if !old_gas 235 .irp m b,w,l 236 .macro getuser.\m src,dest,label,addr 237 getuser .\m,\src,\dest,\label,\addr 238 .endm 239 .macro putuser.\m src,dest,label,addr 240 putuser .\m,\src,\dest,\label,\addr 241 .endm 242 .endr 243 .endif 244 245 .macro movestack nr,arg1,arg2,arg3,arg4,arg5 246 .if \nr 247 movestack (\nr-1),\arg2,\arg3,\arg4,\arg5 248 move.l \arg1,-(%sp) 249 .endif 250 .endm 251 252 .macro printf bit=-1,string,nr=0,arg1,arg2,arg3,arg4,arg5 253 #ifdef FPU_EMU_DEBUG 254 .data 255 .Lpdata\@: 256 .string "\string" 257 .previous 258 259 movem.l %d0/%d1/%a0/%a1,-(%sp) 260 .if \bit+1 261 #if 0 262 moveq #\bit,%d0 263 andw #7,%d0 264 btst %d0,fp_debugprint+((31-\bit)/8) 265 #else 266 btst #\bit,fp_debugprint+((31-\bit)/8) 267 #endif 268 jeq .Lpskip\@ 269 .endif 270 movestack \nr,\arg1,\arg2,\arg3,\arg4,\arg5 271 pea .Lpdata\@ 272 jsr printk 273 lea ((\nr+1)*4,%sp),%sp 274 .Lpskip\@: 275 movem.l (%sp)+,%d0/%d1/%a0/%a1 276 #endif 277 .endm 278 279 .macro printx bit,fp 280 #ifdef FPU_EMU_DEBUG 281 movem.l %d0/%a0,-(%sp) 282 lea \fp,%a0 283 #if 0 284 moveq #'+',%d0 285 tst.w (%a0) 286 jeq .Lx1\@ 287 moveq #'-',%d0 288 .Lx1\@: printf \bit," %c",1,%d0 289 move.l (4,%a0),%d0 290 bclr #31,%d0 291 jne .Lx2\@ 292 printf \bit,"0." 293 jra .Lx3\@ 294 .Lx2\@: printf \bit,"1." 295 .Lx3\@: printf \bit,"%08x%08x",2,%d0,%a0@(8) 296 move.w (2,%a0),%d0 297 ext.l %d0 298 printf \bit,"E%04x",1,%d0 299 #else 300 printf \bit," %08x%08x%08x",3,%a0@,%a0@(4),%a0@(8) 301 #endif 302 movem.l (%sp)+,%d0/%a0 303 #endif 304 .endm 305 306 .macro debug instr,args 307 #ifdef FPU_EMU_DEBUG 308 \instr \args 309 #endif 310 .endm 311 312 313 #endif /* __ASSEMBLY__ */ 314 315 #endif /* _ASM_M68K_SETUP_H */ 316