#![allow(
dead_code,
unsafe_op_in_unsafe_fn,
clippy::missing_safety_doc,
clippy::needless_range_loop
)]
use core::arch::asm;
use half::{bf16, f16};
pub use super::sme1::*;
macro_rules! mma_wide_2x2 {
($name:ident, $t:ty, $zero:expr, $sz:expr, $e:literal, $ld:literal, $st:literal,
$cnt:literal, $open:literal) => {
#[inline]
pub unsafe fn $name<const M: usize, const N: usize, const K: usize>(
a: *const $t,
lda: usize,
b: *const $t,
ldb: usize,
c: *mut $t,
ldc: usize,
) {
let mut at = [[$zero; M]; K];
for m in 0..M {
let row = a.add(m * lda);
for k in 0..K {
at[k][m] = *row.add(k);
}
}
asm!(
$open,
"smstart",
concat!($cnt, " {q}"), concat!("whilelt p0.", $e, ", xzr, {m}"), concat!("whilelt p1.", $e, ", xzr, {n}"), concat!("whilelt p2.", $e, ", {q}, {m}"), concat!("whilelt p3.", $e, ", {q}, {n}"), concat!("whilelt pn8.", $e, ", xzr, {m}, vlx2"), concat!("whilelt pn9.", $e, ", xzr, {n}, vlx2"), "mov {i}, xzr",
"30:",
"cmp {i}, {m}",
"b.hs 31f",
"madd {addr}, {i}, {ldc_b}, {c}",
concat!($ld, " {{z0.", $e, "-z1.", $e, "}}, pn9/z, [{addr}]"),
"cmp {i}, {q}",
"b.hs 32f",
"mov w12, {i:w}",
concat!("mova za0h.", $e, "[w12, 0], p1/m, z0.", $e),
concat!("mova za1h.", $e, "[w12, 0], p3/m, z1.", $e),
"b 33f",
"32:",
"sub {t}, {i}, {q}",
"mov w12, {t:w}",
concat!("mova za2h.", $e, "[w12, 0], p1/m, z0.", $e),
concat!("mova za3h.", $e, "[w12, 0], p3/m, z1.", $e),
"33:",
"add {i}, {i}, #1",
"b 30b",
"31:",
"mov {k}, xzr",
"34:",
"cmp {k}, {kk}",
"b.hs 35f",
"madd {addr}, {k}, {m_b}, {at}",
concat!($ld, " {{z0.", $e, "-z1.", $e, "}}, pn8/z, [{addr}]"),
"madd {addr}, {k}, {ldb_b}, {b}",
concat!($ld, " {{z2.", $e, "-z3.", $e, "}}, pn9/z, [{addr}]"),
concat!("fmopa za0.", $e, ", p0/m, p1/m, z0.", $e, ", z2.", $e),
concat!("fmopa za1.", $e, ", p0/m, p3/m, z0.", $e, ", z3.", $e),
concat!("fmopa za2.", $e, ", p2/m, p1/m, z1.", $e, ", z2.", $e),
concat!("fmopa za3.", $e, ", p2/m, p3/m, z1.", $e, ", z3.", $e),
"add {k}, {k}, #1",
"b 34b",
"35:",
"mov {i}, xzr",
"36:",
"cmp {i}, {m}",
"b.hs 37f",
"cmp {i}, {q}",
"b.hs 38f",
"mov w12, {i:w}",
concat!("mova z0.", $e, ", p1/m, za0h.", $e, "[w12, 0]"),
concat!("mova z1.", $e, ", p3/m, za1h.", $e, "[w12, 0]"),
"b 39f",
"38:",
"sub {t}, {i}, {q}",
"mov w12, {t:w}",
concat!("mova z0.", $e, ", p1/m, za2h.", $e, "[w12, 0]"),
concat!("mova z1.", $e, ", p3/m, za3h.", $e, "[w12, 0]"),
"39:",
"madd {addr}, {i}, {ldc_b}, {c}",
concat!($st, " {{z0.", $e, "-z1.", $e, "}}, pn9, [{addr}]"),
"add {i}, {i}, #1",
"b 36b",
"37:",
"smstop",
".arch_extension nosme2",
m = in(reg) M,
n = in(reg) N,
kk = in(reg) K,
at = in(reg) at.as_ptr(),
b = in(reg) b,
c = in(reg) c,
ldc_b = in(reg) ldc * $sz,
ldb_b = in(reg) ldb * $sz,
m_b = in(reg) M * $sz,
q = out(reg) _,
i = out(reg) _,
k = out(reg) _,
addr = out(reg) _,
t = out(reg) _,
out("x12") _,
out("z0") _, out("z1") _, out("z2") _, out("z3") _, out("z4") _, out("z5") _,
out("z6") _, out("z7") _, out("z8") _, out("z9") _, out("z10") _, out("z11") _,
out("z12") _, out("z13") _, out("z14") _, out("z15") _, out("z16") _, out("z17") _,
out("z18") _, out("z19") _, out("z20") _, out("z21") _, out("z22") _, out("z23") _,
out("z24") _, out("z25") _, out("z26") _, out("z27") _, out("z28") _, out("z29") _,
out("z30") _, out("z31") _,
out("p0") _, out("p1") _, out("p2") _, out("p3") _, out("p4") _, out("p5") _,
out("p6") _, out("p7") _, out("p8") _, out("p9") _, out("p10") _, out("p11") _,
out("p12") _, out("p13") _, out("p14") _, out("p15") _,
options(nostack),
);
}
};
}
mma_wide_2x2!(mma_f32_wide, f32, 0.0f32, 4, "s", "ld1w", "st1w", "cntw", ".arch_extension sme2");
mma_wide_2x2!(
mma_f64_wide, f64, 0.0f64, 8, "d", "ld1d", "st1d", "cntd",
".arch_extension sme2\n.arch_extension sme-f64f64"
);
macro_rules! mma_grid_2x2_packed {
($name:ident, $e:literal, $ld:literal, $st:literal, $cnt:literal, $shift:literal, $open:literal,
$t:ty) => {
#[inline]
pub unsafe fn $name(
ap: *const $t,
bp: *const $t,
c: *mut $t,
ldc_b: usize,
pm: usize,
pn: usize,
k: usize,
) {
asm!(
$open,
"smstart",
concat!($cnt, " {q}"),
"lsl {blk}, {q}, #1", concat!("lsl {step}, {q}, #", $shift), "mul {panel_b}, {kk}, {step}", "mul {row_b}, {blk}, {ldc_b}", concat!("whilelt p0.", $e, ", xzr, {blk}"),
concat!("whilelt p1.", $e, ", xzr, {blk}"),
concat!("whilelt p2.", $e, ", {q}, {blk}"),
concat!("whilelt p3.", $e, ", {q}, {blk}"),
concat!("whilelt pn8.", $e, ", xzr, {blk}, vlx2"),
concat!("whilelt pn9.", $e, ", xzr, {blk}, vlx2"),
"mov {mi}, xzr",
"100:", "cmp {mi}, {pm}",
"b.hs 199f",
"mov {nj}, xzr",
"110:", "cmp {nj}, {pn}",
"b.hs 198f",
"madd {apw}, {mi}, {panel_b}, {ap}", "madd {bpw}, {nj}, {panel_b}, {bp}", "madd {ctile}, {mi}, {row_b}, {c}", "madd {ctile}, {nj}, {step}, {ctile}",
"mov {i}, xzr",
"120:",
"cmp {i}, {blk}",
"b.hs 121f",
"madd {row}, {i}, {ldc_b}, {ctile}",
concat!($ld, " {{z0.", $e, "-z1.", $e, "}}, pn9/z, [{row}]"),
"cmp {i}, {q}",
"b.hs 122f",
"mov w12, {i:w}",
concat!("mova za0h.", $e, "[w12, 0], p1/m, z0.", $e),
concat!("mova za1h.", $e, "[w12, 0], p3/m, z1.", $e),
"b 123f",
"122:",
"sub {t}, {i}, {q}",
"mov w12, {t:w}",
concat!("mova za2h.", $e, "[w12, 0], p1/m, z0.", $e),
concat!("mova za3h.", $e, "[w12, 0], p3/m, z1.", $e),
"123:",
"add {i}, {i}, #1",
"b 120b",
"121:",
"mov {kc}, {kk}",
"mov {aw}, {apw}",
"mov {bw}, {bpw}",
"130:",
concat!($ld, " {{z0.", $e, "-z1.", $e, "}}, pn8/z, [{aw}]"),
concat!($ld, " {{z2.", $e, "-z3.", $e, "}}, pn9/z, [{bw}]"),
concat!("fmopa za0.", $e, ", p0/m, p1/m, z0.", $e, ", z2.", $e),
concat!("fmopa za1.", $e, ", p0/m, p3/m, z0.", $e, ", z3.", $e),
concat!("fmopa za2.", $e, ", p2/m, p1/m, z1.", $e, ", z2.", $e),
concat!("fmopa za3.", $e, ", p2/m, p3/m, z1.", $e, ", z3.", $e),
"add {aw}, {aw}, {step}",
"add {bw}, {bw}, {step}",
"subs {kc}, {kc}, #1",
"b.ne 130b",
"131:",
"mov {i}, xzr",
"140:",
"cmp {i}, {blk}",
"b.hs 141f",
"cmp {i}, {q}",
"b.hs 142f",
"mov w12, {i:w}",
concat!("mova z0.", $e, ", p1/m, za0h.", $e, "[w12, 0]"),
concat!("mova z1.", $e, ", p3/m, za1h.", $e, "[w12, 0]"),
"b 143f",
"142:",
"sub {t}, {i}, {q}",
"mov w12, {t:w}",
concat!("mova z0.", $e, ", p1/m, za2h.", $e, "[w12, 0]"),
concat!("mova z1.", $e, ", p3/m, za3h.", $e, "[w12, 0]"),
"143:",
"madd {row}, {i}, {ldc_b}, {ctile}",
concat!($st, " {{z0.", $e, "-z1.", $e, "}}, pn9, [{row}]"),
"add {i}, {i}, #1",
"b 140b",
"141:",
"add {nj}, {nj}, #1",
"b 110b",
"198:",
"add {mi}, {mi}, #1",
"b 100b",
"199:",
"smstop",
".arch_extension nosme2",
ap = in(reg) ap,
bp = in(reg) bp,
c = in(reg) c,
ldc_b = in(reg) ldc_b,
pm = in(reg) pm,
pn = in(reg) pn,
kk = in(reg) k,
q = out(reg) _,
blk = out(reg) _,
step = out(reg) _,
panel_b = out(reg) _,
row_b = out(reg) _,
mi = out(reg) _,
nj = out(reg) _,
kc = out(reg) _,
i = out(reg) _,
t = out(reg) _,
apw = out(reg) _,
bpw = out(reg) _,
ctile = out(reg) _,
row = out(reg) _,
aw = out(reg) _,
bw = out(reg) _,
out("x12") _,
out("z0") _, out("z1") _, out("z2") _, out("z3") _, out("z4") _, out("z5") _,
out("z6") _, out("z7") _, out("z8") _, out("z9") _, out("z10") _, out("z11") _,
out("z12") _, out("z13") _, out("z14") _, out("z15") _, out("z16") _, out("z17") _,
out("z18") _, out("z19") _, out("z20") _, out("z21") _, out("z22") _, out("z23") _,
out("z24") _, out("z25") _, out("z26") _, out("z27") _, out("z28") _, out("z29") _,
out("z30") _, out("z31") _,
out("p0") _, out("p1") _, out("p2") _, out("p3") _, out("p4") _, out("p5") _,
out("p6") _, out("p7") _, out("p8") _, out("p9") _, out("p10") _, out("p11") _,
out("p12") _, out("p13") _, out("p14") _, out("p15") _,
options(nostack),
);
}
};
}
mma_grid_2x2_packed!(mma_f32_grid_packed, "s", "ld1w", "st1w", "cntw", "3", ".arch_extension sme2", f32);
mma_grid_2x2_packed!(
mma_f64_grid_packed, "d", "ld1d", "st1d", "cntd", "4",
".arch_extension sme2\n.arch_extension sme-f64f64", f64
);
macro_rules! mma_grid_2x2_widen {
($name:ident, $t:ty, $mopa:literal, $open:literal) => {
#[inline]
pub unsafe fn $name(
ap: *const $t,
bp: *const $t,
c: *mut f32,
ldc_b: usize,
pm: usize,
pn: usize,
pairs: usize,
) {
asm!(
$open,
"smstart",
"cntw {q}", "lsl {blk}, {q}, #1", "lsl {step}, {q}, #3", "mul {panel_b}, {pairs}, {step}", "mul {row_b}, {blk}, {ldc_b}", "ptrue p0.s", "ptrue p1.h", "ptrue pn9.s", "ptrue pn8.h", "mov {mi}, xzr",
"200:",
"cmp {mi}, {pm}",
"b.hs 299f",
"mov {nj}, xzr",
"210:",
"cmp {nj}, {pn}",
"b.hs 298f",
"madd {apw}, {mi}, {panel_b}, {ap}",
"madd {bpw}, {nj}, {panel_b}, {bp}",
"madd {ctile}, {mi}, {row_b}, {c}",
"madd {ctile}, {nj}, {step}, {ctile}",
"mov {i}, xzr",
"220:",
"cmp {i}, {blk}",
"b.hs 221f",
"madd {row}, {i}, {ldc_b}, {ctile}",
"ld1w {{z4.s-z5.s}}, pn9/z, [{row}]",
"cmp {i}, {q}",
"b.hs 222f",
"mov w12, {i:w}",
"mova za0h.s[w12, 0], p0/m, z4.s",
"mova za1h.s[w12, 0], p0/m, z5.s",
"b 223f",
"222:",
"sub {t}, {i}, {q}",
"mov w12, {t:w}",
"mova za2h.s[w12, 0], p0/m, z4.s",
"mova za3h.s[w12, 0], p0/m, z5.s",
"223:",
"add {i}, {i}, #1",
"b 220b",
"221:",
"mov {kc}, {pairs}",
"mov {aw}, {apw}",
"mov {bw}, {bpw}",
"230:",
"ld1h {{z0.h-z1.h}}, pn8/z, [{aw}]",
"ld1h {{z2.h-z3.h}}, pn8/z, [{bw}]",
concat!($mopa, " za0.s, p1/m, p1/m, z0.h, z2.h"),
concat!($mopa, " za1.s, p1/m, p1/m, z0.h, z3.h"),
concat!($mopa, " za2.s, p1/m, p1/m, z1.h, z2.h"),
concat!($mopa, " za3.s, p1/m, p1/m, z1.h, z3.h"),
"add {aw}, {aw}, {step}",
"add {bw}, {bw}, {step}",
"subs {kc}, {kc}, #1",
"b.ne 230b",
"231:",
"mov {i}, xzr",
"240:",
"cmp {i}, {blk}",
"b.hs 241f",
"cmp {i}, {q}",
"b.hs 242f",
"mov w12, {i:w}",
"mova z4.s, p0/m, za0h.s[w12, 0]",
"mova z5.s, p0/m, za1h.s[w12, 0]",
"b 243f",
"242:",
"sub {t}, {i}, {q}",
"mov w12, {t:w}",
"mova z4.s, p0/m, za2h.s[w12, 0]",
"mova z5.s, p0/m, za3h.s[w12, 0]",
"243:",
"madd {row}, {i}, {ldc_b}, {ctile}",
"st1w {{z4.s-z5.s}}, pn9, [{row}]",
"add {i}, {i}, #1",
"b 240b",
"241:",
"add {nj}, {nj}, #1",
"b 210b",
"298:",
"add {mi}, {mi}, #1",
"b 200b",
"299:",
"smstop",
".arch_extension nosme2",
ap = in(reg) ap,
bp = in(reg) bp,
c = in(reg) c,
ldc_b = in(reg) ldc_b,
pm = in(reg) pm,
pn = in(reg) pn,
pairs = in(reg) pairs,
q = out(reg) _,
blk = out(reg) _,
step = out(reg) _,
panel_b = out(reg) _,
row_b = out(reg) _,
mi = out(reg) _,
nj = out(reg) _,
kc = out(reg) _,
i = out(reg) _,
t = out(reg) _,
apw = out(reg) _,
bpw = out(reg) _,
ctile = out(reg) _,
row = out(reg) _,
aw = out(reg) _,
bw = out(reg) _,
out("x12") _,
out("z0") _, out("z1") _, out("z2") _, out("z3") _, out("z4") _, out("z5") _,
out("z6") _, out("z7") _, out("z8") _, out("z9") _, out("z10") _, out("z11") _,
out("z12") _, out("z13") _, out("z14") _, out("z15") _, out("z16") _, out("z17") _,
out("z18") _, out("z19") _, out("z20") _, out("z21") _, out("z22") _, out("z23") _,
out("z24") _, out("z25") _, out("z26") _, out("z27") _, out("z28") _, out("z29") _,
out("z30") _, out("z31") _,
out("p0") _, out("p1") _, out("p2") _, out("p3") _, out("p4") _, out("p5") _,
out("p6") _, out("p7") _, out("p8") _, out("p9") _, out("p10") _, out("p11") _,
out("p12") _, out("p13") _, out("p14") _, out("p15") _,
options(nostack),
);
}
};
}
mma_grid_2x2_widen!(mma_bf16_grid_packed, bf16, "bfmopa", ".arch_extension sme2");
mma_grid_2x2_widen!(mma_f16_grid_packed, f16, "fmopa", ".arch_extension sme2\n.arch_extension sme-f16f16");
#[inline]
pub unsafe fn mma_f16_wide<const M: usize, const N: usize, const K: usize>(
a: *const f16,
lda: usize,
b: *const f16,
ldb: usize,
c: *mut f16,
ldc: usize,
) {
let mut at = [[f16::ZERO; M]; K];
for m in 0..M {
let row = a.add(m * lda);
for k in 0..K {
at[k][m] = *row.add(k);
}
}
asm!(
".arch_extension sme2\n.arch_extension sme-f16f16",
"smstart",
"cnth {q}", "whilelt p0.h, xzr, {m}", "whilelt p1.h, xzr, {n}", "whilelt p3.h, {q}, {n}", "whilelt pn9.h, xzr, {n}, vlx2", "mov {i}, xzr",
"40:",
"cmp {i}, {m}",
"b.hs 41f",
"madd {addr}, {i}, {ldc_b}, {c}",
"ld1h {{z0.h-z1.h}}, pn9/z, [{addr}]",
"mov w12, {i:w}",
"mova za0h.h[w12, 0], p1/m, z0.h",
"mova za1h.h[w12, 0], p3/m, z1.h",
"add {i}, {i}, #1",
"b 40b",
"41:",
"mov {k}, xzr",
"42:",
"cmp {k}, {kk}",
"b.hs 43f",
"madd {addr}, {k}, {m_b}, {at}",
"ld1h {{z0.h}}, p0/z, [{addr}]",
"madd {addr}, {k}, {ldb_b}, {b}",
"ld1h {{z2.h-z3.h}}, pn9/z, [{addr}]",
"fmopa za0.h, p0/m, p1/m, z0.h, z2.h",
"fmopa za1.h, p0/m, p3/m, z0.h, z3.h",
"add {k}, {k}, #1",
"b 42b",
"43:",
"mov {i}, xzr",
"44:",
"cmp {i}, {m}",
"b.hs 45f",
"mov w12, {i:w}",
"mova z0.h, p1/m, za0h.h[w12, 0]",
"mova z1.h, p3/m, za1h.h[w12, 0]",
"madd {addr}, {i}, {ldc_b}, {c}",
"st1h {{z0.h-z1.h}}, pn9, [{addr}]",
"add {i}, {i}, #1",
"b 44b",
"45:",
"smstop",
".arch_extension nosme2",
m = in(reg) M,
n = in(reg) N,
kk = in(reg) K,
at = in(reg) at.as_ptr(),
b = in(reg) b,
c = in(reg) c,
ldc_b = in(reg) ldc * 2,
ldb_b = in(reg) ldb * 2,
m_b = in(reg) M * 2,
q = out(reg) _,
i = out(reg) _,
k = out(reg) _,
addr = out(reg) _,
out("x12") _,
out("z0") _, out("z1") _, out("z2") _, out("z3") _, out("z4") _, out("z5") _,
out("z6") _, out("z7") _, out("z8") _, out("z9") _, out("z10") _, out("z11") _,
out("z12") _, out("z13") _, out("z14") _, out("z15") _, out("z16") _, out("z17") _,
out("z18") _, out("z19") _, out("z20") _, out("z21") _, out("z22") _, out("z23") _,
out("z24") _, out("z25") _, out("z26") _, out("z27") _, out("z28") _, out("z29") _,
out("z30") _, out("z31") _,
out("p0") _, out("p1") _, out("p2") _, out("p3") _, out("p4") _, out("p5") _,
out("p6") _, out("p7") _, out("p8") _, out("p9") _, out("p10") _, out("p11") _,
out("p12") _, out("p13") _, out("p14") _, out("p15") _,
options(nostack),
);
}
#[inline]
pub unsafe fn mma_bf16_wide<const M: usize, const N: usize, const K: usize>(
a: *const bf16,
lda: usize,
b: *const bf16,
ldb: usize,
c: *mut f32,
ldc: usize,
) {
let pairs = K.div_ceil(2);
let mut apack = [[[bf16::ZERO; 2]; M]; K];
let mut bpack = [[[bf16::ZERO; 2]; N]; K];
for p in 0..pairs {
let (k0, k1) = (2 * p, 2 * p + 1);
for i in 0..M {
let row = a.add(i * lda);
apack[p][i] = [*row.add(k0), if k1 < K { *row.add(k1) } else { bf16::ZERO }];
}
for j in 0..N {
let r0 = b.add(k0 * ldb);
bpack[p][j] = [*r0.add(j), if k1 < K { *b.add(k1 * ldb).add(j) } else { bf16::ZERO }];
}
}
asm!(
".arch_extension sme2",
"smstart",
"cntw {q}", "lsl {q2}, {q}, #1", "whilelt p1.s, xzr, {n}", "whilelt p3.s, {q}, {n}", "whilelt pn9.s, xzr, {n}, vlx2", "whilelt p4.h, xzr, {m2}", "whilelt p5.h, {q2}, {m2}", "whilelt p6.h, xzr, {n2}", "whilelt p7.h, {q2}, {n2}", "whilelt pn8.h, xzr, {m2}, vlx2", "whilelt pn10.h, xzr, {n2}, vlx2", "mov {i}, xzr",
"50:",
"cmp {i}, {m}",
"b.hs 51f",
"madd {addr}, {i}, {ldc_b}, {c}",
"ld1w {{z4.s-z5.s}}, pn9/z, [{addr}]",
"cmp {i}, {q}",
"b.hs 52f",
"mov w12, {i:w}",
"mova za0h.s[w12, 0], p1/m, z4.s",
"mova za1h.s[w12, 0], p3/m, z5.s",
"b 53f",
"52:",
"sub {t}, {i}, {q}",
"mov w12, {t:w}",
"mova za2h.s[w12, 0], p1/m, z4.s",
"mova za3h.s[w12, 0], p3/m, z5.s",
"53:",
"add {i}, {i}, #1",
"b 50b",
"51:",
"mov {k}, xzr",
"54:",
"cmp {k}, {pairs}",
"b.hs 55f",
"madd {addr}, {k}, {ap_b}, {apack}", "ld1h {{z0.h-z1.h}}, pn8/z, [{addr}]",
"madd {addr}, {k}, {bp_b}, {bpack}", "ld1h {{z2.h-z3.h}}, pn10/z, [{addr}]",
"bfmopa za0.s, p4/m, p6/m, z0.h, z2.h",
"bfmopa za1.s, p4/m, p7/m, z0.h, z3.h",
"bfmopa za2.s, p5/m, p6/m, z1.h, z2.h",
"bfmopa za3.s, p5/m, p7/m, z1.h, z3.h",
"add {k}, {k}, #1",
"b 54b",
"55:",
"mov {i}, xzr",
"56:",
"cmp {i}, {m}",
"b.hs 57f",
"cmp {i}, {q}",
"b.hs 58f",
"mov w12, {i:w}",
"mova z4.s, p1/m, za0h.s[w12, 0]",
"mova z5.s, p3/m, za1h.s[w12, 0]",
"b 59f",
"58:",
"sub {t}, {i}, {q}",
"mov w12, {t:w}",
"mova z4.s, p1/m, za2h.s[w12, 0]",
"mova z5.s, p3/m, za3h.s[w12, 0]",
"59:",
"madd {addr}, {i}, {ldc_b}, {c}",
"st1w {{z4.s-z5.s}}, pn9, [{addr}]",
"add {i}, {i}, #1",
"b 56b",
"57:",
"smstop",
".arch_extension nosme2",
m = in(reg) M,
n = in(reg) N,
m2 = in(reg) 2 * M,
n2 = in(reg) 2 * N,
pairs = in(reg) pairs,
apack = in(reg) apack.as_ptr(),
bpack = in(reg) bpack.as_ptr(),
ap_b = in(reg) 4 * M,
bp_b = in(reg) 4 * N,
c = in(reg) c,
ldc_b = in(reg) ldc * 4,
q = out(reg) _,
q2 = out(reg) _,
i = out(reg) _,
k = out(reg) _,
addr = out(reg) _,
t = out(reg) _,
out("x12") _,
out("z0") _, out("z1") _, out("z2") _, out("z3") _, out("z4") _, out("z5") _,
out("z6") _, out("z7") _, out("z8") _, out("z9") _, out("z10") _, out("z11") _,
out("z12") _, out("z13") _, out("z14") _, out("z15") _, out("z16") _, out("z17") _,
out("z18") _, out("z19") _, out("z20") _, out("z21") _, out("z22") _, out("z23") _,
out("z24") _, out("z25") _, out("z26") _, out("z27") _, out("z28") _, out("z29") _,
out("z30") _, out("z31") _,
out("p0") _, out("p1") _, out("p2") _, out("p3") _, out("p4") _, out("p5") _,
out("p6") _, out("p7") _, out("p8") _, out("p9") _, out("p10") _, out("p11") _,
out("p12") _, out("p13") _, out("p14") _, out("p15") _,
options(nostack),
);
}
#[cfg(feature = "std")]
pub fn is_supported() -> bool {
static CACHE: core::sync::atomic::AtomicU8 = core::sync::atomic::AtomicU8::new(0);
match CACHE.load(core::sync::atomic::Ordering::Relaxed) {
0 => {
let v = is_supported_uncached();
CACHE.store(1 + v as u8, core::sync::atomic::Ordering::Relaxed);
v
}
c => c == 2,
}
}
fn is_supported_uncached() -> bool {
#[cfg(target_os = "linux")]
{
unsafe extern "C" {
fn getauxval(ty: core::ffi::c_ulong) -> core::ffi::c_ulong;
}
const AT_HWCAP2: core::ffi::c_ulong = 26;
const HWCAP2_SME2: core::ffi::c_ulong = 1 << 37;
unsafe { getauxval(AT_HWCAP2) & HWCAP2_SME2 != 0 }
}
#[cfg(target_vendor = "apple")]
{
super::apple_sysctl_flag(c"hw.optional.arm.FEAT_SME2")
}
#[cfg(not(any(target_os = "linux", target_vendor = "apple")))]
{
false
}
}