Beispiel #1
0
void
faddp_()
{
	/* faddp st(i),st */
	reg_add(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
	pop();
}
Beispiel #2
0
static void
f2xm1(void)
{
    switch (FPU_st0_tag) {
    case TW_Valid:
    {
        FPU_REG rv, tmp;

#ifdef DENORM_OPERAND
        if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
            return;
#endif				/* DENORM_OPERAND */

        if (FPU_st0_ptr->sign == SIGN_POS) {
            /* poly_2xm1(x) requires 0 < x < 1. */
            if (poly_2xm1(FPU_st0_ptr, &rv))
                return;	/* error */
            reg_mul(&rv, FPU_st0_ptr, FPU_st0_ptr, FULL_PRECISION);
        } else {
            /* **** Should change poly_2xm1() to at least handle numbers near 0 */
            /* poly_2xm1(x) doesn't handle negative
             * numbers. */
            /* So we compute (poly_2xm1(x+1)-1)/2, for -1
             * < x < 0 */
            reg_add(FPU_st0_ptr, &CONST_1, &tmp, FULL_PRECISION);
            poly_2xm1(&tmp, &rv);
            reg_mul(&rv, &tmp, &tmp, FULL_PRECISION);
            reg_sub(&tmp, &CONST_1, FPU_st0_ptr, FULL_PRECISION);
            FPU_st0_ptr->exp--;
            if (FPU_st0_ptr->exp <= EXP_UNDER)
                arith_underflow(FPU_st0_ptr);
        }
        return;
    }
    case TW_Zero:
        return;
    case TW_Infinity:
        if (FPU_st0_ptr->sign == SIGN_NEG) {
            /* -infinity gives -1 (p16-10) */
            reg_move(&CONST_1, FPU_st0_ptr);
            FPU_st0_ptr->sign = SIGN_NEG;
        }
        return;
    default:
        single_arg_error();
    }
}
Beispiel #3
0
int wmain(int argc, WCHAR *argvW[])
{
    int i;

    static const WCHAR addW[] = {'a','d','d',0};
    static const WCHAR deleteW[] = {'d','e','l','e','t','e',0};
    static const WCHAR queryW[] = {'q','u','e','r','y',0};
    static const WCHAR slashDW[] = {'/','d',0};
    static const WCHAR slashFW[] = {'/','f',0};
    static const WCHAR slashHW[] = {'/','h',0};
    static const WCHAR slashSW[] = {'/','s',0};
    static const WCHAR slashTW[] = {'/','t',0};
    static const WCHAR slashVW[] = {'/','v',0};
    static const WCHAR slashVAW[] = {'/','v','a',0};
    static const WCHAR slashVEW[] = {'/','v','e',0};
    static const WCHAR slashHelpW[] = {'/','?',0};

    if (argc < 2 || !lstrcmpW(argvW[1], slashHelpW)
            || !lstrcmpiW(argvW[1], slashHW))
    {
        reg_message(STRING_USAGE);
        return 0;
    }

    if (!lstrcmpiW(argvW[1], addW))
    {
        WCHAR *key_name, *value_name = NULL, *type = NULL, separator = '\0', *data = NULL;
        BOOL value_empty = FALSE, force = FALSE;

        if (argc < 3)
        {
            reg_message(STRING_INVALID_CMDLINE);
            return 1;
        }
        else if (argc == 3 && (!lstrcmpW(argvW[2], slashHelpW) ||
                               !lstrcmpiW(argvW[2], slashHW)))
        {
            reg_message(STRING_ADD_USAGE);
            return 0;
        }

        key_name = argvW[2];
        for (i = 1; i < argc; i++)
        {
            if (!lstrcmpiW(argvW[i], slashVW))
                value_name = argvW[++i];
            else if (!lstrcmpiW(argvW[i], slashVEW))
                value_empty = TRUE;
            else if (!lstrcmpiW(argvW[i], slashTW))
                type = argvW[++i];
            else if (!lstrcmpiW(argvW[i], slashSW))
                separator = argvW[++i][0];
            else if (!lstrcmpiW(argvW[i], slashDW))
                data = argvW[++i];
            else if (!lstrcmpiW(argvW[i], slashFW))
                force = TRUE;
        }
        return reg_add(key_name, value_name, value_empty, type, separator,
                       data, force);
    }
    else if (!lstrcmpiW(argvW[1], deleteW))
    {
        WCHAR *key_name, *value_name = NULL;
        BOOL value_empty = FALSE, value_all = FALSE, force = FALSE;

        if (argc < 3)
        {
            reg_message(STRING_INVALID_CMDLINE);
            return 1;
        }
        else if (argc == 3 && (!lstrcmpW(argvW[2], slashHelpW) ||
                               !lstrcmpiW(argvW[2], slashHW)))
        {
            reg_message(STRING_DELETE_USAGE);
            return 0;
        }

        key_name = argvW[2];
        for (i = 1; i < argc; i++)
        {
            if (!lstrcmpiW(argvW[i], slashVW))
                value_name = argvW[++i];
            else if (!lstrcmpiW(argvW[i], slashVEW))
                value_empty = TRUE;
            else if (!lstrcmpiW(argvW[i], slashVAW))
                value_all = TRUE;
            else if (!lstrcmpiW(argvW[i], slashFW))
                force = TRUE;
        }
        return reg_delete(key_name, value_name, value_empty, value_all, force);
    }
    else if (!lstrcmpiW(argvW[1], queryW))
    {
        WCHAR *key_name, *value_name = NULL;
        BOOL value_empty = FALSE, subkey = FALSE;

        if (argc < 3)
        {
            reg_message(STRING_INVALID_CMDLINE);
            return 1;
        }
        else if (argc == 3 && (!lstrcmpW(argvW[2], slashHelpW) ||
                               !lstrcmpiW(argvW[2], slashHW)))
        {
            reg_message(STRING_QUERY_USAGE);
            return 0;
        }

        key_name = argvW[2];
        for (i = 1; i < argc; i++)
        {
            if (!lstrcmpiW(argvW[i], slashVW))
                value_name = argvW[++i];
            else if (!lstrcmpiW(argvW[i], slashVEW))
                value_empty = TRUE;
            else if (!lstrcmpiW(argvW[i], slashSW))
                subkey = TRUE;
        }
        return reg_query(key_name, value_name, value_empty, subkey);
    }
    else
    {
        reg_message(STRING_INVALID_CMDLINE);
        return 1;
    }
}
Beispiel #4
0
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) {
Beispiel #5
0
void
fadd__()
{
	/* fadd st,st(i) */
	reg_add(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word);
}
Beispiel #6
0
void
fadd_i()
{
	/* fadd st(i),st */
	reg_add(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
}
Beispiel #7
0
/*--- 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);
	}

}
Beispiel #8
0
/**
 * Allocate a SIP User-Agent
 *
 * @param uap   Pointer to allocated User-Agent object
 * @param aor   SIP Address-of-Record (AOR)
 *
 * @return 0 if success, otherwise errorcode
 */
int ua_alloc(struct ua **uap, const char *aor)
{
	struct ua *ua;
	int err;

	if (!aor)
		return EINVAL;

	ua = mem_zalloc(sizeof(*ua), ua_destructor);
	if (!ua)
		return ENOMEM;

	MAGIC_INIT(ua);

	list_init(&ua->calls);

#if HAVE_INET6
	ua->af   = uag.prefer_ipv6 ? AF_INET6 : AF_INET;
#else
	ua->af   = AF_INET;
#endif

	/* Decode SIP address */

	err = account_alloc(&ua->acc, aor);
	if (err)
		goto out;

	/* generate a unique contact-user, this is needed to route
	   incoming requests when using multiple useragents */
	err = re_sdprintf(&ua->cuser, "%r-%p", &ua->acc->luri.user, ua);
	if (err)
		goto out;

	if (ua->acc->sipnat) {
		ua_printf(ua, "Using sipnat: `%s'\n", ua->acc->sipnat);
	}

	if (ua->acc->mnat) {
		ua_printf(ua, "Using medianat `%s'\n",
			  ua->acc->mnat->id);

		if (0 == str_casecmp(ua->acc->mnat->id, "ice"))
			add_extension(ua, "ice");
	}

	if (ua->acc->menc) {
		ua_printf(ua, "Using media encryption `%s'\n",
			  ua->acc->menc->id);
	}

	/* Register clients */
	if (str_isset(uag.cfg->uuid))
	        add_extension(ua, "gruu");

	if (0 == str_casecmp(ua->acc->sipnat, "outbound")) {

		size_t i;

		add_extension(ua, "path");
		add_extension(ua, "outbound");

		if (!str_isset(uag.cfg->uuid)) {

			warning("ua: outbound requires valid UUID!\n");
			err = ENOSYS;
			goto out;
		}

		for (i=0; i<ARRAY_SIZE(ua->acc->outbound); i++) {

			if (ua->acc->outbound[i] && ua->acc->regint) {
				err = reg_add(&ua->regl, ua, (int)i+1);
				if (err)
					break;
			}
		}
	}
	else if (ua->acc->regint) {
		err = reg_add(&ua->regl, ua, 0);
	}
	if (err)
		goto out;

	list_append(&uag.ual, &ua->le, ua);

	if (ua->acc->regint) {
		err = ua_register(ua);
	}

	if (!uag_current())
		uag_current_set(ua);

 out:
	if (err)
		mem_deref(ua);
	else if (uap) {
		*uap = ua;

		ua->uap = uap;
	}

	return err;
}