Add native self-hosted instance connection to fluxer_desktop

Trimmed monorepo checkout (fluxer_desktop + packages/voice_engine_v2 +
tools/ci) with a "Connect to a Different Server" menu item and popout
that lets the desktop app switch to any self-hosted Fluxer instance,
plus fixes for well-known discovery on single-domain self-hosted
deployments and a false-positive ERR_ABORTED on same-origin client
redirects during the switch. Defaults to chat.fluxr.chat and uses an
isolated userData directory from the official build.
This commit is contained in:
2026-07-01 18:22:43 -04:00
commit 682afacd30
1763 changed files with 613720 additions and 0 deletions
@@ -0,0 +1,71 @@
// vim: ft=arm
// no preservation either for v0-v7 and v16-v31
.text
.align 4
{% if needs_pragma == true %}
.cpu generic+fp+simd+fp16
{% endif %}
.global {{G}}arm64fp16_leaky_relu_f16_8n_{{suffix}}
{{G}}arm64fp16_leaky_relu_f16_8n_{{suffix}}:
cmp x1, #0
beq .return
mov v31.h[0], w2
dup v31.8h, v31.h[0]
mov x2, x0
cmp x1, #64
blt .loop
ld1 { v16.8h, v17.8h, v18.8h, v19.8h }, [x2], #64
.loop4:
ld1 { v0.8h, v1.8h, v2.8h, v3.8h }, [x2], #64
fmul v20.8h, v16.8h, v31.8h
fmul v21.8h, v17.8h, v31.8h
fmul v22.8h, v18.8h, v31.8h
fmul v23.8h, v19.8h, v31.8h
fcmge v24.8h, v16.8h, #0.0
fcmge v25.8h, v17.8h, #0.0
fcmge v26.8h, v18.8h, #0.0
fcmge v27.8h, v19.8h, #0.0
bsl v24.16b, v16.16b, v20.16b
bsl v25.16b, v17.16b, v21.16b
bsl v26.16b, v18.16b, v22.16b
bsl v27.16b, v19.16b, v23.16b
st1 { v24.8h, v25.8h, v26.8h, v27.8h }, [x0], #64
and v16.16b, v0.16b, v0.16b
and v17.16b, v1.16b, v1.16b
and v18.16b, v2.16b, v2.16b
and v19.16b, v3.16b, v3.16b
subs x1, x1, #32
cmp x1, #64
bge .loop4
cmp x1, #0
beq .return
.loop:
ld1 { v16.8h }, [x0]
fmul v17.8h, v16.8h, v31.8h
fcmge v18.8h, v16.8h, #0.0
bsl v18.16b, v16.16b, v17.16b
st1 { v18.8h }, [x0], #16
subs x1, x1, #8
bne .loop
.return:
ret
@@ -0,0 +1,86 @@
{% macro scalar(label, op, from, to, flipped=false) %}
.{{label}}:
add x2, x0, #8
ld1 {v0.h}[0], [ x2 ]
dup v0.8h, v0.h[0]
{% if flipped %}
{% for reg in range(from, to + 1) %}
{{op}} v{{reg}}.8h, v{{reg}}.8h, v0.8h
{% endfor %}
{% else %}
{% for reg in range(from, to + 1) %}
{{op}} v{{reg}}.8h, v0.8h, v{{reg}}.8h
{% endfor %}
{% endif %}
b .non_linear_loop
{% endmacro %}
{% macro per_row(label, op, mr, from, to, flipped=false) %}
.{{label}}:
ldr x2, [x0, #8]
{% set mr_over_8 = mr // 8 %}
{% set mr_over_8_min_1 = mr // 8 - 1 %}
{% for reg in range(0, mr_over_8_min_1 + 1) %}
ldr q{{reg}}, [ x2 ], #16
{% endfor %}
{% if flipped %}
{% for acc in range(from, to + 1) %}
{% set other = (acc - from) % mr_over_8 %}
{{op}} v{{acc}}.8h, v{{acc}}.8h, v{{other}}.8h
{% endfor %}
{% else %}
{% for acc in range(from, to + 1) %}
{% set other = (acc - from) % mr_over_8 %}
{{op}} v{{acc}}.8h, v{{other}}.8h, v{{acc}}.8h
{% endfor %}
{% endif %}
b .non_linear_loop
{% endmacro %}
{% macro per_col(label, op, mr, from, to, flipped=false) %}
.{{label}}:
ldr x2, [x0, #8]
{% set mr_over_8 = mr // 8 %}
{% set cols = (to + 1 - from) // mr_over_8 %}
{% set loads = cols // 8 %}
{%if cols == 1 %}
ld1 {v0.h}[0], [ x2 ]
{% elif cols == 3 %}
ld1 {v0.s}[0], [ x2 ], #4
ld1 {v0.h}[2], [ x2 ]
{% elif cols == 4 %}
ldr d0, [ x2 ]
{% elif cols == 6 %}
ldr d0, [ x2 ], #8
ld1 {v0.s}[2], [ x2 ]
{% else %}
{% for reg in range(1, loads + 1) %}
ldr q{{ reg - 1 }}, [ x2 ], #16
{% endfor %}
{% endif %}
// mr:{{mr}} {{ loads }} {{cols}}
{% for col in range(1, cols + 1) %}
dup v3.8h, v{{ (col - 1) // 8 }}.h[{{ (col - 1) % 8 }}]
{% for row in range(1, mr_over_8 + 1) %}
{% set acc = (col - 1) * mr_over_8 + row - 1 + from %}
{% if flipped %}
{{op}} v{{acc}}.8h, v{{acc}}.8h, v3.8h
{% else %}
{{op}} v{{acc}}.8h, v3.8h, v{{acc}}.8h
{% endif %}
{% endfor %}
{% endfor %}
b .non_linear_loop
{% endmacro %}
@@ -0,0 +1,65 @@
fmla v16.4s, v0.4s, v8.s[0]
ldr x5, [x1, #128]
fmla v17.4s, v1.4s, v8.s[0]
ldr x6, [x1, #136]
fmla v18.4s, v2.4s, v8.s[0]
ldr x7, [x1, #144]
fmla v19.4s, v3.4s, v8.s[0]
ldr x9, [x1, #152]
ld1 {{ v0.4s, v1.4s, v2.4s, v3.4s }}, [ x1 ], #64
fmla v20.4s, v4.4s, v8.s[0]
ldr x10, [x1, #96]
fmla v21.4s, v5.4s, v8.s[0]
ldr x11, [x1, #104]
fmla v22.4s, v6.4s, v8.s[0]
ldr x12, [x1, #112]
fmla v23.4s, v7.4s, v8.s[0]
ldr x13, [x1, #120]
ld1 {{ v4.4s, v5.4s, v6.4s, v7.4s }}, [ x1 ]
fmla v24.4s, v0.4s, v8.s[0]
ldr x14, [x1, #128]
fmla v25.4s, v1.4s, v8.s[0]
ldr x15, [x1, #136]
fmla v26.4s, v2.4s, v8.s[0]
ldr x20, [x1, #144]
fmla v27.4s, v3.4s, v8.s[0]
ldr x21, [x1, #152]
fmla v28.4s, v4.4s, v8.s[0]
ldr x22, [x1, #160]
fmla v29.4s, v5.4s, v8.s[0]
ldr x23, [x1, #168]
fmla v30.4s, v6.4s, v8.s[0]
ldr x24, [x1, #176]
fmla v31.4s, v7.4s, v8.s[0]
ldr x25, [x1, #184]
ld1 {{ v8.s }}[0], [ x2 ], #4
prfm pldl1keep, [x1, #1024]
prfm pldl1keep, [x1, #1088]
prfm pldl1keep, [x1, #1152]
prfm pldl1keep, [x1, #1216]
prfm pldl1keep, [x2, #256]
ins v0.d[0], x5
ins v1.d[0], x7
ins v2.d[0], x10
ins v3.d[0], x12
ins v4.d[0], x14
ins v5.d[0], x20
ins v6.d[0], x22
ins v7.d[0], x24
ins v0.d[1], x6
ins v1.d[1], x9
ins v2.d[1], x11
ins v3.d[1], x13
ins v4.d[1], x15
ins v5.d[1], x21
ins v6.d[1], x23
ins v7.d[1], x25
add x1, x1, #192
@@ -0,0 +1,32 @@
ld1 {{ v9.8h, v10.8h, v11.8h, v12.8h }}, [x1], #64
ld1 {{ v13.8h, v14.8h, v15.8h }}, [x1], #48
fmla v16.8h, v0.8h, v8.h[0]
fmla v17.8h, v1.8h, v8.h[0]
fmla v18.8h, v2.8h, v8.h[0]
fmla v19.8h, v3.8h, v8.h[0]
fmla v20.8h, v4.8h, v8.h[0]
fmla v21.8h, v5.8h, v8.h[0]
fmla v22.8h, v6.8h, v8.h[0]
fmla v23.8h, v7.8h, v8.h[0]
fmla v24.8h, v9.8h, v8.h[0]
ld1 {{ v9.8h }}, [ x1 ], #16
ld1 {{ v0.8h, v1.8h, v2.8h, v3.8h }}, [x1], #64
ld1 {{ v4.8h, v5.8h, v6.8h, v7.8h }}, [x1], #64
fmla v25.8h, v10.8h, v8.h[0]
fmla v26.8h, v11.8h, v8.h[0]
fmla v27.8h, v12.8h, v8.h[0]
fmla v28.8h, v13.8h, v8.h[0]
fmla v29.8h, v14.8h, v8.h[0]
fmla v30.8h, v15.8h, v8.h[0]
fmla v31.8h, v9.8h, v8.h[0]
ld1 {{ v8.h }}[0], [ x2 ], #2
prfm pldl1keep, [x1, #1024]
prfm pldl1keep, [x1, #1088]
prfm pldl1keep, [x1, #1152]
prfm pldl1keep, [x1, #1216]
prfm pldl1keep, [x2, #256]
@@ -0,0 +1,85 @@
ld1 {{ v9.4s, v10.4s, v11.4s }}, [x1], #48
fmla v16.8h, v0.8h, v8.h[0]
ldr w8, [x2], #4
fmla v17.8h, v1.8h, v8.h[0]
ldr d12, [x1], #8
fmla v18.8h, v2.8h, v8.h[0]
ldr x12, [x1], #8
fmla v19.8h, v3.8h, v8.h[0]
ldr d13, [x1], #8
fmla v20.8h, v4.8h, v8.h[0]
ldr x13, [x1], #8
fmla v21.8h, v5.8h, v8.h[0]
ldr d14, [x1], #8
fmla v22.8h, v6.8h, v8.h[0]
ldr x14, [x1], #8
fmla v23.8h, v7.8h, v8.h[0]
ldr d15, [x1], #8
fmla v24.8h, v9.8h, v8.h[0]
ldr x15, [x1], #8
ld1 {{ v0.8h, v1.8h, v2.8h, v3.8h }}, [x1], #64
ins v8.s[1], w8
ld1 {{ v4.8h, v5.8h, v6.8h, v7.8h }}, [x1], #64
fmla v25.8h, v10.8h, v8.h[0]
ins v12.d[1], x12
fmla v26.8h, v11.8h, v8.h[0]
ins v13.d[1], x13
fmla v27.8h, v12.8h, v8.h[0]
ins v14.d[1], x14
fmla v28.8h, v13.8h, v8.h[0]
ins v15.d[1], x15
ld1 {{ v9.8h, v10.8h, v11.8h, v12.8h }}, [x1], #64
fmla v29.8h, v14.8h, v8.h[0]
ldr d13, [x1], #8
fmla v30.8h, v15.8h, v8.h[0]
ldr x13, [x1], #8
fmla v31.8h, v0.8h, v8.h[0]
ldr d14, [x1], #8
fmla v16.8h, v1.8h, v8.h[2]
ldr x14, [x1], #8
fmla v17.8h, v2.8h, v8.h[2]
ldr d15, [x1], #8
fmla v18.8h, v3.8h, v8.h[2]
ldr x15, [x1], #8
fmla v19.8h, v4.8h, v8.h[2]
ld1 {{ v0.8h }}, [x1], #16
fmla v20.8h, v5.8h, v8.h[2]
ldr d1, [x1], #8
fmla v21.8h, v6.8h, v8.h[2]
ldr x10, [x1], #8
fmla v22.8h, v7.8h, v8.h[2]
fmla v23.8h, v9.8h, v8.h[2]
ins v13.d[1], x13
fmla v24.8h, v10.8h, v8.h[2]
ins v14.d[1], x14
fmla v25.8h, v11.8h, v8.h[2]
ins v15.d[1], x15
fmla v26.8h, v12.8h, v8.h[2]
prfm pldl1keep, [x1, #1024]
fmla v27.8h, v13.8h, v8.h[2]
ins v1.d[1], x10
fmla v28.8h, v14.8h, v8.h[2]
prfm pldl1keep, [x1, #1088]
fmla v29.8h, v15.8h, v8.h[2]
prfm pldl1keep, [x1, #1152]
fmla v30.8h, v0.8h, v8.h[2]
prfm pldl1keep, [x1, #1216]
fmla v31.8h, v1.8h, v8.h[2]
prfm pldl1keep, [x2, #256]
ld1 {{ v0.4s, v1.4s, v2.4s, v3.4s }}, [x1], #64
ins v8.h[0], v8.h[3]
ld1 {{ v4.4s, v5.4s, v6.4s, v7.4s }}, [x1], #64
@@ -0,0 +1,203 @@
// vim: ft=arm
// C tile regs: v16 to v31, no need to preserve
// no preservation either for v0-v7...
// v8..v15 are callee-preserved
// packed A buffering (2x8 values): alternating v0, v1 with v2, v3
// packed B buffering (2x8 values): alternating v4, v5 with v6, v7
.text
.align 4
{% if needs_pragma == true %}
.cpu generic+fp+simd+fp16
{% endif %}
.global {{G}}arm64fp16_mmm_f16_128x1_{{core}}_{{suffix}}
{{G}}arm64fp16_mmm_f16_128x1_{{core}}_{{suffix}}:
stp x20, x21, [sp, #-16]!
stp x22, x23, [sp, #-16]!
stp x24, x25, [sp, #-16]!
stp d8, d9, [sp, #-16]!
stp d10, d11, [sp, #-16]!
stp d12, d13, [sp, #-16]!
stp d14, d15, [sp, #-16]!
{% include "dispatcher.j2" %}
.add_mat_mul:
ldr x2, [x0, #24] // b
ldp x3, x1, [x0, #8] // k, a
cmp x3, #0
beq .non_linear_loop
sub x3, x3, #1
ld1 { v8.h }[0], [ x2 ], #2
ld1 { v0.4s, v1.4s, v2.4s, v3.4s }, [ x1 ], #64
ld1 { v4.4s, v5.4s, v6.4s, v7.4s }, [ x1 ], #64
cmp x3, #0
beq .packed_packed_loop_1_last
cmp x3, #4
blt .packed_packed_loop_1
{% set packed_packed_loop1 %}
{% include "arm64fp16_mmm_f16_128x1/loop1/naive.S.raw" %}
{% endset %}
{% set packed_packed_loop2 %}
{% include "arm64fp16_mmm_f16_128x1/loop2/cortex_a55.S.raw" %}
{% endset %}
.p2align 4
.packed_packed_loop_4:
{{ packed_packed_loop2 }}
{{ packed_packed_loop2 }}
sub x3, x3, #4
cmp x3, #4
bge .packed_packed_loop_4
cmp x3, #0
beq .packed_packed_loop_1_last
.p2align 4
.packed_packed_loop_1:
{{ packed_packed_loop1 }}
subs x3, x3, #1
bne .packed_packed_loop_1
// last loop can't read beyond actual input as it's likely not packed and padded
.packed_packed_loop_1_last:
ld1 { v9.8h, v10.8h, v11.8h, v12.8h }, [x1], #64
ld1 { v13.8h, v14.8h, v15.8h }, [x1], #48
fmla v16.8h, v0.8h, v8.h[0]
fmla v17.8h, v1.8h, v8.h[0]
ld1 { v0.8h }, [ x1 ]
fmla v18.8h, v2.8h, v8.h[0]
fmla v19.8h, v3.8h, v8.h[0]
fmla v20.8h, v4.8h, v8.h[0]
fmla v21.8h, v5.8h, v8.h[0]
fmla v22.8h, v6.8h, v8.h[0]
fmla v23.8h, v7.8h, v8.h[0]
fmla v24.8h, v9.8h, v8.h[0]
fmla v25.8h, v10.8h, v8.h[0]
fmla v26.8h, v11.8h, v8.h[0]
fmla v27.8h, v12.8h, v8.h[0]
fmla v28.8h, v13.8h, v8.h[0]
fmla v29.8h, v14.8h, v8.h[0]
fmla v30.8h, v15.8h, v8.h[0]
fmla v31.8h, v0.8h, v8.h[0]
b .non_linear_loop
{% set from = 16 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_scalars.j2" %}
{% set mr = 128 %}{% set from = 16 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_per_rows.j2" %}
{% set mr = 128 %}{% set from = 16 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_per_cols.j2" %}
{% set from = 16 %}{% set to = 31 %}{% include "arm64fp16_mmm_load_tile.j2" %}
.add_unicast:
ldp x5, x6, [x0, #8] // c base ptr, rsc
cmp x6, #2
beq .do_per_row_add
{% for reg in range(16, 32) %}
{% for lane in range(0, 8) %}
ld1 {v0.h}[{{lane}}], [ x5 ], x6
{% endfor %}
fadd v{{reg}}.8h, v{{reg}}.8h, v0.8h
{% endfor %}
b .non_linear_loop
.do_per_row_add:
ld1 {v0.8h-v3.8h}, [x5], #64
ld1 {v4.8h-v7.8h}, [x5], #64
ld1 {v8.8h-v11.8h}, [x5], #64
ld1 {v12.8h-v15.8h}, [x5], #64
{% for r in range(0, 16) %}
fadd v{{ r + 16 }}.8h, v{{ r + 16 }}.8h, v{{r}}.8h
{% endfor %}
b .non_linear_loop
.add_row_col_products:
ldr x3, [x0, #16]
ldr x2, [x0, #8]
ld1 {v8.h}[0], [ x3 ]
{% for r in range(0, 8) %}
ldr q{{r}}, [x2], #16
{% endfor %}
fmla v16.8h, v0.8h, v8.h[0]
ldr q0, [x2], #16
fmla v17.8h, v1.8h, v8.h[0]
ldr q1, [x2], #16
fmla v18.8h, v2.8h, v8.h[0]
ldr q2, [x2], #16
fmla v19.8h, v3.8h, v8.h[0]
ldr q3, [x2], #16
fmla v20.8h, v4.8h, v8.h[0]
ldr q4, [x2], #16
fmla v21.8h, v5.8h, v8.h[0]
ldr q5, [x2], #16
fmla v22.8h, v6.8h, v8.h[0]
ldr q6, [x2], #16
fmla v23.8h, v7.8h, v8.h[0]
ldr q7, [x2], #16
fmla v24.8h, v0.8h, v8.h[0]
fmla v25.8h, v1.8h, v8.h[0]
fmla v26.8h, v2.8h, v8.h[0]
fmla v27.8h, v3.8h, v8.h[0]
fmla v28.8h, v4.8h, v8.h[0]
fmla v29.8h, v5.8h, v8.h[0]
fmla v30.8h, v6.8h, v8.h[0]
fmla v31.8h, v7.8h, v8.h[0]
b .non_linear_loop
.store:
ldp x5, x6, [x0, #8] // c base ptr, rsc$
cmp x6, #2
beq .store_strides_contig
{% for reg in range(16, 32) %}
{% for lane in range(0, 8) %}
st1 { v{{reg}}.h }[{{lane}}], [ x5 ], x6
{% endfor %}
{% endfor %}
b .non_linear_loop
.store_strides_contig:
{% for reg in range(16, 32) %}
st1 { v{{reg}}.8h }, [ x5 ], #16
{% endfor %}
b .non_linear_loop
.return:
ldp d14, d15, [sp], #16
ldp d12, d13, [sp], #16
ldp d10, d11, [sp], #16
ldp d8, d9, [sp], #16
ldp x24, x25, [sp], #16
ldp x22, x23, [sp], #16
ldp x20, x21, [sp], #16
ret
@@ -0,0 +1,21 @@
fmla v16.8h, v0.8h, v4.h[0]
fmla v17.8h, v1.8h, v4.h[0]
fmla v18.8h, v0.8h, v4.h[1]
fmla v19.8h, v1.8h, v4.h[1]
fmla v20.8h, v0.8h, v4.h[2]
fmla v21.8h, v1.8h, v4.h[2]
fmla v22.8h, v0.8h, v4.h[3]
fmla v23.8h, v1.8h, v4.h[3]
fmla v24.8h, v0.8h, v4.h[4]
fmla v25.8h, v1.8h, v4.h[4]
fmla v26.8h, v0.8h, v4.h[5]
fmla v27.8h, v1.8h, v4.h[5]
fmla v28.8h, v0.8h, v4.h[6]
fmla v29.8h, v1.8h, v4.h[6]
fmla v30.8h, v0.8h, v4.h[7]
fmla v31.8h, v1.8h, v4.h[7]
ld1 {{ v0.8h, v1.8h }}, [x1], #32
ld1 {{ v4.8h }}, [x2], #16
@@ -0,0 +1,54 @@
fmla v16.8h, v0.8h, v4.h[0]
ldr d2, [x1], #8
fmla v17.8h, v1.8h, v4.h[0]
ldr d6, [x2], #8
fmla v18.8h, v0.8h, v4.h[1]
ldr x5, [x1], #8
fmla v19.8h, v1.8h, v4.h[1]
ldr x7, [x2], #8
fmla v20.8h, v0.8h, v4.h[2]
ldr d3, [x1], #8
fmla v21.8h, v1.8h, v4.h[2]
fmla v22.8h, v0.8h, v4.h[3]
ldr x6, [x1], #8
fmla v23.8h, v1.8h, v4.h[3]
fmla v24.8h, v0.8h, v4.h[4]
fmla v25.8h, v1.8h, v4.h[4]
fmla v26.8h, v0.8h, v4.h[5]
fmla v27.8h, v1.8h, v4.h[5]
fmla v28.8h, v0.8h, v4.h[6]
ins v2.d[1], x5
fmla v29.8h, v1.8h, v4.h[6]
ins v6.d[1], x7
fmla v30.8h, v0.8h, v4.h[7]
ins v3.d[1], x6
fmla v31.8h, v1.8h, v4.h[7]
fmla v16.8h, v2.8h, v6.h[0]
ldr d0, [x1], #8
fmla v17.8h, v3.8h, v6.h[0]
ldr d4, [x2], #8
fmla v18.8h, v2.8h, v6.h[1]
ldr x5, [x1], #8
fmla v19.8h, v3.8h, v6.h[1]
ldr x7, [x2], #8
fmla v20.8h, v2.8h, v6.h[2]
ldr d1, [x1], #8
fmla v21.8h, v3.8h, v6.h[2]
fmla v22.8h, v2.8h, v6.h[3]
ldr x6, [x1], #8
fmla v23.8h, v3.8h, v6.h[3]
fmla v24.8h, v2.8h, v6.h[4]
fmla v25.8h, v3.8h, v6.h[4]
fmla v26.8h, v2.8h, v6.h[5]
fmla v27.8h, v3.8h, v6.h[5]
fmla v28.8h, v2.8h, v6.h[6]
ins v0.d[1], x5
fmla v29.8h, v3.8h, v6.h[6]
ins v4.d[1], x7
fmla v30.8h, v2.8h, v6.h[7]
ins v1.d[1], x6
fmla v31.8h, v3.8h, v6.h[7]
@@ -0,0 +1,174 @@
// vim: ft=arm
// x20..x27 are used, callee-preserved
// C tile regs: v16 to v31, (scratch)
//
// v16[0] v18[0] v20[0] v22[0] v24[0] v26[0] v28[0] v30[0]
// v16[1] v18[1]
// v16[2] v18[2]
// v16[3] v18[3]
//
// v17[0] v19[0] v21[0] v23[0] v25[0] v27[0] v29[0] v31[0]
// v17[1] v19[1]
// v17[2] v19[2]
// v17[3] v19[3]
// v8 is used, d8 (lower half) must preserved
// v0-v7 (scratch registers)
// packed A buffering (2x8 values): alternating v0, v1 with v2, v3
// packed B buffering (2x8 values): alternating v4, v5 with v6, v7
.text
.align 4
{% if needs_pragma == true %}
.cpu generic+fp+simd+fp16
{% endif %}
.global {{G}}arm64fp16_mmm_f16_16x8_{{core}}_{{suffix}}
{{G}}arm64fp16_mmm_f16_16x8_{{core}}_{{suffix}}:
stp x20, x21, [sp, #-16]!
stp x22, x23, [sp, #-16]!
stp x24, x25, [sp, #-16]!
stp x26, x27, [sp, #-16]!
str q8, [sp, #-16]!
{% include "dispatcher.j2" %}
.add_mat_mul:
ldr x2, [x0, #24] // b
ldp x3, x1, [x0, #8] // k, a
cmp x3, #0
beq .non_linear_loop
.packed_packed:
ld1 { v0.4s, v1.4s }, [ x1 ], #32
ld1 { v4.4s }, [ x2 ], #16
{% set packed_packed_loop1 %}
{% include "arm64fp16_mmm_f16_16x8/loop1/naive.S.raw" %}
{% endset %}
{% set packed_packed_loop2 %}
{% if core == "a55" %}
{% include "arm64fp16_mmm_f16_16x8/loop2/cortex_a55.S.raw" %}
{% else %}
{{ packed_packed_loop1 }}
{{ packed_packed_loop1 }}
{% endif %}
{% endset %}
cmp x3, #4
blt .packed_packed_loop_1
.p2align 4
.packed_packed_loop_4:
{{ packed_packed_loop2 }}
{{ packed_packed_loop2 }}
sub x3, x3, #4
cmp x3, #4
bge .packed_packed_loop_4
cmp x3, #0
beq .non_linear_loop
.p2align 4
.packed_packed_loop_1:
{{ packed_packed_loop1 }}
subs x3, x3, #1
bne .packed_packed_loop_1
b .non_linear_loop
{% set from = 16 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_scalars.j2" %}
{% set mr = 16 %}{% set from = 16 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_per_rows.j2" %}
{% set mr = 16 %}{% set from = 16 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_per_cols.j2" %}
{% set from = 16 %}{% set to = 31 %}{% include "arm64fp16_mmm_load_tile.j2" %}
.add_unicast:
ldp x5, x6, [x0, #8]
ldp x7, x8, [x0, #24]
{% for col in range(8, 16) %}
mov x4, x5
{% for reg in range(0, 2) %}
{% for lane in range(0, 8) %}
ld1 {v0.h}[{{lane}}], [ x4 ], x6
{% endfor %}
fadd v{{ col * 2 + reg }}.8h, v{{ col * 2 + reg }}.8h, v0.8h
{% endfor %}
add x5, x5, x7
{% endfor %}
b .non_linear_loop
.add_row_col_products:
ldr x2, [x0, #8]
ldr x3, [x0, #16]
ld1 { v0.4s, v1.4s }, [ x2 ], #32
ld1 { v4.4s }, [ x3 ], #16
fmla v16.8h, v0.8h, v4.h[0]
fmla v17.8h, v1.8h, v4.h[0]
fmla v18.8h, v0.8h, v4.h[1]
fmla v19.8h, v1.8h, v4.h[1]
fmla v20.8h, v0.8h, v4.h[2]
fmla v21.8h, v1.8h, v4.h[2]
fmla v22.8h, v0.8h, v4.h[3]
fmla v23.8h, v1.8h, v4.h[3]
fmla v24.8h, v0.8h, v4.h[4]
fmla v25.8h, v1.8h, v4.h[4]
fmla v26.8h, v0.8h, v4.h[5]
fmla v27.8h, v1.8h, v4.h[5]
fmla v28.8h, v0.8h, v4.h[6]
fmla v29.8h, v1.8h, v4.h[6]
fmla v30.8h, v0.8h, v4.h[7]
fmla v31.8h, v1.8h, v4.h[7]
b .non_linear_loop
.store:
ldp x5, x6, [x0, #8] // c base ptr, rsc
ldp x7, x8, [x0, #24] // csc, item_size
cmp x6, #2
bne .store_strides_generic
{% for col in range(8, 16) %}
str q{{ col * 2 }}, [ x5 ]
str q{{ col * 2 + 1 }}, [ x5, #16 ]
add x5, x5, x7
{% endfor %}
b .non_linear_loop
.store_strides_generic:
{% for col in range(8, 16) %}
mov x4, x5
{% for reg in range(0, 2) %}
{% for lane in range(0, 8) %}
st1 { v{{ col * 2 + reg }}.h }[{{lane}}], [ x4 ], x6
{% endfor %}
{% endfor %}
add x5, x5, x7
{% endfor %}
b .non_linear_loop
.return:
ldr q8, [sp], #16
ldp x26, x27, [sp], #16
ldp x24, x25, [sp], #16
ldp x22, x23, [sp], #16
ldp x20, x21, [sp], #16
ret
@@ -0,0 +1,21 @@
fmla v16.8h, v0.8h, v4.h[0]
fmla v17.8h, v1.8h, v4.h[0]
fmla v18.8h, v2.8h, v4.h[0]
fmla v19.8h, v3.8h, v4.h[0]
fmla v20.8h, v0.8h, v4.h[1]
fmla v21.8h, v1.8h, v4.h[1]
fmla v22.8h, v2.8h, v4.h[1]
fmla v23.8h, v3.8h, v4.h[1]
fmla v24.8h, v0.8h, v4.h[2]
fmla v25.8h, v1.8h, v4.h[2]
fmla v26.8h, v2.8h, v4.h[2]
fmla v27.8h, v3.8h, v4.h[2]
fmla v28.8h, v0.8h, v4.h[3]
fmla v29.8h, v1.8h, v4.h[3]
fmla v30.8h, v2.8h, v4.h[3]
fmla v31.8h, v3.8h, v4.h[3]
ld1 {{ v0.8h, v1.8h, v2.8h, v3.8h }}, [ x1 ], #64
ldr d4, [x2], #8
@@ -0,0 +1,71 @@
// mul a: v0, v1, v2, v3 b: v4
// load a: v5(d5/x5), v6(d6,x6), v7(d7,x7), v8(d8, x8)
// load b: v9 as d9
fmla v16.8h, v0.8h, v4.h[0]
ldr d5, [x1], #8
fmla v17.8h, v1.8h, v4.h[0]
ldr d9, [x2], #8
fmla v18.8h, v2.8h, v4.h[0]
ldr x5, [x1], #8
fmla v19.8h, v3.8h, v4.h[0]
fmla v20.8h, v0.8h, v4.h[1]
ldr d6, [x1], #8
fmla v21.8h, v1.8h, v4.h[1]
ldr x6, [x1], #8
fmla v22.8h, v2.8h, v4.h[1]
ldr d7, [x1], #8
fmla v23.8h, v3.8h, v4.h[1]
ldr x7, [x1], #8
fmla v24.8h, v0.8h, v4.h[2]
ldr d8, [x1], #8
fmla v25.8h, v1.8h, v4.h[2]
ldr x8, [x1], #8
fmla v26.8h, v2.8h, v4.h[2]
ins v5.d[1], x5
fmla v27.8h, v3.8h, v4.h[2]
ins v6.d[1], x6
fmla v28.8h, v0.8h, v4.h[3]
ins v7.d[1], x7
fmla v29.8h, v1.8h, v4.h[3]
ins v8.d[1], x8
fmla v30.8h, v2.8h, v4.h[3]
ins v9.d[1], x9
fmla v31.8h, v3.8h, v4.h[3]
// mul a: v5, v6, v7, v8 b: v9
// load a: v0(d0/x5), v1(d1,x6), v2(d2,x7), v3(d3, x8)
// load b: v4 as d4
fmla v16.8h, v5.8h, v9.h[0]
ldr d0, [x1], #8
fmla v17.8h, v6.8h, v9.h[0]
ldr d4, [x2], #8
fmla v18.8h, v7.8h, v9.h[0]
ldr x5, [x1], #8
fmla v19.8h, v8.8h, v9.h[0]
fmla v20.8h, v5.8h, v9.h[1]
ldr d1, [x1], #8
fmla v21.8h, v6.8h, v9.h[1]
ldr x6, [x1], #8
fmla v22.8h, v7.8h, v9.h[1]
ldr d2, [x1], #8
fmla v23.8h, v8.8h, v9.h[1]
ldr x7, [x1], #8
fmla v24.8h, v5.8h, v9.h[2]
ldr d3, [x1], #8
fmla v25.8h, v6.8h, v9.h[2]
ldr x8, [x1], #8
fmla v26.8h, v7.8h, v9.h[2]
ins v0.d[1], x5
fmla v27.8h, v8.8h, v9.h[2]
ins v1.d[1], x6
fmla v28.8h, v5.8h, v9.h[3]
ins v2.d[1], x7
fmla v29.8h, v6.8h, v9.h[3]
ins v3.d[1], x8
fmla v30.8h, v7.8h, v9.h[3]
ins v4.d[1], x9
fmla v31.8h, v8.8h, v9.h[3]
@@ -0,0 +1,165 @@
// vim: ft=arm
// x20..x27 are used, callee-preserved
// C tile regs: v16 to v31, (scratch)
// v8 is used, d8 (lower half) must preserved
// v0-v7 (scratch registers)
// packed A buffering (2x8 values): alternating v0, v1 with v2, v3
// packed B buffering (2x8 values): alternating v4, v5 with v6, v7
.text
.align 4
{% if needs_pragma == true %}
.cpu generic+fp+simd+fp16
{% endif %}
.global {{G}}arm64fp16_mmm_f16_32x4_{{core}}_{{suffix}}
{{G}}arm64fp16_mmm_f16_32x4_{{core}}_{{suffix}}:
stp x20, x21, [sp, #-16]!
stp x22, x23, [sp, #-16]!
stp x24, x25, [sp, #-16]!
stp x26, x27, [sp, #-16]!
stp d8, d9, [sp, #-16]!
{% include "dispatcher.j2" %}
.add_mat_mul:
ldr x2, [x0, #24] // b
ldp x3, x1, [x0, #8] // k, a
cmp x3, #0
beq .non_linear_loop
ld1 { v0.4s, v1.4s, v2.4s, v3.4s }, [ x1 ], #64
ldr d4, [x2], #8
{% set packed_packed_loop1 %}
{% include "arm64fp16_mmm_f16_32x4/loop1/naive.S.raw" %}
{% endset %}
{% set packed_packed_loop2 %}
{% if core == "a55" %}
{% include "arm64fp16_mmm_f16_32x4/loop2/cortex_a55.S.raw" %}
{% else %}
{{ packed_packed_loop1 }}
{{ packed_packed_loop1 }}
{% endif %}
{% endset %}
cmp x3, #4
blt .packed_packed_loop_1
.p2align 4
.packed_packed_loop_4:
{{ packed_packed_loop2 }}
{{ packed_packed_loop2 }}
sub x3, x3, #4
cmp x3, #4
bge .packed_packed_loop_4
cmp x3, #0
beq .non_linear_loop
.p2align 4
.packed_packed_loop_1:
{{ packed_packed_loop1 }}
subs x3, x3, #1
bne .packed_packed_loop_1
b .non_linear_loop
{% set from = 16 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_scalars.j2" %}
{% set mr = 32 %}{% set from = 16 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_per_rows.j2" %}
{% set mr = 32 %}{% set from = 16 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_per_cols.j2" %}
{% set from = 16 %}{% set to = 31 %}{% include "arm64fp16_mmm_load_tile.j2" %}
.add_unicast:
ldp x5, x6, [x0, #8]
ldp x7, x8, [x0, #24]
{% for col in range(0, 4) %}
mov x4, x5
{% for reg in range(0, 4) %}
{% for lane in range(0, 8) %}
ld1 {v0.h}[{{lane}}], [ x4 ], x6
{% endfor %}
fadd v{{ col * 4 + 16 + reg }}.8h, v{{ col * 4 + 16 + reg }}.8h, v0.8h
{% endfor %}
add x5, x5, x7
{% endfor %}
b .non_linear_loop
.add_row_col_products:
ldr x2, [x0, #8]
ldr x3, [x0, #16]
ld1 { v0.8h, v1.8h, v2.8h, v3.8h }, [ x2 ]
ldr d4, [x3]
fmla v16.8h, v0.8h, v4.h[0]
fmla v17.8h, v1.8h, v4.h[0]
fmla v18.8h, v2.8h, v4.h[0]
fmla v19.8h, v3.8h, v4.h[0]
fmla v20.8h, v0.8h, v4.h[1]
fmla v21.8h, v1.8h, v4.h[1]
fmla v22.8h, v2.8h, v4.h[1]
fmla v23.8h, v3.8h, v4.h[1]
fmla v24.8h, v0.8h, v4.h[2]
fmla v25.8h, v1.8h, v4.h[2]
fmla v26.8h, v2.8h, v4.h[2]
fmla v27.8h, v3.8h, v4.h[2]
fmla v28.8h, v0.8h, v4.h[3]
fmla v29.8h, v1.8h, v4.h[3]
fmla v30.8h, v2.8h, v4.h[3]
fmla v31.8h, v3.8h, v4.h[3]
b .non_linear_loop
.store:
ldp x5, x6, [x0, #8] // c base ptr, rsc
ldp x7, x8, [x0, #24] // csc, item_size
cmp x6, #2
bne .store_strides_generic
{% for col in range(0, 4) %}
str q{{ col * 4 + 16 + 0 }}, [ x5 ]
str q{{ col * 4 + 16 + 1 }}, [ x5, #16 ]
str q{{ col * 4 + 16 + 2 }}, [ x5, #32 ]
str q{{ col * 4 + 16 + 3 }}, [ x5, #48 ]
add x5, x5, x7
{% endfor %}
b .non_linear_loop
.store_strides_generic:
{% for col in range(0, 4) %}
mov x4, x5
{% for reg in range(0, 4) %}
{% for lane in range(0, 8) %}
st1 { v{{ col * 4 + 16 + reg }}.h }[{{lane}}], [ x4 ], x6
{% endfor %}
{% endfor %}
add x5, x5, x7
{% endfor %}
b .non_linear_loop
.return:
ldp d8, d9, [sp], #16
ldp x26, x27, [sp], #16
ldp x24, x25, [sp], #16
ldp x22, x23, [sp], #16
ldp x20, x21, [sp], #16
ret
@@ -0,0 +1,148 @@
// vim: ft=arm
// C tile regs: v16 to v31, no need to preserve
// no preservation either for v0-v7...
// v8..v15 are callee-preserved
// packed A buffering (2x8 values): alternating v0, v1 with v2, v3
// packed B buffering (2x8 values): alternating v4, v5 with v6, v7
.text
.align 4
{% if needs_pragma == true %}
.cpu generic+fp+simd+fp16
{% endif %}
.global {{G}}arm64fp16_mmm_f16_32x6_{{core}}_{{suffix}}
{{G}}arm64fp16_mmm_f16_32x6_{{core}}_{{suffix}}:
stp x20, x21, [sp, #-16]!
stp x22, x23, [sp, #-16]!
stp x24, x25, [sp, #-16]!
stp d8, d9, [sp, #-16]!
stp d10, d11, [sp, #-16]!
stp d12, d13, [sp, #-16]!
stp d14, d15, [sp, #-16]!
{% include "dispatcher.j2" %}
.add_mat_mul:
ldp x2, x4, [x0, #24] // b, packing
ldp x3, x1, [x0, #8] // k, a
cmp x3, #0
beq .non_linear_loop
.p2align 4
.packed_packed_loop_1:
ld1 { v7.8h }, [ x2 ]
ld1 { v0.8h, v1.8h, v2.8h, v3.8h }, [ x1 ], #64
add x2, x2, 12
{% for row in range(0, 4) %}
{% for col in range(0, 6) %}
fmla v{{ col * 4 + 8 + row }}.8h, v{{row}}.8h, v7.h[{{col}}]
{% endfor %}
/*
{% for col in range(0, 2) %}
fmla v{{ (col + 4) * 4 + 8 + row }}.8h, v{{row}}.8h, v6.h[{{col}}]
{% endfor %}
*/
{% endfor %}
subs x3, x3, #1
bne .packed_packed_loop_1
b .non_linear_loop
{% set from = 8 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_scalars.j2" %}
{% set mr = 32 %}{% set from = 8 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_per_rows.j2" %}
{% set mr = 32 %}{% set from = 8 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_per_cols.j2" %}
{% set from = 8 %}{% set to = 31 %}{% include "arm64fp16_mmm_load_tile.j2" %}
.add_unicast:
ldp x5, x6, [x0, #8]
ldp x7, x8, [x0, #24]
{% for col in range(0, 6) %}
mov x4, x5
{% for reg in range(0, 4) %}
{% for lane in range(0, 8) %}
ld1 {v0.h}[{{lane}}], [ x4 ], x6
{% endfor %}
fadd v{{ col * 4 + 8 + reg }}.8h, v{{ col * 4 + 8 + reg }}.8h, v0.8h
{% endfor %}
add x5, x5, x7
{% endfor %}
b .non_linear_loop
.do_per_row_add:
ld1 {v0.8h-v3.8h}, [x5], #64
ld1 {v4.8h-v7.8h}, [x5], #64
{% for r in range(0, 8) %}
fadd v{{ r + 24 }}.8h, v{{ r + 24 }}.8h, v{{r}}.8h
{% endfor %}
b .non_linear_loop
.add_row_col_products:
ldp x2, x3, [x0, #8]
ld1 { v7.d }[0], [ x3 ], #8
ld1 { v7.s }[2], [ x3 ], #4
ld1 { v0.8h, v1.8h, v2.8h, v3.8h }, [ x2 ], #64
{% for row in range(0, 4) %}
{% for col in range(0, 6) %}
fmla v{{ col * 4 + 8 + row }}.8h, v{{row}}.8h, v7.h[{{col}}]
{% endfor %}
{% endfor %}
b .non_linear_loop
.store:
ldp x5, x6, [x0, #8] // c base ptr, rsc
ldp x7, x8, [x0, #24] // csc, item_size
cmp x6, #2
beq .store_strides_contig
{% for col in range(0, 6) %}
mov x4, x5
{% for reg in range(0, 4) %}
{% for lane in range(0, 8) %}
st1 { v{{ col * 4 + 8 + reg }}.h }[{{lane}}], [ x4 ], x6
{% endfor %}
{% endfor %}
add x5, x5, x7
{% endfor %}
b .non_linear_loop
.store_strides_contig:
{% for col in range(0, 6) %}
mov x4, x5
{% for r in range(0, 4) %}
st1 { v{{ col * 4 + 8 + r }}.8h }, [ x4 ], 16
{% endfor %}
add x5, x5, x7
{% endfor %}
b .non_linear_loop
.return:
ldp d14, d15, [sp], #16
ldp d12, d13, [sp], #16
ldp d10, d11, [sp], #16
ldp d8, d9, [sp], #16
ldp x24, x25, [sp], #16
ldp x22, x23, [sp], #16
ldp x20, x21, [sp], #16
ret
@@ -0,0 +1,264 @@
// vim: ft=arm
// C tile regs: v16 to v31, no need to preserve
// no preservation either for v0-v7...
// v8..v15 are callee-preserved
// packed A buffering (2x8 values): alternating v0, v1 with v2, v3
// packed B buffering (2x8 values): alternating v4, v5 with v6, v7
.text
.align 4
{% if needs_pragma == true %}
.cpu generic+fp+simd+fp16
{% endif %}
.global {{G}}arm64fp16_mmm_f16_64x1_{{core}}_{{suffix}}
{{G}}arm64fp16_mmm_f16_64x1_{{core}}_{{suffix}}:
stp x20, x21, [sp, #-16]!
stp x22, x23, [sp, #-16]!
stp x24, x25, [sp, #-16]!
stp d8, d9, [sp, #-16]!
stp d10, d11, [sp, #-16]!
stp d12, d13, [sp, #-16]!
stp d14, d15, [sp, #-16]!
{% include "dispatcher.j2" %}
.add_mat_mul:
ldp x2, x4, [x0, #24] // b, packing
ldp x3, x1, [x0, #8] // k, a
cmp x3, #0
beq .non_linear_loop
cmp x4, #1
beq .q4f16se
cmp x4, #2
beq .q4f16
.p2align 4
.packed_packed_loop_1:
ld1 { v8.h }[0], [ x2 ], #2
ld1 { v0.8h, v1.8h, v2.8h, v3.8h }, [ x1 ], #64
ld1 { v4.8h, v5.8h, v6.8h, v7.8h }, [ x1 ], #64
fmla v24.8h, v0.8h, v8.h[0]
fmla v25.8h, v1.8h, v8.h[0]
fmla v26.8h, v2.8h, v8.h[0]
fmla v27.8h, v3.8h, v8.h[0]
fmla v28.8h, v4.8h, v8.h[0]
fmla v29.8h, v5.8h, v8.h[0]
fmla v30.8h, v6.8h, v8.h[0]
fmla v31.8h, v7.8h, v8.h[0]
subs x3, x3, #1
bne .packed_packed_loop_1
b .non_linear_loop
.p2align 8
.q40f16_const:
.byte 0xc8, 0xc7, 0xc6, 0xc5, 0xc4, 0xc2, 0xc0, 0xbc
.byte 0x00, 0x3c, 0x40, 0x42, 0x44, 0x45, 0x46, 0x47
.q4f16se:
adr x4, .q40f16_const
movi v15.16b, 15
ld1 {v13.16b}, [ x4 ]
eor v12.16b, v12.16b, v12.16b
.q4f16se_outerloop:
{% for i in range(0, 8) %}
eor v{{ i + 16 }}.16b, v{{ i + 16 }}.16b, v{{ i + 16 }}.16b
{% endfor %}
mov x4, #32
.p2align 4
.q4f16se_innerloop:
ld1 { v9.16b-v10.16b }, [x1], #32
ld1 { v8.h }[0], [ x2 ], #2
and v0.16b, v9.16b, v15.16b
ushr v2.16b, v9.16b, 4
and v4.16b, v10.16b, v15.16b
ushr v6.16b, v10.16b, 4
tbl v0.16b, { v13.16b }, v0.16b
tbl v2.16b, { v13.16b }, v2.16b
tbl v4.16b, { v13.16b }, v4.16b
tbl v6.16b, { v13.16b }, v6.16b
zip2 v1.16b, v12.16b, v0.16b
zip2 v3.16b, v12.16b, v2.16b
zip2 v5.16b, v12.16b, v4.16b
zip2 v7.16b, v12.16b, v6.16b
zip1 v0.16b, v12.16b, v0.16b
zip1 v2.16b, v12.16b, v2.16b
zip1 v4.16b, v12.16b, v4.16b
zip1 v6.16b, v12.16b, v6.16b
{% for i in range(0, 8) %}
fmla v{{ i + 16 }}.8h, v{{i}}.8h, v8.h[0]
{% endfor %}
subs x4, x4, #1
bne .q4f16se_innerloop
// scales
ld1 { v0.8h-v3.8h }, [ x1 ], #64
ld1 { v4.8h-v7.8h }, [ x1 ], #64
{% for i in range(0, 8) %}
fmla v{{ i + 24 }}.8h, v{{i}}.8h, v{{ i + 16 }}.8h
{% endfor %}
subs x3, x3, #32
bne .q4f16se_outerloop
b .non_linear_loop
.q4f16:
adr x4, .q40f16_const
movi v15.16b, 15
ld1 {v13.16b}, [ x4 ]
eor v12.16b, v12.16b, v12.16b
.q4f16_outerloop:
// scales
ld1 { v16.8h-v19.8h }, [ x1 ], #64
ld1 { v20.8h-v23.8h }, [ x1 ], #64
mov x4, #32
.p2align 4
.q4f16_innerloop:
ld1 { v9.16b-v10.16b }, [x1], #32
ld1 { v8.h }[0], [ x2 ], #2
and v0.16b, v9.16b, v15.16b
ushr v2.16b, v9.16b, 4
and v4.16b, v10.16b, v15.16b
ushr v6.16b, v10.16b, 4
tbl v0.16b, { v13.16b }, v0.16b
tbl v2.16b, { v13.16b }, v2.16b
tbl v4.16b, { v13.16b }, v4.16b
tbl v6.16b, { v13.16b }, v6.16b
zip2 v1.16b, v12.16b, v0.16b
zip2 v3.16b, v12.16b, v2.16b
zip2 v5.16b, v12.16b, v4.16b
zip2 v7.16b, v12.16b, v6.16b
zip1 v0.16b, v12.16b, v0.16b
zip1 v2.16b, v12.16b, v2.16b
zip1 v4.16b, v12.16b, v4.16b
zip1 v6.16b, v12.16b, v6.16b
{% for i in range(0, 8) %}
fmul v{{i}}.8h, v{{i}}.8h, v{{ i + 16 }}.8h
{% endfor %}
{% for i in range(0, 8) %}
fmla v{{ i + 24 }}.8h, v{{i}}.8h, v8.h[0]
{% endfor %}
subs x4, x4, #1
bne .q4f16_innerloop
subs x3, x3, #32
bne .q4f16_outerloop
b .non_linear_loop
{% set from = 24 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_scalars.j2" %}
{% set mr = 64 %}{% set from = 24 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_per_rows.j2" %}
{% set mr = 64 %}{% set from = 24 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_per_cols.j2" %}
{% set from = 24 %}{% set to = 31 %}{% include "arm64fp16_mmm_load_tile.j2" %}
.add_unicast:
ldp x5, x6, [x0, #8] // c base ptr, rsc
cmp x6, #2
beq .do_per_row_add
{% for reg in range(24, 32) %}
{% for lane in range(0, 8) %}
ld1 {v0.h}[{{lane}}], [ x5 ], x6
{% endfor %}
fadd v{{reg}}.8h, v{{reg}}.8h, v0.8h
{% endfor %}
b .non_linear_loop
.do_per_row_add:
ld1 {v0.8h-v3.8h}, [x5], #64
ld1 {v4.8h-v7.8h}, [x5], #64
{% for r in range(0, 8) %}
fadd v{{ r + 24 }}.8h, v{{ r + 24 }}.8h, v{{r}}.8h
{% endfor %}
b .non_linear_loop
.add_row_col_products:
ldr x3, [x0, #16]
ldr x2, [x0, #8]
ld1 {v8.h}[0], [ x3 ]
{% for r in range(0, 8) %}
ldr q{{r}}, [x2], #16
{% endfor %}
fmla v24.8h, v0.8h, v8.h[0]
fmla v25.8h, v1.8h, v8.h[0]
fmla v26.8h, v2.8h, v8.h[0]
fmla v27.8h, v3.8h, v8.h[0]
fmla v28.8h, v4.8h, v8.h[0]
fmla v29.8h, v5.8h, v8.h[0]
fmla v30.8h, v6.8h, v8.h[0]
fmla v31.8h, v7.8h, v8.h[0]
b .non_linear_loop
.store:
ldp x5, x6, [x0, #8] // c base ptr, rsc$
cmp x6, #2
beq .store_strides_contig
{% for reg in range(24, 32) %}
{% for lane in range(0, 8) %}
st1 { v{{reg}}.h }[{{lane}}], [ x5 ], x6
{% endfor %}
{% endfor %}
b .non_linear_loop
.store_strides_contig:
{% for reg in range(24, 32) %}
st1 { v{{reg}}.8h }, [ x5 ], #16
{% endfor %}
b .non_linear_loop
.return:
ldp d14, d15, [sp], #16
ldp d12, d13, [sp], #16
ldp d10, d11, [sp], #16
ldp d8, d9, [sp], #16
ldp x24, x25, [sp], #16
ldp x22, x23, [sp], #16
ldp x20, x21, [sp], #16
ret
@@ -0,0 +1,165 @@
// vim: ft=arm
// C tile regs: v16 to v31, no need to preserve
// no preservation either for v0-v7...
// v8..v15 are callee-preserved
// packed A buffering (2x8 values): alternating v0, v1 with v2, v3
// packed B buffering (2x8 values): alternating v4, v5 with v6, v7
.text
.align 4
{% if needs_pragma == true %}
.cpu generic+fp+simd+fp16
{% endif %}
.global {{G}}arm64fp16_mmm_f16_64x3_{{core}}_{{suffix}}
{{G}}arm64fp16_mmm_f16_64x3_{{core}}_{{suffix}}:
stp x20, x21, [sp, #-16]!
stp x22, x23, [sp, #-16]!
stp x24, x25, [sp, #-16]!
stp d8, d9, [sp, #-16]!
stp d10, d11, [sp, #-16]!
stp d12, d13, [sp, #-16]!
stp d14, d15, [sp, #-16]!
{% include "dispatcher.j2" %}
.add_mat_mul:
ldp x2, x4, [x0, #24] // b, packing
ldp x3, x1, [x0, #8] // k, a
cmp x3, #0
beq .non_linear_loop
.p2align 4
.packed_packed_loop_1:
ld1 { v7.4s }, [ x2 ]
ld1 { v0.8h, v1.8h, v2.8h, v3.8h }, [ x1 ], #64
ld1 { v4.8h, v5.8h, v6.8h }, [ x1 ], #48
add x2, x2, #6
{% for col in range(0, 3) %}
fmla v{{ col * 8 + 8 }}.8h, v0.8h, v7.h[{{ col }}]
{% endfor %}
ld1 { v0.8h }, [ x1 ], #16
{% for row in range(1, 7) %}
{% for col in range(0, 3) %}
fmla v{{ col * 8 + 8 + row }}.8h, v{{row}}.8h, v7.h[{{ col }}]
{% endfor %}
{% endfor %}
{% for col in range(0, 3) %}
fmla v{{ col * 8 + 15 }}.8h, v0.8h, v7.h[{{ col }}]
{% endfor %}
subs x3, x3, #1
bne .packed_packed_loop_1
b .non_linear_loop
{% set from = 8 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_scalars.j2" %}
{% set mr = 64 %}{% set from = 8 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_per_rows.j2" %}
{% set mr = 64 %}{% set from = 8 %}{% set to = 31 %}{% include "arm64fp16_mmm_f16_per_cols.j2" %}
{% set from = 8 %}{% set to = 31 %}{% include "arm64fp16_mmm_load_tile.j2" %}
.add_unicast:
ldp x5, x6, [x0, #8]
ldp x7, x8, [x0, #24]
{% for col in range(0, 3) %}
mov x4, x5
{% for reg in range(0, 8) %}
{% for lane in range(0, 8) %}
ld1 {v0.h}[{{lane}}], [ x4 ], x6
{% endfor %}
fadd v{{ col * 8 + 8 + reg }}.8h, v{{ col * 8 + 8 + reg }}.8h, v0.8h
{% endfor %}
add x5, x5, x7
{% endfor %}
b .non_linear_loop
.do_per_row_add:
ld1 {v0.8h-v3.8h}, [x5], #64
ld1 {v4.8h-v7.8h}, [x5], #64
{% for r in range(0, 8) %}
fadd v{{ r + 24 }}.8h, v{{ r + 24 }}.8h, v{{r}}.8h
{% endfor %}
b .non_linear_loop
.add_row_col_products:
ldp x2, x3, [x0, #8]
ld1 { v7.s }[0], [ x3 ], #4
ld1 { v7.h }[2], [ x3 ], #2
ld1 { v0.8h, v1.8h, v2.8h, v3.8h }, [ x2 ], #64
ld1 { v4.8h, v5.8h, v6.8h }, [ x2 ], #48
{% for col in range(0, 3) %}
fmla v{{ col * 8 + 8 }}.8h, v0.8h, v7.h[{{ col }}]
{% endfor %}
ld1 { v0.8h }, [ x2 ], #16
{% for row in range(1, 7) %}
{% for col in range(0, 3) %}
fmla v{{ col * 8 + 8 + row }}.8h, v{{row}}.8h, v7.h[{{ col }}]
{% endfor %}
{% endfor %}
{% for col in range(0, 3) %}
fmla v{{ col * 8 + 15 }}.8h, v0.8h, v7.h[{{ col }}]
{% endfor %}
b .non_linear_loop
.store:
ldp x5, x6, [x0, #8] // c base ptr, rsc
ldp x7, x8, [x0, #24] // csc, item_size
cmp x6, #2
beq .store_strides_contig
{% for col in range(0, 3) %}
mov x4, x5
{% for reg in range(0, 8) %}
{% for lane in range(0, 8) %}
st1 { v{{ col * 8 + 8 + reg }}.h }[{{lane}}], [ x4 ], x6
{% endfor %}
{% endfor %}
add x5, x5, x7
{% endfor %}
b .non_linear_loop
.store_strides_contig:
{% for col in range(0, 3) %}
mov x4, x5
{% for r in range(0, 8) %}
st1 { v{{ col * 8 + 8 + r }}.8h }, [ x4 ], 16
{% endfor %}
add x5, x5, x7
{% endfor %}
b .non_linear_loop
.return:
ldp d14, d15, [sp], #16
ldp d12, d13, [sp], #16
ldp d10, d11, [sp], #16
ldp d8, d9, [sp], #16
ldp x24, x25, [sp], #16
ldp x22, x23, [sp], #16
ldp x20, x21, [sp], #16
ret
@@ -0,0 +1,10 @@
// vim: ft=arm
{% from "arm64fp16_mmm_8h_ops.j2" import per_col %}
{{ per_col(label="per_col_min", op="fmin", mr=mr, from=from, to=to) }}
{{ per_col(label="per_col_max", op="fmax", mr=mr, from=from, to=to) }}
{{ per_col(label="per_col_mul", op="fmul", mr=mr, from=from, to=to) }}
{{ per_col(label="per_col_add", op="fadd", mr=mr, from=from, to=to) }}
{{ per_col(label="per_col_sub", op="fsub", mr=mr, from=from, to=to) }}
{{ per_col(label="per_col_sub_flipped", op="fsub", mr=mr, from=from, to=to, flipped=true) }}
@@ -0,0 +1,10 @@
// vim: ft=arm
{% from "arm64fp16_mmm_8h_ops.j2" import per_row %}
{{ per_row(label="per_row_min", op="fmin", mr=mr, from=from, to=to) }}
{{ per_row(label="per_row_max", op="fmax", mr=mr, from=from, to=to) }}
{{ per_row(label="per_row_mul", op="fmul", mr=mr, from=from, to=to) }}
{{ per_row(label="per_row_add", op="fadd", mr=mr, from=from, to=to) }}
{{ per_row(label="per_row_sub", op="fsub", mr=mr, from=from, to=to) }}
{{ per_row(label="per_row_sub_flipped", op="fsub", mr=mr, from=from, to=to, flipped=true) }}
@@ -0,0 +1,38 @@
// vim: ft=arm
{% from "arm64fp16_mmm_8h_ops.j2" import scalar %}
{{ scalar(label="scalar_min", op="fmin", from=from, to=to) }}
{{ scalar(label="scalar_max", op="fmax", from=from, to=to) }}
{{ scalar(label="scalar_mul", op="fmul", from=from, to=to) }}
{{ scalar(label="scalar_add", op="fadd", from=from, to=to) }}
{{ scalar(label="scalar_sub", op="fsub", from=from, to=to) }}
{{ scalar(label="scalar_sub_flipped", op="fsub", from=from, to=to, flipped=true) }}
.clear:
{% for r in range(from, to + 1) %}
eor v{{r}}.8b, v{{r}}.8b, v{{r}}.8b
{% endfor %}
b .non_linear_loop
.leaky_relu:
add x2, x0, #8
ld1 {v4.s}[0], [ x2 ]
dup v4.8h, v4.h[0]
// bsl cond/dst, then, else
// fcmge dst, src, #0.0
{% for r in range(from, to + 1) %}
fmul v0.8h, v{{r}}.8h, v4.8h
fcmge v1.8h, v{{r}}.8h, #0.0
bsl v1.16b, v{{r}}.16b, v0.16b
and v{{r}}.16b, v1.16b, v1.16b
{% endfor %}
b .non_linear_loop
.q_scale:
.q_shl:
.q_shr:
b .unsupported
@@ -0,0 +1,10 @@
// vim: ft=arm
.load_tile:
ldr x2, [ x0, #8 ]
{% for reg in range(from, to + 1) %}
ld1 { v{{reg}}.4s }, [ x2 ], #16
{% endfor %}
b .non_linear_loop
@@ -0,0 +1,131 @@
// vim: ft=arm
// no preservation either for v0-v7 and v16-v31
.text
.align 4
{% if needs_pragma == true %}
.cpu generic+fp+simd+fp16
{% endif %}
.global {{G}}arm64fp16_sigmoid_f16_8n_{{suffix}}
{{G}}arm64fp16_sigmoid_f16_8n_{{suffix}}:
cmp x1, #0
beq .return
adr x2, .coeffs_num
ld1 { v0.8h }, [x2]
dup v5.8h, v0.h[0] // v5 <- low, broadcasted
dup v6.8h, v0.h[1] // v6 <- high, broadcasted
dup v7.8h, v0.h[7] // v7 <- half, broadcasted
cmp x1, #32
blt .loop
.loop4:
ld1 { v16.8h, v17.8h, v18.8h, v19.8h }, [x0]
fmax v16.8h, v16.8h, v5.8h
fmax v17.8h, v17.8h, v5.8h
fmax v18.8h, v18.8h, v5.8h
fmax v19.8h, v19.8h, v5.8h
fmin v16.8h, v16.8h, v6.8h
fmin v17.8h, v17.8h, v6.8h
fmin v18.8h, v18.8h, v6.8h
fmin v19.8h, v19.8h, v6.8h // v16 <- x
fmul v20.8h, v16.8h, v16.8h
fmul v21.8h, v17.8h, v17.8h
fmul v22.8h, v18.8h, v18.8h
fmul v23.8h, v19.8h, v19.8h // v20 <- x2
dup v28.8h, v0.h[3]
fmla v28.8h, v20.8h, v0.h[2]
dup v29.8h, v0.h[3]
fmla v29.8h, v21.8h, v0.h[2]
dup v30.8h, v0.h[3]
fmla v30.8h, v22.8h, v0.h[2]
dup v31.8h, v0.h[3]
fmla v31.8h, v23.8h, v0.h[2]
dup v24.8h, v0.h[4]
fmla v24.8h, v20.8h, v28.8h
dup v25.8h, v0.h[4]
fmla v25.8h, v21.8h, v29.8h
dup v26.8h, v0.h[4]
fmla v26.8h, v22.8h, v30.8h
dup v27.8h, v0.h[4]
fmla v27.8h, v23.8h, v31.8h
fmul v16.8h, v16.8h, v24.8h
fmul v17.8h, v17.8h, v25.8h
fmul v18.8h, v18.8h, v26.8h
fmul v19.8h, v19.8h, v27.8h // v16 <- numerator
dup v24.8h, v0.h[6]
dup v25.8h, v0.h[6]
dup v26.8h, v0.h[6]
dup v27.8h, v0.h[6]
fmla v24.8h, v20.8h, v0.h[5]
fmla v25.8h, v21.8h, v0.h[5]
fmla v26.8h, v22.8h, v0.h[5]
fmla v27.8h, v23.8h, v0.h[5] // v24 <- denum
fdiv v16.8h, v16.8h, v24.8h
fdiv v17.8h, v17.8h, v25.8h
fdiv v18.8h, v18.8h, v26.8h
fdiv v19.8h, v19.8h, v27.8h
fadd v16.8h, v16.8h, v7.8h
fadd v17.8h, v17.8h, v7.8h
fadd v18.8h, v18.8h, v7.8h
fadd v19.8h, v19.8h, v7.8h
st1 { v16.8h, v17.8h, v18.8h, v19.8h }, [x0], #64
subs x1, x1, #32
cmp x1, #32
bge .loop4
cmp x1, #0
beq .return
.loop:
ld1 { v16.8h }, [x0]
fmax v16.8h, v16.8h, v5.8h
fmin v16.8h, v16.8h, v6.8h // v16 <- x
fmul v20.8h, v16.8h, v16.8h // v20 <- x2
dup v28.8h, v0.h[3]
fmla v28.8h, v20.8h, v0.h[2]
dup v24.8h, v0.h[4]
fmla v24.8h, v20.8h, v28.8h
fmul v16.8h, v16.8h, v24.8h // v16 <- numerator
dup v24.8h, v0.h[6]
fmla v24.8h, v20.8h, v0.h[5] // v24 <- denum
fdiv v16.8h, v16.8h, v24.8h
fadd v16.8h, v16.8h, v7.8h
st1 { v16.8h }, [x0], #16
subs x1, x1, #8
bne .loop
.return:
ret
.coeffs_num:
{{ -6.92 | float16 }}
{{ 6.92 | float16 }}
{{ -0.0000124702 | float16 }}
{{ 0.00400222 | float16 }}
{{ 0.249895 | float16 }}
{{ 0.098734 | float16 }}
{{ 1.0 | float16 }}
{{ 0.5 | float16 }}
@@ -0,0 +1,124 @@
// vim: ft=arm
// no preservation either for v0-v7 and v16-v31
.text
.align 4
{% if needs_pragma == true %}
.cpu generic+fp+simd+fp16
{% endif %}
.global {{G}}arm64fp16_tanh_f16_8n_{{suffix}}
{{G}}arm64fp16_tanh_f16_8n_{{suffix}}:
cmp x1, #0
beq .return
adr x2, .coeffs_num
ld1 { v0.8h }, [x2]
dup v5.8h, v0.h[0] // v5 <- low, broadcasted
dup v6.8h, v0.h[1] // v6 <- high, broadcasted
cmp x1, #32
blt .loop
.loop4:
ld1 { v16.8h, v17.8h, v18.8h, v19.8h }, [x0]
fmax v16.8h, v16.8h, v5.8h
fmax v17.8h, v17.8h, v5.8h
fmax v18.8h, v18.8h, v5.8h
fmax v19.8h, v19.8h, v5.8h
fmin v16.8h, v16.8h, v6.8h
fmin v17.8h, v17.8h, v6.8h
fmin v18.8h, v18.8h, v6.8h
fmin v19.8h, v19.8h, v6.8h // v16 <- x
fmul v20.8h, v16.8h, v16.8h
fmul v21.8h, v17.8h, v17.8h
fmul v22.8h, v18.8h, v18.8h
fmul v23.8h, v19.8h, v19.8h // v20 <- x2
dup v24.8h, v0.h[3]
fmla v24.8h, v20.8h, v0.h[2]
dup v25.8h, v0.h[3]
fmla v25.8h, v21.8h, v0.h[2]
dup v26.8h, v0.h[3]
fmla v26.8h, v22.8h, v0.h[2]
dup v27.8h, v0.h[3]
fmla v27.8h, v23.8h, v0.h[2]
fmul v16.8h, v16.8h, v24.8h
fmul v17.8h, v17.8h, v25.8h
fmul v18.8h, v18.8h, v26.8h
fmul v19.8h, v19.8h, v27.8h // v16 <- numerator
dup v28.8h, v0.h[5]
fmla v28.8h, v20.8h, v0.h[4]
dup v29.8h, v0.h[5]
fmla v29.8h, v21.8h, v0.h[4]
dup v30.8h, v0.h[5]
fmla v30.8h, v22.8h, v0.h[4]
dup v31.8h, v0.h[5]
fmla v31.8h, v23.8h, v0.h[4]
dup v24.8h, v0.h[6]
fmla v24.8h, v20.8h, v28.8h
dup v25.8h, v0.h[6]
fmla v25.8h, v21.8h, v29.8h
dup v26.8h, v0.h[6]
fmla v26.8h, v22.8h, v30.8h
dup v27.8h, v0.h[6]
fmla v27.8h, v23.8h, v31.8h // v24 <- denum
fdiv v16.8h, v16.8h, v24.8h
fdiv v17.8h, v17.8h, v25.8h
fdiv v18.8h, v18.8h, v26.8h
fdiv v19.8h, v19.8h, v27.8h
st1 { v16.8h, v17.8h, v18.8h, v19.8h }, [x0], #64
subs x1, x1, #32
cmp x1, #32
bge .loop4
cmp x1, #0
beq .return
.loop:
ld1 { v16.8h }, [x0]
fmax v16.8h, v16.8h, v5.8h
fmin v16.8h, v16.8h, v6.8h // v16 <- x
fmul v20.8h, v16.8h, v16.8h // v20 <- x2
dup v24.8h, v0.h[3]
fmla v24.8h, v20.8h, v0.h[2]
fmul v16.8h, v16.8h, v24.8h // v16 <- numerator
dup v28.8h, v0.h[5]
fmla v28.8h, v20.8h, v0.h[4]
dup v24.8h, v0.h[6]
fmla v24.8h, v20.8h, v28.8h // v24 <- denum
fdiv v16.8h, v16.8h, v24.8h
st1 { v16.8h }, [x0], #16
subs x1, x1, #8
bne .loop
.return:
ret
.coeffs_num:
{{ -3.84 | float16 }}
{{ 3.84 | float16 }}
{{ 0.082654955 | float16 }} // alpha
{{ 0.99963124 | float16 }}
{{ 0.0065383179 | float16 }} // beta
{{ 0.41401828 | float16 }}
{{ 1.0 | float16 }}
{{ 0 | float16 }} // padding
@@ -0,0 +1,37 @@
// vim: ft=arm
.non_linear:
sub x0, x0, 40
.non_linear_loop:
add x0, x0, 40
ldr x2, [x0]
mov x4, #{{ jump_table | length }}
cmp x2, #{{ jump_table | length }}
csel x2, x2, x4, lt
cmp x2, #0
csel x2, x4, x2, lt
adr x3, .jmp_table
add x3, x3, x2, LSL#2
br x3
.jmp_table:
{% for j in jump_table %}
b .{{j}}
{% endfor %}
b .unsupported
add x0, x2, #4000
b .return
.unsupported:
mov x0, #1
b .return
.done:
mov x0, 0
b .return
@@ -0,0 +1,13 @@
// vim: ft=arm
// serves as a canary build file to figure out which flag combination will accept half precision fmla
.text
.align 4
// .cpu generic+fp+simd+fp16
.global foo
foo:
fmla v16.8h, v0.8h, v8.h[0]
ret
@@ -0,0 +1,13 @@
// vim: ft=arm
// serves as a canary build file to figure out which flag combination will accept half precision fmla
.text
.align 4
.cpu generic+fp+simd+fp16
.global foo
foo:
fmla v16.8h, v0.8h, v8.h[0]
ret