diff options
author | Dino Li <Dino.Li@ite.com.tw> | 2017-05-26 10:11:25 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-05-29 21:49:05 -0700 |
commit | c35fad0f2bc16fffe25dfe3b86f0df508d6d0b87 (patch) | |
tree | 5044d9499277a8e9bb1997f7c10e522bd0dac8ea | |
parent | a8cf9d92139eeebc412e2527d2c4329208af6901 (diff) | |
download | chrome-ec-c35fad0f2bc16fffe25dfe3b86f0df508d6d0b87.tar.gz |
chip: it83xx: add support for floating point unit
Because N8 CPU doesn't have floating point unit,
so we implement an extra floating point engine
(single-precision addition, subtraction, multiplication,
and division) into it8320 to improve performance of
floating point operation.
To make CPU's instruction compatible, we use register (DLMB)
to switch ALU (Arithmetic Logic Unit). eg:
Instruction 'ADD45' adds the contents of two registers then
writes the result to the source register.
But if we switch ALU to floating point operation mode,
this instruction will do a floating-point addition instead.
For the other FPU that we don't support as far,
we have to use soft float library routines of nds32.
Signed-off-by: Dino Li <dino.li@ite.com.tw>
BRANCH=none
BUG=none
TEST=add the following console command and test different
scenarios by changing variable a and b.
#define PRINTF_FLOAT(x) ((int)((x) * 1000.0f))
static int it83xx_fpu_test(int argc, char **argv)
{
volatile float a = 1.23f;
volatile float b = 4.56f;
volatile float c;
c = a + b;
ccprintf("__addsf3: (%d)\n", PRINTF_FLOAT(c));
c = a - b;
ccprintf("__subsf3: (%d)\n", PRINTF_FLOAT(c));
c = a * b;
ccprintf("__mulsf3: (%d)\n", PRINTF_FLOAT(c));
c = a / b;
ccprintf("__divsf3: (%d)\n", PRINTF_FLOAT(c));
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(fpu, it83xx_fpu_test, "", "");
Change-Id: I4fc1c08d8c2376156bec9f098491187675c4a88f
Reviewed-on: https://chromium-review.googlesource.com/427640
Commit-Ready: Dino Li <Dino.Li@ite.com.tw>
Tested-by: Dino Li <Dino.Li@ite.com.tw>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | chip/it83xx/build.mk | 1 | ||||
-rw-r--r-- | chip/it83xx/it83xx_fpu.S | 81 | ||||
-rw-r--r-- | core/nds32/init.S | 11 | ||||
-rw-r--r-- | core/nds32/task.c | 4 |
4 files changed, 93 insertions, 4 deletions
diff --git a/chip/it83xx/build.mk b/chip/it83xx/build.mk index 47820aba34..97f41ce287 100644 --- a/chip/it83xx/build.mk +++ b/chip/it83xx/build.mk @@ -18,6 +18,7 @@ chip-y=hwtimer.o uart.o gpio.o system.o jtag.o clock.o irq.o intc.o chip-$(CONFIG_WATCHDOG)+=watchdog.o chip-$(CONFIG_FANS)+=fan.o pwm.o chip-$(CONFIG_FLASH_PHYSICAL)+=flash.o +chip-$(CONFIG_FPU)+=it83xx_fpu.o chip-$(CONFIG_PWM)+=pwm.o chip-$(CONFIG_ADC)+=adc.o chip-$(CONFIG_EC2I)+=ec2i.o diff --git a/chip/it83xx/it83xx_fpu.S b/chip/it83xx/it83xx_fpu.S new file mode 100644 index 0000000000..d98ba0fa67 --- /dev/null +++ b/chip/it83xx/it83xx_fpu.S @@ -0,0 +1,81 @@ +/* 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. + */ + +/* + * DLMB register = 0x80189: + * Disable all interrupts and switching CPU's + * ALU (Arithmetic Logic Unit) to floating point operation mode. + * (IEEE standard 754 floating point) + * + * DLMB register = 0x80009: + * Restore interrupts and ALU. + */ + .text + .align 2 + .global __addsf3 + .type __addsf3, @function +__addsf3: + sethi $r2, 0x80 /* r2 = 0x80000 */ + addi $r3, $r2, 0x189 /* r3 = 0x80189 */ + addi45 $r2, 0x9 /* r2 = 0x80009 */ + mtsr $r3, $dlmb /* dlmb = 0x80189 */ + dsb + /* Floating-point addition single-precision */ + add45 $r0, $r1 + mtsr $r2, $dlmb /* dlmb = 0x80009 */ + dsb + ret5 $lp + .size __addsf3, .-__addsf3 + + .text + .align 2 + .global __subsf3 + .type __subsf3, @function +__subsf3: + sethi $r2, 0x80 /* r2 = 0x80000 */ + addi $r3, $r2, 0x189 /* r3 = 0x80189 */ + addi45 $r2, 0x9 /* r2 = 0x80009 */ + mtsr $r3, $dlmb /* dlmb = 0x80189 */ + dsb + /* Floating-point subtraction single-precision */ + sub45 $r0, $r1 + mtsr $r2, $dlmb /* dlmb = 0x80009 */ + dsb + ret5 $lp + .size __subsf3, .-__subsf3 + + .text + .align 2 + .global __mulsf3 + .type __mulsf3, @function +__mulsf3: + sethi $r2, 0x80 /* r2 = 0x80000 */ + addi $r3, $r2, 0x189 /* r3 = 0x80189 */ + addi45 $r2, 0x9 /* r2 = 0x80009 */ + mtsr $r3, $dlmb /* dlmb = 0x80189 */ + dsb + /* Floating-point multiplication single-precision */ + mul33 $r0, $r1 + mtsr $r2, $dlmb /* dlmb = 0x80009 */ + dsb + ret5 $lp + .size __mulsf3, .-__mulsf3 + + .text + .align 2 + .global __divsf3 + .type __divsf3, @function +__divsf3: + sethi $r2, 0x80 /* r2 = 0x80000 */ + addi $r3, $r2, 0x189 /* r3 = 0x80189 */ + addi45 $r2, 0x9 /* r2 = 0x80009 */ + mtsr $r3, $dlmb /* dlmb = 0x80189 */ + dsb + /* Floating-point division single-precision */ + divsr $r0,$r0,$r0,$r1 + mtsr $r2, $dlmb /* dlmb = 0x80009 */ + dsb + ret5 $lp + .size __divsf3, .-__divsf3 diff --git a/core/nds32/init.S b/core/nds32/init.S index 28dd1a5ca1..d278d4a899 100644 --- a/core/nds32/init.S +++ b/core/nds32/init.S @@ -192,6 +192,17 @@ excep_handler: la $r0, saved_regs + 4 smw.bim $r1, [$r0], $r10, 0 smw.bim $r15,[$r0], $r15, 0xF +#ifdef CONFIG_FPU + /* + * We have to restore ALU so that we can continue the next + * sequence if arithmetic instructions are used. + * (Apply to floating point division by zero) + */ + sethi $r4, 0x80 + ori $r4, $r4,0x9 + mtsr $r4, $dlmb + dsb +#endif /* put a sane stack pointer */ la $sp, stack_end /* add IPC, IPSW to the context */ diff --git a/core/nds32/task.c b/core/nds32/task.c index 88bd731051..9310223989 100644 --- a/core/nds32/task.c +++ b/core/nds32/task.c @@ -134,11 +134,7 @@ uint8_t task_stacks[0 #undef TASK /* Reserve space to discard context on first context switch. */ -#ifdef CONFIG_FPU -uint32_t scratchpad[19+18]; -#else uint32_t scratchpad[19]; -#endif task_ *current_task = (task_ *)scratchpad; |