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,35 @@
// vim: ft=arm
.{{label}}:
ldr x2, [x0, #8]
{% capture mr_over_8 %}{{ mr | divided_by: 8}}{%endcapture%}
{% capture cols%}{{to | plus: 1| minus:from| divided_by:mr_over_8}}{%endcapture%}
{% capture loads %}{{cols | divided_by: 8}}{% endcapture %}
{%if cols == "1" %}
ld1 {v0.h}[0], [ x2 ]
{% elsif cols == "4" %}
ldr d0, [ x2 ]
{% else %}
{% for reg in (1..loads) %}
ldr q{{reg |minus:1}}, [ x2 ], #16
{% endfor %}
{% endif %}
// mr:{{mr}} {{ loads }} {{cols}}
{% for col in (1..cols) %}
dup v3.8h, v{{col| minus: 1|divided_by:8}}.h[{{col| minus: 1|modulo:8}}]
{% for row in (1..mr_over_8) %}
{% capture acc %}{{ col|minus:1|times:mr_over_8|plus:row|minus:1|plus:from }}{% endcapture %}
{% 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
@@ -0,0 +1,25 @@
// vim: ft=arm
.{{label}}:
ldr x2, [x0, #8]
{% capture mr_over_8 %}{{ mr | divided_by: 8 }}{%endcapture%}
{% capture mr_over_8_min_1 %}{{ mr | divided_by: 8 | minus: 1 }}{%endcapture%}
{% for reg in (0..mr_over_8_min_1) %}
ldr q{{reg}}, [ x2 ], #16
{% endfor %}
{% if flipped %}
{% for acc in (from..to) %}
{% capture other%}{{acc | minus: from | modulo: mr_over_8}}{%endcapture%}
{{op}} v{{acc}}.8h, v{{acc}}.8h, v{{other}}.8h
{% endfor %}
{% else %}
{% for acc in (from..to) %}
{% capture other%}{{acc | minus: from | modulo: mr_over_8}}{%endcapture%}
{{op}} v{{acc}}.8h, v{{other}}.8h, v{{acc}}.8h
{% endfor %}
{% endif %}
b .non_linear_loop
@@ -0,0 +1,18 @@
// vim: ft=arm
.{{label}}:
add x2, x0, #8
ld1 {v0.h}[0], [ x2 ]
dup v0.8h, v0.h[0]
{% if flipped %}
{% for reg in (from..to) %}
{{op}} v{{reg}}.8h, v{{reg}}.8h, v0.8h
{% endfor %}
{% else %}
{% for reg in (from..to) %}
{{op}} v{{reg}}.8h, v0.8h, v{{reg}}.8h
{% endfor %}
{% endif %}
b .non_linear_loop
@@ -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,212 @@
// vim: ft=arm
// C tile regs: v16 to v31, no need to preserve
//
// 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]
// 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.tmpliq" %}
.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
{% capture packed_packed_loop1 %}
{% include "arm64fp16_mmm_f16_128x1/loop1/naive.tmpli" %}
{% endcapture %}
{% capture packed_packed_loop2 %}
{% include "arm64fp16_mmm_f16_128x1/loop2/cortex_a55.tmpli" %}
{% endcapture %}
.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
{% include "arm64fp16_mmm_f16_scalars.tmpliq" from:16, to:31%}
{% include "arm64fp16_mmm_f16_per_rows.tmpliq" mr:128, from:16, to:31%}
{% include "arm64fp16_mmm_f16_per_cols.tmpliq" mr:128, from:16, to:31%}
.add_unicast:
ldp x5, x6, [x0, #8] // c base ptr, rsc
cmp x6, #2
beq .do_per_row_add
{% for reg in (16..31) %}
{% for lane in (0..7) %}
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 (0..15) %}
fadd v{{r| plus: 16}}.8h, v{{r | plus: 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 (0..7) %}
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 (16..31) %}
{% for lane in (0..7) %}
st1 { v{{reg}}.h }[{{lane}}], [ x5 ], x6
{% endfor %}
{% endfor %}
b .non_linear_loop
.store_strides_contig:
{% for reg in (16..31) %}
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,173 @@
// 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.tmpliq" %}
.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
{% capture packed_packed_loop1 %}
{% include "arm64fp16_mmm_f16_16x8/loop1/naive.tmpli" %}
{% endcapture %}
{% capture packed_packed_loop2 %}
{% if core == "a55" %}
{% include "arm64fp16_mmm_f16_16x8/loop2/cortex_a55.tmpli" %}
{% else %}
{{ packed_packed_loop1 }}
{{ packed_packed_loop1 }}
{% endif %}
{% endcapture %}
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
{% include "arm64fp16_mmm_f16_scalars.tmpliq" from:16, to:31%}
{% include "arm64fp16_mmm_f16_per_rows.tmpliq" mr:16, from:16, to:31 %}
{% include "arm64fp16_mmm_f16_per_cols.tmpliq" mr:16, from:16, to:31 %}
.add_unicast:
ldp x5, x6, [x0, #8]
ldp x7, x8, [x0, #24]
{% for col in (8..15) %}
mov x4, x5
{% for reg in (0..1) %}
{% for lane in (0..7) %}
ld1 {v0.h}[{{lane}}], [ x4 ], x6
{% endfor %}
fadd v{{col | times:2 | plus: reg}}.8h, v{{col | times:2 | plus: 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 (8..15) %}
str q{{col | times:2 }}, [ x5 ]
str q{{col | times:2 | plus: 1}}, [ x5, #16 ]
add x5, x5, x7
{% endfor %}
b .non_linear_loop
.store_strides_generic:
{% for col in (8..15) %}
mov x4, x5
{% for reg in (0..1) %}
{% for lane in (0..7) %}
st1 { v{{col | times:2 | plus: 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,164 @@
// 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.tmpliq" %}
.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
{% capture packed_packed_loop1 %}
{% include "arm64fp16_mmm_f16_32x4/loop1/naive.tmpli" %}
{% endcapture %}
{% capture packed_packed_loop2 %}
{% if core == "a55" %}
{% include "arm64fp16_mmm_f16_32x4/loop2/cortex_a55.tmpli" %}
{% else %}
{{ packed_packed_loop1 }}
{{ packed_packed_loop1 }}
{% endif %}
{% endcapture %}
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
{% include "arm64fp16_mmm_f16_scalars.tmpliq" from:16, to:31%}
{% include "arm64fp16_mmm_f16_per_rows.tmpliq" mr:32, from:16, to:31 %}
{% include "arm64fp16_mmm_f16_per_cols.tmpliq" mr:32, from:16, to:31 %}
.add_unicast:
ldp x5, x6, [x0, #8]
ldp x7, x8, [x0, #24]
{% for col in (0..3) %}
mov x4, x5
{% for reg in (0..3) %}
{% for lane in (0..7) %}
ld1 {v0.h}[{{lane}}], [ x4 ], x6
{% endfor %}
fadd v{{col | times:4 | plus: 16| plus: reg}}.8h, v{{col | times:4 | plus: 16 | plus: 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 (0..3) %}
str q{{col | times:4 | plus:16 | plus: 0}}, [ x5 ]
str q{{col | times:4 | plus:16 | plus: 1}}, [ x5, #16 ]
str q{{col | times:4 | plus:16 | plus: 2}}, [ x5, #32 ]
str q{{col | times:4 | plus:16 | plus: 3}}, [ x5, #48 ]
add x5, x5, x7
{% endfor %}
b .non_linear_loop
.store_strides_generic:
{% for col in (0..3) %}
mov x4, x5
{% for reg in (0..3) %}
{% for lane in (0..7) %}
st1 { v{{col | times:4 | plus: 16 | plus: 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,9 @@
// vim: ft=arm
{% include "arm64fp16_mmm_8h_per_col.tmpliq" label:"per_col_min", op:"fmin", mr:mr, from:from, to:to %}
{% include "arm64fp16_mmm_8h_per_col.tmpliq" label:"per_col_max", op:"fmax", mr:mr, from:from, to:to %}
{% include "arm64fp16_mmm_8h_per_col.tmpliq" label:"per_col_mul", op:"fmul", mr:mr, from:from, to:to %}
{% include "arm64fp16_mmm_8h_per_col.tmpliq" label:"per_col_add", op:"fadd", mr:mr, from:from, to:to %}
{% include "arm64fp16_mmm_8h_per_col.tmpliq" label:"per_col_sub", op:"fsub", mr:mr, from:from, to:to %}
{% include "arm64fp16_mmm_8h_per_col.tmpliq" label:"per_col_sub_flipped", op:"fsub", mr:mr, from:from, to:to, flipped: true%}
@@ -0,0 +1,9 @@
// vim: ft=arm
{% include "arm64fp16_mmm_8h_per_row.tmpliq" label:"per_row_min", op:"fmin", mr:mr, from:from, to:to %}
{% include "arm64fp16_mmm_8h_per_row.tmpliq" label:"per_row_max", op:"fmax", mr:mr, from:from, to:to %}
{% include "arm64fp16_mmm_8h_per_row.tmpliq" label:"per_row_mul", op:"fmul", mr:mr, from:from, to:to %}
{% include "arm64fp16_mmm_8h_per_row.tmpliq" label:"per_row_add", op:"fadd", mr:mr, from:from, to:to %}
{% include "arm64fp16_mmm_8h_per_row.tmpliq" label:"per_row_sub", op:"fsub", mr:mr, from:from, to:to %}
{% include "arm64fp16_mmm_8h_per_row.tmpliq" label:"per_row_sub_flipped", op:"fsub", mr:mr, from:from, to:to, flipped: true%}
@@ -0,0 +1,19 @@
// vim: ft=arm
{% include "arm64fp16_mmm_8h_scalar.tmpliq" label:"scalar_min", op:"fmin", from:from, to:to %}
{% include "arm64fp16_mmm_8h_scalar.tmpliq" label:"scalar_max", op:"fmax", from:from, to:to %}
{% include "arm64fp16_mmm_8h_scalar.tmpliq" label:"scalar_mul", op:"fmul", from:from, to:to %}
{% include "arm64fp16_mmm_8h_scalar.tmpliq" label:"scalar_add", op:"fadd", from:from, to:to %}
{% include "arm64fp16_mmm_8h_scalar.tmpliq" label:"scalar_sub", op:"fsub", from:from, to:to %}
{% include "arm64fp16_mmm_8h_scalar.tmpliq" label:"scalar_sub_flipped", op:"fsub", from:from, to:to, flipped:true %}
.clear:
{% for r in (from..to) %}
eor v{{r}}.8b, v{{r}}.8b, v{{r}}.8b
{% endfor %}
b .non_linear_loop
.q_scale:
.q_shl:
.q_shr:
b .unsupported
@@ -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 | size }}
cmp x2, #{{ jump_table | size }}
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