Subject: FPA support in libc
To: None <port-arm32@netbsd.org>
From: Richard Earnshaw <rearnsha@buzzard.freeserve.co.uk>
List: port-arm32
Date: 02/26/2001 23:25:50
This is a multipart MIME message.

--==_Exmh_-12163169480
Content-Type: text/plain; charset=us-ascii


Although totally untested, other than by checking it compiles, I believe 
the following may well be sufficient to allow those people with an FPA to 
make use of it to accelerate execution of FP operations.  To use it, 
simply build a libc.so with the following code instead of the normal 
soft-float code (up to you to work out how).

The code should also compile correctly with the new VFP endianness model 
(also untested).

Let me know how you get on.

R.

Oh! it doesn't support apcs-26 calling conventions, but modifying it 
wouldn't be that hard.

--==_Exmh_-12163169480
Content-Type: text/plain ; name="soft-fpa.S"; charset=us-ascii
Content-Description: soft-fpa.S
Content-Disposition: attachment; filename="soft-fpa.S"

/*	$NetBSD:	 $   */

/*-
 * Copyright (c) 2001, Richard Earnshaw
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote 
 *    products derived from this software without specific prior written
 *    permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

/* Support code for soft-float API when FPA is present.  */

#include <machine/asm.h>

#define SIGN_BIT_TWIDDLE 0x80000000

#define MOV2_regs_sf		  \
	stmfd	sp!, {r0, r1}	; \
	ldfs	f0, [sp], #4	; \
	ldfs	f1, [sp], #4

