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

📄 ccmmath_cpu.s

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 S
📖 第 1 页 / 共 5 页
字号:
        tmcr    wCGR0, FEXP1        textrcb R15, #7        wzero   wR0        tmia    wR0, FMANT1, FMANT2             /* {wR0} = FMANT1 * FMANT2. */        wsrldg  wR0, wR0, wCGR0        tmrrc   r3, r0, wR0        movpl   r1, #0        movmi   r1, #0x80000000        cmp     r3, #0x80000000        addhs   r0, r0, #1        biceq   r0, r0, #1        eor     r0, r0, r1        mov     pc, lrLABEL(fmul_result_too_big)        tst     r0, #0x01000000                 /* if result has carry, return inf */        bne     fmul_return_inf        movs    r3, r3, lsl #1        adc     r0, r0, #0        bcs     fmul_result_too_big_roundLABEL(fmul_result_too_big_round_done)        tst     r0, #0x01000000                 /* if result has carry, return inf */        bne     fmul_return_inf        textrcb R15, #7        bic     r0, r0, #0x01800000        orrmi   r0, r0, #0x80000000        orr     r0, r0, FEXP1, lsr #1        mov     pc, lrLABEL(fmul_result_too_big_round)        teq     r3, #0        biceq   r0, r0, #1        b       fmul_result_too_big_round_doneLABEL(fmul_fexp_too_big)        cmp     FEXP1, #0x7e000000        blo     fmul_result_normalLABEL(fmul_return_inf)        textrcb R15, #7        mov     r0, #0x7f000000        add     r0, r0, #0x00800000        orrmi   r0, r0, #0x80000000        mov     pc, lr#undef FEXP1#undef FEXP2#undef FMANT1#undef FMANT2#undef SIGN#else        /* The following saves registers that we're going to use and extracts           exponents and mantissa from the floats. */        mov     EMASK, #0xff        /* Setup the pre-shifted exponent mask. */	stmfd	sp!, FLOAT_SAVE_SET        and     EXP1, EMASK, FLOAT1, LSR #23    /* Extract exponent1. */        and     EXP2, EMASK, FLOAT2, LSR #23    /* Extract exponent2. */        mvn     MMASK, #0x80000000        and     MANT1, MMASK, FLOAT1, LSL #8    /* Extract mantissa1. */        and     MANT2, MMASK, FLOAT2, LSL #8    /* Extract mantissa2. */        /* NOTE: r12 is free now because MMASK is no longer needed. */        /* Set the sign bit in r0 and free up r1: */        eor     r0, r0, r1              /* Positive if same, else negative. */        and     r0, r0, #0x80000000     /* Zero out the other bits. */        /* Check if float1 or float2 is NaN or infinity: */        cmp     EXP1, #0xff             /* Check for infinity or nan. */        cmpne   EXP2, #0xff             /* Check for infinity or nan. */        beq     _fmulFloatCheckForNaNOrInfinity        /* Check float1 for 0 or denormalized number: */        cmp    EXP1, #0        beq     _fmulCheckFloat1ForZero        orr     MANT1, MANT1, #0x80000000       /* Set the implied high bit. */LABEL(_fmulFloat1IsNotZero)        cmp     EXP2, #0        beq     _fmulCheckFloat2ForZero        orr     MANT2, MANT2, #0x80000000       /* Set the implied high bit. */LABEL(_fmulFloat2IsNotZero)        /* Now we're ready to do the multiplication.   First add the exponents           together and store the result in EXP1.  EXP2 is free after that: */        sub     EXP1, EXP1, #126        /* exp1 -= 127 (i.e. the bias) + 1. */        add     EXP1, EXP1, EXP2        /* exp1 = exp1 + exp2. */        /* After the multiplication, the resultant binary point will be 2           digits from the high end of the 64 bit number as follows:           result = [xx.xx xxxx xxxx xxxx xxxx xxxx 0000 0000]           But we want the binary point to be 1 from the high end.  To do this           we divide the number by 2 and add 1 to the exponent.  Well, we           don't actually have to divide the number by 2.  We just know that           the binary point is now 1 from the left.           EXP1 is already incremented above.  See how the bias is being           subtracted from it.        */        umull   r3, r1, MANT1, MANT2    /* {hi<r1>,lo<r3>} = MANT1 * MANT2. */        /* NOTE: r6, r7, and r12 are now free again: */        /* Normalize the result: */        cmp     EXP1, #1        blt     _fmulDoGradualUnderflow0        /* Normalize the resultant mantissa if necessary: */        movs    MANT1, r1               /* Put the mantissa in { r6, r3 } */        bmi     _fmulCheckForStickyBit  /* If high bit is set (i.e. already */                                        /*   normalized, then move on. */LABEL(_fmulNormalizing)        cmp     EXP1, #1                /* See if exponent is down to 1. */        beq     _fmulCheckForStickyBit  /* Cannot normalize.  Go wrap-up. */        /* Shift the 64bit number left by 1: */        movs    r3, r3, LSL #1          /* Shift low-order word left by 1. */        sub     EXP1, EXP1, #1          /* exponent--. */        adcs    MANT1, MANT1, MANT1     /* Shift high-order word left by 1. */        bpl     _fmulNormalizing        /* If high bit not set, continue. */        /* Fall through to _fmulCheckForStickyBit. */#endif/* IAI - 16 */LABEL(_fmulCheckForStickyBit)        /* Is already normalized.  Check the sticky bit for rounding: */        cmp     r3, #0        orrne   MANT1, MANT1, #0x20     /* Set the sticky bit if necessary. */        b       _floatRoundResult       /* Go round the result and exit. */LABEL(_fmulDoGradualUnderflow0)        mov     MANT1, r1               /* Put the mantissa in { r6, r3 } */        /* Fall thru to _fmulDoGradualUnderflow: */LABEL(_fmulDoGradualUnderflow)        /* Compute the number of bits we have to shift right by in order to           bring EXP1 up to 1: */        rsb     r7, EXP1, #1        cmp     r7, #31        /* If we have to shift 31 or more bits, then the result must be an           underflow to zero: */	FLOAT_RETURN_TO_CALLER_IF(ge) 	/* result = sign | 0. */        /* Else, shift right and let the rounding do gradual underflow: */        mov     EXP1, #1        orr     r3, r3, MANT1, LSL r7   /* Compute the sticky bit. */        mov     MANT1, MANT1, LSR r7    /* Shift right be said bits. */        b       _fmulCheckForStickyBit  /* Go do rounding for the result. *//* IAI - 16 */#ifndef IAI_WMMX_FMULLABEL(_fmulCheckFloat1ForZero)        /* If we get here, then float1 and float2 are finite: */        cmp     MANT1, #0               /* Check for 0. */	FLOAT_RETURN_TO_CALLER_IF(eq) /* result = sign | 0. Return to caller. */        mov     EXP1, #1                /* Adjust exponent for denormalized #. */        b       _fmulFloat1IsNotZeroLABEL(_fmulCheckFloat2ForZero)        /* If we get here, then float1 and float2 are finite: */        cmp     MANT2, #0               /* Check for 0. */	FLOAT_RETURN_TO_CALLER_IF(eq) /* result = sign | 0. Return to caller. */        mov     EXP2, #1                /* Adjust exponent for denormalized #. */        b       _fmulFloat2IsNotZeroLABEL(_fmulFloatCheckForNaNOrInfinity)        /* Check if float1 is NaN or infinity: */        cmp     EXP1, #0xff             /* Check for infinity or nan. */        beq     _fmulFloat1CheckForNaNOrInfinity        /* Else, float2 is NaN or infinity: */LABEL(_fmulFloat2CheckForNaNOrInfinity)        /* 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.  Check float1 for 0: */        orrs    r12, EXP1, MANT1        /* Check for 0. */        beq     _floatReturnNaN         /* 0 * inf => nan. */        b       _floatReturnInfinity    /* finite * inf => inf. */LABEL(_fmulFloat1CheckForNaNOrInfinity)        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     _fmulFloat1CheckForZeroInFloat2        cmp     MANT2, #0               /* Check for infinity. */        bne     _floatReturnNaN         /* inf * nan => nan. */        b       _floatReturnInfinity    /* inf * inf => inf. */LABEL(_fmulFloat1CheckForZeroInFloat2)        orrs    r12, EXP2, MANT2        /* Check for 0. */        beq     _floatReturnNaN         /* inf * 0 => nan. */        b       _floatReturnInfinity    /* inf * finite => inf. */#endif/* IAI - 16 *//* * The following are common to FAdd, FSub, and FMul: */LABEL(_floatRoundResult)        /* NOTE: _floatRoundResult expects the sign in r0, the exponent in                 EXP1 (i.e. r2), and the normalized mantissa in MANT1 (i.e.                 r6) with the binary point between bit 31 and 30. */        /* Round the mantissa using IEEE 754 round to nearest mode: */        and     r12, MANT1, #0xff      /* Extract the low 8 bits for rounding. */        cmp     r12, #0x80        blt     _floatRoundingDone      /* Round down.  Nothing to do. */        bgt     _floatRoundUp           /* Go round up. */        /* Else round to the nearest 0 in the LSBit in the result mantissa: */        tst     MANT1, #0x100           /* Check LSBit of result mantissa. */        beq     _floatRoundingDone      /* If already 0, then done rounding. */                                        /* Else, round up. */LABEL(_floatRoundUp)        adds    MANT1, MANT1, #0x80        /* After rounding, we have to re-check if we're normalized, and re-           normalize if we're not: */        bcc     _floatRoundingDone        /* If we get here, then the high bit was in the carry.  Move the carry           back into the high bit and adjust the exponent accordingly: */        mov     MANT1, MANT1, LSR #1        orr     MANT1, MANT1, #0x80000000        add     EXP1, EXP1, #1        /* Fall through to _floatRoundingDone. */LABEL(_floatRoundingDone)        /* Now check for overflow to infinities: */        cmp     EXP1, #255        bge     _floatReturnInfinity        /* Check to see if the result is a denormalized number: */        tst     MANT1, #0x80000000        /* If the number is denormalized, mark it as so: */        moveq   EXP1, #0                    /* Indicate denormalized. */        /* Only do the following 2 inst if result is normalized: */        bicne   MANT1, MANT1, #0x80000000   /* Clear the top bit. */        orrne   r0, r0, EXP1, LSL #23       /* Set the exponent. */        mov     MANT1, MANT1, LSR #8        /* Set the mantissa. */        orr     r0, r0, MANT1        /* Fall through to _floatReturnToCaller. */LABEL(_floatReturnToCaller)        /* Restore the saved registers: */	FLOAT_RETURN_TO_CALLER	 	/* Return to caller. */LABEL(_floatReturnInfinity)        mov     r1, #0xff        orr     r0, r0, r1, LSL #23     /* result = sign | infinity. */	FLOAT_RETURN_TO_CALLER	 	/* Return the result */LABEL(_floatReturnNaN)        ldr     r0, floatNaN            /* result = nan. */	FLOAT_RETURN_TO_CALLER	 	/* Return the result *//* * Entry point for dividing floats. * NOTE: The result is in r0. */	ENTRY(CVMCCMruntimeFDiv)ENTRY1 ( CVMCCMruntimeFDiv )	ENTRY(CVMCCMruntimeFDiv_C)ENTRY1 ( CVMCCMruntimeFDiv_C )        /* r0 = a1 = float1          * r1 = a2 = float2          * v1 = jfp          * v2 = jsp          * sp = ccee	 */#define QUOT	r12#define ITER	r3        /* The following saves registers that we're going to use and extracts           exponents and mantissa from the floats. */	stmfd	sp!, FLOAT_SAVE_SET        mov     EMASK, #0xff        /* Setup the pre-shifted exponent mask. */        and     EXP1, EMASK, FLOAT1, LSR #23    /* Extract exponent1. */        and     EXP2, EMASK, FLOAT2, LSR #23    /* Extract exponent2. */	orr	EMASK, EMASK, #0x100        bic     MANT1, FLOAT1, EMASK, LSL #23    /* Extract mantissa1. */        bic     MANT2, FLOAT2, EMASK, LSL #23    /* Extract mantissa2. */        /* Set the sign bit in r0 and free up r1: */        eor     r0, r0, r1              /* Positive if same, else negative. */        and     r0, r0, #0x80000000     /* Zero out the other bits. */        /* Check if float1 or float2 is NaN or infinity: */        cmp     EXP1, #0xff             /* Check for infinity or nan. */        cmpne   EXP2, #0xff             /* Check for infinity or nan. */        beq     _fdivFloatCheckForNaNOrInfinity        /* Check float1 for 0 or denormalized number: */        cmp    EXP1, #0        beq     _fdivCheckFloat1ForZero        orr     MANT1, MANT1, #0x800000       /* Set the implied high bit. */LABEL(_fdivFloat1IsNotZero)        cmp     EXP2, #0        beq     _fdivCheckFloat2ForZero        orr     MANT2, MANT2, #0x800000       /* Set the implied high bit. */LABEL(_fdivFloat2IsNotZero)	/*         * Now we're ready to do the division.   First subtract the exponents         * and store the result in EXP1.  EXP2 is free after that.	 * Ensure that the first digit of the quotient will be a '1'	 * by shifting MANT1 if necessary. Decrease exponent accordingly.	 *	 * Do the division as 25 successive divide steps	 * of MANT1 by MANT2, developing the quotient in QUOT.	 */        sub     EXP1, EXP1, EXP2        /* exp1 = exp1 - exp2. */        add     EXP1, EXP1, #127        /* exp1 += 127 (i.e. the bias) */	cmp	MANT1, MANT2	movlt	MANT1, MANT1, LSL #1	sublt	EXP1,  EXP1, #1	mov	ITER, #25	mov	QUOT, #0	/* loop unrolled by a factor of 5 */LABEL(_fdivIterationLoopTop)	cmp	MANT1, MANT2	subhs	MANT1, MANT1, MANT2	adc	QUOT, QUOT, QUOT	mov	MANT1, MANT1, LSL #1	cmp	MANT1, MANT2	subhs	MANT1, MANT1, MANT2	adc	QUOT, QUOT, QUOT	mov	MANT1, MANT1, LSL #1	cmp	MANT1, MANT2	subhs	MANT1, MANT1, MANT2	adc	QUOT, QUOT, QUOT	mov	MANT1, MANT1, LSL #1	cmp	MANT1, MANT2	subhs	MANT1, MANT1, MANT2	adc	QUOT, QUOT, QUOT	mov	MANT1, MANT1, LSL #1	cmp	MANT1, MANT2	subhs	MANT1, MANT1, MANT2	adc	QUOT, QUOT, QUOT	mov	MANT1, MANT1, LSL #1	subs	ITER, ITER, #5	bgt	_fdivIterationLoopTop	/* adjust remainder: only for non-restoring. */	/* cmp	MANT1, #0 */	/* addlt	MANT1, MANT1, MANT2 */	/*	 * In order to share rounding and packing code with fmul,	 * move QUOT to MANT1, shifting left s.t. the high-order bit is set.	 * Also insert the sticky bit.	 */	cmp	MANT1, #0	mov	MANT1, QUOT, LSL #7

⌨️ 快捷键说明

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