这很难。。没有一条指令可以做到这一点,最好的解决方案取决于数据是在内存中还是已经在寄存器中。
你至少需要两个操作来进行转换。。首先是一个向量转向,它将你的论点排列成这样:
a = a1 a2
b = b1 b2
vtrn.32 a, b
a = a1 b1
b = a2 b2
然后必须交换每个操作的参数。或者把每个向量自己倒过来,或者把两个向量当作一个四元向量,做一个长倒过来。
temp = {a, b}
temp = a1 b1 a2 b2
vrev64.32 temp, temp
temp = b1 a1 b2 a2 <-- this is what you want.
.globl asmtest
asmtest:
vld2.32 {d0-d1}, [r0] # load two vectors and transose
vrev64.32 q0, q0 # reverse within d0 and d1
vst1.32 {d0-d1}, [r0] # store result
mov pc, lr # return from subroutine..
顺便说一句,请注意:vtrn.32、vzip.32和vuzp.32指令是相同的(但仅当您使用32位实体时)
这是我提出的使用内部函数的最好方法(它没有使用vld2.32技巧来提高可读性):
int main (int argc, char **args)
{
const float32_t data[4] =
{
1, 2, 3, 4
};
float32_t output[4];
/* load test vectors */
float32x2_t a = vld1_f32 (data + 0);
float32x2_t b = vld1_f32 (data + 2);
/* transpose and convert to float32x4_t */
float32x2x2_t temp = vzip_f32 (b,a);
float32x4_t result = vcombine_f32 (temp.val[0], temp.val[1]);
/* store for printing */
vst1q_f32 (output, result);
/* print out the original and transposed result */
printf ("%f %f %f %f\n", data[0], data[1], data[2], data[3]);
printf ("%f %f %f %f\n", output[0], output[1], output[2], output[3]);
}
如果您使用的是GCC,这将是可行的,但GCC生成的代码将是可怕的和缓慢的。我还很年轻。使用直接的C代码,您可能会获得更好的性能。。