diff options
Diffstat (limited to 'Runtime/Math/Matrix4x4_NEON.s')
-rw-r--r-- | Runtime/Math/Matrix4x4_NEON.s | 375 |
1 files changed, 375 insertions, 0 deletions
diff --git a/Runtime/Math/Matrix4x4_NEON.s b/Runtime/Math/Matrix4x4_NEON.s new file mode 100644 index 0000000..12f2ffd --- /dev/null +++ b/Runtime/Math/Matrix4x4_NEON.s @@ -0,0 +1,375 @@ +#define UNITY_ASSEMBLER +#include "Configuration/PrefixConfigure.h" + +#if UNITY_SUPPORTS_NEON + +.set device,0 +.set device,__arm__ + +.if device + +//.code32 + +.globl _CopyMatrix_NEON +.globl _TransposeMatrix4x4_NEON +.globl _MultiplyMatrices4x4_NEON +.globl _MultiplyMatrixArray4x4_NEON +.globl _MultiplyMatrixArrayWithBase4x4_NEON + +#if UNITY_ANDROID +.hidden _CopyMatrix_NEON +.hidden _TransposeMatrix4x4_NEON +.hidden _MultiplyMatrices4x4_NEON +.hidden _MultiplyMatrixArray4x4_NEON +.hidden _MultiplyMatrixArrayWithBase4x4_NEON +#endif + + +//=========================================================================================================================================== + +// void CopyMatrix_NEON(const float* __restrict lhs, float* __restrict res) +_CopyMatrix_NEON: +// r0: src +// r1: dst + +vld1.32 {q0,q1}, [r0]! +vld1.32 {q2,q3}, [r0] +vst1.32 {q0,q1}, [r1]! +vst1.32 {q2,q3}, [r1] + +bx lr + + +//=========================================================================================================================================== + +// void TransposeMatrix4x4_NEON(const Matrix4x4f* __restrict lhs, Matrix4x4f* __restrict res) +_TransposeMatrix4x4_NEON: +// r0: src +// r1: dst + +vld4.32 {d0,d2,d4,d6}, [r0]! +vld4.32 {d1,d3,d5,d7}, [r0] +vst1.32 {d0,d1,d2,d3}, [r1]! +vst1.32 {d4,d5,d6,d7}, [r1] + +bx lr + + +//=========================================================================================================================================== + +// void MultiplyMatrices4x4_NEON(const Matrix4x4f* __restrict lhs, const Matrix4x4f* __restrict rhs, Matrix4x4f* __restrict res) +_MultiplyMatrices4x4_NEON: +// r0: A +// r1: B +// r2: dst + +vld1.32 {q0,q1}, [r1]! // load Brow1-2 +vld1.32 {q8}, [r0]! // load Arow1 + +// R = Arow1 * Bcol1 +vmul.f32 q12, q8, d0[0] +vld1.32 {q2}, [r1]! // load Brow3 + +vmul.f32 q13, q8, d2[0] +vld1.32 {q3}, [r1]! // load Brow4 + +vmul.f32 q14, q8, d4[0] +vld1.32 {q9}, [r0]! // load Arow2 + +vmul.f32 q15, q8, d6[0] +vld1.32 {q10}, [r0]! // load Arow3 + +// R += Arow2 * Bcolumn2 +vmla.f32 q12, q9, d0[1] +vld1.32 {q11}, [r0]! // load Arow4 + +vmla.f32 q13, q9, d2[1] +vmla.f32 q14, q9, d4[1] +vmla.f32 q15, q9, d6[1] + +// R += Arow3 * Bcolumn3 +vmla.f32 q12, q10, d1[0] +vmla.f32 q13, q10, d3[0] +vmla.f32 q14, q10, d5[0] +vmla.f32 q15, q10, d7[0] + +// R += Arow4 * Bcolumn4 +vmla.f32 q12, q11, d1[1] +vmla.f32 q13, q11, d3[1] +vmla.f32 q14, q11, d5[1] +vmla.f32 q15, q11, d7[1] + +vst1.32 {q12,q13}, [r2]! +vst1.32 {q14,q15}, [r2]! + +bx lr + + +//=========================================================================================================================================== + +// void MultiplyMatrixArray4x4_NEON(const Matrix4x4f* arrayA, const Matrix4x4f* arrayB, Matrix4x4f* arrayRes, size_t count) +_MultiplyMatrixArray4x4_NEON: +// r0: A +// r1: B +// r2: dst +// r3: A end + +vpush {d8-d15} +add r3, r0, r3, lsl #6 + +vld1.32 {q0,q1}, [r1]! +vld1.32 {q2,q3}, [r1]! +vld1.32 {q8}, [r0]! + + +.align 4 +_MultiplyMatrixArray4x4_NEON_loop: + +vmul.f32 q12, q8, d0[0] +vld1.32 {q9}, [r0]! // load Arow2 + +vmul.f32 q13, q8, d2[0] +vmul.f32 q14, q8, d4[0] +vmul.f32 q15, q8, d6[0] + + +vmla.f32 q12, q9, d0[1] + +vld1.32 {q10}, [r0]! // load Arow3 +vmla.f32 q13, q9, d2[1] + +vld1.32 {q4,q5}, [r1]! // load B[i+1] +vmla.f32 q14, q9, d4[1] + +vld1.32 {q6,q7}, [r1]! // load B[i+1] +vmla.f32 q15, q9, d6[1] + +vmla.f32 q12, q10, d1[0] +vld1.32 {q11}, [r0]! // load Arow3 + +vmla.f32 q13, q10, d3[0] +vmla.f32 q14, q10, d5[0] +vmla.f32 q15, q10, d7[0] + +vmla.f32 q12, q11, d1[1] +vld1.32 {q8}, [r0]! // load A[i+1]row1 + +vmla.f32 q13, q11, d3[1] +vmla.f32 q14, q11, d5[1] +vmla.f32 q15, q11, d7[1] + +vst1.32 {q12,q13}, [r2]! +vst1.32 {q14,q15}, [r2]! + +cmp r0, r3 +bcs _MultiplyMatrixArray4x4_out + + +vmul.f32 q12, q8, d8[0] +vld1.32 {q9}, [r0]! // load A[i+1]row2 + +vmul.f32 q13, q8, d10[0] +vmul.f32 q14, q8, d12[0] +vmul.f32 q15, q8, d14[0] + +vmla.f32 q12, q9, d8[1] + +vld1.32 {q10}, [r0]! // load A[i+1]row3 +vmla.f32 q13, q9, d10[1] + +vld1.32 {q0,q1}, [r1]! // load B[i+2] +vmla.f32 q14, q9, d12[1] + +vld1.32 {q2,q3}, [r1]! // load B[i+2] +vmla.f32 q15, q9, d14[1] + +vmla.f32 q12, q10, d9[0] +vld1.32 {q11}, [r0]! // load A[i+1]row4 + +vmla.f32 q13, q10, d11[0] +vmla.f32 q14, q10, d13[0] +vmla.f32 q15, q10, d15[0] + +vmla.f32 q12, q11, d9[1] +vld1.32 {q8}, [r0]! // load A[i+2]row1 + +vmla.f32 q13, q11, d11[1] +vmla.f32 q14, q11, d13[1] +vmla.f32 q15, q11, d15[1] + +vst1.32 {q12,q13}, [r2]! +vst1.32 {q14,q15}, [r2]! + +cmp r0, r3 +bcc _MultiplyMatrixArray4x4_NEON_loop + + +.align 4 +_MultiplyMatrixArray4x4_out: + +vpop {d8-d15} +bx lr + + + +//=========================================================================================================================================== + +#define MT_11_1 \ + vmul.f32 q12, q10, d8[0] ; \ + vmul.f32 q13, q10, d10[0] ; + +#define MT_11_2 \ + vmul.f32 q14, q10, d12[0] ; \ + vmul.f32 q15, q10, d14[0] ; + +#define MT_22_1 \ + vmla.f32 q12, q11, d8[1] ; \ + vmla.f32 q13, q11, d10[1] ; + +#define MT_22_2 \ + vmla.f32 q14, q11, d12[1] ; \ + vmla.f32 q15, q11, d14[1] ; + +#define MT_33_1 \ + vmla.f32 q12, q8, d9[0] ; \ + vmla.f32 q13, q8, d11[0] ; + +#define MT_33_2_44_1 \ + vmla.f32 q14, q8, d13[0] ; \ + vmla.f32 q12, q9, d9[1] ; \ + vmla.f32 q13, q9, d11[1] ; \ + vmla.f32 q15, q8, d15[0] ; + + + +// void MultiplyMatrixArrayWithBase4x4_NEON( const Matrix4x4f* base, const Matrix4x4f* arrayA, const Matrix4x4f* arrayB, Matrix4x4f* arrayRes, size_t count ) +_MultiplyMatrixArrayWithBase4x4_NEON: +// r0: base +// r1: A +// r2: B +// r3: dst +// r4: A end + +mov ip, sp + +vpush {d8-d15} +stmfd sp!, {r4-r5} + + +ldr r4, [ip, #0] +add r4, r1, r4, lsl #6 + + +vld1.32 {q8}, [r1]! // load Arow1 +vld1.32 {q0,q1}, [r2]! // load Brow1-2 +vld1.32 {q2,q3}, [r2]! // load Brow3-4 +vld1.32 {q10,q11}, [r0]! // load Mrow1-2 + +add r5, r0, #16 + +// T = Arow1 * Bcol1 + +vmul.f32 q4, q8, d0[0] +vmul.f32 q5, q8, d2[0] + + +.align 4 +_MultiplyMatrixArrayWithBase4x4_NEON_loop: + +// T = Arow1 * Bcol1 + +vld1.32 {q9}, [r1]! // load Arow2 +vmul.f32 q6, q8, d4[0] +vmul.f32 q7, q8, d6[0] + +// T += Arow2 * Bcol2 + +vmla.f32 q4, q9, d0[1] +vmla.f32 q5, q9, d2[1] + + vld1.32 {q8}, [r1]! // load Arow3 +vmla.f32 q6, q9, d4[1] +vmla.f32 q7, q9, d6[1] + +// T += Arow3 * Bcol3 + +vmla.f32 q4, q8, d1[0] +vmla.f32 q5, q8, d3[0] + +vld1.32 {q9}, [r1]! // load Arow4 + +vmla.f32 q6, q8, d5[0] +vmla.f32 q7, q8, d7[0] + +cmp r1, r4 + +// T += Arow4 * Bcol4 + +vmla.f32 q4, q9, d1[1] +vmla.f32 q5, q9, d3[1] + +vld1.32 {q8}, [r0] // load Mrow3 +vmla.f32 q6, q9, d5[1] +vmla.f32 q7, q9, d7[1] + +// R = M * T + +vld1.32 {q9}, [r5] // load Mrow4 +MT_11_1 + +bge _MultiplyMatrixArrayWithBase4x4_NEON_epilogue + +vld1.32 {q0}, [r2]! // load B[i+1]row1 +MT_11_2 +MT_22_1 + +vld1.32 {q1}, [r2]! // load B[i+1]row2 +MT_22_2 + +MT_33_1 +vld1.32 {q2}, [r2]! // load B[i+1]row3 + +MT_33_2_44_1 +vld1.32 {q3}, [r2]! // load B[i+1]row4 + +vmla.f32 q14, q9, d13[1] +vld1.32 {q8}, [r1]! // load A[i+1]row1 + +vmla.f32 q15, q9, d15[1] +vst1.32 {q12,q13}, [r3]! + +// interleave T = Arow1 * Bcol1 +vmul.f32 q4, q8, d0[0] +vmul.f32 q5, q8, d2[0] +vst1.32 {q14,q15}, [r3]! + +bcc _MultiplyMatrixArrayWithBase4x4_NEON_loop + +.align 4 +_MultiplyMatrixArrayWithBase4x4_NEON_epilogue: + +MT_11_2 +MT_22_1 +MT_22_2 +MT_33_1 +MT_33_2_44_1 +vmla.f32 q14, q9, d13[1] +vmla.f32 q15, q9, d15[1] +vst1.32 {q12,q13}, [r3]! +vst1.32 {q14,q15}, [r3]! + + +ldmfd sp!, {r4-r5} +vpop {d8-d15} +bx lr + +.endif + +#undef MT_11_1 +#undef MT_11_2 +#undef MT_22_1 +#undef MT_22_2 +#undef MT_33_1 +#undef MT_33_2_44_1 + +#endif |