Hi Nordic Team,
The atomic fifo implementation is based on armv7-M, right now I want to port it into cortex-A processor, I made some changes to get it compiled without errors
in cortex-A platform, but seems not work as expect, can you help check what's wrong with the below code, also do you have a C implementation, thanks.
origin code for armv7-M:
bool nrf_atfifo_wspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail)
{
volatile bool ret;
volatile uint32_t old_tail;
uint32_t new_tail;
uint32_t temp;
__ASM volatile(
/* For more comments see Keil version above */
"1: \n"
" ldrex %[old_tail], [%[p_fifo], %[offset_tail]] \n"
" uxth %[new_tail], %[old_tail] \n"
" \n"
" ldrh %[temp], [%[p_fifo], %[offset_item_size]] \n"
" add %[new_tail], %[temp] \n"
" ldrh %[temp], [%[p_fifo], %[offset_buf_size]] \n"
" cmp %[new_tail], %[temp] \n"
" it hs \n"
" subhs %[new_tail], %[new_tail], %[temp] \n"
" \n"
" ldrh %[temp], [%[p_fifo], %[offset_head_wr]] \n"
" cmp %[new_tail], %[temp] \n"
" ittt eq \n"
" clrexeq \n"
" moveq %[ret], %[false_val] \n"
" beq.n 2f \n"
" \n"
" pkhbt %[new_tail], %[new_tail], %[old_tail] \n"
" \n"
" strex %[temp], %[new_tail], [%[p_fifo], %[offset_tail]] \n"
" cmp %[temp], #0 \n"
" bne.n 1b \n"
" \n"
" mov %[ret], %[true_val] \n"
"2: \n"
: /* Output operands */
[ret] "=r"(ret),
[temp] "=&r"(temp),
[old_tail]"=&r"(old_tail),
[new_tail]"=&r"(new_tail)
: /* Input operands */
[p_fifo] "r"(p_fifo),
[offset_tail] "J"(offsetof(nrf_atfifo_t, tail)),
[offset_head_wr] "J"(offsetof(nrf_atfifo_t, head) + offsetof(nrf_atfifo_postag_pos_t, wr)),
[offset_item_size]"J"(offsetof(nrf_atfifo_t, item_size)),
[offset_buf_size] "J"(offsetof(nrf_atfifo_t, buf_size)),
[true_val] "I"(true),
[false_val] "I"(false)
: /* Clobbers */
"cc");
p_old_tail->tag = old_tail;
UNUSED_VARIABLE(new_tail);
UNUSED_VARIABLE(temp);
return ret;
}
modify code for armv7-A:
bool nrf_atfifo_wspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail)
{
nrf_atfifo_t *temp_p_fifo;
volatile bool ret;
volatile uint32_t old_tail;
uint32_t new_tail;
uint32_t temp;
__ASM volatile(
/* For more comments see Keil version above */
"1: \n"
" add %[temp_p_fifo], %[p_fifo], %[offset_tail] \n"
" ldrex %[old_tail], [%[temp_p_fifo]] \n"
" uxth %[new_tail], %[old_tail] \n"
" \n"
" ldrh %[temp], [%[p_fifo], %[offset_item_size]] \n"
" add %[new_tail], %[new_tail], %[temp] \n"
" ldrh %[temp], [%[p_fifo], %[offset_buf_size]] \n"
" cmp %[new_tail], %[temp] \n"
" it hs \n"
" subhs %[new_tail], %[new_tail], %[temp] \n"
" \n"
" ldrh %[temp], [%[p_fifo], %[offset_head_wr]] \n"
" cmp %[new_tail], %[temp] \n"
" ittt eq \n"
" clrex \n"
" moveq %[ret], %[false_val] \n"
" beq 2f \n"
" \n"
" pkhbt %[new_tail], %[new_tail], %[old_tail] \n"
" \n"
" strex %[temp], %[new_tail], [%[temp_p_fifo]] \n"
" cmp %[temp], #0 \n"
" bne 1b \n"
" \n"
" mov %[ret], %[true_val] \n"
"2: \n"
: /* Output operands */
[ret] "=r"(ret),
[temp] "=&r"(temp),
[temp_p_fifo] "=&r"(temp_p_fifo),
[old_tail]"=&r"(old_tail),
[new_tail]"=&r"(new_tail)
: /* Input operands */
[p_fifo] "r"(p_fifo),
[offset_tail] "J"(offsetof(nrf_atfifo_t, tail)),
[offset_head_wr] "J"(offsetof(nrf_atfifo_t, head) + offsetof(nrf_atfifo_postag_pos_t, wr)),
[offset_item_size]"J"(offsetof(nrf_atfifo_t, item_size)),
[offset_buf_size] "J"(offsetof(nrf_atfifo_t, buf_size)),
[true_val] "I"(true),
[false_val] "I"(false)
: /* Clobbers */
"cc");
p_old_tail->tag = old_tail;
UNUSED_VARIABLE(new_tail);
UNUSED_VARIABLE(temp);
UNUSED_VARIABLE(temp_p_fifo);
return ret;
}