日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

arm汇编解析—qnnpack卷积实现

發(fā)布時間:2024/4/18 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 arm汇编解析—qnnpack卷积实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

前言

基礎(chǔ)直通車

arm基礎(chǔ)知識

arm指令釋義

qnn匯編代碼解析


前言

最近在移植QNNPACK神經(jīng)網(wǎng)絡(luò)加速庫,涉及到對卷積arm匯編的修改,這邊做個記錄,對匯編部分的內(nèi)容進行注釋,順便學(xué)習(xí)一下匯編的語法。

?

基礎(chǔ)直通車

首先要補充arm匯編基礎(chǔ)知識,特別是如何傳參一定要搞清楚,另外對arm寄存器要了然于胸,剩下的就是指令的用法了:

利用堆棧入?yún)⒖?#xff1a;https://www.cnblogs.com/qq78292959/p/4013356.html

arm 32位NEON寄存器:https://blog.csdn.net/SoaringLee_fighting/article/details/81743505

ARM匯編器對ARM的寄存器預(yù)定義:https://blog.csdn.net/SoaringLee_fighting/article/details/81287824

ARM匯編指令:https://blog.csdn.net/zhangmiaoping23/article/details/8875193

?

arm基礎(chǔ)知識?

R0-R15和r0-r15
a1-a4(參數(shù),結(jié)果或者臨時寄存器,與r0-r3同意)
v1-v8(變量寄存器,與r4-r11同意)
sb和SB(靜態(tài)基址寄存器,與r9同意)
sl和SL(堆棧限制寄存器,與r10同意)
fp和FP(幀指針,與r11同意)
ip和IP(過程調(diào)用中間臨時寄存器,與r12同意)
sp和SP(堆棧指針,與r13同意)
lr和LR(連接寄存器,與r14同意)
pc和PC(程序計數(shù)器,與r15同意)
cpsr和CPSR(程序狀態(tài)寄存器)
spsr和SPSR(程序狀態(tài)寄存器)
f0-f7和F0-F7(FPA寄存器)
s0-s31和S0-S31(VFP單精度寄存器)
d0-d15和D0-D15(VFP雙精度寄存器)
p0-p15(協(xié)處理器0-15)
c0-c15(協(xié)處理器寄存器0-15)


使用說明:
1、當(dāng)參數(shù)少于4個時,子程序間通過寄存器R0~R3來傳遞參數(shù);當(dāng)參數(shù)個數(shù)多于4個時,將多余的參數(shù)通過數(shù)據(jù)棧進行傳遞,入棧順序與參數(shù)順序正好相反,子程序返回前無需恢復(fù)R0~R3的值;?
2、在子程序中,使用R4~R11保存局部變量,若使用需要入棧保存,子程序返回前需要恢復(fù)這些寄存器;R12是臨時寄存器,使用不需要保存。?
3、R13用作數(shù)據(jù)幀指針,記作SP;R14用作鏈接寄存器,記作LR,用于保存子程序返回時的地址;R15是程序計數(shù)器,記作PC。?
4、ATPCS規(guī)定堆棧是滿遞減堆棧FD;?
5、子程序返回32位的整數(shù),使用R0返回;返回64位整數(shù)時,使用R0返回低位,R1返回高位。

Arm32位寄存器主要分為ARM寄存器和NEON寄存器。?
ARM32寄存器包括15個通用寄存器R0~R14和一個程序計數(shù)器PC,共16個,均為32位寬。?
ARM32位寄存器的調(diào)用規(guī)則:遵循ATPCS調(diào)用規(guī)則

32位 NEON寄存器:?
包括:32個S寄存器,S0~S31,(單字,32bit)?
32個D寄存器,D0~D31,(雙字,64bit)?
16個Q寄存器,Q0~Q15,(四字,128bit)?
寄存器的對應(yīng)關(guān)系如下圖所示:?


使用說明:?
1、NEON寄存器將每個寄存器均視為一個向量,該向量又包含1,2,4,8或16個大小和類型均相同的元素。也可以將各個元素當(dāng)做標量訪問。?
NEON的這三種寄存器是重疊的,物理地址是一樣的。?
2、NEON寄存器在使用時,如果用到d8~d15寄存器,需要先入棧保存vpush {d8-d15},使用完之后要出棧vpop {d8-d15}

arm指令釋義

條件分支:

CMP:算數(shù)處理指令,用于把一個寄存器的內(nèi)容和另一個寄存器的內(nèi)容或立即數(shù)進行減法比較,不存儲結(jié)果,都會更改標志位

BNE:?數(shù)據(jù)跳轉(zhuǎn)指令,標志寄存器中Z標志位不等于零時,?跳轉(zhuǎn)到BNE后標簽處

BNE 3f 0b f:forwardb:backward

BEQ:?數(shù)據(jù)跳轉(zhuǎn)指令,標志寄存器中Z標志位等于零時,?跳轉(zhuǎn)到BEQ后標簽處

BLO指令 ?小于(無符號數(shù))跳轉(zhuǎn)

BLT:小于跳轉(zhuǎn);

TEQ:用于把一個寄存器的內(nèi)容和另一個寄存器的內(nèi)容或立即數(shù)進行按位的異或運算,并根據(jù)運算結(jié)果更新CPSR中條件標志位的值。該指令通常用于比較操作數(shù)1和操作數(shù)2是否相等。(EOR指令也是實現(xiàn)異或運算,只是不更新CPSR)

LSL:邏輯左移,LSR:邏輯右移

助記符

含????義

EQ

相等equal

NE

不相等not equal

CS

無符號數(shù)大于或等于Carry Set

CC

無符號數(shù)小于

MI

負數(shù)minus

PL

正數(shù)或零plus

VS

溢出

VC

沒有溢出

HI

無符號數(shù)大于high

LS

無符號數(shù)小于或等于less

GE

帶符號數(shù)大于或等于

LT

帶符號數(shù)小于less than

GT

帶符號數(shù)大于great than

LE

帶符號數(shù)小于或等于

AL

無條件執(zhí)行all

數(shù)據(jù)加載及存儲:

ldr ip,[sp],#4 將sp中內(nèi)容存入ip,之后sp=sp+4;

