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--