Fix Operand::IsPlainRegister.
- Operand(w0, UXTW) is not a plain register in a 64-bit context. The Operand
class doesn't know the context, so it must return false for UXTW and SXTW.
- Operand(x0, UXTX, 1) is not a plain register.
This patch also adds tests to check and demonstrate the behaviour.
Change-Id: I85a56a2d9d9ec6fce814f0e57a4f87dd7f21fd6c
diff --git a/src/aarch64/operands-aarch64.cc b/src/aarch64/operands-aarch64.cc
index 55aadb6..2036461 100644
--- a/src/aarch64/operands-aarch64.cc
+++ b/src/aarch64/operands-aarch64.cc
@@ -332,8 +332,14 @@
// No-op shifts.
((shift_ != NO_SHIFT) && (shift_amount_ == 0)) ||
// No-op extend operations.
- ((extend_ == UXTX) || (extend_ == SXTX) ||
- (reg_.IsW() && ((extend_ == UXTW) || (extend_ == SXTW)))));
+ // We can't include [US]XTW here without knowing more about the
+ // context; they are only no-ops for 32-bit operations.
+ //
+ // For example, this operand could be replaced with w1:
+ // __ Add(w0, w0, Operand(w1, UXTW));
+ // However, no plain register can replace it in this context:
+ // __ Add(x0, x0, Operand(w1, UXTW));
+ (((extend_ == UXTX) || (extend_ == SXTX)) && (shift_amount_ == 0)));
}
diff --git a/test/aarch64/test-assembler-aarch64.cc b/test/aarch64/test-assembler-aarch64.cc
index 50e7800..f083b35 100644
--- a/test/aarch64/test-assembler-aarch64.cc
+++ b/test/aarch64/test-assembler-aarch64.cc
@@ -23316,5 +23316,44 @@
}
+TEST(is_plain_register) {
+ SETUP();
+
+ VIXL_CHECK(Operand(x0).IsPlainRegister());
+ VIXL_CHECK(Operand(x1, LSL, 0).IsPlainRegister());
+ VIXL_CHECK(Operand(x2, LSR, 0).IsPlainRegister());
+ VIXL_CHECK(Operand(x3, ASR, 0).IsPlainRegister());
+ VIXL_CHECK(Operand(x4, ROR, 0).IsPlainRegister());
+ VIXL_CHECK(Operand(x5, UXTX).IsPlainRegister());
+ VIXL_CHECK(Operand(x6, SXTX).IsPlainRegister());
+ VIXL_CHECK(Operand(w7).IsPlainRegister());
+ VIXL_CHECK(Operand(w8, LSL, 0).IsPlainRegister());
+ VIXL_CHECK(Operand(w9, LSR, 0).IsPlainRegister());
+ VIXL_CHECK(Operand(w10, ASR, 0).IsPlainRegister());
+ VIXL_CHECK(Operand(w11, ROR, 0).IsPlainRegister());
+
+ VIXL_CHECK(!Operand(x0, LSL, 1).IsPlainRegister());
+ VIXL_CHECK(!Operand(x1, LSR, 2).IsPlainRegister());
+ VIXL_CHECK(!Operand(x2, ASR, 3).IsPlainRegister());
+ VIXL_CHECK(!Operand(x3, ROR, 4).IsPlainRegister());
+ VIXL_CHECK(!Operand(x5, UXTX, 1).IsPlainRegister());
+ VIXL_CHECK(!Operand(x6, SXTX, 2).IsPlainRegister());
+ VIXL_CHECK(!Operand(w7, LSL, 1).IsPlainRegister());
+ VIXL_CHECK(!Operand(w8, LSR, 2).IsPlainRegister());
+ VIXL_CHECK(!Operand(w9, ASR, 3).IsPlainRegister());
+ VIXL_CHECK(!Operand(w10, ROR, 4).IsPlainRegister());
+ VIXL_CHECK(!Operand(w11, UXTB).IsPlainRegister());
+ VIXL_CHECK(!Operand(w12, SXTB).IsPlainRegister());
+ VIXL_CHECK(!Operand(w13, UXTH).IsPlainRegister());
+ VIXL_CHECK(!Operand(w14, SXTH).IsPlainRegister());
+ // UXTW and SXTW could be treated as plain registers in 32-bit contexts, but
+ // the Operand class doesn't know the context so it has to return false.
+ VIXL_CHECK(!Operand(w15, UXTW).IsPlainRegister());
+ VIXL_CHECK(!Operand(w16, SXTW).IsPlainRegister());
+
+ TEARDOWN();
+}
+
+
} // namespace aarch64
} // namespace vixl