ARM NEON 基本指令集介紹

2021-08-02 09:58:56 字數 4769 閱讀 8400

目錄

暫存器基本資料型別

結構化資料型別

基本指令集

armv7架構包含:

下面這些資料型別是上述基本資料型別的組合而成的結構化資料型別,通常為被對映到多個暫存器中。

typedef struct int8x8x2_t

int8x8x2_t;

...//省略...

...#ifdef __arm_feature_crypto

typedef struct poly64x2x4_t

poly64x2x4_t;

#endif

neon指令按照運算元型別可以分為正常指令、寬指令、窄指令、飽和指令、長指令。

neon指令按照作用可以分為:載入資料、儲存資料、加減乘除運算、邏輯and/or/xor運算、比較大小運算等。

常用的指令集包括:

儲存暫存器資料到記憶體

間隔為x,儲存neon暫存器的資料到記憶體中

void vstx_type(scalar_t* n)

void vstxq_type(scalar_t* n)

間隔為x,儲存neon暫存器的相關lane(通道)到記憶體中

result_t vst[x]_lane_type(scalar_t* n,vector_t m,int n)

result_t vst[x]q_lane_type(scalar_t* n,vector_t m,int n)

讀取/修改暫存器資料

讀取暫存器第n個通道的資料

result_t vget_lane_type(vector_t m,int n)
讀取暫存器的高/低部分到新的暫存器中,資料變窄(長度減半)。

result_t vget_low_type(vector_t m)

result_t vget_high_type(vector_t m)

返回在複製m的基礎上設定通道n為n的暫存器資料

result_t vset_lane_type(scalar n,vector_t m,int n)

暫存器資料重排

從暫存器m中取出後n個通道的資料置於低位,再從暫存器n中取出x-n個通道的資料置於高位,組成乙個新的暫存器資料。

result_t vext_type(vector_t n,vector_t m,int n)

result_t vextq_type(vector_t n,vector_t m,int n)

其他資料重排指令還有:

vtbl_tyoe,vrev_type,vtrn_type,vzip_type,vunzip_type,vcombine ...

等以後有時間一一講解。

型別轉換指令

強制重新解釋暫存器的值型別,從srctype轉化為dsttype,其內部實際值不變且總的位元組數不變,舉例:vreinterpret_f32_s32(int32x2_t),從int32x2_t轉化為float32x2_t。

vreinterpret_dsttype_srctype(vector_t n)
算數運算指令

[普通指令] 普通加法運算 res = m+n

result_t vadd_type(vector_t m,vector_t n)

result_t vaddq_type(vector_t m,vector_t n)

[長指令] 變長加法運算 res = m+n,為了防止溢位,一種做法是使用如下指令,加法結果儲存到長度x2的暫存器中,如:vuint16x8_t res = vaddl_u8(uint8x8_t m,uint8x8_t n)。

result_t vaddl_type(vector_t m,vector_t n)
[寬指令] 加法運算 res = m+n,第乙個引數m寬度大於第二個引數n。

result_t vaddw_type(vector_t m,vector_t n)
[普通指令] 加法運算 res = trunct(m+n)(溢位則截斷)之後向右平移1位,即計算m和n的平均值

result_t vhadd_type(vector_t m,vector_t n)
[普通指令] 加法運算 res = round(m+n)(溢位則迴圈)之後向右平移1位,即計算m和n的平均值

result_t vrhadd_type(vector_t m,vector_t n)
[飽和指令] 飽和加法運算 res = st(m+n),如:vuint8x8_t res = vqadd_u8(uint8x8_t m,uint8x8_t n),res超出int8_t的表示範圍(0,255),比如256,則設為255.

result_t vqadd_type(vector_t m,vector_t n)
[窄指令] 加法運算 res = m+n,結果比引數m/n的長度小一半,如 uint8x8_t res = vaddhn_u16(uint16x8_t m,uint16x8_t n)

result_t vaddhn_type(vector_t m,vector_t n)
[普通指令] 減法運算 res = m-n

result_t vsub_type(vector_t m,vector_t n)
[普通指令] 乘法運算 res = m*n

result_t vmul_type(vector_t m,vector_t n)

result_t vmulq_type(vector_t m,vector_t n)

[普通指令] 乘&加法運算 res = m+n*p

result_t vmla_type(vector_t m,vector_t n,vector_t p)

result_t vmlaq_type(vector_t m,vector_t n,vector_t p)

[普通指令] 乘&減法運算 res = m-n*p

result_t vmls_type(vector_t m,vector_t n,vector_t p)

result_t vmlsq_type(vector_t m,vector_t n,vector_t p)

類似加法運算,減法和乘法運算也有一系列變種...

資料處理指令

[普通指令] 計算絕對值 res=abs(m)

result_t vabs_type(vector_t m)
[普通指令] 計算負值 res=-m

result_t vneg_type(vector_t m)
[普通指令] 計算最大值 res=max(m,n)

result_t vmax_type(vector_t m,vector_t n)
[普通指令] 計算最小值 res=min(m,n)

result_t vmin_type(vector_t m,vector_t n)
...

比較指令

[普通指令] 比較是否相等 res=mask(m == n)

result_t vceg_type(vector_t m,vector_t n)
[普通指令] 比較是否大於或等於 res=mask(m >= n)

result_t vcge_type(vector_t m,vector_t n)
[普通指令] 比較是否大於 res=mask(m > n)

result_t vcgt_type(vector_t m,vector_t n)
[普通指令] 比較是否小於或等於 res=mask(m <= n)

result_t vcle_type(vector_t m,vector_t n)
[普通指令] 比較是否小於 res=mask(m < n)

result_t vclt_type(vector_t m,vector_t n)
...

歸約指令

[普通指令] 歸約加法,m和n內部的元素各自相加,最後組成乙個新的結果

result_t vpadd_type(vector_t m,vector_t n)
[普通指令] 歸約最大比較,m和n內部的元素比較得出最大值,最後組成乙個新的結果

result_t vpmax_type(vector_t m,vector_t n)
[普通指令] 歸約最小比較,m和n內部的元素比較得出最小值,最後組成乙個新的結果

result_t vpmin_type(vector_t m,vector_t n)

RISC V指令集介紹 整數基本指令集

前段時間在修改 picorv32 核心 乙個riscv 32的cpu核心 閱讀了一下riscv指令集的手冊。在此,做一下簡單記錄。rv32i 32位risc v整數指令集 1.暫存器 32個x暫存器,rv32下x reg是32位寬 x0 硬連線 常數0 x1 x31 31個通用reg pc 額外的使...

基本彙編指令集

基本彙編指令集 彙編指令集 1.通用資料傳送指令 mov 傳送字或位元組.movsx 先符號擴充套件,再傳送.movzx 先零擴充套件,再傳送.push 把字壓入堆疊.pop 把字彈出堆疊.pusha 把ax,cx,dx,bx,sp,bp,si,di依次壓入堆疊.popa 把di,si,bp,sp,...

mysql bin指令集 mysql指令集

一 連線mysql。1 連線到本機上的mysql。首先開啟dos視窗,然後進入目錄mysql bin,再鍵入命令mysql u root p,回車後提示你輸密碼.注意使用者名稱前可以有空格也可以沒有空格,但是密碼前必須沒有空格,否則讓你重新輸入密碼.如果剛安裝好mysql,超級使用者root是沒有密...