[libcpu][c28x]Add __rt_ffs support
Use a native instruction "Count Sign Bits" to support fast ffs function, then add __rt_ffs support in C28x.
This commit is contained in:
parent
c578016f92
commit
d68220d866
|
@ -6,6 +6,8 @@
|
||||||
; Change Logs:
|
; Change Logs:
|
||||||
; Date Author Notes
|
; Date Author Notes
|
||||||
; 2018-09-01 xuzhuoyi the first version.
|
; 2018-09-01 xuzhuoyi the first version.
|
||||||
|
; 2019-06-17 zhaoxiaowei fix bugs of old c28x interrupt api.
|
||||||
|
; 2019-07-03 zhaoxiaowei add _rt_hw_calc_csb function to support __rt_ffs.
|
||||||
;
|
;
|
||||||
|
|
||||||
.ref _rt_interrupt_to_thread
|
.ref _rt_interrupt_to_thread
|
||||||
|
@ -15,6 +17,7 @@
|
||||||
.def _RTOSINT_Handler
|
.def _RTOSINT_Handler
|
||||||
.def _rt_hw_get_st0
|
.def _rt_hw_get_st0
|
||||||
.def _rt_hw_get_st1
|
.def _rt_hw_get_st1
|
||||||
|
.def _rt_hw_calc_csb
|
||||||
.def _rt_hw_context_switch_interrupt
|
.def _rt_hw_context_switch_interrupt
|
||||||
.def _rt_hw_context_switch
|
.def _rt_hw_context_switch
|
||||||
.def _rt_hw_context_switch_to
|
.def _rt_hw_context_switch_to
|
||||||
|
@ -229,6 +232,25 @@ _rt_hw_get_st1:
|
||||||
LRETR
|
LRETR
|
||||||
.endasmfunc
|
.endasmfunc
|
||||||
|
|
||||||
|
; C28x do not have a build-in "__ffs" func in its C compiler.
|
||||||
|
; We can use the "Count Sign Bits" (CSB) instruction to make one.
|
||||||
|
; CSB will return the number of 0's minus 1 above the highest set bit.
|
||||||
|
; The count is placed in T. For example:
|
||||||
|
; ACC T maxbit
|
||||||
|
; 0x00000001 30 0
|
||||||
|
; 0x00000010 26 4
|
||||||
|
; 0x000001FF 22 8
|
||||||
|
; 0x000001F0 22 8
|
||||||
|
.asmfunc
|
||||||
|
_rt_hw_calc_csb:
|
||||||
|
MOV AH, #0
|
||||||
|
CSB ACC ; T = no. of sign bits - 1
|
||||||
|
MOVU ACC, T ; ACC = no. of sign bits - 1
|
||||||
|
SUBB ACC, #30 ; ACC = ACC - 30
|
||||||
|
ABS ACC ; ACC = |ACC|
|
||||||
|
lretr
|
||||||
|
.endasmfunc
|
||||||
|
|
||||||
;
|
;
|
||||||
; * void rt_hw_context_switch_to(rt_uint32 to);
|
; * void rt_hw_context_switch_to(rt_uint32 to);
|
||||||
; * r0 --> to
|
; * r0 --> to
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2018-09-01 xuzhuoyi the first version.
|
* 2018-09-01 xuzhuoyi the first version.
|
||||||
|
* 2019-07-03 zhaoxiaowei add support for __rt_ffs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
@ -19,6 +20,7 @@ static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL;
|
||||||
|
|
||||||
extern rt_uint16_t rt_hw_get_st0(void);
|
extern rt_uint16_t rt_hw_get_st0(void);
|
||||||
extern rt_uint16_t rt_hw_get_st1(void);
|
extern rt_uint16_t rt_hw_get_st1(void);
|
||||||
|
extern int rt_hw_calc_csb(int value);
|
||||||
|
|
||||||
struct exception_stack_frame
|
struct exception_stack_frame
|
||||||
{
|
{
|
||||||
|
@ -102,6 +104,19 @@ struct exception_info
|
||||||
struct stack_frame stack_frame;
|
struct stack_frame stack_frame;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef RT_USING_CPU_FFS
|
||||||
|
/*
|
||||||
|
* This function called rt_hw_calc_csb to finds the first bit set in value.
|
||||||
|
* rt_hw_calc_csb is a native assembly program that use "CSB" instruction in C28x.
|
||||||
|
* When you use this function, remember that "int" is only 16-bit in C28x's C compiler.
|
||||||
|
* If value is a number bigger that 0xFFFF, trouble may be caused.
|
||||||
|
* Maybe change "int __rt_ffs(int value)" to "rt_int32_t __rt_ffs(rt_int32_t value)" will be better.
|
||||||
|
*/
|
||||||
|
int __rt_ffs(int value)
|
||||||
|
{
|
||||||
|
return rt_hw_calc_csb(value);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shutdown CPU
|
* shutdown CPU
|
||||||
|
|
Loading…
Reference in New Issue