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

📄 ccmmath_cpu.s

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 S
📖 第 1 页 / 共 5 页
字号:
/* * @(#)ccmmath_cpu.S	1.112 06/10/10 * * Portions Copyright  2000-2008 Sun Microsystems, Inc. All Rights   * Reserved.  Use is subject to license terms.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.   *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).   *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA   *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions. *//* * Copyright 2005 Intel Corporation. All rights reserved.   */#include "javavm/include/asmmacros_cpu.h"#include "javavm/include/porting/endianness.h"#include "javavm/include/iai_opt_config.h"#ifdef __RVCT__#define OR2(x,y)	((x) :OR: (y))#define OR3(x,y,z)	((x) :OR: (y) :OR: (z))#define OR4(x,y,z,p)	((x) :OR: (y) :OR: (z) :OR: (p))#else#define OR2(x,y)	((x) | (y))#define OR3(x,y,z)	((x) | (y) | (z))#define OR4(x,y,z,p)	((x) | (y) | (z) | (p))#endif/* * NOTE: Some linker such as the ARM RVCT (v2.2) linker sorts  *	 sections by attributes and section name. To make sure *	 the CCM copied code in the same order as they are included *	 in ccmcodecachecopy_cpu.S, we need to name the sections *	 in alphabetical order. */	SET_SECTION_EXEC(s4_ccmmath_cpu)/************************************* * Float helpers start here! *************************************/ /* * Entry point for comparing floats. * 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(CVMCCMruntimeFCmp)ENTRY1 ( CVMCCMruntimeFCmp )	ENTRY(CVMCCMruntimeFCmp_C)ENTRY1 ( CVMCCMruntimeFCmp_C )        /* r0 = a1 = float1          * r1 = a2 = float2          * r2 = a3 = return value if nan.          * v1 = jfp           * v2 = jsp          * sp = ccee	 */        /* uses r0, r1, r2, r3 */#define FLOAT1      r0#define FLOAT2      r1#define NAN_RESULT  r2        /* Extract exponent1 and check float1 for a NaN: */        mov     r3, #0xff        and     r3, r3, FLOAT1, LSR #23     /* Extract exponent1. */        cmp     r3, #0xff                   /* Check for infinity or nan. */        beq     _fcmpFloat1CheckForNanLABEL(_fcmpFloat1IsNotNan)        /* Extract exponent2 and check float2 for a NaN: */        mov     r3, #0xff        and     r3, r3, FLOAT2, LSR #23     /* Extract exponent2. */        cmp     r3, #0xff                   /* Check for infinity or nan. */        beq     _fcmpFloat2CheckForNanLABEL(_fcmpFloat2IsNotNan)        /* Check if the 2 floats have the same sign bit: */        eor     r2, FLOAT1, FLOAT2      /* Check to see if the sign bit is the */        tst     r2, #0x80000000         /*    same. */        bne     _fcmpEvaluateResultBasedOnSigns        /* If we get here, then the sign bits are the same.  Next, check if           the sign bits are negative: */        tst     FLOAT1, #0x80000000     /* Check for negative sign bit. */        bic     FLOAT1, FLOAT1, #0x80000000     /* Remove float1's sign. */        bic     FLOAT2, FLOAT2, #0x80000000     /* Remove float2's sign. */        bne     _fcmpDoNegativeChecks        /* Do positive version of comparing the floats: */        cmp     FLOAT1, FLOAT2        mov     pc, lr                  /* Return to the caller. */LABEL(_fcmpDoNegativeChecks)        /* Do negative version of comparing the floats: */        cmp     FLOAT2, FLOAT1        mov     pc, lr                  /* Return to the caller. */LABEL(_fcmpEvaluateResultBasedOnSigns)        /* Check for the special case where the 2 numbers are zeroes.  If so,           the two are still equal even if their signs are not: */        mov     r3, #0        cmp     r3, FLOAT1, LSL #1      /* Check if float1 w/o sign is 0. */        bne     _fcmpNotBothZeroes        cmp     r3, FLOAT2, LSL #1      /* Check if float2 w/o sign is 0. */        /* If it's a zero, then both numbers are 0s and equal.  The condition           code is already set correctly.  Just return to the caller: */        moveq   pc, lr                  /* Return the result. */LABEL(_fcmpNotBothZeroes)        cmp     FLOAT1, FLOAT2          /* Compare the signs. */        mov     pc, lr                  /* Return the result. */LABEL(_fcmpFloat1CheckForNan)        /* Check if the mantissa is 0 (i.e. float1 is an infinity): */        mov     r3, FLOAT1, LSL #9      /* mantissa1 = float1 << 9. */        cmp     r3, #0                  /* Check if mantissa1 is 0. */        beq     _fcmpFloat1IsNotNan     /* If is infinity, resume in main code.*/        cmp     NAN_RESULT, #0          /* Else, is NaN.  Return the desired */        mov     pc, lr                  /*   condition code result. */LABEL(_fcmpFloat2CheckForNan)        /* Check if the mantissa is 0 (i.e. float2 is an infinity): */        mov     r3, FLOAT2, LSL #9      /* mantissa2 = float2 << 9. */        cmp     r3, #0                  /* Check if mantissa2 is 0. */        beq     _fcmpFloat2IsNotNan     /* If is infinity, resume in main code.*/        cmp     NAN_RESULT, #0          /* Else, is NaN.  Return the desired */        mov     pc, lr                  /*   condition code result. */#undef FLOAT1#undef FLOAT2#undef NAN_RESULT/* * NOTE: FAdd, FSub, and FMul all use the same register designations. */#define FLOAT1  r0#define FLOAT2  r1#define EXP1    r2#define EXP2    r3#define MANT1   r6#define MANT2   r7#define EMASK   r12#define MMASK   r12#define FLOAT_SAVE_SET 	  {r6-r7, lr}#define FLOAT_RESTORE_SET {r6-r7, pc}#ifndef __RVCT__#define	FLOAT_RETURN_TO_CALLER_IF(cond) \	ldm/**/cond/**/fd	sp!, FLOAT_RESTORE_SET#else#define	FLOAT_RETURN_TO_CALLER_IF(cond) \	ldm##cond##fd	sp!, FLOAT_RESTORE_SET#endif#define	FLOAT_RETURN_TO_CALLER \    FLOAT_RETURN_TO_CALLER_IF(al)/* * Entry point for subtracting floats. * NOTE: The result is in r0. */	ENTRY(CVMCCMruntimeFSub)ENTRY1 ( CVMCCMruntimeFSub )	ENTRY(CVMCCMruntimeFSub_C)ENTRY1 ( CVMCCMruntimeFSub_C )        /* r0 = a1 = float1 */        /* r1 = a2 = float2 */        /* v1 = jfp */        /* v2 = jsp */        /* sp = ccee */        eor     r1, r1, #0x80000000     /* Negate float2. */        /* Fall through to CVMCCMruntimeFAdd: *//* * Entry point for adding floats. * NOTE: The result is in r0. */	ENTRY(CVMCCMruntimeFAdd)ENTRY1 ( CVMCCMruntimeFAdd )	ENTRY(CVMCCMruntimeFAdd_C)ENTRY1 ( CVMCCMruntimeFAdd_C )        /* r0 = a1 = float1          * r1 = a2 = float2          * v1 = jfp           * v2 = jsp          * sp = ccee	 *//* IAI - 16 */#ifdef IAI_WMMX_FADD#define FEXP1 r2#define FEXP2 r3#define FMANT1 ip#define FMANT2 r1        @ arrange for the larger summand to be in FLOAT1        mov	ip, FLOAT1, LSL #1              cmp	ip, FLOAT2, LSL #1        tmcrrlo	wR0, FLOAT1, FLOAT2        tmrrclo	FLOAT2, FLOAT1, wR0		/* exchage FLOAT1 and FLOAT2 */LABEL(_fadd_noxchng)        mov     EMASK, #0xff			/* Setup the pre-shifted exponent mask. */        ands    FEXP2, EMASK, FLOAT2, LSR #23	/* Extract exponent2. */        beq	_fadd_fexp2_equal_0        and	FEXP1, EMASK, FLOAT1, LSR #23	/* Extract exponent1. */                cmp     FEXP1, EMASK        cmpne   FEXP2, EMASK        beq     _fadd_fexp_equal_emask               sub	r3, FEXP1, FEXP2		/* exp1 = exp1 - exp2. */        cmp	r3, #25				/* difference too large, return */        movhi	pc, lr                teq	FLOAT1, FLOAT2        bic	FMANT2, FLOAT2, #0xff000000	/* Extract mantissa2.	*/        orr	FMANT2, FMANT2, #0x00800000       	bmi	_fadd_sub		LABEL(_fadd_add)               bic	FMANT1, FLOAT1, #0xff000000	/* Extract mantissa1.	*/        orr	FMANT1, FMANT1, #0x00800000        add	ip, FMANT1, FMANT2, LSR r3	/* {hi<ip>,lo<r1>} = FMANT1 + FMANT2. */        rsb     r3, r3, #32	mov	FMANT2, FMANT2, LSL r3	LABEL(_fadd_process_result)                tst	ip, #0x01000000 	addne	FEXP1, FEXP1, #1	movnes	ip, ip, lsr #1	moveqs  r1, r1, lsl #1	adc	ip, ip, #0	bcs	_fadd_process_result_round	/* r1 = #0x8xxxxxxx */LABEL(_fadd_process_result_done)		tst	ip, #0x01000000	addne	FEXP1, FEXP1, #1	cmp	FEXP1, #0xff	and	r0, r0, #0x80000000	orr	r0, r0, FEXP1, lsl #23	bicne	ip, ip, #0x01800000	orrne	r0, ip, r0	mov 	pc, lr				/* normalized result returned. */LABEL(_fadd_process_result_round)	teq	r1, #0	biceq	ip, ip, #1	b	_fadd_process_result_doneLABEL(_fadd_fexp2_equal_0)        ands	FEXP1, EMASK, FLOAT1, LSR #23	/* Extract exponent1. */        beq	_fadd_fexp1_equal_0                cmp     FEXP1, EMASK        moveq	pc, lr                teq	FLOAT1,FLOAT2        bic	FMANT2, FLOAT2, #0x80000000        sub	r3, FEXP1, #1        bpl	_fadd_add	LABEL(_fadd_sub)        bic	FMANT1, FLOAT1, #0x7f000000	/* Extract mantissa1.	*/        orr	FMANT1, FMANT1, #0x00800000	rsb	r0, r3, #32	mov	r0, FMANT2, LSL r0	rsbs	r0, r0, #0	sbc	ip, FMANT1, FMANT2, LSR r3	/* {hi<ip>,lo<r0>} = FMANT1 - FMANT2. */	tst	ip, #0x00800000	beq	_fadd_sub_result_need_shift		cmp	r0, #0x80000000	addhs	ip, ip, #1	biceq	ip, ip, #1	bic	r0, ip, #0x00800000	orr	r0, r0, FEXP1, lsl #23	mov	pc, lrLABEL(_fadd_sub_result_need_shift)	bic	r3, ip, #0x80000000	orrs	r1, r3, r0	moveq	r0, #0	moveq	pc, lr				/* FLOAT1 = - FLOAT2, return 0 */		clz	r1, r3	sub	r1, r1, #8		cmp	FEXP1, r1	suble	r1, FEXP1, #1	movle	FEXP1, ip, LSR #23	subgt	FEXP1, FEXP1, r1	orrgt	FEXP1, FEXP1, ip, LSR #23		mov	ip, r3, LSL r1			/* need shift left */	rsb	r3, r1, #32	orr	ip, ip, r0, LSR r3	mov	r0, r0, LSL r1		cmp	r0, #0x80000000	addhs	ip, ip, #1	biceq	ip, ip, #1	tst	ip, #0x01000000	addne	FEXP1, FEXP1, #1	bic	ip, ip, #0x01800000	orr	r0, ip, FEXP1, LSL #23	mov	pc, lr        LABEL(_fadd_fexp1_equal_0)   	eors	r3, FLOAT1, FLOAT2	bic	r2, FLOAT2, #0x80000000	addpl	r0, FLOAT1, r2	movpl	pc, lr		teq	r3, #0x80000000	moveq	r0, #0	subne	r0, FLOAT1, r2	mov	pc, lr	     LABEL(_fadd_fexp_equal_emask)	cmp	FEXP1, EMASK	movne	r0, FLOAT2        cmpeq   FEXP2, EMASK        movne	pc, lr        	eors	r2, FLOAT1, FLOAT2	        orr	r0, FLOAT1, FLOAT2	        movpl	pc, lr        mov	r0, #0x7f000000        orr	r0, r0, #0x00c00000        mov	pc, lr        #else /* IAI - 16 */LABEL(_faddStart)        /* The following saves registers that we're going to use and extracts           exponents and mantissas 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, #0xc0000000        and     MANT1, MMASK, FLOAT1, LSL #7    /* Extract mantissa1. */        and     MANT2, MMASK, FLOAT2, LSL #7    /* Extract mantissa2. */        /* Check if float1 or float2 is NaN or infinity: */

⌨️ 快捷键说明

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