Skip to content
Permalink
Browse files

arch: arc: optimize the float support

* enable float support
* implement z_arch_float_disable
* add arc support in fp_sharing test

Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
  • Loading branch information...
vonhust authored and andrewboie committed Jun 17, 2019
1 parent 98a3399 commit 8b04c7de1352fa3e174df8a0056d141fa799554d
@@ -455,7 +455,7 @@ config MPU_REQUIRES_NON_OVERLAPPING_REGIONS
menuconfig FLOAT
bool "Floating point"
depends on CPU_HAS_FPU
depends on ARM || X86
depends on ARM || X86 || ARC
help
This option allows threads to use the floating point registers.
By default, only a single thread may use the registers.
@@ -269,3 +269,21 @@ FUNC_NORETURN void z_arch_user_mode_enter(k_thread_entry_t user_entry,
}

#endif

#if defined(CONFIG_FLOAT) && defined(CONFIG_FP_SHARING)
int z_arch_float_disable(struct k_thread *thread)
{
unsigned int key;

/* Ensure a preemptive context switch does not occur */

key = irq_lock();

/* Disable all floating point capabilities for the thread */
thread->base.user_options &= ~K_FP_REGS;

irq_unlock(key);

return 0;
}
#endif /* CONFIG_FLOAT && CONFIG_FP_SHARING */
@@ -56,6 +56,9 @@ extern "C" {
st r30, [sp, ___callee_saved_stack_t_r30_OFFSET]

#ifdef CONFIG_FP_SHARING
ld r13, [r2, ___thread_base_t_user_options_OFFSET]
/* K_FP_REGS is bit 1 */
bbit0 r13, 1, 1f
st r58, [sp, ___callee_saved_stack_t_r58_OFFSET]
st r59, [sp, ___callee_saved_stack_t_r59_OFFSET]
lr r13, [_ARC_V2_FPU_STATUS]
@@ -73,7 +76,7 @@ extern "C" {
lr r13, [_ARC_V2_FPU_DPFP2H]
st_s r13, [sp, ___callee_saved_stack_t_dpfp2h_OFFSET]
#endif

1 :
#endif

/* save stack pointer in struct k_thread */
@@ -86,6 +89,9 @@ extern "C" {
ld sp, [r2, _thread_offset_to_sp]

#ifdef CONFIG_FP_SHARING
ld r13, [r2, ___thread_base_t_user_options_OFFSET]
/* K_FP_REGS is bit 1 */
bbit0 r13, 1, 2f
ld r58, [sp, ___callee_saved_stack_t_r58_OFFSET]
ld r59, [sp, ___callee_saved_stack_t_r59_OFFSET]

@@ -104,7 +110,7 @@ extern "C" {
ld_s r13, [sp, ___callee_saved_stack_t_dpfp2h_OFFSET]
sr r13, [_ARC_V2_FPU_DPFP2H]
#endif

2 :
#endif

#ifdef CONFIG_USERSPACE
@@ -36,6 +36,9 @@ config ARC_FIRQ
config CACHE_FLUSHING
default y

config FP_FPU_DA
def_bool y

if (ARC_MPU_VER = 2)

config MAIN_STACK_SIZE
@@ -88,6 +88,24 @@ struct fp_non_volatile_register_set {
#define SIZEOF_FP_NON_VOLATILE_REGISTER_SET \
sizeof(struct fp_non_volatile_register_set)

#elif defined(CONFIG_CPU_ARCV2)

struct fp_volatile_register_set {
#ifdef CONFIG_FP_FPU_DA
u32_t dpfp2h;
u32_t dpfp2l;
u32_t dpfp1h;
u32_t dpfp1l;
#endif
};

struct fp_non_volatile_register_set {
/* No non-volatile floating point registers */
};

#define SIZEOF_FP_VOLATILE_REGISTER_SET sizeof(struct fp_volatile_register_set)
#define SIZEOF_FP_NON_VOLATILE_REGISTER_SET 0

#else

#error "Architecture must provide the following definitions:\n"
@@ -0,0 +1,114 @@
/**
* @file
* @brief ARC GCC specific floating point register macros
*/

/*
* Copyright (c) 2019, Synopsys.
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef _FLOAT_REGS_ARC_GCC_H
#define _FLOAT_REGS_ARC_GCC_H

#if !defined(__GNUC__) || !defined(CONFIG_CPU_ARCV2)
#error __FILE__ goes only with ARC GCC
#endif

#include <toolchain.h>
#include "float_context.h"

/**
*
* @brief Load all floating point registers
*
* This function loads ALL floating point registers pointed to by @a regs.
* It is expected that a subsequent call to _store_all_float_registers()
* will be issued to dump the floating point registers to memory.
*
* The format/organization of 'struct fp_register_set'; the generic C test
* code (main.c) merely treat the register set as an array of bytes.
*
* The only requirement is that the arch specific implementations of
* _load_all_float_registers() and _store_all_float_registers() agree
* on the format.
*
* @return N/A
*/
static inline void _load_all_float_registers(struct fp_register_set *regs)
{
u32_t temp = 0;

#ifdef CONFIG_FP_FPU_DA
__asm__ volatile (
"ld.ab %1, [%0, 4];\n\t"
"sr %1, [%2];\n\t"
"ld.ab %1, [%0, 4];\n\t"
"sr %1, [%3];\n\t"
"ld.ab %1, [%0, 4];\n\t"
"sr %1, [%4];\n\t"
"ld.ab %1, [%0, 4];\n\t"
"sr %1, [%5];\n\t"
: : "r" (regs), "r" (temp),
"i"(_ARC_V2_FPU_DPFP1L), "i"(_ARC_V2_FPU_DPFP1H),
"i"(_ARC_V2_FPU_DPFP2L), "i"(_ARC_V2_FPU_DPFP2H)
: "memory"
);
#endif
}

/**
*
* @brief Dump all floating point registers to memory
*
* This function stores ALL floating point registers to the memory buffer
* specified by @a regs. It is expected that a previous invocation of
* _load_all_float_registers() occurred to load all the floating point
* registers from a memory buffer.
*
* @return N/A
*/

static inline void _store_all_float_registers(struct fp_register_set *regs)
{
u32_t temp = 0;

#ifdef CONFIG_FP_FPU_DA
__asm__ volatile (
"lr %1, [%2];\n\t"
"st.ab %1, [%0, 4];\n\t"
"lr %1, [%3];\n\t"
"st.ab %1, [%0, 4];\n\t"
"lr %1, [%4];\n\t"
"st.ab %1, [%0, 4];\n\t"
"lr %1, [%5];\n\t"
"st.ab %1, [%0, 4];\n\t"
: : "r" (regs), "r" (temp),
"i"(_ARC_V2_FPU_DPFP1L), "i"(_ARC_V2_FPU_DPFP1H),
"i"(_ARC_V2_FPU_DPFP2L), "i"(_ARC_V2_FPU_DPFP2H)
);
#endif
}

/**
*
* @brief Load then dump all float registers to memory
*
* This function loads ALL floating point registers from the memory buffer
* specified by @a regs, and then stores them back to that buffer.
*
* This routine is called by a high priority thread prior to calling a primitive
* that pends and triggers a co-operative context switch to a low priority
* thread.
*
* @return N/A
*/

static inline void _load_then_store_all_float_registers(struct fp_register_set
*regs)
{
_load_all_float_registers(regs);
_store_all_float_registers(regs);
}
#endif /* _FLOAT_REGS_ARC_GCC_H */
@@ -63,6 +63,12 @@
#else
#include "float_regs_arm_other.h"
#endif /* __GNUC__ */
#elif defined(CONFIG_CPU_ARCV2)
#if defined(__GNUC__)
#include "float_regs_arc_gcc.h"
#else
#include "float_regs_arc_other.h"
#endif /* __GNUC__ */
#endif

#include <tc_util.h>
@@ -12,3 +12,10 @@ tests:
slow: true
tags: kernel
timeout: 600
kernel.fp_sharing.arc:
extra_args: PI_NUM_ITERATIONS=500
filter: CONFIG_CPU_ARCV2 and CONFIG_CPU_HAS_FPU
slow: true
tags: kernel
timeout: 600
min_ram: 16

0 comments on commit 8b04c7d

Please sign in to comment.
You can’t perform that action at this time.