Pregunta

Soy nuevo en el ensamblador y la programación de neón. Mi tarea es convertir parte de un algoritmo de c a ensamblador de brazo utilizando instrucciones de neón. El algoritmo toma una matriz INT32, carga valores diferentes de esta matriz, hace un poco de cambio de bits y Xor y escribe el resultado en otra matriz. Más tarde usaré una matriz con valores de 64 bits, pero por ahora solo trato de reescribir el código.

C Pseudo code:

out_array[index] = shiftSome( in_array[index] ) ^ shiftSome( in_array[index] );

Así que aquí están mis preguntas sobre las instrucciones de neón:

1.) Si carga un registro como este:

vld1.32 d0, [r1]

¿Se cargará solo 32 bits desde la memoria o 2x32 bits para llenar el registro D de neón de 64 bits?

2.) ¿Cómo puedo acceder a las partes 2/4/8 (i32, i16, i8) del registro D?

3.) Estoy tratando de cargar valores diferentes de la matriz con un desplazamiento, pero no parece funcionar ... ¿Qué estoy haciendo mal? Aquí está mi código: (es una matriz entera, así que yo soy yo m tratando de cargar, por ejemplo, el elemento de 3, que debería tener un desplazamiento de 64 bits = 8 byte)

asm volatile(
"vld1.32 d0, [%0], #8 \n"     
"vst1.32 d0, [%1]" : : "r" (a), "r" (out): "d0", "r5");

donde "A" es la matriz y "fuera" es un puntero a un entero (para la depuración).

4.) Después de cargar un valor de la matriz, necesito cambiarlo hacia la derecha, pero no parece funcionar:

vshr.u32 d0, d0, #24     // C code:   x >> 24;

5.) ¿Es posible cargar solo 1 byte en un registro de neón para que no tenga que cambiar/enmascarar algo para obtener solo el único byte que necesito?

6.) Necesito usar ensamblador en línea, pero no estoy seguro de para qué sirve la última línea:

input list : output list : what is this for?

7.) ¿Conoce alguna buena referencia de neón con ejemplos de código?

El programa debe ejecutarse en un procesador Samsung Galaxy S2, Cortex-A9 si eso hace alguna diferencia. Gracias por la ayuda.

----------------editar-------------------

Eso es lo que descubrí:

  1. Siempre cargará el registro completo (64 bits)
  2. Puede usar la instrucción "VMOV" para transferir parte de un registro de neón a un registro de brazo.
  3. El desplazamiento debe estar en un registro de brazo y se agregará a la dirección base después el acceso a la memoria.
  4. Es la "lista de regalos clobbered". Cada registro que se usa y ni en la lista de entrada o salida debe escribirse aquí.
¿Fue útil?

Solución

Puedo responder la mayoría de sus preguntas: (Actualización: problema de "carril" aclarado)

1) Las instrucciones de neón solo pueden cargar y almacenar registros completos (64 bits, 128 bits) a la vez desde y hacia la memoria. Hay una variante de instrucción MOV que permite que se muevan los "carriles" individuales hacia o desde los registros de brazos.

2) Puede usar las instrucciones de neon Mov para afectar carriles individuales. El rendimiento sufrirá al hacer demasiadas operaciones de un solo elemento. Las instrucciones de neón benefician el rendimiento de la aplicación al realizar operaciones paralelas en vectores (grupos de flotadores/ints).

3) El valor inmediato de las compensaciones en el lenguaje de ensamblaje del brazo son bytes, no elementos/registros. Las instrucciones de neón permiten el incremento posterior con un registro, no un valor inmediato. Para las instrucciones normales del brazo, su posterior al incremento de 8 agregará 8 (bytes) al puntero de origen.

4) Los cambios en el neón afectan todos los elementos de un vector. Un cambio a la derecha de 24 bits usando VSHR.U32 cambiará los largos sin firmar de 32 bits por 24 bits y tirará los bits que se desplazan.

5) Las instrucciones de neón permiten que se muevan elementos individuales dentro y fuera de los registros de brazo normales, pero no permitan cargas o tiendas de la memoria directamente en "carriles".

6) ?

7) Comience aquí: http://blogs.arm.com/software-enablement/161-coding-for-neon-tart-1-load-and-stores/ El sitio del brazo tiene un buen tutorial sobre neón.

Otros consejos

6) Registros de clobbered.

asm(code : output operand list : input operand list : clobber list);

Si está utilizando registros, que no se habían pasado como operandos, debe informar al compilador sobre esto. El siguiente código ajustará un valor a un múltiplo de cuatro. Utiliza R3 como registro de rascar y le informa al compilador sobre esto especificando R3 en la lista de Clobber. Además, los indicadores de estado de la CPU se modifican por la instrucción de ANDS. Agregar el pseudo registro CC a la lista de clobber mantendrá al compilador informado sobre esta modificación también.

asm (
"ands R3, %1, #3"
"eor %0, %0, r3"
: "=r"(len)
: "0"(len)
: "cc", "r3"
);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top