Ejemplo n.º 1
0
Archivo: stubs.c Proyecto: E-LLP/VICAR
/*
 *  Raise num to exp (an integer)
 */
FUNCTION DOUBLE power 
(
    DOUBLE	num,		/* input: the number to raise		*/
    FUNINT	exp		/* input: the exponent			*/

 )
    {
    DOUBLE	temp;
    TAEINT	i;


    temp = 1;
    if (exp>=0)
    	{
        for(i=1; i<=exp; i++)
       	    if (fl_mult(temp, num, &temp) != SUCCESS)   /* floating mult routine */
    		return(0);		/* failure			*/
        return(temp);
        }
    else
    	{
    	for (i=1; i <= -exp; i++)
    	    if (fl_div(temp, num, &temp) != SUCCESS)
    		return(0);
    	return(temp);
    	}
    }
Ejemplo n.º 2
0
static sCmdArg eval_binOpExp(const sASTNode *node,octa offset,bool *finished) {
	sCmdArg res = {ARGVAL_INT,ORG_EXPR,0,{0}};
	sCmdArg left = eval_get(node->d.binOpExp.left,offset,finished);
	sCmdArg right = eval_get(node->d.binOpExp.right,offset,finished);
	if(left.type == ARGVAL_STR || right.type == ARGVAL_STR)
		cmds_throwEx("Unsupported operation!\n");

	if(left.type == ARGVAL_FLOAT || right.type == ARGVAL_FLOAT) {
		unsigned ex;
		if(left.type != ARGVAL_FLOAT) {
			left.d.integer = fl_floatit(left.d.integer,0,true,false,&ex);
			left.type = ARGVAL_FLOAT;
		}
		if(right.type != ARGVAL_FLOAT) {
			right.d.integer = fl_floatit(right.d.integer,0,true,false,&ex);
			right.type = ARGVAL_FLOAT;
		}

		res.type = ARGVAL_FLOAT;
		switch(node->d.binOpExp.op) {
			case BINOP_ADD:
				res.d.integer = fl_add(left.d.integer,right.d.integer,&ex);
				break;
			case BINOP_SUB:
				res.d.integer = fl_sub(left.d.integer,right.d.integer,&ex);
				break;
			case BINOP_MULU:
			case BINOP_MUL:
				res.d.integer = fl_mult(left.d.integer,right.d.integer,&ex);
				break;
			case BINOP_DIVU:
			case BINOP_DIV:
				res.d.integer = fl_divide(left.d.integer,right.d.integer,&ex);
				break;
			case BINOP_MODU:
			case BINOP_MOD:
				// 2500 makes sure that the remainder can be calculated in one step
				res.d.integer = fl_remstep(left.d.integer,right.d.integer,2500,&ex);
				break;

			case BINOP_AND:
			case BINOP_OR:
			case BINOP_XOR:
			case BINOP_SL:
			case BINOP_SAR:
			case BINOP_SR:
				cmds_throwEx("Unsupported operation!\n");
				break;

			default:
				assert(false);
				break;
		}
	}
	else {
		// note: some of the operations are the same on x86 and mmix. but some of them aren't.
		// therefore, we use the mmix-integer-arithmetic-functions if they are different.
		octa aux;
		switch(node->d.binOpExp.op) {
			case BINOP_ADD:
				res.d.integer = left.d.integer + right.d.integer;
				break;
			case BINOP_SUB:
				res.d.integer = left.d.integer - right.d.integer;
				break;
			case BINOP_MUL:
				res.d.integer = int_smult(left.d.integer,right.d.integer,&aux);
				break;
			case BINOP_MULU:
				res.d.integer = int_umult(left.d.integer,right.d.integer,&aux);
				break;
			case BINOP_DIV:
				res.d.integer = int_sdiv(left.d.integer,right.d.integer,&aux);
				break;
			case BINOP_DIVU:
				res.d.integer = int_udiv(0,left.d.integer,right.d.integer,&aux);
				break;
			case BINOP_MOD:
				int_sdiv(left.d.integer,right.d.integer,&aux);
				res.d.integer = aux;
				break;
			case BINOP_MODU:
				int_udiv(0,left.d.integer,right.d.integer,&aux);
				res.d.integer = aux;
				break;
			case BINOP_AND:
				res.d.integer = left.d.integer & right.d.integer;
				break;
			case BINOP_OR:
				res.d.integer = left.d.integer | right.d.integer;
				break;
			case BINOP_XOR:
				res.d.integer = left.d.integer ^ right.d.integer;
				break;
			case BINOP_SL:
				res.d.integer = int_shiftLeft(left.d.integer,right.d.integer);
				break;
			case BINOP_SAR:
				res.d.integer = int_shiftRightArith(left.d.integer,right.d.integer);
				break;
			case BINOP_SR:
				res.d.integer = int_shiftRightLog(left.d.integer,right.d.integer);
				break;
			default:
				assert(false);
				break;
		}
	}
	if(offset == 0)
		*finished = false;
	return res;
}