diff options
author | Dino Li <Dino.Li@ite.com.tw> | 2017-06-08 16:19:17 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-06-23 03:14:51 -0700 |
commit | 52fa37a8010f04930a4ecc81c001f0ab16d86939 (patch) | |
tree | 641c0f1797e0d26ce01da47bda52b56ade2c98a0 | |
parent | 79a5a035eafe3a9caa5184e0df73fb2de31f5b72 (diff) | |
download | chrome-ec-52fa37a8010f04930a4ecc81c001f0ab16d86939.tar.gz |
nds32: add software floating point library routines
We need to add a few library routines for sensor task.
Routines added are taken from nds32's library.
BRANCH=none
BUG=none
TEST=Add sensor task to reef_it8320 board.
Test screen rotation functionality on reef_it8320.
Change-Id: I2eee33f897b38e05bddd30b16f875944259b2c0d
Signed-off-by: Dino Li <Dino.Li@ite.com.tw>
Reviewed-on: https://chromium-review.googlesource.com/527537
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | core/nds32/__libsoftfpu.S | 195 | ||||
-rw-r--r-- | core/nds32/build.mk | 1 |
2 files changed, 196 insertions, 0 deletions
diff --git a/core/nds32/__libsoftfpu.S b/core/nds32/__libsoftfpu.S new file mode 100644 index 0000000000..672e6bbb3d --- /dev/null +++ b/core/nds32/__libsoftfpu.S @@ -0,0 +1,195 @@ +/* Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + .text + .align 2 + .global __gtsf2 + .type __gtsf2, @function +__gtsf2: + ! --------------------------------------------------------------------- + ! int __gtsf2(float a, float b): + ! This function returns a value greater than zero if neither argument + ! is NaN and a is strictly greater than b. + ! --------------------------------------------------------------------- + .global __gesf2 + .type __gesf2, @function +__gesf2: + ! --------------------------------------------------------------------- + ! int __gesf2(float a, float b): + ! This function returns a value greater than or equal to zero if + ! neither argument is NaN and a is greater than or equal to b. + ! --------------------------------------------------------------------- + move $r4, #-1 + b .LA + + .global __eqsf2 + .type __eqsf2, @function +__eqsf2: + ! --------------------------------------------------------------------- + ! int __eqsf2(float a, float b): + ! This function returns zero value if neither argument is NaN, + ! and a and b are equal. + ! --------------------------------------------------------------------- + .global __nesf2 + .type __nesf2, @function +__nesf2: + ! --------------------------------------------------------------------- + ! int __nesf2(float a, float b): + ! This function returns a nonzero value if either argument is NaN or if + ! a and b are unequal. + ! --------------------------------------------------------------------- + .global __lesf2 + .type __lesf2, @function +__lesf2: + ! --------------------------------------------------------------------- + ! int __lesf2(float a, float b): + ! This function returns a value less than or equal to zero if neither + ! argument is NaN and a is less than b. + ! --------------------------------------------------------------------- + .global __ltsf2 + .type __ltsf2, @function +__ltsf2: + ! --------------------------------------------------------------------- + ! int __ltsf2(float a, float b): + ! This function returns a value less than zero if neither argument is + ! NaN and a is strictly less than b. + ! --------------------------------------------------------------------- + .global __cmpsf2 + .type __cmpsf2, @function +__cmpsf2: + ! --------------------------------------------------------------------- + ! int __cmpsf2(float a, float b); + ! This function calculates a <=> b. That is, if a is less than b, it + ! returns -1; if a if greater than b, it returns 1; and if a and b are + ! equal, it returns 0. If either argument is NaN, it returns 1, But you + ! should not rely on this; If NaN is a possibility, use higher-level + ! comparison function __unordsf2(). + ! --------------------------------------------------------------------- + move $r4, #1 + + .align 2 +.LA: + move $r5, #0xff000000 + slli $r2, $r0, #1 + slt $r15, $r5, $r2 + bnez $r15, .LMnan ! a is NaN + slli $r3, $r1, #1 + slt $r15, $r5, $r3 + bnez $r15, .LMnan ! b is NaN + xor $r5, $r0, $r1 ! a and b have same sign? + bgez $r5, .LSameSign +.LDiffSign: + or $r2, $r2, $r3 + beqz $r2, .LMequ ! 0.0f and -0.0f are equal + move $r2, #1 ! when a==0.0f, return 1 + cmovz $r0, $r2, $r0 ! otherwise, simply return a + ret5 $lp +.LSameSign: + sltsi $r15, $r0, 0 ! a < 0 ? + bnez $r15, .LSameSignNeg +.LSameSignPos: + ! a >= 0 && b >= 0, return a - b + sub $r0, $r0, $r1 + ret5 $lp +.LSameSignNeg: + ! a < 0 && b < 0, return b - a + sub $r0, $r1, $r0 + ret5 $lp +.LMequ: + move $r0, #0 + ret5 $lp +.LMnan: + move $r0, $r4 + ret5 $lp + .size __cmpsf2, .-__cmpsf2 + .size __ltsf2, .-__ltsf2 + .size __lesf2, .-__lesf2 + .size __nesf2, .-__nesf2 + .size __eqsf2, .-__eqsf2 + .size __gesf2, .-__gesf2 + .size __gtsf2, .-__gtsf2 + +#define MANTA $r0 +#define EXPOA $r1 + .text + .align 2 + .global __floatsisf + .type __floatsisf, @function +__floatsisf: + beqz $r0, .LKzero ! A is zero + move $r4, #0x80000000 + and $r2, $r0, $r4 ! sign(A) + beqz $r2, .LKcont + subri $r0, $r0, #0 + ! abs(A) +.LKcont: + move EXPOA, #0x9e + move $r5, 16 + move $r3, 0 +.LKloop: + add $r3, $r3, $r5 + srl $r15, MANTA, $r3 + bnez $r15, .LKloop2 + sll MANTA, MANTA, $r5 + sub EXPOA, EXPOA, $r5 +.LKloop2: + srli $r5, $r5, #1 + bnez $r5, .LKloop + ! do rounding + srli $r4, $r4, #24 ! 0x80 + add MANTA, MANTA, $r4 + slt $r15, MANTA, $r4 + add EXPOA, EXPOA, $r15 + srai $r4, MANTA, #8 + andi $r4, $r4, #1 + sub MANTA, MANTA, $r4 + slli MANTA, MANTA, #1 ! shift out implied 1 + ! pack + srli MANTA, MANTA, #9 + slli $r4, EXPOA, #23 + or $r0, MANTA, $r4 + or $r0, $r0, $r2 +.LKzero: + ret5 $lp + .size __floatsisf, .-__floatsisf + +#undef EXPOA +#undef MANTA +#define VALUA $r1 +#define EXPOA VALUA +#define MANTA $r2 +#define W0 $r4 +#define W1 $r5 + .text + .align 2 + .global __fixsfsi + .type __fixsfsi, @function +__fixsfsi: + slli VALUA, $r0, #1 + slli MANTA, VALUA, #7 + srli EXPOA, VALUA, #24 + subri EXPOA, EXPOA, #0x9e + move W1, #0x80000000 + blez EXPOA, .LJover ! number is too big + sltsi $r15, EXPOA, #0x20 + beqz $r15, .LJzero ! number is too small + or MANTA, MANTA, W1 + srl MANTA, MANTA, EXPOA + sltsi $r15, $r0, #0 + subri $r0, MANTA, #0 + cmovz $r0, MANTA, $r15 + ret5 $lp +.LJzero: + move $r0, #0 + ret5 $lp +.LJover: + move W0, #0x7f800000 + slt $r15, W0, $r0 + beqzs8 .LJnan + move $r0, W1 + ret5 $lp +.LJnan: + addi $r0, W1, -1 + ret5 $lp + .size __fixsfsi, .-__fixsfsi diff --git a/core/nds32/build.mk b/core/nds32/build.mk index 52009a6eff..68dd1585ab 100644 --- a/core/nds32/build.mk +++ b/core/nds32/build.mk @@ -13,3 +13,4 @@ CROSS_COMPILE?=nds32le-cros-elf- CFLAGS_CPU+=-march=v3m -Os core-y=cpu.o init.o panic.o task.o switch.o __muldi3.o math.o +core-$(CONFIG_FPU)+=__libsoftfpu.o |