⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccmmath_cpu.s

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 S
📖 第 1 页 / 共 5 页
字号:
	orrne	MANT1, MANT1, #20        cmp     EXP1, #1        bge     _floatRoundResult       /* Go round the result and exit. */        b       _fmulDoGradualUnderflowLABEL(_fdivFloatCheckForNaNOrInfinity)        /* Check if float1 is NaN or infinity: */        cmp     EXP1, #0xff             /* Check for infinity or nan. */        beq     _fdivFloat1CheckForNaNOrInfinity        /* Else, float2 is NaN or infinity: */LABEL(_fdivFloat2CheckForNaNOrInfinity)        /* If we get here, then float1 is not nan nor infinity: */        cmp     MANT2, #0               /* Check for infinity. */        bne     _floatReturnNaN         /* finite / nan => nan. */        /* Else, float2 is an infinity.  Result is 0 */	FLOAT_RETURN_TO_CALLER	 	/* Return the result. */LABEL(_fdivFloat1CheckForNaNOrInfinity)        cmp     MANT1, #0               /* Check for infinity. */        bne     _floatReturnNaN         /* nan / ? => nan. */        /* Else, float1 is an infinity.  Check float2 for nan or infinity: */        cmp     EXP2, #0xff        bne     _floatReturnInfinity	/* inf / finite => inf */        b       _floatReturnNaN         /* inf / {nan or inf} => nan. */#ifndef __RVCT__#define FLOAT_NORMALIZE_LOOP( _MANT, _EXP ) \        mov     _EXP, #1;		\1:					\	mov	_MANT, _MANT, LSL #1;	\	sub	_EXP, _EXP, #1;		\	cmp	_MANT, #0x800000;	\	blt	1b#else	MACRO	FLOAT_NORMALIZE_LOOP0 $_MANT, $_EXP	mov     $_EXP, #11	mov	$_MANT, $_MANT, LSL #1	sub	$_EXP, $_EXP, #1	cmp	$_MANT, #0x800000	blt	%b1	MEND#define FLOAT_NORMALIZE_LOOP( _MANT, _EXP ) \	FLOAT_NORMALIZE_LOOP0 _MANT, _EXP#endifLABEL(_fdivCheckFloat1ForZero)        /* If we get here, then float1 and float2 are finite: */        cmp     MANT1, #0               /* Check for 0. */        beq     _fdivFloat1IsZero	FLOAT_NORMALIZE_LOOP( MANT1, EXP1 )        b       _fdivFloat1IsNotZeroLABEL(_fdivFloat1IsZero)	cmp	EXP2, #0	cmpeq	MANT2, #0	FLOAT_RETURN_TO_CALLER_IF(ne) /* result = sign | 0. Return to caller. */	b	_floatReturnNaN		/* 0 / 0 => NaN */LABEL(_fdivCheckFloat2ForZero)        /* If we get here, then float1 is finite and non-zero: */        cmp     MANT2, #0               /* Check for 0. */        beq     _floatReturnInfinity	FLOAT_NORMALIZE_LOOP( MANT2, EXP2 )        b       _fdivFloat2IsNotZero#undef FLOAT1#undef FLOAT2#undef EXP1#undef EXP2#undef MANT1#undef MANT2#undef EMASK#undef MMASK#undef ITER#undef QUOT/* * Entry point for converting floats to doubles. * NOTE: The result is in FLOAT (high word) and MANT (low word). */	ENTRY(CVMCCMruntimeF2D)ENTRY1 ( CVMCCMruntimeF2D )	ENTRY(CVMCCMruntimeF2D_C)ENTRY1 ( CVMCCMruntimeF2D_C )        /* r0 = a1 = float1          * v1 = jfp           * v2 = jsp          * sp = ccee	 */#if CVM_DOUBLE_ENDIANNESS == CVM_BIG_ENDIAN#define FLOAT   r0#define MANT    r1#elif CVM_DOUBLE_ENDIANNESS == CVM_LITTLE_ENDIAN#define FLOAT   r1#define MANT    r0#endif#define EXP     r2#define EMASK   r3#define MMASK   r3        ldr     MMASK, floatMantissaMask#if CVM_DOUBLE_ENDIANNESS == CVM_LITTLE_ENDIAN        mov     FLOAT, r0#endif        and     MANT, FLOAT, MMASK          /* Extract the mantissa. */        mov     EMASK, #0xff        and     EXP, FLOAT, EMASK, LSL #23  /* Extract the exponent. */        /* Check for NaNs or infinities: */        cmp     EXP, EMASK, LSL #23        beq     _f2dHandleNaNOrInfinity     /* Go handle the nan or infinity. */        /* Prepare the mantissa for conversion: */        mov     MANT, MANT, LSL #9          /* Remove the leading zeroes. */        cmp     EXP, #0                    /* Check for a denormalized number. */        beq     _f2dHandleDenormalized        /* Set the new exponent: */        mov     EXP, EXP, LSR #3            /* The new exponent is 11 bits. */        add     EXP, EXP, #0x38000000       /* Add the difference in the bias. */LABEL(_f2dSetMantissaAndSignAndReturn)        /* Set the new mantissa: */        orr     EXP, EXP, MANT, LSR #12     /* Mask in the mantissa high bits. */        mov     MANT, MANT, LSL #20         /* Set the low bits. */LABEL(_f2dSetSignAndReturn)        /* Set the sign of the result: */        and     FLOAT, FLOAT, #0x80000000   /* Copy the sign. */        orr     FLOAT, FLOAT, EXP           /* Add the exponent and high mant. */        mov     pc, lr                      /* Return to caller. */LABEL(_f2dHandleNaNOrInfinity)        ldr     EXP, doubleExponentMask     /* Set the special exponent. */        /* Note: If the mantissa is 0, then we have an infinity which requires           that we return 0 in MANT.  If the mantissa is not zero, then we	   have a NaN which requires a non zero mantissa which we already	   have.  Hence, there is nothing to do. */        b       _f2dSetSignAndReturn        /* Return to caller. */LABEL(_f2dHandleDenormalized)        cmp     MANT, #0                    /* Check if float is 0. */        /* If the mantissa is 0, then we have a 0 float which requires 0 in           MANT. */        beq     _f2dSetSignAndReturn        /* Return to caller. */        /* If we get here, then there must be a non zero bit somewhere in the           mantissa.  Just shift left until we get it normalized.  Not that           we also don't have to check for underflow because every non-zero           finite float number can be expressed as a normalized double. */        /* Convert the exponent.           NOTE: float exponent 1 = double exponent 1 - 127 + 1023 = 897                                  = 0x381 = 0x380 + 1: */        mov     EXP, #0x38000000        add     EXP, EXP, #0x00100000        /* Normalize the mantissa: */LABEL(_f2dNormalizing)        sub     EXP, EXP, #0x00100000        movs    MANT, MANT, LSL #1  /* Shift left until high bit is seen. */        bcc     _f2dNormalizing     /* High bit not seen yet, continue. */        b       _f2dSetMantissaAndSignAndReturn#undef FLOAT#undef EXP#undef EMASK#undef MMASK#undef MANT/* * Entry point for comparing doubles. * NOTE: The result is in the condition codes that have been set by various *       comparisons. Even though the C prototype for this helper indicates *       that the helper is to return an integer status in a register, this *       assembly version returns the result in the CPU condition code *       register (thus effectively making the return type of the function *       void).  This is OK because the ARM specific rules which emits calls *       to this helper function will be expecting the result to be in the *       condition code register.  This method of returning the result is *       done for optimization purposes. */	ENTRY(CVMCCMruntimeDCmpg)ENTRY1 ( CVMCCMruntimeDCmpg )	ENTRY(CVMCCMruntimeDCmpg_C)ENTRY1 ( CVMCCMruntimeDCmpg_C )        /* r0 = a1 = double1 high          * r1 = a2 = double1 low          * r2 = a3 = double2 high          * r3 = a4 = double2 low          * v1 = jfp           * v2 = jsp          * sp = ccee 	 */        orr     lr, lr, #0x2            /* NaN returns 'greater than' status.*/        /* Fall through to _dcmpStart: */	ENTRY(CVMCCMruntimeDCmpl)ENTRY1 ( CVMCCMruntimeDCmpl )	ENTRY(CVMCCMruntimeDCmpl_C)ENTRY1 ( CVMCCMruntimeDCmpl_C )        /* r0 = a1 = double1 high          * r1 = a2 = double1 low          * r2 = a3 = double2 high          * r3 = a4 = double2 low          * v1 = jfp           * v2 = jsp          * sp = ccee	 */        /* NaN returns 'less than' status. */        /* uses r0, r1, r2, r3, r12 */LABEL(_dcmpStart)/* Registers definition for different endianness. */#if CVM_DOUBLE_ENDIANNESS == CVM_BIG_ENDIAN#define DBL1LO  r1#define DBL1HI  r0#define DBL2LO  r3#define DBL2HI  r2#elif CVM_DOUBLE_ENDIANNESS == CVM_LITTLE_ENDIAN#define DBL1LO  r0#define DBL1HI  r1#define DBL2LO  r2#define DBL2HI  r3#endif        /* Check for NaN in double1 and double2.  Note that the double value           can only be a NaN if the exponent value is 0x7ff00000.  This means           that adding 0x00100000 to it will result in a negative value i.e.           0x80000000.  We can check for this without using yet another           register: */        /* Check double1 for a NaN: */        ldr     r12, doubleExponentMask /* load the exponent mask. */        and     r12, DBL1HI, r12        /* Extract exponent1. */        adds    r12, r12, #0x00100000   /* Check for infinity or nan. */        bmi     _dcmpDouble1CheckForNanLABEL(_dcmpDouble1IsNotNan)        /* Check double2 for a NaN: */        ldr     r12, doubleExponentMask /* load the exponent mask. */        and     r12, DBL2HI, r12        /* Extract exponent2. */        adds    r12, r12, #0x00100000   /* Check for infinity or nan. */        bmi     _dcmpDouble2CheckForNanLABEL(_dcmpDouble2IsNotNan)        /* Check if the 2 doubles have the same sign bit: */        eor     r12, DBL1HI, DBL2HI     /* Check to see if the sign bit is the */        tst     r12, #0x80000000        /*    same. */        bne     _dcmpEvaluateResultBasedOnSigns        /* If we get here, then the sign bits are the same.  Next, check if           the sign bits are negative: */        tst     DBL1HI, #0x80000000         /* Check for negative sign bit. */        bic     DBL1HI, DBL1HI, #0x80000000 /* Clear the sign bit. */        bic     DBL2HI, DBL2HI, #0x80000000 /* Clear the sign bit. */        bne     _dcmpDoNegativeChecks        /* Do positive version of checks: */        /* Compare high word: */        cmp     DBL1HI, DBL2HI        bne     _dcmpReturnToCaller     /* If not equal, we have our result. */        /* Compare the mantissas: */        eors    r12, DBL1LO, DBL2LO        bmi     _dcmpPositiveRevLowTest        cmp     DBL1LO, DBL2LO        b       _dcmpReturnToCallerLABEL(_dcmpPositiveRevLowTest)        cmp     DBL2LO, DBL1LO        /* Fall thru to _dcmpReturnToCaller. */LABEL(_dcmpReturnToCaller)        bic     lr, lr, #0x3            /* Clear the low bits set above. */        mov     pc, lr                  /* Return to the caller. */LABEL(_dcmpDoNegativeChecks)        /* Do negative version of checks: */        /* Compare high word: */        cmp     DBL2HI, DBL1HI        bne     _dcmpReturnToCaller     /* If not equal, we have our result. */        /* Compare the mantissa upper low bits: */        mov     r12, DBL2LO, LSR #16        cmp     r12, DBL1LO, LSR #16        bne     _dcmpReturnToCaller     /* If not equal, we have our answer. */        /* Compare the mantissa lower low bits: */        mvn     r12, #0                         /* r12 = 0xffffffff. */        and     DBL1LO, DBL1LO, r12, LSR #16    /* mask with 0xffff. */        and     DBL2LO, DBL2LO, r12, LSR #16    /* mask with 0xffff. */        cmp     DBL2LO, DBL1LO        b       _dcmpReturnToCaller             /* Return the result. */LABEL(_dcmpEvaluateResultBasedOnSigns)        /* Check for the special case where the 2 numbers are zeroes.  If so,           the two are still equal even if their signs are not: */        orrs    r12, DBL1LO, DBL1HI, LSL #1     /* See if double1 is 0. */        bne     _dcmpNotBothZeroes        orrs    r12, DBL2LO, DBL2HI, LSL #1     /* See if double2 is 0. */        beq     _dcmpReturnToCaller             /* Return the result. */LABEL(_dcmpNotBothZeroes)        cmp     DBL1HI, DBL2HI          /* Compare the signs. */        b       _dcmpReturnToCaller     /* Return the result. */LABEL(_dcmpDouble1CheckForNan)        /* Check if the mantissa is 0 i.e. the double is an infinity: */        orrs    r12, DBL1LO, DBL1HI, LSL #12        beq     _dcmpDouble1IsNotNan   /* If is infinity, resume in main code. */        b       _dcmpNanFoundLABEL(_dcmpDouble2CheckForNan)        /* Check if the mantissa is 0 i.e. the double is an infinity: */        orrs    r12, DBL2LO, DBL2HI, LSL #12        beq     _dcmpDouble2IsNotNan   /* If is infinity, resume in main code. */LABEL(_dcmpNanFound)        /* The return value for NaN is encoded in the low 2 bits of the lr           which is normally 0: */        and     r12, lr, #0x3           /* Else, is NaN.  Return the desired */        cmp     r12, #1                 /*   condition code result. */        b       _dcmpReturnToCaller     #undef DBL1LO#undef DBL1HI#undef DBL1LO#undef DBL1HI	ENTRY(CVMCCMruntimeF2I)ENTRY1 ( CVMCCMruntimeF2I )	ENTRY(CVMCCMruntimeF2I_C)ENTRY1 ( CVMCCMruntimeF2I_C )	/*	 * Keep the original argument in r0 (it has the sign)	 * Working registers are F (Fraction) and  EXP (exponent)	 */#define F	r1#define EXP	r2	bic	F, r0, #0x80000000 	/* Strip sign */	subs	EXP, F, #0x3f800000	/* De-bias exponent */	blt	_f2iTooLittle		/* If exponent small, number is < 1 */	cmp	EXP, #(31<<23)		/* If debiased exponent is > 31 */	bhs	_f2iTooBig		/* ...then the number is > max int. */	mov	F, F, LSL #8		/* Shift fraction far to the left */	orr	F, F, #0x80000000	/* ...& insert implicit high order bit */	mov	EXP, EXP, LSR #23	/* Shift the exponent down. */	/* now need to shift F right by 31 - exponent */	/* we know that 31 > EXP >= 0 */	rsb	EXP, EXP, #31	mov	F, F, LSR EXP	/* apply the sign and return */	cmp	r0, #0	rsblt	F, F, #0	mov	r0, F	mov	pc, lr	LABEL(_f2iTooBig)	/* test for Nan, which returns a zero */	cmp	EXP, #(0x7f800000-0x3f800000)	/* (comparing after de-biasing) */	bhi	_f2iTooLittle	ands	r0, r0, #0x80000000	/* check the original sign */	mvnpl	r0, #0x80000000		/* deliver maxint or minint accordingly */	mov	pc, lrLABEL(_f2iTooLittle)	mov	r0, #0	mov	pc, lr

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -