MNN/source/backend/cpu/arm/arm32/MNNGelu.S

147 lines
2.7 KiB
ArmAsm
Raw Normal View History

2023-03-20 11:32:29 +08:00
//
// MNNGelu.S
// MNN
//
// Created by MNN on 2023/2/27.
// Copyright © 2018, Alibaba Group Holding Limited
//
#ifdef __arm__
#ifndef __aarch64__
#include "MNNAsmGlobal.h"
.text
.align 5
asm_function MNNGelu
//void MNNGelu(float* dst, const float* src, size_t size, float* parameters);
//Auto Load:
//r0:dst, r1:src, r2:size, r3: *parameters
push {r4-r8, r10, r11, lr}
vpush {q4-q7}
cmp r2, #0
beq GeluEnd
ldr lr, [r3, #0]
ldr r4, [r3, #4] // r4: 0.79788458f
ldr r5, [r3, #8] // r5: 378.f
ldr r6, [r3, #12] // r6: 17325.f
ldr r7, [r3, #16] // r7: 135135.f
ldr r8, [r3, #20] // r8: 28.f
ldr r10, [r3, #24] // r10: 3150.f
ldr r11, [r3, #28] // r11: 62370.f
vdup.32 q15, lr //q15: [0.044715f]x4
vdup.32 q14, r4 //q16: [0.79788458f]x4
vdup.32 q13, r5 //q13: [378.f]x4
vdup.32 q12, r6 //q12: [17325.f]x4
vdup.32 q11, r7 //q11: [135135.f]x4
vdup.32 q10, r8 //q10: [28.f]x4
vdup.32 q9, r10 //q9: [3150.f]x4
vdup.32 q8, r11 //q8: [62370.f]x4
2023-12-27 17:26:44 +08:00
mov r4, #5
mov r5, #-5
2023-12-04 11:12:20 +08:00
2023-03-20 11:32:29 +08:00
GeluZLoop:
vld1.32 {q0, q1}, [r1]! // q0, q1: fp32x4
vmul.f32 q2, q0, q0
vmul.f32 q3, q1, q1
vmul.f32 q2, q2, q0
vmul.f32 q3, q3, q1
vmul.f32 q2, q2, q15
vadd.f32 q2, q2, q0
vmul.f32 q3, q3, q15
vadd.f32 q3, q3, q1
2023-10-18 10:31:02 +08:00
vmul.f32 q2, q2, q14 // value
vmul.f32 q3, q3, q14 // value
// if value > 5, then value=5; if value<-5, then value=-5
2023-12-04 11:12:20 +08:00
vdup.32 q7, r4
vdup.32 q6, r5
2023-12-27 17:26:44 +08:00
vcvt.f32.s32 q7, q7
vcvt.f32.s32 q6, q6
2023-10-18 10:31:02 +08:00
vmax.f32 q2, q2, q6
vmax.f32 q3, q3, q6
vmin.f32 q2, q2, q7
vmin.f32 q3, q3, q7
2023-03-20 11:32:29 +08:00
// tanh(value)
vmul.f32 q4, q2, q2 // q4: value*value
vmul.f32 q5, q3, q3 // q5: value*value
// a
vadd.f32 q6, q4, q13
vadd.f32 q7, q5, q13
vmul.f32 q6, q6, q4
vmul.f32 q7, q7, q5
vadd.f32 q6, q6, q12
vadd.f32 q7, q7, q12
vmul.f32 q6, q6, q4
vmul.f32 q7, q7, q5
vadd.f32 q6, q6, q11
vadd.f32 q7, q7, q11
vmul.f32 q6, q6, q2
vmul.f32 q7, q7, q3
//b
vmul.f32 q2, q4, q10
vmul.f32 q3, q5, q10
vadd.f32 q2, q2, q9
vadd.f32 q3, q3, q9
vmul.f32 q2, q2, q4
vmul.f32 q3, q3, q5
vadd.f32 q2, q2, q8
vadd.f32 q3, q3, q8
vmul.f32 q2, q2, q4
vmul.f32 q3, q3, q5
vadd.f32 q2, q2, q11
vadd.f32 q3, q3, q11
//a/b
vdiv.f32 s24, s24, s8
vdiv.f32 s25, s25, s9
vdiv.f32 s26, s26, s10
vdiv.f32 s27, s27, s11
vdiv.f32 s28, s28, s12
vdiv.f32 s29, s29, s13
vdiv.f32 s30, s30, s14
vdiv.f32 s31, s31, s15
// border case
vmov.f32 q2, #1.0
vmov.f32 q3, #-1.0
vmov.f32 q4, #0.5
vmin.f32 q6, q6, q2
vmin.f32 q7, q7, q2
vmax.f32 q6, q6, q3
vmax.f32 q7, q7, q3
// tanh(value)
vadd.f32 q6, q6, q2
vadd.f32 q7, q7, q2
vmul.f32 q6, q6, q0
vmul.f32 q7, q7, q1
vmul.f32 q6, q6, q4
vmul.f32 q7, q7, q4
vst1.32 {q6, q7}, [r0]!
subs r2, r2, #1
bne GeluZLoop
GeluEnd:
vpop {q4-q7}
pop {r4-r8, r10, r11, pc}
#endif
#endif