diff -r linux-sharp-6000/arch/arm/nwfpe/ChangeLog linux-sharp-6000+nwfpe/arch/arm/nwfpe/ChangeLog 0a1,8 > 2003-03-22 Ralph Siemsen > * Reformat all but softfloat files to get a consistent coding style. > Used "indent -kr -i8 -ts8 -sob -l132 -ss" and a few manual fixups. > * Removed dead code and fixed function protypes to match definitions. > * Consolidated use of (opcode && MASK_ARITHMETIC_OPCODE) >> 20. > * Make 80-bit precision a compile-time option. (1%) > * Only initialize FPE state once in repeat-FP situations. (6%) > diff -r linux-sharp-6000/arch/arm/nwfpe/Makefile linux-sharp-6000+nwfpe/arch/arm/nwfpe/Makefile 21c21,25 < single_cpdo.o double_cpdo.o extended_cpdo.o --- > single_cpdo.o double_cpdo.o > > ifeq ($(CONFIG_FPE_NWFPE_XP),y) > nwfpe-objs += extended_cpdo.o > endif diff -r linux-sharp-6000/arch/arm/nwfpe/double_cpdo.c linux-sharp-6000+nwfpe/arch/arm/nwfpe/double_cpdo.c 25a26,30 > union float64_components { > float64 f64; > unsigned int i[2]; > }; > 35,36c40,41 < float64 float64_pow(float64 rFn,float64 rFm); < float64 float64_pol(float64 rFn,float64 rFm); --- > float64 float64_pow(float64 rFn, float64 rFm); > float64 float64_pol(float64 rFn, float64 rFm); 38c43 < unsigned int DoubleCPDO(const unsigned int opcode) --- > static float64 float64_rsf(float64 rFn, float64 rFm) 40,223c45 < FPA11 *fpa11 = GET_FPA11(); < float64 rFm, rFn; < unsigned int Fd, Fm, Fn, nRc = 1; < < //printk("DoubleCPDO(0x%08x)\n",opcode); < < Fm = getFm(opcode); < if (CONSTANT_FM(opcode)) < { < rFm = getDoubleConstant(Fm); < } < else < { < switch (fpa11->fType[Fm]) < { < case typeSingle: < rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle); < break; < < case typeDouble: < rFm = fpa11->fpreg[Fm].fDouble; < break; < < case typeExtended: < // !! patb < //printk("not implemented! why not?\n"); < //!! ScottB < // should never get here, if extended involved < // then other operand should be promoted then < // ExtendedCPDO called. < break; < < default: return 0; < } < } < < if (!MONADIC_INSTRUCTION(opcode)) < { < Fn = getFn(opcode); < switch (fpa11->fType[Fn]) < { < case typeSingle: < rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle); < break; < < case typeDouble: < rFn = fpa11->fpreg[Fn].fDouble; < break; < < default: return 0; < } < } < < Fd = getFd(opcode); < /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */ < switch (opcode & MASK_ARITHMETIC_OPCODE) < { < /* dyadic opcodes */ < case ADF_CODE: < fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm); < break; < < case MUF_CODE: < case FML_CODE: < fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm); < break; < < case SUF_CODE: < fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm); < break; < < case RSF_CODE: < fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn); < break; < < case DVF_CODE: < case FDV_CODE: < fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm); < break; < < case RDF_CODE: < case FRD_CODE: < fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn); < break; < < #if 0 < case POW_CODE: < fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm); < break; < < case RPW_CODE: < fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn); < break; < #endif < < case RMF_CODE: < fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm); < break; < < #if 0 < case POL_CODE: < fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm); < break; < #endif < < /* monadic opcodes */ < case MVF_CODE: < fpa11->fpreg[Fd].fDouble = rFm; < break; < < case MNF_CODE: < { < unsigned int *p = (unsigned int*)&rFm; < p[1] ^= 0x80000000; < fpa11->fpreg[Fd].fDouble = rFm; < } < break; < < case ABS_CODE: < { < unsigned int *p = (unsigned int*)&rFm; < p[1] &= 0x7fffffff; < fpa11->fpreg[Fd].fDouble = rFm; < } < break; < < case RND_CODE: < case URD_CODE: < fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm); < break; < < case SQT_CODE: < fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm); < break; < < #if 0 < case LOG_CODE: < fpa11->fpreg[Fd].fDouble = float64_log(rFm); < break; < < case LGN_CODE: < fpa11->fpreg[Fd].fDouble = float64_ln(rFm); < break; < < case EXP_CODE: < fpa11->fpreg[Fd].fDouble = float64_exp(rFm); < break; < < case SIN_CODE: < fpa11->fpreg[Fd].fDouble = float64_sin(rFm); < break; < < case COS_CODE: < fpa11->fpreg[Fd].fDouble = float64_cos(rFm); < break; < < case TAN_CODE: < fpa11->fpreg[Fd].fDouble = float64_tan(rFm); < break; < < case ASN_CODE: < fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm); < break; < < case ACS_CODE: < fpa11->fpreg[Fd].fDouble = float64_arccos(rFm); < break; < < case ATN_CODE: < fpa11->fpreg[Fd].fDouble = float64_arctan(rFm); < break; < #endif < < case NRM_CODE: < break; < < default: < { < nRc = 0; < } < } < < if (0 != nRc) fpa11->fType[Fd] = typeDouble; < return nRc; --- > return float64_sub(rFm, rFn); 226,227c48 < #if 0 < float64 float64_exp(float64 rFm) --- > static float64 float64_rdv(float64 rFn, float64 rFm) 229,230c50 < return rFm; < //series --- > return float64_div(rFm, rFn); 233,237c53,60 < float64 float64_ln(float64 rFm) < { < return rFm; < //series < } --- > static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = { > [ADF_CODE >> 20] = float64_add, > [MUF_CODE >> 20] = float64_mul, > [SUF_CODE >> 20] = float64_sub, > [RSF_CODE >> 20] = float64_rsf, > [DVF_CODE >> 20] = float64_div, > [RDF_CODE >> 20] = float64_rdv, > [RMF_CODE >> 20] = float64_rem, 239,243c62,66 < float64 float64_sin(float64 rFm) < { < return rFm; < //series < } --- > /* strictly, these opcodes should not be implemented */ > [FML_CODE >> 20] = float64_mul, > [FDV_CODE >> 20] = float64_div, > [FRD_CODE >> 20] = float64_rdv, > }; 245c68 < float64 float64_cos(float64 rFm) --- > static float64 float64_mvf(float64 rFm) 247,248c70 < return rFm; < //series --- > return rFm; 251,252c73 < #if 0 < float64 float64_arcsin(float64 rFm) --- > static float64 float64_mnf(float64 rFm) 254,255c75 < //series < } --- > union float64_components u; 257,261c77,78 < float64 float64_arctan(float64 rFm) < { < //series < } < #endif --- > u.f64 = rFm; > u.i[1] ^= 0x80000000; 263,265c80 < float64 float64_log(float64 rFm) < { < return float64_div(float64_ln(rFm),getDoubleConstant(7)); --- > return u.f64; 268c83 < float64 float64_tan(float64 rFm) --- > static float64 float64_abs(float64 rFm) 270,271c85 < return float64_div(float64_sin(rFm),float64_cos(rFm)); < } --- > union float64_components u; 273,277c87,88 < float64 float64_arccos(float64 rFm) < { < return rFm; < //return float64_sub(halfPi,float64_arcsin(rFm)); < } --- > u.f64 = rFm; > u.i[1] &= 0x7fffffff; 279,281c90 < float64 float64_pow(float64 rFn,float64 rFm) < { < return float64_exp(float64_mul(rFm,float64_ln(rFn))); --- > return u.f64; 284c93,103 < float64 float64_pol(float64 rFn,float64 rFm) --- > static float64 (*const monadic_double[16])(float64 rFm) = { > [MVF_CODE >> 20] = float64_mvf, > [MNF_CODE >> 20] = float64_mnf, > [ABS_CODE >> 20] = float64_abs, > [RND_CODE >> 20] = float64_round_to_int, > [URD_CODE >> 20] = float64_round_to_int, > [SQT_CODE >> 20] = float64_sqrt, > [NRM_CODE >> 20] = float64_mvf, > }; > > unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd) 286c105,158 < return float64_arctan(float64_div(rFn,rFm)); --- > FPA11 *fpa11 = GET_FPA11(); > float64 rFm; > unsigned int Fm, opc_mask_shift; > > Fm = getFm(opcode); > if (CONSTANT_FM(opcode)) { > rFm = getDoubleConstant(Fm); > } else { > switch (fpa11->fType[Fm]) { > case typeSingle: > rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle); > break; > > case typeDouble: > rFm = fpa11->fpreg[Fm].fDouble; > break; > > default: > return 0; > } > } > > opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20; > if (!MONADIC_INSTRUCTION(opcode)) { > unsigned int Fn = getFn(opcode); > float64 rFn; > > switch (fpa11->fType[Fn]) { > case typeSingle: > rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle); > break; > > case typeDouble: > rFn = fpa11->fpreg[Fn].fDouble; > break; > > default: > return 0; > } > > if (dyadic_double[opc_mask_shift]) { > rFd->fDouble = dyadic_double[opc_mask_shift](rFn, rFm); > } else { > return 0; > } > } else { > if (monadic_double[opc_mask_shift]) { > rFd->fDouble = monadic_double[opc_mask_shift](rFm); > } else { > return 0; > } > } > > return 1; 288d159 < #endif diff -r linux-sharp-6000/arch/arm/nwfpe/entry.S linux-sharp-6000+nwfpe/arch/arm/nwfpe/entry.S 73,78c73,81 < mov r4, lr @ save the failure-return addresses < mov sl, sp @ we access the registers via 'sl' < < ldr r5, [sp, #60] @ get contents of PC; < sub r8, r5, #4 < .Lx2: ldrt r0, [r8] @ get actual instruction into r0 --- > mov r4, lr @ save the failure-return addresses > ldr ip, [r10, #112] @ get init_flag > mov sl, sp @ we access the registers via 'sl' > > ldr r5, [sp, #60] @ get contents of PC; > cmp ip, #0 > bleq nwfpe_init_fpa > sub r8, r5, #4 > .Lx1: ldrt r0, [r8] @ get actual instruction into r0 80,82c83,85 < bl EmulateAll @ emulate the instruction < cmp r0, #0 @ was emulation successful < moveq pc, r4 @ no, return failure --- > bl EmulateAll @ emulate the instruction > cmp r0, #0 @ was emulation successful > moveq pc, r4 @ no, return failure 85c88 < .Lx1: ldrt r6, [r5], #4 @ get the next instruction and --- > .Lx2: ldrt r6, [r5], #4 @ get the next instruction and 88,105c91,108 < and r2, r6, #0x0F000000 @ test for FP insns < teq r2, #0x0C000000 < teqne r2, #0x0D000000 < teqne r2, #0x0E000000 < movne pc, r9 @ return ok if not a fp insn < < str r5, [sp, #60] @ update PC copy in regs < < mov r0, r6 @ save a copy < ldr r1, [sp, #64] @ fetch the condition codes < bl checkCondition @ check the condition < cmp r0, #0 @ r0 = 0 ==> condition failed < < @ if condition code failed to match, next insn < beq next @ get the next instruction; < < mov r0, r6 @ prepare for EmulateAll() < b emulate @ if r0 != 0, goto EmulateAll --- > and r2, r6, #0x0F000000 @ test for FP insns > teq r2, #0x0C000000 > teqne r2, #0x0D000000 > teqne r2, #0x0E000000 > movne pc, r9 @ return ok if not a fp insn > > str r5, [sp, #60] @ update PC copy in regs > > mov r0, r6 @ save a copy > ldr r1, [sp, #64] @ fetch the condition codes > bl checkCondition @ check the condition > cmp r0, #0 @ r0 = 0 ==> condition failed > > @ if condition code failed to match, next insn > beq next @ get the next instruction; > > mov r0, r6 @ prepare for EmulateAll() > b emulate @ if r0 != 0, goto EmulateAll diff -r linux-sharp-6000/arch/arm/nwfpe/entry26.S linux-sharp-6000+nwfpe/arch/arm/nwfpe/entry26.S 98c98 < --- > diff -r linux-sharp-6000/arch/arm/nwfpe/extended_cpdo.c linux-sharp-6000+nwfpe/arch/arm/nwfpe/extended_cpdo.c 35,36c35,36 < floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm); < floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm); --- > floatx80 floatx80_pow(floatx80 rFn, floatx80 rFm); > floatx80 floatx80_pol(floatx80 rFn, floatx80 rFm); 38c38 < unsigned int ExtendedCPDO(const unsigned int opcode) --- > static floatx80 floatx80_rsf(floatx80 rFn, floatx80 rFm) 40,215c40 < FPA11 *fpa11 = GET_FPA11(); < floatx80 rFm, rFn; < unsigned int Fd, Fm, Fn, nRc = 1; < < //printk("ExtendedCPDO(0x%08x)\n",opcode); < < Fm = getFm(opcode); < if (CONSTANT_FM(opcode)) < { < rFm = getExtendedConstant(Fm); < } < else < { < switch (fpa11->fType[Fm]) < { < case typeSingle: < rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle); < break; < < case typeDouble: < rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble); < break; < < case typeExtended: < rFm = fpa11->fpreg[Fm].fExtended; < break; < < default: return 0; < } < } < < if (!MONADIC_INSTRUCTION(opcode)) < { < Fn = getFn(opcode); < switch (fpa11->fType[Fn]) < { < case typeSingle: < rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); < break; < < case typeDouble: < rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); < break; < < case typeExtended: < rFn = fpa11->fpreg[Fn].fExtended; < break; < < default: return 0; < } < } < < Fd = getFd(opcode); < switch (opcode & MASK_ARITHMETIC_OPCODE) < { < /* dyadic opcodes */ < case ADF_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_add(rFn,rFm); < break; < < case MUF_CODE: < case FML_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_mul(rFn,rFm); < break; < < case SUF_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_sub(rFn,rFm); < break; < < case RSF_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_sub(rFm,rFn); < break; < < case DVF_CODE: < case FDV_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_div(rFn,rFm); < break; < < case RDF_CODE: < case FRD_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_div(rFm,rFn); < break; < < #if 0 < case POW_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_pow(rFn,rFm); < break; < < case RPW_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_pow(rFm,rFn); < break; < #endif < < case RMF_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_rem(rFn,rFm); < break; < < #if 0 < case POL_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_pol(rFn,rFm); < break; < #endif < < /* monadic opcodes */ < case MVF_CODE: < fpa11->fpreg[Fd].fExtended = rFm; < break; < < case MNF_CODE: < rFm.high ^= 0x8000; < fpa11->fpreg[Fd].fExtended = rFm; < break; < < case ABS_CODE: < rFm.high &= 0x7fff; < fpa11->fpreg[Fd].fExtended = rFm; < break; < < case RND_CODE: < case URD_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_round_to_int(rFm); < break; < < case SQT_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_sqrt(rFm); < break; < < #if 0 < case LOG_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_log(rFm); < break; < < case LGN_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_ln(rFm); < break; < < case EXP_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_exp(rFm); < break; < < case SIN_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_sin(rFm); < break; < < case COS_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_cos(rFm); < break; < < case TAN_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_tan(rFm); < break; < < case ASN_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_arcsin(rFm); < break; < < case ACS_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_arccos(rFm); < break; < < case ATN_CODE: < fpa11->fpreg[Fd].fExtended = floatx80_arctan(rFm); < break; < #endif < < case NRM_CODE: < break; < < default: < { < nRc = 0; < } < } < < if (0 != nRc) fpa11->fType[Fd] = typeExtended; < return nRc; --- > return floatx80_sub(rFm, rFn); 218,219c43 < #if 0 < floatx80 floatx80_exp(floatx80 Fm) --- > static floatx80 floatx80_rdv(floatx80 rFn, floatx80 rFm) 221c45 < //series --- > return floatx80_div(rFm, rFn); 224,227c48,55 < floatx80 floatx80_ln(floatx80 Fm) < { < //series < } --- > static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = { > [ADF_CODE >> 20] = floatx80_add, > [MUF_CODE >> 20] = floatx80_mul, > [SUF_CODE >> 20] = floatx80_sub, > [RSF_CODE >> 20] = floatx80_rsf, > [DVF_CODE >> 20] = floatx80_div, > [RDF_CODE >> 20] = floatx80_rdv, > [RMF_CODE >> 20] = floatx80_rem, 229,232c57,61 < floatx80 floatx80_sin(floatx80 rFm) < { < //series < } --- > /* strictly, these opcodes should not be implemented */ > [FML_CODE >> 20] = floatx80_mul, > [FDV_CODE >> 20] = floatx80_div, > [FRD_CODE >> 20] = floatx80_rdv, > }; 234c63 < floatx80 floatx80_cos(floatx80 rFm) --- > static floatx80 floatx80_mvf(floatx80 rFm) 236c65 < //series --- > return rFm; 239c68 < floatx80 floatx80_arcsin(floatx80 rFm) --- > static floatx80 floatx80_mnf(floatx80 rFm) 241c70,71 < //series --- > rFm.high ^= 0x8000; > return rFm; 244c74 < floatx80 floatx80_arctan(floatx80 rFm) --- > static floatx80 floatx80_abs(floatx80 rFm) 246c76,77 < //series --- > rFm.high &= 0x7fff; > return rFm; 249,252c80,88 < floatx80 floatx80_log(floatx80 rFm) < { < return floatx80_div(floatx80_ln(rFm),getExtendedConstant(7)); < } --- > static floatx80 (*const monadic_extended[16])(floatx80 rFm) = { > [MVF_CODE >> 20] = floatx80_mvf, > [MNF_CODE >> 20] = floatx80_mnf, > [ABS_CODE >> 20] = floatx80_abs, > [RND_CODE >> 20] = floatx80_round_to_int, > [URD_CODE >> 20] = floatx80_round_to_int, > [SQT_CODE >> 20] = floatx80_sqrt, > [NRM_CODE >> 20] = floatx80_mvf, > }; 254c90 < floatx80 floatx80_tan(floatx80 rFm) --- > unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd) 256,257c92,94 < return floatx80_div(floatx80_sin(rFm),floatx80_cos(rFm)); < } --- > FPA11 *fpa11 = GET_FPA11(); > floatx80 rFm; > unsigned int Fm, opc_mask_shift; 259,262c96,103 < floatx80 floatx80_arccos(floatx80 rFm) < { < //return floatx80_sub(halfPi,floatx80_arcsin(rFm)); < } --- > Fm = getFm(opcode); > if (CONSTANT_FM(opcode)) { > rFm = getExtendedConstant(Fm); > } else { > switch (fpa11->fType[Fm]) { > case typeSingle: > rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle); > break; 264,267c105,107 < floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm) < { < return floatx80_exp(floatx80_mul(rFm,floatx80_ln(rFn))); < } --- > case typeDouble: > rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble); > break; 269,271c109,153 < floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm) < { < return floatx80_arctan(floatx80_div(rFn,rFm)); --- > case typeExtended: > rFm = fpa11->fpreg[Fm].fExtended; > break; > > default: > return 0; > } > } > > opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20; > if (!MONADIC_INSTRUCTION(opcode)) { > unsigned int Fn = getFn(opcode); > floatx80 rFn; > > switch (fpa11->fType[Fn]) { > case typeSingle: > rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); > break; > > case typeDouble: > rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); > break; > > case typeExtended: > rFn = fpa11->fpreg[Fn].fExtended; > break; > > default: > return 0; > } > > if (dyadic_extended[opc_mask_shift]) { > rFd->fExtended = dyadic_extended[opc_mask_shift](rFn, rFm); > } else { > return 0; > } > } else { > if (monadic_extended[opc_mask_shift]) { > rFd->fExtended = monadic_extended[opc_mask_shift](rFm); > } else { > return 0; > } > } > > return 1; 273d154 < #endif diff -r linux-sharp-6000/arch/arm/nwfpe/fpa11.c linux-sharp-6000+nwfpe/arch/arm/nwfpe/fpa11.c 3a4 > (c) Philip Blundell, 2001 23d23 < 39,54c39,48 < int i; < FPA11 *fpa11 = GET_FPA11(); < < /* initialize the register type array */ < for (i=0;i<=7;i++) < { < fpa11->fType[i] = typeNone; < } < < /* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */ < fpa11->fpsr = FP_EMULATOR | BIT_AC; < < /* FPCR: set SB, AB and DA bits, clear all others */ < #if MAINTAIN_FPCR < fpa11->fpcr = MASK_RESET; < #endif --- > int i; > FPA11 *fpa11 = GET_FPA11(); > > /* initialize the register type array */ > for (i = 0; i <= 7; i++) { > fpa11->fType[i] = typeNone; > } > > /* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */ > fpa11->fpsr = FP_EMULATOR | BIT_AC; 59,93c53,70 < #if MAINTAIN_FPCR < FPA11 *fpa11 = GET_FPA11(); < fpa11->fpcr &= ~MASK_ROUNDING_MODE; < #endif < switch (opcode & MASK_ROUNDING_MODE) < { < default: < case ROUND_TO_NEAREST: < float_rounding_mode = float_round_nearest_even; < #if MAINTAIN_FPCR < fpa11->fpcr |= ROUND_TO_NEAREST; < #endif < break; < < case ROUND_TO_PLUS_INFINITY: < float_rounding_mode = float_round_up; < #if MAINTAIN_FPCR < fpa11->fpcr |= ROUND_TO_PLUS_INFINITY; < #endif < break; < < case ROUND_TO_MINUS_INFINITY: < float_rounding_mode = float_round_down; < #if MAINTAIN_FPCR < fpa11->fpcr |= ROUND_TO_MINUS_INFINITY; < #endif < break; < < case ROUND_TO_ZERO: < float_rounding_mode = float_round_to_zero; < #if MAINTAIN_FPCR < fpa11->fpcr |= ROUND_TO_ZERO; < #endif < break; < } --- > switch (opcode & MASK_ROUNDING_MODE) { > default: > case ROUND_TO_NEAREST: > float_rounding_mode = float_round_nearest_even; > break; > > case ROUND_TO_PLUS_INFINITY: > float_rounding_mode = float_round_up; > break; > > case ROUND_TO_MINUS_INFINITY: > float_rounding_mode = float_round_down; > break; > > case ROUND_TO_ZERO: > float_rounding_mode = float_round_to_zero; > break; > } 98,126c75,92 < #if MAINTAIN_FPCR < FPA11 *fpa11 = GET_FPA11(); < fpa11->fpcr &= ~MASK_ROUNDING_PRECISION; < #endif < switch (opcode & MASK_ROUNDING_PRECISION) < { < case ROUND_SINGLE: < floatx80_rounding_precision = 32; < #if MAINTAIN_FPCR < fpa11->fpcr |= ROUND_SINGLE; < #endif < break; < < case ROUND_DOUBLE: < floatx80_rounding_precision = 64; < #if MAINTAIN_FPCR < fpa11->fpcr |= ROUND_DOUBLE; < #endif < break; < < case ROUND_EXTENDED: < floatx80_rounding_precision = 80; < #if MAINTAIN_FPCR < fpa11->fpcr |= ROUND_EXTENDED; < #endif < break; < < default: floatx80_rounding_precision = 80; < } --- > #ifdef CONFIG_FPE_NWFPE_XP > switch (opcode & MASK_ROUNDING_PRECISION) { > case ROUND_SINGLE: > floatx80_rounding_precision = 32; > break; > > case ROUND_DOUBLE: > floatx80_rounding_precision = 64; > break; > > case ROUND_EXTENDED: > floatx80_rounding_precision = 80; > break; > > default: > floatx80_rounding_precision = 80; > } > #endif 129,130c95 < /* Emulate the instruction in the opcode. */ < unsigned int EmulateAll(unsigned int opcode) --- > void nwfpe_init_fpa(void) 132,174c97,104 < unsigned int nRc = 0; < unsigned long flags; < FPA11 *fpa11; < save_flags(flags); sti(); < < fpa11 = GET_FPA11(); < < if (fpa11->initflag == 0) /* good place for __builtin_expect */ < { < resetFPA11(); < SetRoundingMode(ROUND_TO_NEAREST); < SetRoundingPrecision(ROUND_EXTENDED); < fpa11->initflag = 1; < } < < if (TEST_OPCODE(opcode,MASK_CPRT)) < { < /* Emulate conversion opcodes. */ < /* Emulate register transfer opcodes. */ < /* Emulate comparison opcodes. */ < nRc = EmulateCPRT(opcode); < } < else if (TEST_OPCODE(opcode,MASK_CPDO)) < { < /* Emulate monadic arithmetic opcodes. */ < /* Emulate dyadic arithmetic opcodes. */ < nRc = EmulateCPDO(opcode); < } < else if (TEST_OPCODE(opcode,MASK_CPDT)) < { < /* Emulate load/store opcodes. */ < /* Emulate load/store multiple opcodes. */ < nRc = EmulateCPDT(opcode); < } < else < { < /* Invalid instruction detected. Return FALSE. */ < nRc = 0; < } < < restore_flags(flags); < < return(nRc); --- > FPA11 *fpa11 = GET_FPA11(); > #ifdef NWFPE_DEBUG > printk("NWFPE: setting up state.\n"); > #endif > resetFPA11(); > SetRoundingMode(ROUND_TO_NEAREST); > SetRoundingPrecision(ROUND_EXTENDED); > fpa11->initflag = 1; 177,178c107,108 < #if 0 < unsigned int EmulateAll1(unsigned int opcode) --- > /* Emulate the instruction in the opcode. */ > unsigned int EmulateAll(const unsigned int opcode) 180,213c110,111 < switch ((opcode >> 24) & 0xf) < { < case 0xc: < case 0xd: < if ((opcode >> 20) & 0x1) < { < switch ((opcode >> 8) & 0xf) < { < case 0x1: return PerformLDF(opcode); break; < case 0x2: return PerformLFM(opcode); break; < default: return 0; < } < } < else < { < switch ((opcode >> 8) & 0xf) < { < case 0x1: return PerformSTF(opcode); break; < case 0x2: return PerformSFM(opcode); break; < default: return 0; < } < } < break; < < case 0xe: < if (opcode & 0x10) < return EmulateCPDO(opcode); < else < return EmulateCPRT(opcode); < break; < < default: return 0; < } < } --- > #ifdef NWFPE_DEBUG > printk("NWFPE: emulating opcode %08x\n", opcode); 215a114,131 > if (TEST_OPCODE(opcode, MASK_CPRT)) { > /* Emulate conversion opcodes. */ > /* Emulate register transfer opcodes. */ > /* Emulate comparison opcodes. */ > return EmulateCPRT(opcode); > } else if (TEST_OPCODE(opcode, MASK_CPDO)) { > /* Emulate monadic arithmetic opcodes. */ > /* Emulate dyadic arithmetic opcodes. */ > return EmulateCPDO(opcode); > } else if (TEST_OPCODE(opcode, MASK_CPDT)) { > /* Emulate load/store opcodes. */ > /* Emulate load/store multiple opcodes. */ > return EmulateCPDT(opcode); > } > > /* Invalid instruction detected. Return FALSE. */ > return 0; > } diff -r linux-sharp-6000/arch/arm/nwfpe/fpa11.h linux-sharp-6000+nwfpe/arch/arm/nwfpe/fpa11.h 40a41 > #include "milieu.h" 52,54c53,59 < floatx80 fExtended; < float64 fDouble; < float32 fSingle; --- > float32 fSingle; > float64 fDouble; > #ifdef CONFIG_FPE_NWFPE_XP > floatx80 fExtended; > #else > int padding[3]; > #endif 71,81c76,86 < /* 0 */ FPREG fpreg[8]; /* 8 floating point registers */ < /* 96 */ FPSR fpsr; /* floating point status register */ < /* 100 */ FPCR fpcr; /* floating point control register */ < /* 104 */ unsigned char fType[8]; /* type of floating point value held in < floating point registers. One of none < single, double or extended. */ < /* 112 */ int initflag; /* this is special. The kernel guarantees < to set it to 0 when a thread is launched, < so we can use it to detect whether this < instance of the emulator needs to be < initialised. */ --- > /* 0 */ FPREG fpreg[8]; /* 8 floating point registers */ > /* 96 */ FPSR fpsr; /* floating point status register */ > /* 100 */ FPCR fpcr; /* floating point control register */ > /* 104 */ unsigned char fType[8]; /* type of floating point value held in > floating point registers. One of > none, single, double or extended. */ > /* 112 */ int initflag; /* this is special. The kernel guarantees > to set it to 0 when a thread is launched, > so we can use it to detect whether this > instance of the emulator needs to be > initialised. */ diff -r linux-sharp-6000/arch/arm/nwfpe/fpa11.inl linux-sharp-6000+nwfpe/arch/arm/nwfpe/fpa11.inl 27,28c27,28 < FPA11 *fpa11 = GET_FPA11(); < return(fpa11->fpsr); --- > FPA11 *fpa11 = GET_FPA11(); > return (fpa11->fpsr); 33,35c33,35 < FPA11 *fpa11 = GET_FPA11(); < /* the sysid byte in the status register is readonly */ < fpa11->fpsr = (fpa11->fpsr & MASK_SYSID) | (reg & ~MASK_SYSID); --- > FPA11 *fpa11 = GET_FPA11(); > /* the sysid byte in the status register is readonly */ > fpa11->fpsr = (fpa11->fpsr & MASK_SYSID) | (reg & ~MASK_SYSID); 41,43c41,43 < FPA11 *fpa11 = GET_FPA11(); < /* clear SB, AB and DA bits before returning FPCR */ < return(fpa11->fpcr & ~MASK_RFC); --- > FPA11 *fpa11 = GET_FPA11(); > /* clear SB, AB and DA bits before returning FPCR */ > return (fpa11->fpcr & ~MASK_RFC); 48,50c48,50 < FPA11 *fpa11 = GET_FPA11(); < fpa11->fpcr &= ~MASK_WFC; /* clear SB, AB and DA bits */ < fpa11->fpcr |= (reg & MASK_WFC); /* write SB, AB and DA bits */ --- > FPA11 *fpa11 = GET_FPA11(); > fpa11->fpcr &= ~MASK_WFC; /* clear SB, AB and DA bits */ > fpa11->fpcr |= (reg & MASK_WFC); /* write SB, AB and DA bits */ diff -r linux-sharp-6000/arch/arm/nwfpe/fpa11_cpdo.c linux-sharp-6000+nwfpe/arch/arm/nwfpe/fpa11_cpdo.c 3a4 > (c) Philip Blundell, 2001 25,27c26,28 < unsigned int SingleCPDO(const unsigned int opcode); < unsigned int DoubleCPDO(const unsigned int opcode); < unsigned int ExtendedCPDO(const unsigned int opcode); --- > unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd); > unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd); > unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd); 31,116c32,130 < FPA11 *fpa11 = GET_FPA11(); < unsigned int Fd, nType, nDest, nRc = 1; < < //printk("EmulateCPDO(0x%08x)\n",opcode); < < /* Get the destination size. If not valid let Linux perform < an invalid instruction trap. */ < nDest = getDestinationSize(opcode); < if (typeNone == nDest) return 0; < < SetRoundingMode(opcode); < < /* Compare the size of the operands in Fn and Fm. < Choose the largest size and perform operations in that size, < in order to make use of all the precision of the operands. < If Fm is a constant, we just grab a constant of a size < matching the size of the operand in Fn. */ < if (MONADIC_INSTRUCTION(opcode)) < nType = nDest; < else < nType = fpa11->fType[getFn(opcode)]; < < if (!CONSTANT_FM(opcode)) < { < register unsigned int Fm = getFm(opcode); < if (nType < fpa11->fType[Fm]) < { < nType = fpa11->fType[Fm]; < } < } < < switch (nType) < { < case typeSingle : nRc = SingleCPDO(opcode); break; < case typeDouble : nRc = DoubleCPDO(opcode); break; < case typeExtended : nRc = ExtendedCPDO(opcode); break; < default : nRc = 0; < } < < /* If the operation succeeded, check to see if the result in the < destination register is the correct size. If not force it < to be. */ < Fd = getFd(opcode); < nType = fpa11->fType[Fd]; < if ((0 != nRc) && (nDest != nType)) < { < switch (nDest) < { < case typeSingle: < { < if (typeDouble == nType) < fpa11->fpreg[Fd].fSingle = < float64_to_float32(fpa11->fpreg[Fd].fDouble); < else < fpa11->fpreg[Fd].fSingle = < floatx80_to_float32(fpa11->fpreg[Fd].fExtended); < } < break; < < case typeDouble: < { < if (typeSingle == nType) < fpa11->fpreg[Fd].fDouble = < float32_to_float64(fpa11->fpreg[Fd].fSingle); < else < fpa11->fpreg[Fd].fDouble = < floatx80_to_float64(fpa11->fpreg[Fd].fExtended); < } < break; < < case typeExtended: < { < if (typeSingle == nType) < fpa11->fpreg[Fd].fExtended = < float32_to_floatx80(fpa11->fpreg[Fd].fSingle); < else < fpa11->fpreg[Fd].fExtended = < float64_to_floatx80(fpa11->fpreg[Fd].fDouble); < } < break; < } < < fpa11->fType[Fd] = nDest; < } < < return nRc; --- > FPA11 *fpa11 = GET_FPA11(); > FPREG *rFd; > unsigned int nType, nDest, nRc; > > /* Get the destination size. If not valid let Linux perform > an invalid instruction trap. */ > nDest = getDestinationSize(opcode); > if (typeNone == nDest) > return 0; > > SetRoundingMode(opcode); > > /* Compare the size of the operands in Fn and Fm. > Choose the largest size and perform operations in that size, > in order to make use of all the precision of the operands. > If Fm is a constant, we just grab a constant of a size > matching the size of the operand in Fn. */ > if (MONADIC_INSTRUCTION(opcode)) > nType = nDest; > else > nType = fpa11->fType[getFn(opcode)]; > > if (!CONSTANT_FM(opcode)) { > register unsigned int Fm = getFm(opcode); > if (nType < fpa11->fType[Fm]) { > nType = fpa11->fType[Fm]; > } > } > > rFd = &fpa11->fpreg[getFd(opcode)]; > > switch (nType) { > case typeSingle: > nRc = SingleCPDO(opcode, rFd); > break; > case typeDouble: > nRc = DoubleCPDO(opcode, rFd); > break; > #ifdef CONFIG_FPE_NWFPE_XP > case typeExtended: > nRc = ExtendedCPDO(opcode, rFd); > break; > #endif > default: > nRc = 0; > } > > /* The CPDO functions used to always set the destination type > to be the same as their working size. */ > > if (nRc != 0) { > /* If the operation succeeded, check to see if the result in the > destination register is the correct size. If not force it > to be. */ > > fpa11->fType[getFd(opcode)] = nDest; > > #ifdef CONFIG_FPE_NWFPE_XP > if (nDest != nType) { > switch (nDest) { > case typeSingle: > { > if (typeDouble == nType) > rFd->fSingle = float64_to_float32(rFd->fDouble); > else > rFd->fSingle = floatx80_to_float32(rFd->fExtended); > } > break; > > case typeDouble: > { > if (typeSingle == nType) > rFd->fDouble = float32_to_float64(rFd->fSingle); > else > rFd->fDouble = floatx80_to_float64(rFd->fExtended); > } > break; > > case typeExtended: > { > if (typeSingle == nType) > rFd->fExtended = float32_to_floatx80(rFd->fSingle); > else > rFd->fExtended = float64_to_floatx80(rFd->fDouble); > } > break; > } > } > #else > if (nDest != nType) { > if (nDest == typeSingle) > rFd->fSingle = float64_to_float32(rFd->fDouble); > else > rFd->fDouble = float32_to_float64(rFd->fSingle); > } > #endif > } > > return nRc; diff -r linux-sharp-6000/arch/arm/nwfpe/fpa11_cpdt.c linux-sharp-6000+nwfpe/arch/arm/nwfpe/fpa11_cpdt.c 4c4 < (c) Philip Blundell, 1998 --- > (c) Philip Blundell, 1998, 2001 31,32c31 < static inline < void loadSingle(const unsigned int Fn,const unsigned int *pMem) --- > static inline void loadSingle(const unsigned int Fn, const unsigned int *pMem) 34,192c33,35 < FPA11 *fpa11 = GET_FPA11(); < fpa11->fType[Fn] = typeSingle; < get_user(fpa11->fpreg[Fn].fSingle, pMem); < } < < static inline < void loadDouble(const unsigned int Fn,const unsigned int *pMem) < { < FPA11 *fpa11 = GET_FPA11(); < unsigned int *p; < p = (unsigned int*)&fpa11->fpreg[Fn].fDouble; < fpa11->fType[Fn] = typeDouble; < get_user(p[0], &pMem[1]); < get_user(p[1], &pMem[0]); /* sign & exponent */ < } < < static inline < void loadExtended(const unsigned int Fn,const unsigned int *pMem) < { < FPA11 *fpa11 = GET_FPA11(); < unsigned int *p; < p = (unsigned int*)&fpa11->fpreg[Fn].fExtended; < fpa11->fType[Fn] = typeExtended; < get_user(p[0], &pMem[0]); /* sign & exponent */ < get_user(p[1], &pMem[2]); /* ls bits */ < get_user(p[2], &pMem[1]); /* ms bits */ < } < < static inline < void loadMultiple(const unsigned int Fn,const unsigned int *pMem) < { < FPA11 *fpa11 = GET_FPA11(); < register unsigned int *p; < unsigned long x; < < p = (unsigned int*)&(fpa11->fpreg[Fn]); < get_user(x, &pMem[0]); < fpa11->fType[Fn] = (x >> 14) & 0x00000003; < < switch (fpa11->fType[Fn]) < { < case typeSingle: < case typeDouble: < { < get_user(p[0], &pMem[2]); /* Single */ < get_user(p[1], &pMem[1]); /* double msw */ < p[2] = 0; /* empty */ < } < break; < < case typeExtended: < { < get_user(p[1], &pMem[2]); < get_user(p[2], &pMem[1]); /* msw */ < p[0] = (x & 0x80003fff); < } < break; < } < } < < static inline < void storeSingle(const unsigned int Fn,unsigned int *pMem) < { < FPA11 *fpa11 = GET_FPA11(); < float32 val; < register unsigned int *p = (unsigned int*)&val; < < switch (fpa11->fType[Fn]) < { < case typeDouble: < val = float64_to_float32(fpa11->fpreg[Fn].fDouble); < break; < < case typeExtended: < val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended); < break; < < default: val = fpa11->fpreg[Fn].fSingle; < } < < put_user(p[0], pMem); < } < < static inline < void storeDouble(const unsigned int Fn,unsigned int *pMem) < { < FPA11 *fpa11 = GET_FPA11(); < float64 val; < register unsigned int *p = (unsigned int*)&val; < < switch (fpa11->fType[Fn]) < { < case typeSingle: < val = float32_to_float64(fpa11->fpreg[Fn].fSingle); < break; < < case typeExtended: < val = floatx80_to_float64(fpa11->fpreg[Fn].fExtended); < break; < < default: val = fpa11->fpreg[Fn].fDouble; < } < put_user(p[1], &pMem[0]); /* msw */ < put_user(p[0], &pMem[1]); /* lsw */ < } < < static inline < void storeExtended(const unsigned int Fn,unsigned int *pMem) < { < FPA11 *fpa11 = GET_FPA11(); < floatx80 val; < register unsigned int *p = (unsigned int*)&val; < < switch (fpa11->fType[Fn]) < { < case typeSingle: < val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); < break; < < case typeDouble: < val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); < break; < < default: val = fpa11->fpreg[Fn].fExtended; < } < < put_user(p[0], &pMem[0]); /* sign & exp */ < put_user(p[1], &pMem[2]); < put_user(p[2], &pMem[1]); /* msw */ < } < < static inline < void storeMultiple(const unsigned int Fn,unsigned int *pMem) < { < FPA11 *fpa11 = GET_FPA11(); < register unsigned int nType, *p; < < p = (unsigned int*)&(fpa11->fpreg[Fn]); < nType = fpa11->fType[Fn]; < < switch (nType) < { < case typeSingle: < case typeDouble: < { < put_user(p[0], &pMem[2]); /* single */ < put_user(p[1], &pMem[1]); /* double msw */ < put_user(nType << 14, &pMem[0]); < } < break; < < case typeExtended: < { < put_user(p[2], &pMem[1]); /* msw */ < put_user(p[1], &pMem[2]); < put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]); < } < break; < } --- > FPA11 *fpa11 = GET_FPA11(); > fpa11->fType[Fn] = typeSingle; > get_user(fpa11->fpreg[Fn].fSingle, pMem); 195c38,167 < unsigned int PerformLDF(const unsigned int opcode) --- > static inline void loadDouble(const unsigned int Fn, const unsigned int *pMem) > { > FPA11 *fpa11 = GET_FPA11(); > unsigned int *p; > p = (unsigned int *) &fpa11->fpreg[Fn].fDouble; > fpa11->fType[Fn] = typeDouble; > get_user(p[0], &pMem[1]); > get_user(p[1], &pMem[0]); /* sign & exponent */ > } > > #ifdef CONFIG_FPE_NWFPE_XP > static inline void loadExtended(const unsigned int Fn, const unsigned int *pMem) > { > FPA11 *fpa11 = GET_FPA11(); > unsigned int *p; > p = (unsigned int *) &fpa11->fpreg[Fn].fExtended; > fpa11->fType[Fn] = typeExtended; > get_user(p[0], &pMem[0]); /* sign & exponent */ > get_user(p[1], &pMem[2]); /* ls bits */ > get_user(p[2], &pMem[1]); /* ms bits */ > } > #endif > > static inline void loadMultiple(const unsigned int Fn, const unsigned int *pMem) > { > FPA11 *fpa11 = GET_FPA11(); > register unsigned int *p; > unsigned long x; > > p = (unsigned int *) &(fpa11->fpreg[Fn]); > get_user(x, &pMem[0]); > fpa11->fType[Fn] = (x >> 14) & 0x00000003; > > switch (fpa11->fType[Fn]) { > case typeSingle: > case typeDouble: > { > get_user(p[0], &pMem[2]); /* Single */ > get_user(p[1], &pMem[1]); /* double msw */ > p[2] = 0; /* empty */ > } > break; > > #ifdef CONFIG_FPE_NWFPE_XP > case typeExtended: > { > get_user(p[1], &pMem[2]); > get_user(p[2], &pMem[1]); /* msw */ > p[0] = (x & 0x80003fff); > } > break; > #endif > } > } > > static inline void storeSingle(const unsigned int Fn, unsigned int *pMem) > { > FPA11 *fpa11 = GET_FPA11(); > float32 val; > register unsigned int *p = (unsigned int *) &val; > > switch (fpa11->fType[Fn]) { > case typeDouble: > val = float64_to_float32(fpa11->fpreg[Fn].fDouble); > break; > > #ifdef CONFIG_FPE_NWFPE_XP > case typeExtended: > val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended); > break; > #endif > > default: > val = fpa11->fpreg[Fn].fSingle; > } > > put_user(p[0], pMem); > } > > static inline void storeDouble(const unsigned int Fn, unsigned int *pMem) > { > FPA11 *fpa11 = GET_FPA11(); > float64 val; > register unsigned int *p = (unsigned int *) &val; > > switch (fpa11->fType[Fn]) { > case typeSingle: > val = float32_to_float64(fpa11->fpreg[Fn].fSingle); > break; > > #ifdef CONFIG_FPE_NWFPE_XP > case typeExtended: > val = floatx80_to_float64(fpa11->fpreg[Fn].fExtended); > break; > #endif > > default: > val = fpa11->fpreg[Fn].fDouble; > } > put_user(p[1], &pMem[0]); /* msw */ > put_user(p[0], &pMem[1]); /* lsw */ > } > > #ifdef CONFIG_FPE_NWFPE_XP > static inline void storeExtended(const unsigned int Fn, unsigned int *pMem) > { > FPA11 *fpa11 = GET_FPA11(); > floatx80 val; > register unsigned int *p = (unsigned int *) &val; > > switch (fpa11->fType[Fn]) { > case typeSingle: > val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); > break; > > case typeDouble: > val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); > break; > > default: > val = fpa11->fpreg[Fn].fExtended; > } > > put_user(p[0], &pMem[0]); /* sign & exp */ > put_user(p[1], &pMem[2]); > put_user(p[2], &pMem[1]); /* msw */ > } > #endif > > static inline void storeMultiple(const unsigned int Fn, unsigned int *pMem) 197,198c169,195 < unsigned int *pBase, *pAddress, *pFinal, nRc = 1, < write_back = WRITE_BACK(opcode); --- > FPA11 *fpa11 = GET_FPA11(); > register unsigned int nType, *p; > > p = (unsigned int *) &(fpa11->fpreg[Fn]); > nType = fpa11->fType[Fn]; > > switch (nType) { > case typeSingle: > case typeDouble: > { > put_user(p[0], &pMem[2]); /* single */ > put_user(p[1], &pMem[1]); /* double msw */ > put_user(nType << 14, &pMem[0]); > } > break; > > #ifdef CONFIG_FPE_NWFPE_XP > case typeExtended: > { > put_user(p[2], &pMem[1]); /* msw */ > put_user(p[1], &pMem[2]); > put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]); > } > break; > #endif > } > } 200c197,200 < //printk("PerformLDF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode)); --- > unsigned int PerformLDF(const unsigned int opcode) > { > unsigned int *pBase, *pAddress, *pFinal, nRc = 1, > write_back = WRITE_BACK(opcode); 202,226c202,237 < pBase = (unsigned int*)readRegister(getRn(opcode)); < if (REG_PC == getRn(opcode)) < { < pBase += 2; < write_back = 0; < } < < pFinal = pBase; < if (BIT_UP_SET(opcode)) < pFinal += getOffset(opcode); < else < pFinal -= getOffset(opcode); < < if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase; < < switch (opcode & MASK_TRANSFER_LENGTH) < { < case TRANSFER_SINGLE : loadSingle(getFd(opcode),pAddress); break; < case TRANSFER_DOUBLE : loadDouble(getFd(opcode),pAddress); break; < case TRANSFER_EXTENDED: loadExtended(getFd(opcode),pAddress); break; < default: nRc = 0; < } < < if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal); < return nRc; --- > pBase = (unsigned int *) readRegister(getRn(opcode)); > if (REG_PC == getRn(opcode)) { > pBase += 2; > write_back = 0; > } > > pFinal = pBase; > if (BIT_UP_SET(opcode)) > pFinal += getOffset(opcode); > else > pFinal -= getOffset(opcode); > > if (PREINDEXED(opcode)) > pAddress = pFinal; > else > pAddress = pBase; > > switch (opcode & MASK_TRANSFER_LENGTH) { > case TRANSFER_SINGLE: > loadSingle(getFd(opcode), pAddress); > break; > case TRANSFER_DOUBLE: > loadDouble(getFd(opcode), pAddress); > break; > #ifdef CONFIG_FPE_NWFPE_XP > case TRANSFER_EXTENDED: > loadExtended(getFd(opcode), pAddress); > break; > #endif > default: > nRc = 0; > } > > if (write_back) > writeRegister(getRn(opcode), (unsigned int) pFinal); > return nRc; 231,261c242,282 < unsigned int *pBase, *pAddress, *pFinal, nRc = 1, < write_back = WRITE_BACK(opcode); < < //printk("PerformSTF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode)); < SetRoundingMode(ROUND_TO_NEAREST); < < pBase = (unsigned int*)readRegister(getRn(opcode)); < if (REG_PC == getRn(opcode)) < { < pBase += 2; < write_back = 0; < } < < pFinal = pBase; < if (BIT_UP_SET(opcode)) < pFinal += getOffset(opcode); < else < pFinal -= getOffset(opcode); < < if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase; < < switch (opcode & MASK_TRANSFER_LENGTH) < { < case TRANSFER_SINGLE : storeSingle(getFd(opcode),pAddress); break; < case TRANSFER_DOUBLE : storeDouble(getFd(opcode),pAddress); break; < case TRANSFER_EXTENDED: storeExtended(getFd(opcode),pAddress); break; < default: nRc = 0; < } < < if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal); < return nRc; --- > unsigned int *pBase, *pAddress, *pFinal, nRc = 1, > write_back = WRITE_BACK(opcode); > > SetRoundingMode(ROUND_TO_NEAREST); > > pBase = (unsigned int *) readRegister(getRn(opcode)); > if (REG_PC == getRn(opcode)) { > pBase += 2; > write_back = 0; > } > > pFinal = pBase; > if (BIT_UP_SET(opcode)) > pFinal += getOffset(opcode); > else > pFinal -= getOffset(opcode); > > if (PREINDEXED(opcode)) > pAddress = pFinal; > else > pAddress = pBase; > > switch (opcode & MASK_TRANSFER_LENGTH) { > case TRANSFER_SINGLE: > storeSingle(getFd(opcode), pAddress); > break; > case TRANSFER_DOUBLE: > storeDouble(getFd(opcode), pAddress); > break; > #ifdef CONFIG_FPE_NWFPE_XP > case TRANSFER_EXTENDED: > storeExtended(getFd(opcode), pAddress); > break; > #endif > default: > nRc = 0; > } > > if (write_back) > writeRegister(getRn(opcode), (unsigned int) pFinal); > return nRc; 266,290c287,288 < unsigned int i, Fd, *pBase, *pAddress, *pFinal, < write_back = WRITE_BACK(opcode); < < pBase = (unsigned int*)readRegister(getRn(opcode)); < if (REG_PC == getRn(opcode)) < { < pBase += 2; < write_back = 0; < } < < pFinal = pBase; < if (BIT_UP_SET(opcode)) < pFinal += getOffset(opcode); < else < pFinal -= getOffset(opcode); < < if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase; < < Fd = getFd(opcode); < for (i=getRegisterCount(opcode);i>0;i--) < { < loadMultiple(Fd,pAddress); < pAddress += 3; Fd++; < if (Fd == 8) Fd = 0; < } --- > unsigned int i, Fd, *pBase, *pAddress, *pFinal, > write_back = WRITE_BACK(opcode); 292,293c290,318 < if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal); < return 1; --- > pBase = (unsigned int *) readRegister(getRn(opcode)); > if (REG_PC == getRn(opcode)) { > pBase += 2; > write_back = 0; > } > > pFinal = pBase; > if (BIT_UP_SET(opcode)) > pFinal += getOffset(opcode); > else > pFinal -= getOffset(opcode); > > if (PREINDEXED(opcode)) > pAddress = pFinal; > else > pAddress = pBase; > > Fd = getFd(opcode); > for (i = getRegisterCount(opcode); i > 0; i--) { > loadMultiple(Fd, pAddress); > pAddress += 3; > Fd++; > if (Fd == 8) > Fd = 0; > } > > if (write_back) > writeRegister(getRn(opcode), (unsigned int) pFinal); > return 1; 298,322c323,324 < unsigned int i, Fd, *pBase, *pAddress, *pFinal, < write_back = WRITE_BACK(opcode); < < pBase = (unsigned int*)readRegister(getRn(opcode)); < if (REG_PC == getRn(opcode)) < { < pBase += 2; < write_back = 0; < } < < pFinal = pBase; < if (BIT_UP_SET(opcode)) < pFinal += getOffset(opcode); < else < pFinal -= getOffset(opcode); < < if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase; < < Fd = getFd(opcode); < for (i=getRegisterCount(opcode);i>0;i--) < { < storeMultiple(Fd,pAddress); < pAddress += 3; Fd++; < if (Fd == 8) Fd = 0; < } --- > unsigned int i, Fd, *pBase, *pAddress, *pFinal, > write_back = WRITE_BACK(opcode); 324,325c326,354 < if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal); < return 1; --- > pBase = (unsigned int *) readRegister(getRn(opcode)); > if (REG_PC == getRn(opcode)) { > pBase += 2; > write_back = 0; > } > > pFinal = pBase; > if (BIT_UP_SET(opcode)) > pFinal += getOffset(opcode); > else > pFinal -= getOffset(opcode); > > if (PREINDEXED(opcode)) > pAddress = pFinal; > else > pAddress = pBase; > > Fd = getFd(opcode); > for (i = getRegisterCount(opcode); i > 0; i--) { > storeMultiple(Fd, pAddress); > pAddress += 3; > Fd++; > if (Fd == 8) > Fd = 0; > } > > if (write_back) > writeRegister(getRn(opcode), (unsigned int) pFinal); > return 1; 328d356 < #if 1 331c359 < unsigned int nRc = 0; --- > unsigned int nRc = 0; 333,356c361,373 < //printk("EmulateCPDT(0x%08x)\n",opcode); < < if (LDF_OP(opcode)) < { < nRc = PerformLDF(opcode); < } < else if (LFM_OP(opcode)) < { < nRc = PerformLFM(opcode); < } < else if (STF_OP(opcode)) < { < nRc = PerformSTF(opcode); < } < else if (SFM_OP(opcode)) < { < nRc = PerformSFM(opcode); < } < else < { < nRc = 0; < } < < return nRc; --- > if (LDF_OP(opcode)) { > nRc = PerformLDF(opcode); > } else if (LFM_OP(opcode)) { > nRc = PerformLFM(opcode); > } else if (STF_OP(opcode)) { > nRc = PerformSTF(opcode); > } else if (SFM_OP(opcode)) { > nRc = PerformSFM(opcode); > } else { > nRc = 0; > } > > return nRc; 358d374 < #endif diff -r linux-sharp-6000/arch/arm/nwfpe/fpa11_cprt.c linux-sharp-6000+nwfpe/arch/arm/nwfpe/fpa11_cprt.c 4c4 < (c) Philip Blundell, 1999 --- > (c) Philip Blundell, 1999, 2001 24,25d23 < #include "milieu.h" < #include "softfloat.h" 30a29 > #ifdef CONFIG_FPE_NWFPE_XP 32,33c31,33 < extern flag float64_is_nan( float64); < extern flag float32_is_nan( float32); --- > #endif > extern flag float64_is_nan(float64); > extern flag float32_is_nan(float32); 40,41c40 < static unsigned int < PerformComparison(const unsigned int opcode); --- > static unsigned int PerformComparison(const unsigned int opcode); 45,47d43 < unsigned int nRc = 1; < < //printk("EmulateCPRT(0x%08x)\n",opcode); 49,71c45,71 < if (opcode & 0x800000) < { < /* This is some variant of a comparison (PerformComparison will < sort out which one). Since most of the other CPRT < instructions are oddball cases of some sort or other it makes < sense to pull this out into a fast path. */ < return PerformComparison(opcode); < } < < /* Hint to GCC that we'd like a jump table rather than a load of CMPs */ < switch ((opcode & 0x700000) >> 20) < { < case FLT_CODE >> 20: nRc = PerformFLT(opcode); break; < case FIX_CODE >> 20: nRc = PerformFIX(opcode); break; < < case WFS_CODE >> 20: writeFPSR(readRegister(getRd(opcode))); break; < case RFS_CODE >> 20: writeRegister(getRd(opcode),readFPSR()); break; < < #if 0 /* We currently have no use for the FPCR, so there's no point < in emulating it. */ < case WFC_CODE >> 20: writeFPCR(readRegister(getRd(opcode))); < case RFC_CODE >> 20: writeRegister(getRd(opcode),readFPCR()); break; < #endif --- > if (opcode & 0x800000) { > /* This is some variant of a comparison (PerformComparison > will sort out which one). Since most of the other CPRT > instructions are oddball cases of some sort or other it > makes sense to pull this out into a fast path. */ > return PerformComparison(opcode); > } > > /* Hint to GCC that we'd like a jump table rather than a load of CMPs */ > switch ((opcode & 0x700000) >> 20) { > case FLT_CODE >> 20: > return PerformFLT(opcode); > break; > case FIX_CODE >> 20: > return PerformFIX(opcode); > break; > > case WFS_CODE >> 20: > writeFPSR(readRegister(getRd(opcode))); > break; > case RFS_CODE >> 20: > writeRegister(getRd(opcode), readFPSR()); > break; > > default: > return 0; > } 73,76c73 < default: nRc = 0; < } < < return nRc; --- > return 1; 81,115c78,110 < FPA11 *fpa11 = GET_FPA11(); < < unsigned int nRc = 1; < SetRoundingMode(opcode); < < switch (opcode & MASK_ROUNDING_PRECISION) < { < case ROUND_SINGLE: < { < fpa11->fType[getFn(opcode)] = typeSingle; < fpa11->fpreg[getFn(opcode)].fSingle = < int32_to_float32(readRegister(getRd(opcode))); < } < break; < < case ROUND_DOUBLE: < { < fpa11->fType[getFn(opcode)] = typeDouble; < fpa11->fpreg[getFn(opcode)].fDouble = < int32_to_float64(readRegister(getRd(opcode))); < } < break; < < case ROUND_EXTENDED: < { < fpa11->fType[getFn(opcode)] = typeExtended; < fpa11->fpreg[getFn(opcode)].fExtended = < int32_to_floatx80(readRegister(getRd(opcode))); < } < break; < < default: nRc = 0; < } < < return nRc; --- > FPA11 *fpa11 = GET_FPA11(); > SetRoundingMode(opcode); > SetRoundingPrecision(opcode); > > switch (opcode & MASK_ROUNDING_PRECISION) { > case ROUND_SINGLE: > { > fpa11->fType[getFn(opcode)] = typeSingle; > fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(readRegister(getRd(opcode))); > } > break; > > case ROUND_DOUBLE: > { > fpa11->fType[getFn(opcode)] = typeDouble; > fpa11->fpreg[getFn(opcode)].fDouble = int32_to_float64(readRegister(getRd(opcode))); > } > break; > > #ifdef CONFIG_FPE_NWFPE_XP > case ROUND_EXTENDED: > { > fpa11->fType[getFn(opcode)] = typeExtended; > fpa11->fpreg[getFn(opcode)].fExtended = int32_to_floatx80(readRegister(getRd(opcode))); > } > break; > #endif > > default: > return 0; > } > > return 1; 120,153c115,116 < FPA11 *fpa11 = GET_FPA11(); < unsigned int nRc = 1; < unsigned int Fn = getFm(opcode); < < SetRoundingMode(opcode); < < switch (fpa11->fType[Fn]) < { < case typeSingle: < { < writeRegister(getRd(opcode), < float32_to_int32(fpa11->fpreg[Fn].fSingle)); < } < break; < < case typeDouble: < { < writeRegister(getRd(opcode), < float64_to_int32(fpa11->fpreg[Fn].fDouble)); < } < break; < < case typeExtended: < { < writeRegister(getRd(opcode), < floatx80_to_int32(fpa11->fpreg[Fn].fExtended)); < } < break; < < default: nRc = 0; < } < < return nRc; < } --- > FPA11 *fpa11 = GET_FPA11(); > unsigned int Fn = getFm(opcode); 155,159c118 < < static unsigned int __inline__ < PerformComparisonOperation(floatx80 Fn, floatx80 Fm) < { < unsigned int flags = 0; --- > SetRoundingMode(opcode); 161,180c120,145 < /* test for less than condition */ < if (floatx80_lt(Fn,Fm)) < { < flags |= CC_NEGATIVE; < } < < /* test for equal condition */ < if (floatx80_eq(Fn,Fm)) < { < flags |= CC_ZERO; < } < < /* test for greater than or equal condition */ < if (floatx80_lt(Fm,Fn)) < { < flags |= CC_CARRY; < } < < writeConditionCodes(flags); < return 1; --- > switch (fpa11->fType[Fn]) { > case typeSingle: > { > writeRegister(getRd(opcode), float32_to_int32(fpa11->fpreg[Fn].fSingle)); > } > break; > > case typeDouble: > { > writeRegister(getRd(opcode), float64_to_int32(fpa11->fpreg[Fn].fDouble)); > } > break; > > #ifdef CONFIG_FPE_NWFPE_XP > case typeExtended: > { > writeRegister(getRd(opcode), floatx80_to_int32(fpa11->fpreg[Fn].fExtended)); > } > break; > #endif > > default: > return 0; > } > > return 1; 184d148 < 187,281c151,358 < FPA11 *fpa11 = GET_FPA11(); < unsigned int Fn, Fm; < floatx80 rFn, rFm; < int e_flag = opcode & 0x400000; /* 1 if CxFE */ < int n_flag = opcode & 0x200000; /* 1 if CNxx */ < unsigned int flags = 0; < < //printk("PerformComparison(0x%08x)\n",opcode); < < Fn = getFn(opcode); < Fm = getFm(opcode); < < /* Check for unordered condition and convert all operands to 80-bit < format. < ?? Might be some mileage in avoiding this conversion if possible. < Eg, if both operands are 32-bit, detect this and do a 32-bit < comparison (cheaper than an 80-bit one). */ < switch (fpa11->fType[Fn]) < { < case typeSingle: < //printk("single.\n"); < if (float32_is_nan(fpa11->fpreg[Fn].fSingle)) < goto unordered; < rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); < break; < < case typeDouble: < //printk("double.\n"); < if (float64_is_nan(fpa11->fpreg[Fn].fDouble)) < goto unordered; < rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); < break; < < case typeExtended: < //printk("extended.\n"); < if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended)) < goto unordered; < rFn = fpa11->fpreg[Fn].fExtended; < break; < < default: return 0; < } < < if (CONSTANT_FM(opcode)) < { < //printk("Fm is a constant: #%d.\n",Fm); < rFm = getExtendedConstant(Fm); < if (floatx80_is_nan(rFm)) < goto unordered; < } < else < { < //printk("Fm = r%d which contains a ",Fm); < switch (fpa11->fType[Fm]) < { < case typeSingle: < //printk("single.\n"); < if (float32_is_nan(fpa11->fpreg[Fm].fSingle)) < goto unordered; < rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle); < break; < < case typeDouble: < //printk("double.\n"); < if (float64_is_nan(fpa11->fpreg[Fm].fDouble)) < goto unordered; < rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble); < break; < < case typeExtended: < //printk("extended.\n"); < if (floatx80_is_nan(fpa11->fpreg[Fm].fExtended)) < goto unordered; < rFm = fpa11->fpreg[Fm].fExtended; < break; < < default: return 0; < } < } < < if (n_flag) < { < rFm.high ^= 0x8000; < } < < return PerformComparisonOperation(rFn,rFm); < < unordered: < /* ?? The FPA data sheet is pretty vague about this, in particular < about whether the non-E comparisons can ever raise exceptions. < This implementation is based on a combination of what it says in < the data sheet, observation of how the Acorn emulator actually < behaves (and how programs expect it to) and guesswork. */ < flags |= CC_OVERFLOW; < flags &= ~(CC_ZERO | CC_NEGATIVE); --- > FPA11 *fpa11 = GET_FPA11(); > unsigned int Fn = getFn(opcode), Fm = getFm(opcode); > int e_flag = opcode & 0x400000; /* 1 if CxFE */ > int n_flag = opcode & 0x200000; /* 1 if CNxx */ > unsigned int flags = 0; > > #ifdef CONFIG_FPE_NWFPE_XP > floatx80 rFn, rFm; > > /* Check for unordered condition and convert all operands to 80-bit > format. > ?? Might be some mileage in avoiding this conversion if possible. > Eg, if both operands are 32-bit, detect this and do a 32-bit > comparison (cheaper than an 80-bit one). */ > switch (fpa11->fType[Fn]) { > case typeSingle: > //printk("single.\n"); > if (float32_is_nan(fpa11->fpreg[Fn].fSingle)) > goto unordered; > rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); > break; > > case typeDouble: > //printk("double.\n"); > if (float64_is_nan(fpa11->fpreg[Fn].fDouble)) > goto unordered; > rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); > break; > > case typeExtended: > //printk("extended.\n"); > if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended)) > goto unordered; > rFn = fpa11->fpreg[Fn].fExtended; > break; > > default: > return 0; > } > > if (CONSTANT_FM(opcode)) { > //printk("Fm is a constant: #%d.\n",Fm); > rFm = getExtendedConstant(Fm); > if (floatx80_is_nan(rFm)) > goto unordered; > } else { > //printk("Fm = r%d which contains a ",Fm); > switch (fpa11->fType[Fm]) { > case typeSingle: > //printk("single.\n"); > if (float32_is_nan(fpa11->fpreg[Fm].fSingle)) > goto unordered; > rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle); > break; > > case typeDouble: > //printk("double.\n"); > if (float64_is_nan(fpa11->fpreg[Fm].fDouble)) > goto unordered; > rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble); > break; > > case typeExtended: > //printk("extended.\n"); > if (floatx80_is_nan(fpa11->fpreg[Fm].fExtended)) > goto unordered; > rFm = fpa11->fpreg[Fm].fExtended; > break; > > default: > return 0; > } > } > > if (n_flag) > rFm.high ^= 0x8000; > > /* test for less than condition */ > if (floatx80_lt(rFn, rFm)) > flags |= CC_NEGATIVE; > > /* test for equal condition */ > if (floatx80_eq(rFn, rFm)) > flags |= CC_ZERO; > > /* test for greater than or equal condition */ > if (floatx80_lt(rFm, rFn)) > flags |= CC_CARRY; > > #else > if (CONSTANT_FM(opcode)) { > /* Fm is a constant. Do the comparison in whatever precision > Fn happens to be stored in. */ > if (fpa11->fType[Fn] == typeSingle) { > float32 rFm = getSingleConstant(Fm); > float32 rFn = fpa11->fpreg[Fn].fSingle; > > if (float32_is_nan(rFn)) > goto unordered; > > if (n_flag) > rFm ^= 0x80000000; > > /* test for less than condition */ > if (float32_lt_nocheck(rFn, rFm)) > flags |= CC_NEGATIVE; > > /* test for equal condition */ > if (float32_eq_nocheck(rFn, rFm)) > flags |= CC_ZERO; > > /* test for greater than or equal condition */ > if (float32_lt_nocheck(rFm, rFn)) > flags |= CC_CARRY; > } else { > float64 rFm = getDoubleConstant(Fm); > float64 rFn = fpa11->fpreg[Fn].fDouble; > > if (float64_is_nan(rFn)) > goto unordered; > > if (n_flag) > rFm ^= 0x8000000000000000ULL; > > /* test for less than condition */ > if (float64_lt_nocheck(rFn, rFm)) > flags |= CC_NEGATIVE; > > /* test for equal condition */ > if (float64_eq_nocheck(rFn, rFm)) > flags |= CC_ZERO; > > /* test for greater than or equal condition */ > if (float64_lt_nocheck(rFm, rFn)) > flags |= CC_CARRY; > } > } else { > /* Both operands are in registers. */ > if (fpa11->fType[Fn] == typeSingle > && fpa11->fType[Fm] == typeSingle) { > float32 rFm = fpa11->fpreg[Fm].fSingle; > float32 rFn = fpa11->fpreg[Fn].fSingle; > > if (float32_is_nan(rFn) > || float32_is_nan(rFm)) > goto unordered; > > if (n_flag) > rFm ^= 0x80000000; > > /* test for less than condition */ > if (float32_lt_nocheck(rFn, rFm)) > flags |= CC_NEGATIVE; > > /* test for equal condition */ > if (float32_eq_nocheck(rFn, rFm)) > flags |= CC_ZERO; > > /* test for greater than or equal condition */ > if (float32_lt_nocheck(rFm, rFn)) > flags |= CC_CARRY; > } else { > /* Promote 32-bit operand to 64 bits. */ > float64 rFm, rFn; > > rFm = (fpa11->fType[Fm] == typeSingle) ? > float32_to_float64(fpa11->fpreg[Fm].fSingle) > : fpa11->fpreg[Fm].fDouble; > > rFn = (fpa11->fType[Fn] == typeSingle) ? > float32_to_float64(fpa11->fpreg[Fn].fSingle) > : fpa11->fpreg[Fn].fDouble; > > if (float64_is_nan(rFn) > || float64_is_nan(rFm)) > goto unordered; > > if (n_flag) > rFm ^= 0x8000000000000000ULL; > > /* test for less than condition */ > if (float64_lt_nocheck(rFn, rFm)) > flags |= CC_NEGATIVE; > > /* test for equal condition */ > if (float64_eq_nocheck(rFn, rFm)) > flags |= CC_ZERO; > > /* test for greater than or equal condition */ > if (float64_lt_nocheck(rFm, rFn)) > flags |= CC_CARRY; > } > } > > #endif > > writeConditionCodes(flags); > > return 1; > > unordered: > /* ?? The FPA data sheet is pretty vague about this, in particular > about whether the non-E comparisons can ever raise exceptions. > This implementation is based on a combination of what it says in > the data sheet, observation of how the Acorn emulator actually > behaves (and how programs expect it to) and guesswork. */ > flags |= CC_OVERFLOW; > flags &= ~(CC_ZERO | CC_NEGATIVE); 283c360,361 < if (BIT_AC & readFPSR()) flags |= CC_CARRY; --- > if (BIT_AC & readFPSR()) > flags |= CC_CARRY; 285c363,364 < if (e_flag) float_raise(float_flag_invalid); --- > if (e_flag) > float_raise(float_flag_invalid); 287,288c366,367 < writeConditionCodes(flags); < return 1; --- > writeConditionCodes(flags); > return 1; diff -r linux-sharp-6000/arch/arm/nwfpe/fpmodule.c linux-sharp-6000+nwfpe/arch/arm/nwfpe/fpmodule.c 44c44,50 < typedef struct task_struct* PTASK; --- > typedef struct task_struct *PTASK; > > #ifdef CONFIG_FPE_NWFPE_XP > #define NWFPE_BITS "extended" > #else > #define NWFPE_BITS "double" > #endif 50c56 < MODULE_DESCRIPTION("NWFPE floating point emulator"); --- > MODULE_DESCRIPTION("NWFPE floating point emulator (" NWFPE_BITS " precision)"); 66c72 < /* Original value of fp_enter from kernel before patched by fpe_init. */ --- > /* Original value of fp_enter from kernel before patched by fpe_init. */ 79c85 < return (kern_fp_enter == nwfpe_enter) ? 0 : 1; --- > return (kern_fp_enter == nwfpe_enter) ? 0 : 1; 85,94c91,99 < if (sizeof(FPA11) > sizeof(union fp_state)) { < printk(KERN_ERR "nwfpe: bad structure size\n"); < return -EINVAL; < } < < if (sizeof(FPREG) != 12) { < printk(KERN_ERR "nwfpe: bad register size\n"); < return -EINVAL; < } < --- > if (sizeof(FPA11) > sizeof(union fp_state)) { > printk(KERN_ERR "nwfpe: bad structure size\n"); > return -EINVAL; > } > > if (sizeof(FPREG) != 12) { > printk(KERN_ERR "nwfpe: bad register size\n"); > return -EINVAL; > } 96,98c101,103 < if (!mod_member_present(&__this_module, can_unload)) < return -EINVAL; < __this_module.can_unload = fpe_unload; --- > if (!mod_member_present(&__this_module, can_unload)) > return -EINVAL; > __this_module.can_unload = fpe_unload; 100,101c105,106 < if (fpe_type[0] && strcmp(fpe_type, "nwfpe")) < return 0; --- > if (fpe_type[0] && strcmp(fpe_type, "nwfpe")) > return 0; 104,110c109,115 < /* Display title, version and copyright information. */ < printk(KERN_WARNING "NetWinder Floating Point Emulator V0.95 " < "(c) 1998-1999 Rebel.com\n"); < < /* Save pointer to the old FP handler and then patch ourselves in */ < orig_fp_enter = kern_fp_enter; < kern_fp_enter = nwfpe_enter; --- > /* Display title, version and copyright information. */ > printk(KERN_WARNING "NetWinder Floating Point Emulator V0.97 (" > NWFPE_BITS " precision)\n"); > > /* Save pointer to the old FP handler and then patch ourselves in */ > orig_fp_enter = kern_fp_enter; > kern_fp_enter = nwfpe_enter; 112c117 < return 0; --- > return 0; 117,118c122,123 < /* Restore the values we saved earlier. */ < kern_fp_enter = orig_fp_enter; --- > /* Restore the values we saved earlier. */ > kern_fp_enter = orig_fp_enter; 143,144c148,149 < register unsigned int fpsr, cumulativeTraps; < --- > register unsigned int fpsr, cumulativeTraps; > 146,177c151,183 < printk(KERN_DEBUG "NWFPE: %s[%d] takes exception %08x at %p from %08x\n", < current->comm, current->pid, flags, < __builtin_return_address(0), GET_USERREG()[15]); < #endif < < /* Keep SoftFloat exception flags up to date. */ < float_exception_flags |= flags; < < /* Read fpsr and initialize the cumulativeTraps. */ < fpsr = readFPSR(); < cumulativeTraps = 0; < < /* For each type of exception, the cumulative trap exception bit is only < set if the corresponding trap enable bit is not set. */ < if ((!(fpsr & BIT_IXE)) && (flags & BIT_IXC)) < cumulativeTraps |= BIT_IXC; < if ((!(fpsr & BIT_UFE)) && (flags & BIT_UFC)) < cumulativeTraps |= BIT_UFC; < if ((!(fpsr & BIT_OFE)) && (flags & BIT_OFC)) < cumulativeTraps |= BIT_OFC; < if ((!(fpsr & BIT_DZE)) && (flags & BIT_DZC)) < cumulativeTraps |= BIT_DZC; < if ((!(fpsr & BIT_IOE)) && (flags & BIT_IOC)) < cumulativeTraps |= BIT_IOC; < < /* Set the cumulative exceptions flags. */ < if (cumulativeTraps) < writeFPSR(fpsr | cumulativeTraps); < < /* Raise an exception if necessary. */ < if (fpsr & (flags << 16)) < fp_send_sig(SIGFPE, current, 1); --- > printk(KERN_DEBUG > "NWFPE: %s[%d] takes exception %08x at %p from %08x\n", > current->comm, current->pid, flags, > __builtin_return_address(0), GET_USERREG()[15]); > #endif > > /* Keep SoftFloat exception flags up to date. */ > float_exception_flags |= flags; > > /* Read fpsr and initialize the cumulativeTraps. */ > fpsr = readFPSR(); > cumulativeTraps = 0; > > /* For each type of exception, the cumulative trap exception bit is only > set if the corresponding trap enable bit is not set. */ > if ((!(fpsr & BIT_IXE)) && (flags & BIT_IXC)) > cumulativeTraps |= BIT_IXC; > if ((!(fpsr & BIT_UFE)) && (flags & BIT_UFC)) > cumulativeTraps |= BIT_UFC; > if ((!(fpsr & BIT_OFE)) && (flags & BIT_OFC)) > cumulativeTraps |= BIT_OFC; > if ((!(fpsr & BIT_DZE)) && (flags & BIT_DZC)) > cumulativeTraps |= BIT_DZC; > if ((!(fpsr & BIT_IOE)) && (flags & BIT_IOC)) > cumulativeTraps |= BIT_IOC; > > /* Set the cumulative exceptions flags. */ > if (cumulativeTraps) > writeFPSR(fpsr | cumulativeTraps); > > /* Raise an exception if necessary. */ > if (fpsr & (flags << 16)) > fp_send_sig(SIGFPE, current, 1); diff -r linux-sharp-6000/arch/arm/nwfpe/fpmodule.inl linux-sharp-6000+nwfpe/arch/arm/nwfpe/fpmodule.inl 25,35c25,36 < /* Note: The CPU thinks it has dealt with the current instruction. As < a result the program counter has been advanced to the next < instruction, and points 4 bytes beyond the actual instruction < that caused the invalid instruction trap to occur. We adjust < for this in this routine. LDF/STF instructions with Rn = PC < depend on the PC being correct, as they use PC+8 in their < address calculations. */ < unsigned int *userRegisters = GET_USERREG(); < unsigned int val = userRegisters[nReg]; < if (REG_PC == nReg) val -= 4; < return val; --- > /* Note: The CPU thinks it has dealt with the current instruction. > As a result the program counter has been advanced to the next > instruction, and points 4 bytes beyond the actual instruction > that caused the invalid instruction trap to occur. We adjust > for this in this routine. LDF/STF instructions with Rn = PC > depend on the PC being correct, as they use PC+8 in their > address calculations. */ > unsigned int *userRegisters = GET_USERREG(); > unsigned int val = userRegisters[nReg]; > if (REG_PC == nReg) > val -= 4; > return val; 41,42c42,43 < unsigned int *userRegisters = GET_USERREG(); < userRegisters[nReg] = val; --- > unsigned int *userRegisters = GET_USERREG(); > userRegisters[nReg] = val; 48c49 < return(readRegister(REG_CPSR)); --- > return (readRegister(REG_CPSR)); 54c55 < writeRegister(REG_CPSR,val); --- > writeRegister(REG_CPSR, val); 61c62 < return(0); --- > return (0); 63c64 < return(readCPSR() & CC_MASK); --- > return (readCPSR() & CC_MASK); 70,77c71,78 < unsigned int *userRegisters = GET_USERREG(); < unsigned int rval; < /* < * Operate directly on userRegisters since < * the CPSR may be the PC register itself. < */ < rval = userRegisters[REG_CPSR] & ~CC_MASK; < userRegisters[REG_CPSR] = rval | (val & CC_MASK); --- > unsigned int *userRegisters = GET_USERREG(); > unsigned int rval; > /* > * Operate directly on userRegisters since > * the CPSR may be the PC register itself. > */ > rval = userRegisters[REG_CPSR] & ~CC_MASK; > userRegisters[REG_CPSR] = rval | (val & CC_MASK); 83c84 < return *pMem; --- > return *pMem; diff -r linux-sharp-6000/arch/arm/nwfpe/fpopcode.c linux-sharp-6000+nwfpe/arch/arm/nwfpe/fpopcode.c 28a29 > #ifdef CONFIG_FPE_NWFPE_XP 30,38c31,40 < { 0x0000, 0x0000000000000000ULL}, /* extended 0.0 */ < { 0x3fff, 0x8000000000000000ULL}, /* extended 1.0 */ < { 0x4000, 0x8000000000000000ULL}, /* extended 2.0 */ < { 0x4000, 0xc000000000000000ULL}, /* extended 3.0 */ < { 0x4001, 0x8000000000000000ULL}, /* extended 4.0 */ < { 0x4001, 0xa000000000000000ULL}, /* extended 5.0 */ < { 0x3ffe, 0x8000000000000000ULL}, /* extended 0.5 */ < { 0x4002, 0xa000000000000000ULL} /* extended 10.0 */ < }; --- > {0x0000, 0x0000000000000000ULL}, /* extended 0.0 */ > {0x3fff, 0x8000000000000000ULL}, /* extended 1.0 */ > {0x4000, 0x8000000000000000ULL}, /* extended 2.0 */ > {0x4000, 0xc000000000000000ULL}, /* extended 3.0 */ > {0x4001, 0x8000000000000000ULL}, /* extended 4.0 */ > {0x4001, 0xa000000000000000ULL}, /* extended 5.0 */ > {0x3ffe, 0x8000000000000000ULL}, /* extended 0.5 */ > {0x4002, 0xa000000000000000ULL} /* extended 10.0 */ > }; > #endif 41,49c43,51 < 0x0000000000000000ULL, /* double 0.0 */ < 0x3ff0000000000000ULL, /* double 1.0 */ < 0x4000000000000000ULL, /* double 2.0 */ < 0x4008000000000000ULL, /* double 3.0 */ < 0x4010000000000000ULL, /* double 4.0 */ < 0x4014000000000000ULL, /* double 5.0 */ < 0x3fe0000000000000ULL, /* double 0.5 */ < 0x4024000000000000ULL /* double 10.0 */ < }; --- > 0x0000000000000000ULL, /* double 0.0 */ > 0x3ff0000000000000ULL, /* double 1.0 */ > 0x4000000000000000ULL, /* double 2.0 */ > 0x4008000000000000ULL, /* double 3.0 */ > 0x4010000000000000ULL, /* double 4.0 */ > 0x4014000000000000ULL, /* double 5.0 */ > 0x3fe0000000000000ULL, /* double 0.5 */ > 0x4024000000000000ULL /* double 10.0 */ > }; 52,121c54,62 < 0x00000000, /* single 0.0 */ < 0x3f800000, /* single 1.0 */ < 0x40000000, /* single 2.0 */ < 0x40400000, /* single 3.0 */ < 0x40800000, /* single 4.0 */ < 0x40a00000, /* single 5.0 */ < 0x3f000000, /* single 0.5 */ < 0x41200000 /* single 10.0 */ < }; < < unsigned int getTransferLength(const unsigned int opcode) < { < unsigned int nRc; < < switch (opcode & MASK_TRANSFER_LENGTH) < { < case 0x00000000: nRc = 1; break; /* single precision */ < case 0x00008000: nRc = 2; break; /* double precision */ < case 0x00400000: nRc = 3; break; /* extended precision */ < default: nRc = 0; < } < < return(nRc); < } < < unsigned int getRegisterCount(const unsigned int opcode) < { < unsigned int nRc; < < switch (opcode & MASK_REGISTER_COUNT) < { < case 0x00000000: nRc = 4; break; < case 0x00008000: nRc = 1; break; < case 0x00400000: nRc = 2; break; < case 0x00408000: nRc = 3; break; < default: nRc = 0; < } < < return(nRc); < } < < unsigned int getRoundingPrecision(const unsigned int opcode) < { < unsigned int nRc; < < switch (opcode & MASK_ROUNDING_PRECISION) < { < case 0x00000000: nRc = 1; break; < case 0x00000080: nRc = 2; break; < case 0x00080000: nRc = 3; break; < default: nRc = 0; < } < < return(nRc); < } < < unsigned int getDestinationSize(const unsigned int opcode) < { < unsigned int nRc; < < switch (opcode & MASK_DESTINATION_SIZE) < { < case 0x00000000: nRc = typeSingle; break; < case 0x00000080: nRc = typeDouble; break; < case 0x00080000: nRc = typeExtended; break; < default: nRc = typeNone; < } < < return(nRc); < } --- > 0x00000000, /* single 0.0 */ > 0x3f800000, /* single 1.0 */ > 0x40000000, /* single 2.0 */ > 0x40400000, /* single 3.0 */ > 0x40800000, /* single 4.0 */ > 0x40a00000, /* single 5.0 */ > 0x3f000000, /* single 0.5 */ > 0x41200000 /* single 10.0 */ > }; 127,142c68,83 < 0xF0F0, // EQ == Z set < 0x0F0F, // NE < 0xCCCC, // CS == C set < 0x3333, // CC < 0xFF00, // MI == N set < 0x00FF, // PL < 0xAAAA, // VS == V set < 0x5555, // VC < 0x0C0C, // HI == C set && Z clear < 0xF3F3, // LS == C clear || Z set < 0xAA55, // GE == (N==V) < 0x55AA, // LT == (N!=V) < 0x0A05, // GT == (!Z && (N==V)) < 0xF5FA, // LE == (Z || (N!=V)) < 0xFFFF, // AL always < 0 // NV --- > 0xF0F0, // EQ == Z set > 0x0F0F, // NE > 0xCCCC, // CS == C set > 0x3333, // CC > 0xFF00, // MI == N set > 0x00FF, // PL > 0xAAAA, // VS == V set > 0x5555, // VC > 0x0C0C, // HI == C set && Z clear > 0xF3F3, // LS == C clear || Z set > 0xAA55, // GE == (N==V) > 0x55AA, // LT == (N!=V) > 0x0A05, // GT == (!Z && (N==V)) > 0xF5FA, // LE == (Z || (N!=V)) > 0xFFFF, // AL always > 0 // NV 147c88 < return (aCC[opcode>>28] >> (ccodes>>28)) & 1; --- > return (aCC[opcode >> 28] >> (ccodes >> 28)) & 1; diff -r linux-sharp-6000/arch/arm/nwfpe/fpopcode.h linux-sharp-6000+nwfpe/arch/arm/nwfpe/fpopcode.h 3a4 > (c) Philip Blundell, 2001 29c30 < |c o n d|1 1 0 P|U|w|W|L| Rn |x| Fd |0|0|0|1| o f f s e t | CPDT --- > |c o n d|1 1 0 P|U|w|W|L| Rn |x| Fd |0|0|1|0| o f f s e t | CPDT (copro 2) 37c38 < LDF, STF, LFM, SFM --- > LDF, STF, LFM (copro 2), SFM (copro 2) 189c190 < #define MASK_CPDT 0x0c000000 /* data processing opcode */ --- > #define MASK_CPDT 0x0c000000 /* data processing opcode */ 239c240 < #define MASK_CPDO 0x0e000000 /* arithmetic opcode */ --- > #define MASK_CPDO 0x0e000000 /* arithmetic opcode */ 285c286 < #define MASK_CPRT 0x0e000010 /* register transfer opcode */ --- > #define MASK_CPRT 0x0e000010 /* register transfer opcode */ 368a370 > #ifdef CONFIG_FPE_NWFPE_XP 371,373c373,376 < extern const floatx80 floatx80Constant[]; < return floatx80Constant[nIndex]; < } --- > extern const floatx80 floatx80Constant[]; > return floatx80Constant[nIndex]; > } > #endif 377,379c380,382 < extern const float64 float64Constant[]; < return float64Constant[nIndex]; < } --- > extern const float64 float64Constant[]; > return float64Constant[nIndex]; > } 383,385c386,472 < extern const float32 float32Constant[]; < return float32Constant[nIndex]; < } --- > extern const float32 float32Constant[]; > return float32Constant[nIndex]; > } > > static inline unsigned int getTransferLength(const unsigned int opcode) > { > unsigned int nRc; > > switch (opcode & MASK_TRANSFER_LENGTH) { > case 0x00000000: > nRc = 1; > break; /* single precision */ > case 0x00008000: > nRc = 2; > break; /* double precision */ > case 0x00400000: > nRc = 3; > break; /* extended precision */ > default: > nRc = 0; > } > > return (nRc); > } > > static inline unsigned int getRegisterCount(const unsigned int opcode) > { > unsigned int nRc; > > switch (opcode & MASK_REGISTER_COUNT) { > case 0x00000000: > nRc = 4; > break; > case 0x00008000: > nRc = 1; > break; > case 0x00400000: > nRc = 2; > break; > case 0x00408000: > nRc = 3; > break; > default: > nRc = 0; > } > > return (nRc); > } > > static inline unsigned int getRoundingPrecision(const unsigned int opcode) > { > unsigned int nRc; > > switch (opcode & MASK_ROUNDING_PRECISION) { > case 0x00000000: > nRc = 1; > break; > case 0x00000080: > nRc = 2; > break; > case 0x00080000: > nRc = 3; > break; > default: > nRc = 0; > } > > return (nRc); > } > > static inline unsigned int getDestinationSize(const unsigned int opcode) > { > unsigned int nRc; > > switch (opcode & MASK_DESTINATION_SIZE) { > case 0x00000000: > nRc = typeSingle; > break; > case 0x00000080: > nRc = typeDouble; > break; > case 0x00080000: > nRc = typeExtended; > break; > default: > nRc = typeNone; > } 387,388c474,475 < extern unsigned int getRegisterCount(const unsigned int opcode); < extern unsigned int getDestinationSize(const unsigned int opcode); --- > return (nRc); > } diff -r linux-sharp-6000/arch/arm/nwfpe/fpsr.h linux-sharp-6000+nwfpe/arch/arm/nwfpe/fpsr.h 41,42c41,42 < typedef unsigned int FPSR; /* type for floating point status register */ < typedef unsigned int FPCR; /* type for floating point control register */ --- > typedef unsigned int FPSR; /* type for floating point status register */ > typedef unsigned int FPCR; /* type for floating point control register */ 46c46 < #define FP_EMULATOR 0x01000000 /* System ID for emulator */ --- > #define FP_EMULATOR 0x01000000 /* System ID for emulator */ 54,58c54,58 < #define BIT_IXE 0x00100000 /* inexact exception enable */ < #define BIT_UFE 0x00080000 /* underflow exception enable */ < #define BIT_OFE 0x00040000 /* overflow exception enable */ < #define BIT_DZE 0x00020000 /* divide by zero exception enable */ < #define BIT_IOE 0x00010000 /* invalid operation exception enable */ --- > #define BIT_IXE 0x00100000 /* inexact exception enable */ > #define BIT_UFE 0x00080000 /* underflow exception enable */ > #define BIT_OFE 0x00040000 /* overflow exception enable */ > #define BIT_DZE 0x00020000 /* divide by zero exception enable */ > #define BIT_IOE 0x00010000 /* invalid operation exception enable */ diff -r linux-sharp-6000/arch/arm/nwfpe/single_cpdo.c linux-sharp-6000+nwfpe/arch/arm/nwfpe/single_cpdo.c 3a4 > (c) Philip Blundell, 2001 35,36c36,37 < float32 float32_pow(float32 rFn,float32 rFm); < float32 float32_pol(float32 rFn,float32 rFm); --- > float32 float32_pow(float32 rFn, float32 rFm); > float32 float32_pol(float32 rFn, float32 rFm); 38c39 < unsigned int SingleCPDO(const unsigned int opcode) --- > static float32 float32_rsf(float32 rFn, float32 rFm) 40,197c41 < FPA11 *fpa11 = GET_FPA11(); < float32 rFm, rFn; < unsigned int Fd, Fm, Fn, nRc = 1; < < Fm = getFm(opcode); < if (CONSTANT_FM(opcode)) < { < rFm = getSingleConstant(Fm); < } < else < { < switch (fpa11->fType[Fm]) < { < case typeSingle: < rFm = fpa11->fpreg[Fm].fSingle; < break; < < default: return 0; < } < } < < if (!MONADIC_INSTRUCTION(opcode)) < { < Fn = getFn(opcode); < switch (fpa11->fType[Fn]) < { < case typeSingle: < rFn = fpa11->fpreg[Fn].fSingle; < break; < < default: return 0; < } < } < < Fd = getFd(opcode); < switch (opcode & MASK_ARITHMETIC_OPCODE) < { < /* dyadic opcodes */ < case ADF_CODE: < fpa11->fpreg[Fd].fSingle = float32_add(rFn,rFm); < break; < < case MUF_CODE: < case FML_CODE: < fpa11->fpreg[Fd].fSingle = float32_mul(rFn,rFm); < break; < < case SUF_CODE: < fpa11->fpreg[Fd].fSingle = float32_sub(rFn,rFm); < break; < < case RSF_CODE: < fpa11->fpreg[Fd].fSingle = float32_sub(rFm,rFn); < break; < < case DVF_CODE: < case FDV_CODE: < fpa11->fpreg[Fd].fSingle = float32_div(rFn,rFm); < break; < < case RDF_CODE: < case FRD_CODE: < fpa11->fpreg[Fd].fSingle = float32_div(rFm,rFn); < break; < < #if 0 < case POW_CODE: < fpa11->fpreg[Fd].fSingle = float32_pow(rFn,rFm); < break; < < case RPW_CODE: < fpa11->fpreg[Fd].fSingle = float32_pow(rFm,rFn); < break; < #endif < < case RMF_CODE: < fpa11->fpreg[Fd].fSingle = float32_rem(rFn,rFm); < break; < < #if 0 < case POL_CODE: < fpa11->fpreg[Fd].fSingle = float32_pol(rFn,rFm); < break; < #endif < < /* monadic opcodes */ < case MVF_CODE: < fpa11->fpreg[Fd].fSingle = rFm; < break; < < case MNF_CODE: < rFm ^= 0x80000000; < fpa11->fpreg[Fd].fSingle = rFm; < break; < < case ABS_CODE: < rFm &= 0x7fffffff; < fpa11->fpreg[Fd].fSingle = rFm; < break; < < case RND_CODE: < case URD_CODE: < fpa11->fpreg[Fd].fSingle = float32_round_to_int(rFm); < break; < < case SQT_CODE: < fpa11->fpreg[Fd].fSingle = float32_sqrt(rFm); < break; < < #if 0 < case LOG_CODE: < fpa11->fpreg[Fd].fSingle = float32_log(rFm); < break; < < case LGN_CODE: < fpa11->fpreg[Fd].fSingle = float32_ln(rFm); < break; < < case EXP_CODE: < fpa11->fpreg[Fd].fSingle = float32_exp(rFm); < break; < < case SIN_CODE: < fpa11->fpreg[Fd].fSingle = float32_sin(rFm); < break; < < case COS_CODE: < fpa11->fpreg[Fd].fSingle = float32_cos(rFm); < break; < < case TAN_CODE: < fpa11->fpreg[Fd].fSingle = float32_tan(rFm); < break; < < case ASN_CODE: < fpa11->fpreg[Fd].fSingle = float32_arcsin(rFm); < break; < < case ACS_CODE: < fpa11->fpreg[Fd].fSingle = float32_arccos(rFm); < break; < < case ATN_CODE: < fpa11->fpreg[Fd].fSingle = float32_arctan(rFm); < break; < #endif < < case NRM_CODE: < break; < < default: < { < nRc = 0; < } < } < < if (0 != nRc) fpa11->fType[Fd] = typeSingle; < return nRc; --- > return float32_sub(rFm, rFn); 200,201c44 < #if 0 < float32 float32_exp(float32 Fm) --- > static float32 float32_rdv(float32 rFn, float32 rFm) 203c46 < //series --- > return float32_div(rFm, rFn); 206,209c49,56 < float32 float32_ln(float32 Fm) < { < //series < } --- > static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = { > [ADF_CODE >> 20] = float32_add, > [MUF_CODE >> 20] = float32_mul, > [SUF_CODE >> 20] = float32_sub, > [RSF_CODE >> 20] = float32_rsf, > [DVF_CODE >> 20] = float32_div, > [RDF_CODE >> 20] = float32_rdv, > [RMF_CODE >> 20] = float32_rem, 211,214c58,61 < float32 float32_sin(float32 rFm) < { < //series < } --- > [FML_CODE >> 20] = float32_mul, > [FDV_CODE >> 20] = float32_div, > [FRD_CODE >> 20] = float32_rdv, > }; 216c63 < float32 float32_cos(float32 rFm) --- > static float32 float32_mvf(float32 rFm) 218c65 < //series --- > return rFm; 221c68 < float32 float32_arcsin(float32 rFm) --- > static float32 float32_mnf(float32 rFm) 223c70 < //series --- > return rFm ^ 0x80000000; 226c73 < float32 float32_arctan(float32 rFm) --- > static float32 float32_abs(float32 rFm) 228c75 < //series --- > return rFm & 0x7fffffff; 231,234c78,86 < float32 float32_arccos(float32 rFm) < { < //return float32_sub(halfPi,float32_arcsin(rFm)); < } --- > static float32 (*const monadic_single[16])(float32 rFm) = { > [MVF_CODE >> 20] = float32_mvf, > [MNF_CODE >> 20] = float32_mnf, > [ABS_CODE >> 20] = float32_abs, > [RND_CODE >> 20] = float32_round_to_int, > [URD_CODE >> 20] = float32_round_to_int, > [SQT_CODE >> 20] = float32_sqrt, > [NRM_CODE >> 20] = float32_mvf, > }; 236c88 < float32 float32_log(float32 rFm) --- > unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd) 238,239c90,92 < return float32_div(float32_ln(rFm),getSingleConstant(7)); < } --- > FPA11 *fpa11 = GET_FPA11(); > float32 rFm; > unsigned int Fm, opc_mask_shift; 241,244c94,101 < float32 float32_tan(float32 rFm) < { < return float32_div(float32_sin(rFm),float32_cos(rFm)); < } --- > Fm = getFm(opcode); > if (CONSTANT_FM(opcode)) { > rFm = getSingleConstant(Fm); > } else if (fpa11->fType[Fm] == typeSingle) { > rFm = fpa11->fpreg[Fm].fSingle; > } else { > return 0; > } 246,249c103,106 < float32 float32_pow(float32 rFn,float32 rFm) < { < return float32_exp(float32_mul(rFm,float32_ln(rFn))); < } --- > opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20; > if (!MONADIC_INSTRUCTION(opcode)) { > unsigned int Fn = getFn(opcode); > float32 rFn; 251,253c108,123 < float32 float32_pol(float32 rFn,float32 rFm) < { < return float32_arctan(float32_div(rFn,rFm)); --- > if (fpa11->fType[Fn] == typeSingle && > dyadic_single[opc_mask_shift]) { > rFn = fpa11->fpreg[Fn].fSingle; > rFd->fSingle = dyadic_single[opc_mask_shift](rFn, rFm); > } else { > return 0; > } > } else { > if (monadic_single[opc_mask_shift]) { > rFd->fSingle = monadic_single[opc_mask_shift](rFm); > } else { > return 0; > } > } > > return 1; 255d124 < #endif diff -r linux-sharp-6000/arch/arm/nwfpe/softfloat.c linux-sharp-6000+nwfpe/arch/arm/nwfpe/softfloat.c 32,33c32,33 < #include "milieu.h" < #include "softfloat.h" --- > //#include "milieu.h" > //#include "softfloat.h" 144a145 > #if 0 /* in softfloat.h */ 150a152 > #endif 187,189c189,191 < __asm__("@ packFloat32; < mov %0, %1, asl #31; < orr %0, %2, asl #23; --- > __asm__("@ packFloat32 \n\ > mov %0, %1, asl #31 \n\ > orr %0, %2, asl #23 \n\ 323a326 > #if 0 /* in softfloat.h */ 329a333 > #endif diff -r linux-sharp-6000/arch/arm/nwfpe/softfloat.h linux-sharp-6000+nwfpe/arch/arm/nwfpe/softfloat.h 42a43 > #ifdef CONFIG_FPE_NWFPE_XP 43a45 > #endif 231a234,275 > static inline flag extractFloat32Sign(float32 a) > { > return a >> 31; > } > > static inline flag float32_eq_nocheck(float32 a, float32 b) > { > return (a == b) || ((bits32) ((a | b) << 1) == 0); > } > > static inline flag float32_lt_nocheck(float32 a, float32 b) > { > flag aSign, bSign; > > aSign = extractFloat32Sign(a); > bSign = extractFloat32Sign(b); > if (aSign != bSign) > return aSign && ((bits32) ((a | b) << 1) != 0); > return (a != b) && (aSign ^ (a < b)); > } > > static inline flag extractFloat64Sign(float64 a) > { > return a >> 63; > } > > static inline flag float64_eq_nocheck(float64 a, float64 b) > { > return (a == b) || ((bits64) ((a | b) << 1) == 0); > } > > static inline flag float64_lt_nocheck(float64 a, float64 b) > { > flag aSign, bSign; > > aSign = extractFloat64Sign(a); > bSign = extractFloat64Sign(b); > if (aSign != bSign) > return aSign && ((bits64) ((a | b) << 1) != 0); > return (a != b) && (aSign ^ (a < b)); > } >