PX4flow中的彙編程式碼
阿新 • • 發佈:2019-01-12
// compliments of Adam Williams
#define ABSDIFF(frame1, frame2) \
({ \
int result = 0; \
asm volatile( \
"mov %[result], #0\n" /* accumulator */ \
\
"ldr r4, [%[src], #0]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #0]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #4]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #4]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
"ldr r4, [%[src], #(64 * 1)]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #(64 * 1)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #(64 * 1 + 4)]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #(64 * 1 + 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
"ldr r4, [%[src], #(64 * 2)]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #(64 * 2)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #(64 * 2 + 4)]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #(64 * 2 + 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
"ldr r4, [%[src], #(64 * 3)]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #(64 * 3)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #(64 * 3 + 4)]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #(64 * 3 + 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
"ldr r4, [%[src], #(64 * 4)]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #(64 * 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #(64 * 4 + 4)]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #(64 * 4 + 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
"ldr r4, [%[src], #(64 * 5)]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #(64 * 5)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #(64 * 5 + 4)]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #(64 * 5 + 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
"ldr r4, [%[src], #(64 * 6)]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #(64 * 6)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #(64 * 6 + 4)]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #(64 * 6 + 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
"ldr r4, [%[src], #(64 * 7)]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #(64 * 7)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #(64 * 7 + 4)]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #(64 * 7 + 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
: [result] "+r" (result) \
: [src] "r" (frame1), [dst] "r" (frame2) \
: "r4", "r5" \
); \
\
result; \
#define ABSDIFF(frame1, frame2) \
({ \
int result = 0; \
asm volatile( \
"mov %[result], #0\n" /* accumulator */ \
\
"ldr r4, [%[src], #0]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #0]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #4]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #4]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
"ldr r4, [%[src], #(64 * 1)]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #(64 * 1)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #(64 * 1 + 4)]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #(64 * 1 + 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
"ldr r4, [%[src], #(64 * 2)]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #(64 * 2)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #(64 * 2 + 4)]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #(64 * 2 + 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
"ldr r4, [%[src], #(64 * 3)]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #(64 * 3)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #(64 * 3 + 4)]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #(64 * 3 + 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
"ldr r4, [%[src], #(64 * 4)]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #(64 * 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #(64 * 4 + 4)]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #(64 * 4 + 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
"ldr r4, [%[src], #(64 * 5)]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #(64 * 5)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #(64 * 5 + 4)]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #(64 * 5 + 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
"ldr r4, [%[src], #(64 * 6)]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #(64 * 6)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #(64 * 6 + 4)]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #(64 * 6 + 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
"ldr r4, [%[src], #(64 * 7)]\n" /* read data from address + offset*/ \
"ldr r5, [%[dst], #(64 * 7)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
"ldr r4, [%[src], #(64 * 7 + 4)]\n" /* read data from address + offset */ \
"ldr r5, [%[dst], #(64 * 7 + 4)]\n" \
"usada8 %[result], r4, r5, %[result]\n" /* difference */ \
\
: [result] "+r" (result) \
: [src] "r" (frame1), [dst] "r" (frame2) \
: "r4", "r5" \
); \
\
result; \
})
翻譯成C語言。
int absdiff(unsigned char *base1,unsigned char *base2)
{
int result = 0;
for(int i = 0;i <8;i++)
{
for(j = 0;j < 8;j++)
{
result += abs(base1[i*64 + j] - base2[i*64 + j]);
}
}
return result;
}
其中usada8可以翻譯成。
int usada8(unsigned int base1,unsigned int base2,unsigned int base)
{
unsigned char *p1 = (unsigned char *)&base1;
unsigned char *p2 = (unsigned char *)&base2;
for(int i = 0;i< 4;i++)
{
base += abs(*(p1 + i) - *(p2 + i));
}
/* for(int i = 0;i< 4;i++)
{
//base += (unsigned char)abs((base1 >> 8*i)- (base2 >> 8*i));
}*/
return base;
}