Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 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_ISA_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)
{
#ifdef CONFIG_FP_FPU_DA
uint32_t temp = 0;
__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)
{
#ifdef CONFIG_FP_FPU_DA
uint32_t temp = 0;
__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 */
|