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