Fix BIC macro assembler definition to be non-commutative (#66)
Without this patch, the macro assembler freely rearranges the registers
passed for the BIC instruction to ensure the first source register is
the same as the destination register, which it does because the
instruction is considered to be commutative. However, the
bit-clear instruction is non-commutative as it is the second source
register which is negated, and so these should not be simply re-arranged
without additional logic.
Instead, define Bic to be non-commutative as part of
VIXL_SVE_NONCOMM_ARITH_ZPZZ_LIST.
Modify the tests for SVE predicated bit-clears accordingly.
diff --git a/src/aarch64/macro-assembler-aarch64.h b/src/aarch64/macro-assembler-aarch64.h
index af9aa52..f0663ee 100644
--- a/src/aarch64/macro-assembler-aarch64.h
+++ b/src/aarch64/macro-assembler-aarch64.h
@@ -3093,7 +3093,6 @@
#define SVE_3VREG_COMMUTATIVE_MACRO_LIST(V) \
V(add, Add) \
V(and_, And) \
- V(bic, Bic) \
V(eor, Eor) \
V(mul, Mul) \
V(orr, Orr) \
@@ -3609,6 +3608,10 @@
MovprfxHelperScope guard(this, zd, pg, zn);
asrd(zd, pg, zd, shift);
}
+ void Bic(const ZRegister& zd,
+ const PRegisterM& pg,
+ const ZRegister& zn,
+ const ZRegister& zm);
void Bic(const PRegisterWithLaneSize& pd,
const PRegisterZ& pg,
const PRegisterWithLaneSize& pn,
diff --git a/src/aarch64/macro-assembler-sve-aarch64.cc b/src/aarch64/macro-assembler-sve-aarch64.cc
index 6bf5607..208f67e 100644
--- a/src/aarch64/macro-assembler-sve-aarch64.cc
+++ b/src/aarch64/macro-assembler-sve-aarch64.cc
@@ -627,6 +627,7 @@
// non-commutative and no reversed form is provided.
#define VIXL_SVE_NONCOMM_ARITH_ZPZZ_LIST(V) \
V(Addp, addp) \
+ V(Bic, bic) \
V(Faddp, faddp) \
V(Fmaxnmp, fmaxnmp) \
V(Fminnmp, fminnmp) \
diff --git a/test/aarch64/test-assembler-sve-aarch64.cc b/test/aarch64/test-assembler-sve-aarch64.cc
index b7c7758..806a7c5 100644
--- a/test/aarch64/test-assembler-sve-aarch64.cc
+++ b/test/aarch64/test-assembler-sve-aarch64.cc
@@ -4483,7 +4483,7 @@
SVE_SETUP_WITH_FEATURES(CPUFeatures::kSVE);
START();
- ZRegister src_a = z31.WithLaneSize(lane_size_in_bits);
+ ZRegister src_a = z30.WithLaneSize(lane_size_in_bits);
ZRegister src_b = z27.WithLaneSize(lane_size_in_bits);
InsrHelper(&masm, src_a, zn_inputs);
InsrHelper(&masm, src_b, zm_inputs);
diff --git a/test/aarch64/test-disasm-sve-aarch64.cc b/test/aarch64/test-disasm-sve-aarch64.cc
index 933e808..c6b7e31 100644
--- a/test/aarch64/test-disasm-sve-aarch64.cc
+++ b/test/aarch64/test-disasm-sve-aarch64.cc
@@ -2381,7 +2381,9 @@
COMPARE_MACRO(Bic(z17.VnB(), p7.Merging(), z17.VnB(), z10.VnB()),
"bic z17.b, p7/m, z17.b, z10.b");
COMPARE_MACRO(Bic(z17.VnS(), p7.Merging(), z10.VnS(), z17.VnS()),
- "bic z17.s, p7/m, z17.s, z10.s");
+ "mov z31.d, z17.d\n"
+ "movprfx z17.s, p7/m, z10.s\n"
+ "bic z17.s, p7/m, z17.s, z31.s");
COMPARE_MACRO(Bic(z17.VnD(), p7.Merging(), z7.VnD(), z27.VnD()),
"movprfx z17.d, p7/m, z7.d\n"
"bic z17.d, p7/m, z17.d, z27.d");