// vim: ft=arm // C tile regs // // q8[0] // q8[1] // q8[2] // q8[3] // // .... // // q15[0] // q15[1] // q15[2] // q15[3] .arm .text .global armv7neon_mmm_f32_32x1_{{core}}_{{suffix}} .type armv7neon_mmm_f32_32x1_{{core}}_{{suffix}}, %function armv7neon_mmm_f32_32x1_{{core}}_{{suffix}}: pld [r0] push { r4-r12 } vpush { q4-q7 } {% include "dispatcher.tmpliq" %} .add_mat_mul: cmp r3, #0 beq .non_linear_loop mov r1, r4 // packed A ptr pld [r3] pld [r5] pld [r1, #128] pld [r1, #192] pld [r1, #256] pld [r1, #320] pld [r1, #384] pld [r1, #448] pld [r1, #512] .packed_packed_loop_1: pld [r5] // packed B ptr {% if core == "cortexa7" %} vldr d0, [r1] vldr d1, [r1, #8] vldr d2, [r1, #16] vldr d3, [r1, #24] vldr d4, [r1, #32] vldr d5, [r1, #40] vldr d6, [r1, #48] vldr d7, [r1, #56] vldr d8, [r1, #64] vldr d9, [r1, #72] vldr d10, [r1, #80] vldr d11, [r1, #88] vldr s30, [r5] pld [r1, #512] pld [r1, #576] pld [r5, #64] vmla.f32 q8, q0, d15[0] vmla.f32 q9, q1, d15[0] vldr d0, [r1, #96] vldr d1, [r1, #104] vldr d2, [r1, #112] vldr d3, [r1, #120] vmla.f32 q10, q2, d15[0] vmla.f32 q11, q3, d15[0] vmla.f32 q12, q4, d15[0] vmla.f32 q13, q5, d15[0] vmla.f32 q14, q0, d15[0] vmla.f32 q15, q1, d15[0] add r1, #128 add r5, #4 {% elsif core == "cortexa9" %} vld1.64 {d0-d3}, [r1]! vld1.64 {d4-d7}, [r1]! pld [r1, #512] pld [r1, #576] vld1.64 {d8-d11}, [r1]! vld1.f32 d15[0], [r5]! pld [r5, #64] vmla.f32 q8, q0, d15[0] vmla.f32 q9, q1, d15[0] vld1.64 {d0-d3}, [r1]! vmla.f32 q10, q2, d15[0] vmla.f32 q11, q3, d15[0] vmla.f32 q12, q4, d15[0] vmla.f32 q13, q5, d15[0] vmla.f32 q14, q0, d15[0] vmla.f32 q15, q1, d15[0] {% else %} vldmia r1!, { q0-q3 } vldmia r5!, { s30 } vmla.f32 q8, q0, d15[0] vmla.f32 q9, q1, d15[0] vldmia r1!, { q0-q1 } vmla.f32 q10, q2, d15[0] vmla.f32 q11, q3, d15[0] vldmia r1!, { q2-q3 } vmla.f32 q12, q0, d15[0] vmla.f32 q13, q1, d15[0] vmla.f32 q14, q2, d15[0] vmla.f32 q15, q3, d15[0] {% endif %} subs r3, r3, #1 bne .packed_packed_loop_1 b .non_linear_loop {% include "armv7neon_mmm_f32_scalars.tmpliq" from:8, to:15 %} {% include "armv7neon_mmm_f32_per_rows.tmpliq" mr:32, from:8, to:15 %} {% include "armv7neon_mmm_f32_per_cols.tmpliq" mr:32, from:8, to:15 %} .add_unicast: {% for reg in (0..15) %} vld1.f32 d{{reg}}[0], [ r3 ], r4 vld1.f32 d{{reg}}[1], [ r3 ], r4 {% endfor %} {% for reg in (0..7) %} vadd.f32 q{{reg|plus:8}}, q{{reg|plus:8}}, q{{reg}} {% endfor %} b .non_linear_loop .add_row_col_products: vld1.f32 d0[0], [ r4 ] vldmia r3!, { q4-q7 } vmla.f32 q8, q4, d0[0] vmla.f32 q9, q5, d0[0] vmla.f32 q10, q6, d0[0] vmla.f32 q11, q7, d0[0] vldmia r3!, { q4-q7 } vmla.f32 q12, q4, d0[0] vmla.f32 q13, q5, d0[0] vmla.f32 q14, q6, d0[0] vmla.f32 q15, q7, d0[0] b .non_linear_loop .store: // r3, r4 <- ptr, rsc cmp r4, #4 bne .store_generic vst1.f64 {d16-d19}, [r3]! vst1.f64 {d20-d23}, [r3]! vst1.f64 {d24-d27}, [r3]! vst1.f64 {d28-d31}, [r3]! b .non_linear_loop .store_generic: {% for reg in (16..31) %} vst1.f32 d{{reg}}[0], [r3], r4 vst1.f32 d{{reg}}[1], [r3], r4 {% endfor %} b .non_linear_loop .return: vpop { q4-q7 } pop { r4-r12 } bx lr