簡體   English   中英

用C ++編寫匯編代碼

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM