void fdivp_() { /* fdivp st(i),st */ reg_div(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); pop(); }
static int trig_arg(FPU_REG * X) { FPU_REG tmp, quot; int rv; long long q; int old_cw = control_word; control_word &= ~CW_RC; control_word |= RC_CHOP; reg_move(X, "); reg_div(", &CONST_PI2, ", FULL_PRECISION); reg_move(", &tmp); round_to_int(&tmp); if (tmp.sigh & 0x80000000) return -1; /* |Arg| is >= 2^63 */ tmp.exp = EXP_BIAS + 63; q = *(long long *) &(tmp.sigl); normalize(&tmp); reg_sub(", &tmp, X, FULL_PRECISION); rv = q & 7; control_word = old_cw; return rv;; }
BroswerContent DingWidget::parseInfo() { QStringList search = lines.grep( queryword , isCaseSensitive ); QString current; QString left; QString right; QRegExp reg_div( trenner ); QRegExp reg_word( queryword ); reg_word.setCaseSensitive( isCaseSensitive ); QStringList toplist, bottomlist; QString substitute = "<strong>"+queryword+"</strong>"; for( QStringList::Iterator it = search.begin() ; it != search.end() ; ++it ) { current = *it; left = current.left( current.find( trenner ) ); right = current.right( current.length() - current.find(trenner) - trenner.length() ); if ( left.contains( queryword , isCaseSensitive ) ) { left.replace( queryword, substitute ); left = left + " --> " + right; toplist.append( left ); } else if( right.contains( queryword , isCaseSensitive ) ) { right.replace( queryword, substitute ); right = right + " --> " + left; bottomlist.append( right ); } } s_strings.top = toplist.join( "<br>" ); s_strings.bottom = bottomlist.join( "<br>" ); return s_strings; }
static int math_emulate(struct trapframe * tframe) { unsigned char FPU_modrm; unsigned short code; #ifdef LOOKAHEAD_LIMIT int lookahead_limit = LOOKAHEAD_LIMIT; #endif #ifdef PARANOID if (emulating) { printf("ERROR: wm-FPU-emu is not RE-ENTRANT!\n"); } REENTRANT_CHECK(ON); #endif /* PARANOID */ if ((((struct pcb *) curproc->p_addr)->pcb_flags & FP_SOFTFP) == 0) { finit(); control_word = __INITIAL_NPXCW__; ((struct pcb *) curproc->p_addr)->pcb_flags |= FP_SOFTFP; } FPU_info = tframe; FPU_ORIG_EIP = FPU_EIP; /* --pink-- */ if (FPU_CS != 0x001f) { printf("math_emulate: %x : %x\n", FPU_CS, FPU_EIP); panic("FPU emulation in kernel"); } #ifdef notyet /* We cannot handle emulation in v86-mode */ if (FPU_EFLAGS & 0x00020000) { FPU_ORIG_EIP = FPU_EIP; math_abort(FPU_info, SIGILL); } #endif FPU_lookahead = FPU_LOOKAHEAD; if (curproc->p_flag & P_TRACED) FPU_lookahead = 0; do_another_FPU_instruction: REENTRANT_CHECK(OFF); code = fuword((u_int *) FPU_EIP); REENTRANT_CHECK(ON); if ((code & 0xff) == 0x9b) { /* fwait */ if (status_word & SW_Summary) goto do_the_FPU_interrupt; else { FPU_EIP++; goto FPU_instruction_done; } } if (status_word & SW_Summary) { /* Ignore the error for now if the current instruction is a * no-wait control instruction */ /* The 80486 manual contradicts itself on this topic, so I use * the following list of such instructions until I can check * on a real 80486: fninit, fnstenv, fnsave, fnstsw, fnstenv, * fnclex. */ if (!((((code & 0xf803) == 0xe003) || /* fnclex, fninit, * fnstsw */ (((code & 0x3003) == 0x3001) && /* fnsave, fnstcw, * fnstenv, fnstsw */ ((code & 0xc000) != 0xc000))))) { /* This is a guess about what a real FPU might do to * this bit: */ /* status_word &= ~SW_Summary; ****/ /* We need to simulate the action of the kernel to FPU * interrupts here. Currently, the "real FPU" part of * the kernel (0.99.10) clears the exception flags, * sets the registers to empty, and passes information * back to the interrupted process via the cs selector * and operand selector, so we do the same. */ do_the_FPU_interrupt: cs_selector &= 0xffff0000; cs_selector |= (status_word & ~SW_Top) | ((top & 7) << SW_Top_Shift); operand_selector = tag_word(); status_word = 0; top = 0; { int r; for (r = 0; r < 8; r++) { regs[r].tag = TW_Empty; } } REENTRANT_CHECK(OFF); math_abort(SIGFPE); } } FPU_entry_eip = FPU_ORIG_EIP = FPU_EIP; if ((code & 0xff) == 0x66) { /* size prefix */ FPU_EIP++; REENTRANT_CHECK(OFF); code = fuword((u_int *) FPU_EIP); REENTRANT_CHECK(ON); } FPU_EIP += 2; FPU_modrm = code >> 8; FPU_rm = FPU_modrm & 7; if (FPU_modrm < 0300) { /* All of these instructions use the mod/rm byte to get a data * address */ get_address(FPU_modrm); if (!(code & 1)) { unsigned short status1 = status_word; FPU_st0_ptr = &st(0); FPU_st0_tag = FPU_st0_ptr->tag; /* Stack underflow has priority */ if (NOT_EMPTY_0) { switch ((code >> 1) & 3) { case 0: reg_load_single(); break; case 1: reg_load_int32(); break; case 2: reg_load_double(); break; case 3: reg_load_int16(); break; } /* No more access to user memory, it is safe * to use static data now */ FPU_st0_ptr = &st(0); FPU_st0_tag = FPU_st0_ptr->tag; /* NaN operands have the next priority. */ /* We have to delay looking at st(0) until * after loading the data, because that data * might contain an SNaN */ if ((FPU_st0_tag == TW_NaN) || (FPU_loaded_data.tag == TW_NaN)) { /* Restore the status word; we might * have loaded a denormal. */ status_word = status1; if ((FPU_modrm & 0x30) == 0x10) { /* fcom or fcomp */ EXCEPTION(EX_Invalid); setcc(SW_C3 | SW_C2 | SW_C0); if (FPU_modrm & 0x08) pop(); /* fcomp, so we pop. */ } else real_2op_NaN(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr); goto reg_mem_instr_done; } switch ((FPU_modrm >> 3) & 7) { case 0: /* fadd */ reg_add(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr, control_word); break; case 1: /* fmul */ reg_mul(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr, control_word); break; case 2: /* fcom */ compare_st_data(); break; case 3: /* fcomp */ compare_st_data(); pop(); break; case 4: /* fsub */ reg_sub(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr, control_word); break; case 5: /* fsubr */ reg_sub(&FPU_loaded_data, FPU_st0_ptr, FPU_st0_ptr, control_word); break; case 6: /* fdiv */ reg_div(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr, control_word); break; case 7: /* fdivr */ if (FPU_st0_tag == TW_Zero) status_word = status1; /* Undo any denorm tag, * zero-divide has * priority. */ reg_div(&FPU_loaded_data, FPU_st0_ptr, FPU_st0_ptr, control_word); break; } } else { if ((FPU_modrm & 0x30) == 0x10) {
/*--- poly_atan() -----------------------------------------------------------+ | | +---------------------------------------------------------------------------*/ void poly_atan(FPU_REG * arg) { char recursions = 0; short exponent; FPU_REG odd_poly, even_poly, pos_poly, neg_poly; FPU_REG argSq; long long arg_signif, argSqSq; #ifdef PARANOID if (arg->sign != 0) { /* Can't hack a number < 0.0 */ arith_invalid(arg); return; } /* Need a positive number */ #endif /* PARANOID */ exponent = arg->exp - EXP_BIAS; if (arg->tag == TW_Zero) { /* Return 0.0 */ reg_move(&CONST_Z, arg); return; } if (exponent >= -2) { /* argument is in the range [0.25 .. 1.0] */ if (exponent >= 0) { #ifdef PARANOID if ((exponent == 0) && (arg->sigl == 0) && (arg->sigh == 0x80000000)) #endif /* PARANOID */ { reg_move(&CONST_PI4, arg); return; } #ifdef PARANOID EXCEPTION(EX_INTERNAL | 0x104); /* There must be a logic * error */ #endif /* PARANOID */ } /* If the argument is greater than sqrt(2)-1 (=0.414213562...) */ /* convert the argument by an identity for atan */ if ((exponent >= -1) || (arg->sigh > 0xd413ccd0)) { FPU_REG numerator, denom; recursions++; arg_signif = *(long long *) &(arg->sigl); if (exponent < -1) { if (shrx(&arg_signif, -1 - exponent) >= (unsigned)0x80000000) arg_signif++; /* round up */ } *(long long *) &(numerator.sigl) = -arg_signif; numerator.exp = EXP_BIAS - 1; normalize(&numerator); /* 1 - arg */ arg_signif = *(long long *) &(arg->sigl); if (shrx(&arg_signif, -exponent) >= (unsigned)0x80000000) arg_signif++; /* round up */ *(long long *) &(denom.sigl) = arg_signif; denom.sigh |= 0x80000000; /* 1 + arg */ arg->exp = numerator.exp; reg_u_div(&numerator, &denom, arg, FULL_PRECISION); exponent = arg->exp - EXP_BIAS; } } *(long long *) &arg_signif = *(long long *) &(arg->sigl); #ifdef PARANOID /* This must always be true */ if (exponent >= -1) { EXCEPTION(EX_INTERNAL | 0x120); /* There must be a logic error */ } #endif /* PARANOID */ /* shift the argument right by the required places */ if (shrx(&arg_signif, -1 - exponent) >= (unsigned)0x80000000) arg_signif++; /* round up */ /* Now have arg_signif with binary point at the left .1xxxxxxxx */ mul64(&arg_signif, &arg_signif, (long long *) (&argSq.sigl)); mul64((long long *) (&argSq.sigl), (long long *) (&argSq.sigl), &argSqSq); /* will be a valid positive nr with expon = 0 */ *(short *) &(pos_poly.sign) = 0; pos_poly.exp = EXP_BIAS; /* Do the basic fixed point polynomial evaluation */ polynomial(&pos_poly.sigl, (unsigned *) &argSqSq, (unsigned short (*)[4]) oddplterms, HIPOWERop - 1); mul64((long long *) (&argSq.sigl), (long long *) (&pos_poly.sigl), (long long *) (&pos_poly.sigl)); /* will be a valid positive nr with expon = 0 */ *(short *) &(neg_poly.sign) = 0; neg_poly.exp = EXP_BIAS; /* Do the basic fixed point polynomial evaluation */ polynomial(&neg_poly.sigl, (unsigned *) &argSqSq, (unsigned short (*)[4]) oddnegterms, HIPOWERon - 1); /* Subtract the mantissas */ *((long long *) (&pos_poly.sigl)) -= *((long long *) (&neg_poly.sigl)); reg_move(&pos_poly, &odd_poly); poly_add_1(&odd_poly); /* The complete odd polynomial */ reg_u_mul(&odd_poly, arg, &odd_poly, FULL_PRECISION); /* will be a valid positive nr with expon = 0 */ *(short *) &(even_poly.sign) = 0; mul64((long long *) (&argSq.sigl), (long long *) (&denomterm), (long long *) (&even_poly.sigl)); poly_add_1(&even_poly); reg_div(&odd_poly, &even_poly, arg, FULL_PRECISION); if (recursions) reg_sub(&CONST_PI4, arg, arg, FULL_PRECISION); }
void fdiv_i() { /* fdiv st(i),st */ reg_div(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); }
void fdivri() { /* fdivr st(i),st */ reg_div(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); }
void fdivr_() { /* fdivr st,st(i) */ reg_div(&st(FPU_rm), FPU_st0_ptr, FPU_st0_ptr, control_word); }
void fdiv__() { /* fdiv st,st(i) */ reg_div(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word); }
/*--- poly_tan() ------------------------------------------------------------+ | | +---------------------------------------------------------------------------*/ void poly_tan(FPU_REG * arg, FPU_REG * y_reg) { char invert = 0; short exponent; FPU_REG odd_poly, even_poly, pos_poly, neg_poly; FPU_REG argSq; long long arg_signif, argSqSq; exponent = arg->exp - EXP_BIAS; if (arg->tag == TW_Zero) { /* Return 0.0 */ reg_move(&CONST_Z, y_reg); return; } if (exponent >= -1) { /* argument is in the range [0.5 .. 1.0] */ if (exponent >= 0) { #ifdef PARANOID if ((exponent == 0) && (arg->sigl == 0) && (arg->sigh == 0x80000000)) #endif /* PARANOID */ { arith_overflow(y_reg); return; } #ifdef PARANOID EXCEPTION(EX_INTERNAL | 0x104); /* There must be a logic * error */ return; #endif /* PARANOID */ } /* The argument is in the range [0.5 .. 1.0) */ /* Convert the argument to a number in the range (0.0 .. 0.5] */ *((long long *) (&arg->sigl)) = -*((long long *) (&arg->sigl)); normalize(arg); /* Needed later */ exponent = arg->exp - EXP_BIAS; invert = 1; } #ifdef PARANOID if (arg->sign != 0) { /* Can't hack a number < 0.0 */ arith_invalid(y_reg); return; } /* Need a positive number */ #endif /* PARANOID */ *(long long *) &arg_signif = *(long long *) &(arg->sigl); if (exponent < -1) { /* shift the argument right by the required places */ if (shrx(&arg_signif, -1 - exponent) >= (unsigned)0x80000000) arg_signif++; /* round up */ } mul64(&arg_signif, &arg_signif, (long long *) (&argSq.sigl)); mul64((long long *) (&argSq.sigl), (long long *) (&argSq.sigl), &argSqSq); /* will be a valid positive nr with expon = 0 */ *(short *) &(pos_poly.sign) = 0; pos_poly.exp = EXP_BIAS; /* Do the basic fixed point polynomial evaluation */ polynomial((u_int *) &pos_poly.sigl, (unsigned *) &argSqSq, oddplterms, HIPOWERop - 1); /* will be a valid positive nr with expon = 0 */ *(short *) &(neg_poly.sign) = 0; neg_poly.exp = EXP_BIAS; /* Do the basic fixed point polynomial evaluation */ polynomial((u_int *) &neg_poly.sigl, (unsigned *) &argSqSq, oddnegterms, HIPOWERon - 1); mul64((long long *) (&argSq.sigl), (long long *) (&neg_poly.sigl), (long long *) (&neg_poly.sigl)); /* Subtract the mantissas */ *((long long *) (&pos_poly.sigl)) -= *((long long *) (&neg_poly.sigl)); /* Convert to 64 bit signed-compatible */ pos_poly.exp -= 1; reg_move(&pos_poly, &odd_poly); normalize(&odd_poly); reg_mul(&odd_poly, arg, &odd_poly, FULL_PRECISION); reg_u_add(&odd_poly, arg, &odd_poly, FULL_PRECISION); /* This is just the odd * polynomial */ /* will be a valid positive nr with expon = 0 */ *(short *) &(pos_poly.sign) = 0; pos_poly.exp = EXP_BIAS; /* Do the basic fixed point polynomial evaluation */ polynomial((u_int *) &pos_poly.sigl, (unsigned *) &argSqSq, evenplterms, HIPOWERep - 1); mul64((long long *) (&argSq.sigl), (long long *) (&pos_poly.sigl), (long long *) (&pos_poly.sigl)); /* will be a valid positive nr with expon = 0 */ *(short *) &(neg_poly.sign) = 0; neg_poly.exp = EXP_BIAS; /* Do the basic fixed point polynomial evaluation */ polynomial((u_int *) &neg_poly.sigl, (unsigned *) &argSqSq, evennegterms, HIPOWERen - 1); /* Subtract the mantissas */ *((long long *) (&neg_poly.sigl)) -= *((long long *) (&pos_poly.sigl)); /* and multiply by argSq */ /* Convert argSq to a valid reg number */ *(short *) &(argSq.sign) = 0; argSq.exp = EXP_BIAS - 1; normalize(&argSq); /* Convert to 64 bit signed-compatible */ neg_poly.exp -= 1; reg_move(&neg_poly, &even_poly); normalize(&even_poly); reg_mul(&even_poly, &argSq, &even_poly, FULL_PRECISION); reg_add(&even_poly, &argSq, &even_poly, FULL_PRECISION); reg_sub(&CONST_1, &even_poly, &even_poly, FULL_PRECISION); /* This is just the even * polynomial */ /* Now ready to copy the results */ if (invert) { reg_div(&even_poly, &odd_poly, y_reg, FULL_PRECISION); } else { reg_div(&odd_poly, &even_poly, y_reg, FULL_PRECISION); } }