ldr ip,[sp,#4] 將sp+4這個新地址下內(nèi)容存入ip,之后sp值保持不變

ldr ip,[sp,#4]!將sp+4這個新地址下內(nèi)容存入ip,之后sp=sp+4將新地址值賦給sp

str ip,[sp],#4 將ip存入sp地址處,之后sp=sp+4;

str ip,[sp,#4] 將ip存入sp+4這個新地址,之后sp值保持不變

str ip,[sp,#4]!將ip存入sp+4這個新地址,之后sp=sp+4將新地址值賦給sp

?

qnn匯編代碼解析

先對BEGIN_FUNCTION定義說明

#ifdef?__ELF__? ? //linux系統(tǒng)編譯宏.macro?BEGIN_FUNCTION?name.text.align?2.global?\name.type?\name,?%function\name:.endm.macro?END_FUNCTION?name.size?\name,?.-\name.endm#elif?defined(__MACH__)? //ios/machos系統(tǒng)編譯宏.macro?BEGIN_FUNCTION?name?.text.align?2.global?_\name.private_extern?_\name_\name:.endm.macro?END_FUNCTION?name.endm#endif

卷積匯編代碼:?

/** Copyright (c) Facebook, Inc. and its affiliates.* All rights reserved.** This source code is licensed under the BSD-style license found in the* LICENSE file in the root directory of this source tree.*/.include "assembly.h".syntax unified# void q8conv_ukernel_4x8__aarch32_neon( # ? ? size_t mr, # ? ? size_t nr, # ? ? size_t kc, # ? ? size_t ks, # ? ? const uint8_t**restrict a, ###### r8 [sp, 96] ,3 # ? ? const void*restrict w, ###### ip [sp, 4] ,1 # ? ? uint8_t*restrict c, -> int32_t*restrict c, ###### r2, r3, [sp, 104] ,4 # ? ? size_t c_stride, # ? ? const union qnnp_conv_quantization_params quantization_params[restrict static 1])? ###### r9 [sp, 112] ,2#關(guān)于參數(shù)說明:從a開始的參數(shù)因為超過了4個,采用堆棧方式傳參,從最后一個參數(shù)params入棧,入棧方式為滿減棧(從上往下遞減)BEGIN_FUNCTION q8conv_ukernel_4x8__aarch32_neon.arm #ifndef __APPLE__.arch armv7-a.fpu neon #endif# Load w# - ip = w# ip==r12:temp register; sp==r13:top stack;# ip=sp+4=w,the 4 is size of?ptr a(地址偏移都以字節(jié)為單位)LDR ip, [sp, 4]PUSH {r4, r5, r6, r7, r8, r9, r10, r11}? ? #壓入棧中保存r4-r11的值。r4-r11用作局部變量VPUSH {d8-d15} #壓棧保存# Load bias0123, bias4567VLDM ip!, {d16-d19}? ?? ?# load bias:8xint32 = 4x64(d16-d19)# Load params:# - r9 = paramsLDR r9, [sp, 112]? ?#sizeof(r4-r11) + sizeof(d8-d15) +sizeof(a+w+c+c_stride)=32/8*8+64/8*8+4*4=112# q10 := vacc1x0123VMOV.I32 q10, q8? ? ?# mov 32x4 bias t0 q10(sizeof(q8)==128 bits)?MOV r4, 4# q11 := vacc1x4567VMOV.I32 q11, q9? ? ?# 將q9中的4個32賦值為q11# Load a# - r8 = aLDR r8, [sp, 96]??#sizeof(r4-r11) + sizeof(d8-d15) = 32/8*8 + 64/8*8=96# q12 := vacc2x0123VMOV.I32 q12, q8# q13 := vacc2x4567VMOV.I32 q13, q9# q14 := vacc3x0123VMOV.I32 q14, q8# Load b_zero_point:# - d15 = b_zero_point?? ?VLD1.8 {d15[]}, [r9], r4? ??# mov the value from r9 to all d15(per 8bit); r9=r9+r4(per 8bit)# q15 := vacc3x4567VMOV.I32 q15, q9# Load multiplier:# - d12 = vmultiplierVLD1.32 {d12[]}, [r9]!.p2align 5 0:SUBS r10, r2, 8# Load a0, a1, a2, a3# - r4 = a0# - r5 = a1# - r6 = a2# - r7 = a3LDM r8!, {r4-r7}BLO 2f1:# Load va0# - d1 = va0VLD1.8 {d1}, [r4]!# Load va1# - d3 = va1VLD1.8 {d3}, [r5]!# Load vb0-vb7 (channel 0)# - d9 = vb0-vb7VLD1.8 {d9}, [ip:64]!# Load va2# - d5 = va2VLD1.8 {d5}, [r6]!# q0 = va0 = a0VMOVL.U8 q0, d1# Load va3# - d7 = va3VLD1.8 {d7}, [r7]!# q1 = va1 = a1VMOVL.U8 q1, d3# q4 = b0:7 - vb_zero_point# - d8 = vb0123 (channel 0)# - d9 = vb4567 (channel 0)VSUBL.U8 q4, d9, d15# q2 = va2 = a2VMOVL.U8 q2, d5# q3 = va3 = a3VMOVL.U8 q3, d7### Channel 0 #### Load b0-b7 (channel 1)# - d11 = b0-b7VLD1.8 {d11}, [ip:64]!# vacc0x0123 += vb0123 * va0[0]VMLAL.S16 q8, d8, d0[0]# vacc0x4567 += vb4567 * va0[0]VMLAL.S16 q9, d9, d0[0]# vacc1x0123 += vb0123 * va1[0]VMLAL.S16 q10, d8, d2[0]# vacc1x4567 += vb4567 * va1[0]VMLAL.S16 q11, d9, d2[0]# vacc2x0123 += vb0123 * va2[0]VMLAL.S16 q12, d8, d4[0]# vacc2x4567 += vb4567 * va2[0]VMLAL.S16 q13, d9, d4[0]# q5 = b0:7 - vb_zero_point# - d10 = vb0123 (channel 1)# - d11 = vb4567 (channel 1)VSUBL.U8 q5, d11, d15# vacc3x0123 += vb0123 * va3[0]VMLAL.S16 q14, d8, d6[0]# vacc3x4567 += vb4567 * va3[0]VMLAL.S16 q15, d9, d6[0]### Channel 1 #### Load b0-b7 (channel 2)# - d9 = b0-b7VLD1.8 {d9}, [ip:64]!# vacc0x0123 += vb0123 * va0[1]VMLAL.S16 q8, d10, d0[1]# vacc0x4567 += vb4567 * va0[1]VMLAL.S16 q9, d11, d0[1]# vacc1x0123 += vb0123 * va1[1]VMLAL.S16 q10, d10, d2[1]# vacc1x4567 += vb4567 * va1[1]VMLAL.S16 q11, d11, d2[1]# vacc2x0123 += vb0123 * va2[1]VMLAL.S16 q12, d10, d4[1]# vacc2x4567 += vb4567 * va2[1]VMLAL.S16 q13, d11, d4[1]# q4 = b0:7 - vb_zero_point# - d8 = vb0123 (channel 2)# - d9 = vb4567 (channel 2)VSUBL.U8 q4, d9, d15# vacc3x0123 += vb0123 * va3[1]VMLAL.S16 q14, d10, d6[1]# vacc3x4567 += vb4567 * va3[1]VMLAL.S16 q15, d11, d6[1]### Channel 2 #### Load b0-b7 (channel 3)# - d11 = b0-b7VLD1.8 {d11}, [ip:64]!# vacc0x0123 += vb0123 * va0[2]VMLAL.S16 q8, d8, d0[2]# vacc0x4567 += vb4567 * va0[2]VMLAL.S16 q9, d9, d0[2]# vacc1x0123 += vb0123 * va1[2]VMLAL.S16 q10, d8, d2[2]# vacc1x4567 += vb4567 * va1[2]VMLAL.S16 q11, d9, d2[2]# vacc2x0123 += vb0123 * va2[2]VMLAL.S16 q12, d8, d4[2]# vacc2x4567 += vb4567 * va2[2]VMLAL.S16 q13, d9, d4[2]# q5 = b0:7 - vb_zero_point# - d10 = vb0123 (channel 3)# - d11 = vb4567 (channel 3)VSUBL.U8 q5, d11, d15# vacc3x0123 += vb0123 * va3[2]VMLAL.S16 q14, d8, d6[2]# vacc3x4567 += vb4567 * va3[2]VMLAL.S16 q15, d9, d6[2]### Channel 3 #### Load b0-b7 (channel 4)# - d9 = b0-b7VLD1.8 {d9}, [ip:64]!# vacc0x0123 += vb0123 * va0[3]VMLAL.S16 q8, d10, d0[3]# vacc0x4567 += vb4567 * va0[3]VMLAL.S16 q9, d11, d0[3]# vacc1x0123 += vb0123 * va1[3]VMLAL.S16 q10, d10, d2[3]# vacc1x4567 += vb4567 * va1[3]VMLAL.S16 q11, d11, d2[3]# vacc2x0123 += vb0123 * va2[3]VMLAL.S16 q12, d10, d4[3]# vacc2x4567 += vb4567 * va2[3]VMLAL.S16 q13, d11, d4[3]# q5 = b0:7 - vb_zero_point# - d10 = vb0123 (channel 4)# - d11 = vb4567 (channel 4)VSUBL.U8 q4, d9, d15# vacc3x0123 += vb0123 * va3[3]VMLAL.S16 q14, d10, d6[3]# vacc3x4567 += vb4567 * va3[3]VMLAL.S16 q15, d11, d6[3]### Channel 4 #### Load b0-b7 (channel 5)# - d11 = b0-b7VLD1.8 {d11}, [ip:64]!# vacc0x0123 += vb0123 * va0[4]VMLAL.S16 q8, d8, d1[0]# vacc0x4567 += vb4567 * va0[4]VMLAL.S16 q9, d9, d1[0]# vacc1x0123 += vb0123 * va1[4]VMLAL.S16 q10, d8, d3[0]# vacc1x4567 += vb4567 * va1[4]VMLAL.S16 q11, d9, d3[0]# vacc2x0123 += vb0123 * va2[4]VMLAL.S16 q12, d8, d5[0]# vacc2x4567 += vb4567 * va2[4]VMLAL.S16 q13, d9, d5[0]# q4 = b0:7 - vb_zero_point# - d8 = vb0123 (channel 5)# - d9 = vb4567 (channel 5)VSUBL.U8 q5, d11, d15# vacc3x0123 += vb0123 * va3[4]VMLAL.S16 q14, d8, d7[0]# vacc3x4567 += vb4567 * va3[4]VMLAL.S16 q15, d9, d7[0]### Channel 5 #### Load b0-b7 (channel 6)# - d9 = b0-b7VLD1.8 {d9}, [ip:64]!# vacc0x0123 += vb0123 * va0[5]VMLAL.S16 q8, d10, d1[1]# vacc0x4567 += vb4567 * va0[5]VMLAL.S16 q9, d11, d1[1]# vacc1x0123 += vb0123 * va1[5]VMLAL.S16 q10, d10, d3[1]# vacc1x4567 += vb4567 * va1[5]VMLAL.S16 q11, d11, d3[1]# vacc2x0123 += vb0123 * va2[5]VMLAL.S16 q12, d10, d5[1]# vacc2x4567 += vb4567 * va2[5]VMLAL.S16 q13, d11, d5[1]# q4 = b0:7 - vb_zero_point# - d8 = vb0123 (channel 6)# - d9 = vb4567 (channel 6)VSUBL.U8 q4, d9, d15# vacc3x0123 += vb0123 * va3[5]VMLAL.S16 q14, d10, d7[1]# vacc3x4567 += vb4567 * va3[5]VMLAL.S16 q15, d11, d7[1]### Channel 6 #### Load b0-b7 (channel 7)# - d11 = b0-b7VLD1.8 {d11}, [ip:64]!# vacc0x0123 += vb0123 * va0[6]VMLAL.S16 q8, d8, d1[2]# vacc0x4567 += vb4567 * va0[6]VMLAL.S16 q9, d9, d1[2]# vacc1x0123 += vb0123 * va1[6]VMLAL.S16 q10, d8, d3[2]# vacc1x4567 += vb4567 * va1[6]VMLAL.S16 q11, d9, d3[2]# vacc2x0123 += vb0123 * va2[6]VMLAL.S16 q12, d8, d5[2]# q5 = b0:7 - vb_zero_point# - d10 = vb0123 (channel 7)# - d11 = vb4567 (channel 7)VSUBL.U8 q5, d11, d15# vacc2x4567 += vb4567 * va2[6]VMLAL.S16 q13, d9, d5[2]# vacc3x0123 += vb0123 * va3[6]VMLAL.S16 q14, d8, d7[2]# vacc3x4567 += vb4567 * va3[6]VMLAL.S16 q15, d9, d7[2]### Channel 8 ###SUBS r10, r10, 8# vacc0x0123 += vb0123 * va0[7]VMLAL.S16 q8, d10, d1[3]# vacc0x4567 += vb4567 * va0[7]VMLAL.S16 q9, d11, d1[3]# vacc1x0123 += vb0123 * va1[7]VMLAL.S16 q10, d10, d3[3]# vacc1x4567 += vb4567 * va1[7]VMLAL.S16 q11, d11, d3[3]# vacc2x0123 += vb0123 * va2[7]VMLAL.S16 q12, d10, d5[3]# vacc2x4567 += vb4567 * va2[7]VMLAL.S16 q13, d11, d5[3]# vacc3x0123 += vb0123 * va3[7]VMLAL.S16 q14, d10, d7[3]# vacc3x4567 += vb4567 * va3[7]VMLAL.S16 q15, d11, d7[3]BHS 1b2:CMP r10, -8BEQ 3f# Adjust a0, a1, a2, a3ADD r4, r10ADD r5, r10ADD r6, r10ADD r7, r10# a_shift = 8 * k - 64LSL r10, r10, 3VDUP.32 d13, r10# Load va0# - d1 = va0VLD1.8 {d1}, [r4]# Load va1# - d3 = va1VLD1.8 {d3}, [r5]# Load b0-b7 (channel 0)# - d9 = b0-b7VLD1.8 {d9}, [ip:64]!# Load a2# - d5 = a2VLD1.8 {d5}, [r6]# q0 = va0 = a0VSHL.U64 d1, d1, d13VMOVL.U8 q0, d1# Load a3# - d7 = a3VLD1.8 {d7}, [r7]# q1 = va1 = a1VSHL.U64 d3, d3, d13VMOVL.U8 q1, d3# q4 = b0:7 - vb_zero_point# - d8 = vb0123 (channel 0)# - d9 = vb4567 (channel 0)VSUBL.U8 q4, d9, d15# q2 = va2 = a2VSHL.U64 d5, d5, d13VMOVL.U8 q2, d5# q3 = va3 = a3VSHL.U64 d7, d7, d13VMOVL.U8 q3, d7### Channel 0 #### vacc0x0123 += vb0123 * va0[0]VMLAL.S16 q8, d8, d0[0]# vacc0x4567 += vb4567 * va0[0]VMLAL.S16 q9, d9, d0[0]# vacc1x0123 += vb0123 * va1[0]VMLAL.S16 q10, d8, d2[0]# vacc1x4567 += vb4567 * va1[0]VMLAL.S16 q11, d9, d2[0]# vacc2x0123 += vb0123 * va2[0]VMLAL.S16 q12, d8, d4[0]# vacc2x4567 += vb4567 * va2[0]VMLAL.S16 q13, d9, d4[0]# vacc3x0123 += vb0123 * va3[0]VMLAL.S16 q14, d8, d6[0]# vacc3x4567 += vb4567 * va3[0]VMLAL.S16 q15, d9, d6[0]CMP r10, -48BLO 3f### Channel 1 #### Load b0-b7 (channel 1)# - d11 = b0-b7VLD1.8 {d11}, [ip:64]!# q5 = b0:7 - vb_zero_point# - d10 = vb0123 (channel 1)# - d11 = vb4567 (channel 1)VSUBL.U8 q5, d11, d15# vacc0x0123 += vb0123 * va0[1]VMLAL.S16 q8, d10, d0[1]# vacc0x4567 += vb4567 * va0[1]VMLAL.S16 q9, d11, d0[1]# vacc1x0123 += vb0123 * va1[1]VMLAL.S16 q10, d10, d2[1]# vacc1x4567 += vb4567 * va1[1]VMLAL.S16 q11, d11, d2[1]# vacc2x0123 += vb0123 * va2[1]VMLAL.S16 q12, d10, d4[1]# vacc2x4567 += vb4567 * va2[1]VMLAL.S16 q13, d11, d4[1]# vacc3x0123 += vb0123 * va3[1]VMLAL.S16 q14, d10, d6[1]# vacc3x4567 += vb4567 * va3[1]VMLAL.S16 q15, d11, d6[1]### Channel 2 ###BLS 3f# Load b0-b7 (channel 2)# - d9 = b0-b7VLD1.8 {d9}, [ip:64]!# q4 = b0:7 - vb_zero_point# - d8 = vb0123 (channel 2)# - d9 = vb4567 (channel 2)VSUBL.U8 q4, d9, d15# vacc0x0123 += vb0123 * va0[2]VMLAL.S16 q8, d8, d0[2]# vacc0x4567 += vb4567 * va0[2]VMLAL.S16 q9, d9, d0[2]# vacc1x0123 += vb0123 * va1[2]VMLAL.S16 q10, d8, d2[2]# vacc1x4567 += vb4567 * va1[2]VMLAL.S16 q11, d9, d2[2]# vacc2x0123 += vb0123 * va2[2]VMLAL.S16 q12, d8, d4[2]# vacc2x4567 += vb4567 * va2[2]VMLAL.S16 q13, d9, d4[2]# vacc3x0123 += vb0123 * va3[2]VMLAL.S16 q14, d8, d6[2]# vacc3x4567 += vb4567 * va3[2]VMLAL.S16 q15, d9, d6[2]### Channel 3 ###CMP r10, -32BLO 3f# Load b0-b7 (channel 3)# - d9 = b0-b7VLD1.8 {d11}, [ip:64]!# q4 = b0:7 - vb_zero_point# - d8 = vb0123 (channel 3)# - d9 = vb4567 (channel 3)VSUBL.U8 q5, d11, d15# vacc0x0123 += vb0123 * va0[3]VMLAL.S16 q8, d10, d0[3]# vacc0x4567 += vb4567 * va0[3]VMLAL.S16 q9, d11, d0[3]# vacc1x0123 += vb0123 * va1[3]VMLAL.S16 q10, d10, d2[3]# vacc1x4567 += vb4567 * va1[3]VMLAL.S16 q11, d11, d2[3]# vacc2x0123 += vb0123 * va2[3]VMLAL.S16 q12, d10, d4[3]# vacc2x4567 += vb4567 * va2[3]VMLAL.S16 q13, d11, d4[3]# vacc3x0123 += vb0123 * va3[3]VMLAL.S16 q14, d10, d6[3]# vacc3x4567 += vb4567 * va3[3]VMLAL.S16 q15, d11, d6[3]### Channel 4 ###BLS 3f# Load b0-b7 (channel 4)# - d11 = b0-b7VLD1.8 {d9}, [ip:64]!# q5 = b0:7 - vb_zero_point# - d10 = vb0123 (channel 4)# - d11 = vb4567 (channel 4)VSUBL.U8 q4, d9, d15# vacc0x0123 += vb0123 * va0[4]VMLAL.S16 q8, d8, d1[0]# vacc0x4567 += vb4567 * va0[4]VMLAL.S16 q9, d9, d1[0]# vacc1x0123 += vb0123 * va1[4]VMLAL.S16 q10, d8, d3[0]# vacc1x4567 += vb4567 * va1[4]VMLAL.S16 q11, d9, d3[0]# vacc2x0123 += vb0123 * va2[4]VMLAL.S16 q12, d8, d5[0]# vacc2x4567 += vb4567 * va2[4]VMLAL.S16 q13, d9, d5[0]# vacc3x0123 += vb0123 * va3[4]VMLAL.S16 q14, d8, d7[0]# vacc3x4567 += vb4567 * va3[4]VMLAL.S16 q15, d9, d7[0]### Channel 5 ###CMP r10, -16BLO 3f# Load b0-b7 (channel 5)# - d13 = b0-b7VLD1.8 {d11}, [ip:64]!# q5 = b0:7 - vb_zero_point# - d10 = vb0123 (channel 5)# - d11 = vb4567 (channel 5)VSUBL.U8 q5, d11, d15# vacc0x0123 += vb0123 * va0[5]VMLAL.S16 q8, d10, d1[1]# vacc0x4567 += vb4567 * va0[5]VMLAL.S16 q9, d11, d1[1]# vacc1x0123 += vb0123 * va1[5]VMLAL.S16 q10, d10, d3[1]# vacc1x4567 += vb4567 * va1[5]VMLAL.S16 q11, d11, d3[1]# vacc2x0123 += vb0123 * va2[5]VMLAL.S16 q12, d10, d5[1]# vacc2x4567 += vb4567 * va2[5]VMLAL.S16 q13, d11, d5[1]# vacc3x0123 += vb0123 * va3[5]VMLAL.S16 q14, d10, d7[1]# vacc3x4567 += vb4567 * va3[5]VMLAL.S16 q15, d11, d7[1]### Channel 6 ###BLS 3f# Load b0-b7 (channel 6)# - d9 = b0-b7VLD1.8 {d9}, [ip:64]!# q4 = b0:7 - vb_zero_point# - d8 = vb0123 (channel 6)# - d9 = vb4567 (channel 6)VSUBL.U8 q4, d9, d15# vacc0x0123 += vb0123 * va0[6]VMLAL.S16 q8, d8, d1[2]# vacc0x4567 += vb4567 * va0[6]VMLAL.S16 q9, d9, d1[2]# vacc1x0123 += vb0123 * va1[6]VMLAL.S16 q10, d8, d3[2]# vacc1x4567 += vb4567 * va1[6]VMLAL.S16 q11, d9, d3[2]# vacc2x0123 += vb0123 * va2[6]VMLAL.S16 q12, d8, d5[2]# vacc2x4567 += vb4567 * va2[6]VMLAL.S16 q13, d9, d5[2]# vacc3x0123 += vb0123 * va3[6]VMLAL.S16 q14, d8, d7[2]# vacc3x4567 += vb4567 * va3[6]VMLAL.S16 q15, d9, d7[2].p2align 4 3:SUBS r3, r3, 1BNE 0b# Load c, c_stride:# - r2 = c# - r3 = c_strideLDRD r2, r3, [sp, 104]# r3 = c_stride*4;MOV r3, r3, LSL 2ADD r4, r2, r3CMP r0, 2?#if r0<2 r4=r2MOVLO r4, r2?ADD r5, r4, r3#if r0==2 r5=r4MOVLS r5, r4CMP r0, 4ADD r3, r5, r3#if r0!=4 r3=r5MOVNE r3, r5CMP r1, 8BNE 5fVST1.I32 {d16-d19}, [r2]VST1.I32 {d20-d23}, [r4]VST1.I32 {d24-d27}, [r5]VST1.I32 {d28-d31}, [r3]VPOP {d8-d15}POP {r4, r5, r6, r7, r8, r9, r10, r11}BX lr.p2align 3 5:CMP r1, 4BLO 6fVST1.32 {d16-d17}, [r2:128]!VST1.32 {d20-d21}, [r4:128]!VST1.32 {d24-d25}, [r5:128]!VST1.32 {d28-d29}, [r3:128]!SUB r1, 4VMOV.I32 q8, q9VMOV.I32 q10, q11VMOV.I32 q12, q13VMOV.I32 q14, q156:CMP r1, 2BLO 7fVST1.32 {d16}, [r2:64]!VST1.32 {d20}, [r4:64]!VST1.32 {d24}, [r5:64]!VST1.32 {d28}, [r3:64]!SUB r1, 2VEXT.32 q8, q8, q8, 2VEXT.32 q10, q10, q10, 2VEXT.32 q12, q12, q12, 2VEXT.32 q14, q14, q14, 27:TEQ r1, 0BEQ 8fVST1.32 {d16}, [r2]VST1.32 {d20}, [r4]VST1.32 {d24}, [r5]VST1.32 {d28}, [r3]8:VPOP {d8-d15}?POP {r4, r5, r6, r7, r8, r9, r10, r11}BX lr #bx?lr?的作用等同于 mov pc,lr?即跳轉(zhuǎn)到lr中存放的地址處 END_FUNCTION q8conv_ukernel_4x8__aarch32_neon#ifdef __ELF__ .section ".note.GNU-stack","",%progbits #endif

?

與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的arm汇编解析—qnnpack卷积实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。