[英]writing assembly code in c++
我在C ++中有以下代碼:
inline void armMultiply(const float* __restrict__ src1,
const float* __restrict__ src2,
float* __restrict__ dst)
{
__asm volatile(
"vld1.f32 {q0}, [%[src1]:128]! \n\t"
:
:[dst] "r" (dst), [src1] "r" (src1), [src2] "r" (src2)
);
}
為什么我得到預期的錯誤向量寄存器?
之所以會出現此錯誤,是因為您的內聯匯編程序是針對32位arm的,但是您正在針對64位arm進行編譯(使用clang-使用gcc,您將得到另一個錯誤)。
(內聯)組件是32位和64位臂之間是不同的,所以你需要用如來保護它#if defined(__ARM_NEON__) && !defined(__aarch64__)
或者如果你想有兩個64位和32位不同的組件: #ifdef __aarch64__
.. #elif defined(__ARM_NEON__)
,等等。
正如其他人所評論的那樣,除非您真的需要手動調整生產的程序集,否則內在函數可能會一樣好(在某些情況下,它會比您自己生產的函數好)。 您可以通過內在函數很好地進行兩個vld1_f32
調用,一個vmul_f32
和一個vst1_f32
調用。
編輯:
要加載到64位SIMD寄存器中的相應內聯匯編行將是:
"ld1 {v0.4s}, [%[src1]], #16 \n\t"
為了同時支持這兩種功能,您的函數應如下所示:
inline void armMultiply(const float* __restrict__ src1,
const float* __restrict__ src2,
float* __restrict__ dst)
{
#ifdef __aarch64__
__asm volatile(
"ld1 {v0.4s}, [%[src1]], #16 \n\t"
:
:[dst] "r" (dst), [src1] "r" (src1), [src2] "r" (src2)
);
#elif defined(__ARM_NEON__)
__asm volatile(
"vld1.f32 {q0}, [%[src1]:128]! \n\t"
:
:[dst] "r" (dst), [src1] "r" (src1), [src2] "r" (src2)
);
#else
#error this requires neon
#endif
}
假設我們在談論GCC,文檔說您應該使用“ w”(“浮點或SIMD矢量寄存器”)而不是“ r”(“允許在通用寄存器中使用寄存器操作數”)作為約束。
https://gcc.gnu.org/onlinedocs/gcc-6.3.0/gcc/Machine-Constraints.html#Machine-Constraints
https://gcc.gnu.org/onlinedocs/gcc-6.3.0/gcc/Simple-Constraints.html#Simple-Constraints
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.