在NEON Cortex-A8的组装示例中

In-Assembly example for NEON Cortex-A8

本文关键字:NEON Cortex-A8      更新时间:2023-10-16

我正在尝试编译并举例说明皮质A8的NEON汇编代码,以便在BeagleBone黑板(BBB)上使用此二进制文件。我使用eclipse工具GCC编译器和下面列出的汇编程序,

GCC:arm linux gneabi GCC

ASSEMBLER:arm-linux-gneabi作为

下面的错误发生在一个例子中,对于我使用的每个例子,我都会发现类似的错误

Description Path    Resource    Location    Type
SP not allowed in register list -- `ldmia r12,{r4-r11,r13,lr}'      EXAMPLE_NEON    line 61, external location: /tmp/ccTXrczs.s C/C++ Problem

我使用的代码

/************************
*neon.c*************************/

#include <stdio.h>

__attribute__((aligned (16)))
unsigned short int data1[8];
unsigned short int data2[8];
unsigned short int out[8];
void* neontest_save_buffer[16];

void
neontest(unsigned short int *a, unsigned short int *b,
                unsigned short int* q)
{
  __asm__(
"   movw        r12, #:lower16:neontest_save_buffernt"
"   movt        r12, #:upper16:neontest_save_buffernt"
"   stmia       r12, {r4-r11, r13, lr}        @ save registersnt"
"   vld1.16     {q1}, [r0:128]nt"
"   vld1.16     {q2}, [r1:128]nt"
"   vadd.i16    q0, q1, q2nt"
"   vst1.32     {q0}, [r2:128]nt"
"   movw        r12, #:lower16:neontest_save_buffernt"
"   movt        r12, #:upper16:neontest_save_buffernt"
"   ldmia       r12, {r4-r11, r13, lr}        @ reload all registers and returnnt"
"finish:nt"
    );
}
int
main(void)
{
    int i;
    for (i=0; i<8; i++)
    {
        data1[i]=i*10;
        data2[i]=5;
        out[i]=0;
    }
    neontest(data1, data2, out);
    printf("output is: ");
    for (i=0; i<7; i++)
    {
        printf("%d, ", out[i]);
    }
    printf("%dn", out[i]);
  return(0);
}

看起来您使用的是Thumb32模式,其中sp cannot be in the list of registers(来自[1])。

如果不设置新堆栈,为什么需要保存堆栈?只需尝试从stm块和ldm块中删除r13。

默认编译器使用拇指模式,在命令行中添加"-marm"以在ARM模式下编译代码:

arm linux gneabihf gcc-mcpu=cortex-a8-mfpu=neon-marm neon.c

您也可以调整代码,让编译器进行寄存器保存/恢复,这样可以为ARM和thumb2指令集编译代码:

#include <stdio.h>

__attribute__((aligned (16)))
unsigned short int data1[8];
unsigned short int data2[8];
unsigned short int out[8];
void
neontest(unsigned short int *a, unsigned short int *b,
                unsigned short int* q)
{
    __asm volatile (
"   vld1.16     {q1}, [%[a]:128]nt"
"   vld1.16     {q2}, [%[b]:128]nt"
"   vadd.i16    q0, q1, q2nt"
"   vst1.32     {q0}, [%[q]:128]nt"
     : [q] "+r" (q)
     : [a] "r" (a), [b] "r" (b)
     : "q0", "q1", "q2"
    );
}
int
main(void)
{
    int i;
    for (i=0; i<8; i++)
    {
        data1[i]=i*10;
        data2[i]=5;
        out[i]=0;
    }
    neontest(data1, data2, out);
    printf("output is: ");
    for (i=0; i<7; i++)
    {
        printf("%d, ", out[i]);
    }
    printf("%dn", out[i]);
  return(0);
}

arm linux gneabihf gcc-mcpu=cortex-a8-mfpu=neon-marm neon2.c

arm linux gneabihf gcc-mcpu=cortex-a8-mfpu=neon-mthumb neon2.c