aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Belliard <vincent.belliard@arm.com>2017-09-08 09:49:29 -0700
committerVincent Belliard <vincent.belliard@arm.com>2017-09-13 18:07:17 +0000
commit8ecc789f1bdda97c006ce4e8e075b9ca1c964dfb (patch)
tree6aab265666b851f258c60b9f83f2852f3b5cebfc
parentc5542c87cf8d412f48a72200080486999ce6b9a3 (diff)
Check unpredictable conditions for vstr.
/r/4070/ Change-Id: I39981e2009e09ae53dd9302300b3772ebdb09ee1
-rw-r--r--src/aarch32/assembler-aarch32.cc6
-rw-r--r--test/aarch32/test-disasm-a32.cc14
2 files changed, 18 insertions, 2 deletions
diff --git a/src/aarch32/assembler-aarch32.cc b/src/aarch32/assembler-aarch32.cc
index f8b5d6b9..c8337acc 100644
--- a/src/aarch32/assembler-aarch32.cc
+++ b/src/aarch32/assembler-aarch32.cc
@@ -27161,7 +27161,8 @@ void Assembler::vstr(Condition cond,
if (IsUsingT32()) {
// VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
- ((offset % 4) == 0) && operand.IsOffset()) {
+ ((offset % 4) == 0) && operand.IsOffset() &&
+ (!rn.IsPC() || AllowUnpredictable())) {
uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
uint32_t offset_ = abs(offset) >> 2;
EmitT32_32(0xed000b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
@@ -27196,7 +27197,8 @@ void Assembler::vstr(Condition cond,
if (IsUsingT32()) {
// VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
- ((offset % 4) == 0) && operand.IsOffset()) {
+ ((offset % 4) == 0) && operand.IsOffset() &&
+ (!rn.IsPC() || AllowUnpredictable())) {
uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
uint32_t offset_ = abs(offset) >> 2;
EmitT32_32(0xed000a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
diff --git a/test/aarch32/test-disasm-a32.cc b/test/aarch32/test-disasm-a32.cc
index 052f9317..98f6c75d 100644
--- a/test/aarch32/test-disasm-a32.cc
+++ b/test/aarch32/test-disasm-a32.cc
@@ -1871,6 +1871,20 @@ TEST(macro_assembler_A32_Vstr_s) { TEST_VMEMOP(Vstr, "vstr ", s3); }
#undef TEST_VMEMOP
+TEST(assembler_vstr_negative) {
+ SETUP();
+
+ ExactAssemblyScope scope(&masm, 8, CodeBufferCheckScope::kMaximumSize);
+
+ MUST_FAIL_TEST_T32(vstr(s0, MemOperand(pc, 0)),
+ "Unpredictable instruction.\n");
+
+ MUST_FAIL_TEST_T32(vstr(d0, MemOperand(pc, 0)),
+ "Unpredictable instruction.\n");
+
+ CLEANUP();
+}
+
TEST(macro_assembler_Vldr_Vstr_negative) {
SETUP();