2010-09-29 29 views
5

No estoy en posición de distinguir entre vld4_f32 y vld4q_f32 en las instrucciones de ARM NEON.ARM NEON: ¿Cuál es la diferencia entre vld4_f32 y vld4q_f32?

La confusión comenzó cuando elevé mis niveles de codificación y comencé a mirar las instrucciones de montaje en lugar de las intrínsecas menos informativas.

La razón por la que necesito para usar la instrucción variante vld4 aquí es porque, me gustaría capturar float32_t 's de todos los cuarta posición de mi gran conjunto.

alt text

Los vld4_f32 intrínsecos y las correspondientes instrucciones de montaje se ven así (From this link)

float32x2x4_t vld4_f32 (const float32_t *) 
Form of expected instruction(s): vld4.32 {d0, d1, d2, d3}, [r0] 

Los vld4q_f32 intrínsecos y sus instrucciones de montaje correspondientes se parece a esto

float32x4x4_t vld4q_f32 (const float32_t *) 
Form of expected instruction(s): vld4.32 {d0, d1, d2, d3}, [r0] 

Bueno, en el nivel intrínseco la diferencia que veo es el tipo de retorno, pero si miro las instrucciones de ensamblaje y el número de registros, ambos tienen el mismo aspecto. ¿Cómo sabrá el compilador o el ensamblador la diferencia entre los dos?

Alguien puede aclarar más en esto y también explicar cómo puedo lograr carga 4 float32_t valores que se colocan en cada posición de memoria cuarto en un único registro?

Respuesta

7

Sí, descubrí la diferencia. Utilicé CodeSourcery para ver el contenido real del registro de todas las instrucciones de carga. El enlace que he publicado no proporciona todos los detalles sobre vld4q_f32.

bien, primero viene la vld4_f32, esto carga 4 d registros (por ejemplo d16-19) cada d registro es de 64 bits de largo, por lo que esta instrucción cargará los primeros 8 valores intercalados con un intervalo de 4 como se muestra en la figura a continuación. alt text

En el segundo caso la vld4q_f32, esto carga 8 d registros (por ejemplo d16-23) en lugar de cuatro. Para un lector de este link, no está del todo claro que se cargarán 8 registros. Cuando miré el código des-ensamblado para un vld4qf32, estaba haciendo uso de 8 registros d.

Esta instrucción realmente hará lo que esperaba que hiciera, es decir, cargar 4 valores float32_t que están en el intervalo de 4 como se muestra en la figura a continuación. alt text

+1

Bueno, cargas vld4q 4 q registros, como su nombre indica ... – jcayzac

1

He desmontado dos funciones intrínsecas, tal vez ayuda a alguien:

// C++ 
uint32x4x4_t r = vld4q_u32((uint32_t *) output); 
// assembly 
VLD4.32   {D16,D18,D20,D22}, [R0]! 
VLD4.32   {D17,D19,D21,D23}, [R0] 

// C++ 
uint32x2x4_t r = vld4_u32((uint32_t *) output); 
// assembly 
VLD4.32   {D20-D23}, [R0] 
Cuestiones relacionadas