#define MOV1_reg_sf		  \
	str	r0, [sp, #-4]!	; \
	ldfs	f0, [sp], #4

#define MOV1_sf_reg		  \
	stfs	f0, [sp, #-4]!	; \
	ldr	r0, [sp], #4

#if defined(__VFP_FP__) && ! defined(__ARMEB__)
#define MOV2_regs_df		  \
	str	r2, [sp, #-4]!	; \
	stmfd	sp!, {r0,r3}	; \
	str	r1, [sp, #-4]!	; \
	ldfd	f0, [sp], #8	; \
	ldfd	f1, [sp], #8

#define MOV1_reg_df		  \
	str	r0, [sp, #-4]!	; \
	str	r1, [sp, #-4]!	; \
	ldfd	f0, [sp], #8

#define MOV1_df_reg		  \
	stfd	f0, [sp, #-8]!	; \
	ldr	r1, [sp], #4	; \
	ldr	r0, [sp], #4

#else
#define MOV2_regs_df		  \
	stmfd	sp!, {r0-r3}	; \
	ldfd	f0, [sp], #8	; \
	ldfd	f1, [sp], #8

#define MOV1_reg_df		  \
	stmfd	sp!, {r0, r1}	; \
	ldfd	f0, [sp], #8

#define MOV1_df_reg		  \
	stfd	f0, [sp, #-8]!	; \
	ldmfd	sp!, {r0, r1}

#endif
	

ENTRY_NP(__nesf2)
ENTRY (__eqsf2)
	MOV2_regs_sf
	cmf	f0, f1
	moveq	r0, #0
	movne	r0, #1
	mov	pc, lr

ENTRY_NP(__nedf2)
ENTRY(__eqdf2)
	MOV2_regs_df
	cmf	f0, f1
	moveq	r0, #0
	movne	r0, #1
	mov	pc, lr

ENTRY(__gtsf2)
	MOV2_regs_sf
	cmfe	f0, f1
	movgt	r0, #0
	mvnle	r0, #0
	mov	pc, lr

ENTRY(__gtdf2)
	MOV2_regs_df
	cmfe	f0, f1
	movgt	r0, #0
	mvnle	r0, #0
	mov	pc, lr

ENTRY(__lesf2)
	MOV2_regs_sf
	cmfe	f0, f1
	movls	r0, #0
	movhi	r0, #1
	mov	pc, lr

ENTRY(__ledf2)
	MOV2_regs_df
	cmfe	f0, f1
	movls	r0, #0
	movhi	r0, #1
	mov	pc, lr

ENTRY(__gesf2)
	MOV2_regs_sf
	cmfe	f0, f1
	movge	r0, #1
	movlt	r0, #0
	mov	pc, lr

ENTRY(__gedf2)
	MOV2_regs_df
	cmfe	f0, f1
	movge	r0, #1
	movlt	r0, #0
	mov	pc, lr

ENTRY(__ltsf2)
	MOV2_regs_sf
	cmfe	f0, f1
	movpl	r0, #0
	mvnmi	r0, #0
	mov	pc, lr

ENTRY(__ltdf2)
	MOV2_regs_df
	cmfe	f0, f1
	movpl	r0, #0
	movmi	r0, #0
	mov	pc, lr

/* No need to move to a FP reg, we can do this as an integer operation.  */
ENTRY(__negsf2)
	eor	r0, r0, #SIGN_BIT_TWIDDLE
	mov	pc, lr

ENTRY(__negdf2)
#if defined (__VFP_FP__) && ! defined(__ARMEB__)
	eor	r1, r1, #SIGN_BIT_TWIDDLE
#else
	eor	r0, r0, #SIGN_BIT_TWIDDLE
#endif
	mov	pc, lr

ENTRY(__addsf3)
	MOV2_regs_sf
	adfs	f0, f0, f1
	MOV1_sf_reg
	mov	pc, lr

ENTRY(__adddf3)
	MOV2_regs_df
	adfd	f0, f0, f1
	MOV1_df_reg
	mov	pc, lr

ENTRY(__subsf3)
	MOV2_regs_sf
	sufs	f0, f0, f1
	MOV1_sf_reg
	mov	pc, lr

ENTRY(__subdf3)
	MOV2_regs_df
	sufd	f0, f0, f1
	MOV1_df_reg
	mov	pc, lr

ENTRY(__mulsf3)
	MOV2_regs_sf
	mufs	f0, f0, f1
	MOV1_sf_reg
	mov	pc, lr

ENTRY(__muldf3)
	MOV2_regs_df
	mufd	f0, f0, f1
	MOV1_df_reg
	mov	pc, lr

ENTRY(__divsf3)
	MOV2_regs_sf
	dvfs	f0, f0, f1
	MOV1_sf_reg
	mov	pc, lr

ENTRY(__divdf3)
	MOV2_regs_df
	dvfd	f0, f0, f1
	MOV1_df_reg
	mov	pc, lr

ENTRY(__truncdfsf2)
	MOV1_reg_df
	mvfs	f0, f0
	MOV1_sf_reg
	mov	pc, lr

ENTRY(__extendsfdf2)
	MOV1_reg_sf
	mvfd	f0, f0
	MOV1_df_reg
	mov	pc, lr

ENTRY(__floatsisf)
	flts	f0, r0
	MOV1_sf_reg
	mov	pc, lr
	
ENTRY(__floatsidf)
	fltd	f0, r0
	MOV1_df_reg
	mov	pc, lr

ENTRY(__fixsfsi)
	MOV1_sf_reg
	fixz	r0, f0
	mov	pc, lr

ENTRY(__fixdfsi)
	MOV1_df_reg
	fixz	r0, f0
	mov	pc, lr

ENTRY(__fixunssfsi)
	MOV1_sf_reg
	ldfs	f1, Lunsfmax
	cmfe	f0, f1
	fixltz	r0, f0
	movlt	pc, lr
	sufs	f0, f0, f1
	fixz	r0, f0
	eor	r0, r0, #-2147483648
	mov	pc, lr
Lunsfmax:
	.word	0x4f000000 @float 2.147483648e9

ENTRY(__fixunsdfsi)
	MOV1_df_reg
	ldfd	f1, Lundfmax
	cmfe	f0, f1
	fixltz	r0, f0
	movlt	pc, lr
	sufd	f0, f0, f1
	fixz	r0, f0
	eor	r0, r0, #-2147483648
	mov	pc, lr
Lundfmax:
	.word	0x41e00000, 0	@double 2.147483648e9



--==_Exmh_-12163169480--