diff options
-rw-r--r-- | src/aarch32/assembler-aarch32.cc | 22 | ||||
-rw-r--r-- | src/aarch32/assembler-aarch32.h | 6 | ||||
-rw-r--r-- | test/aarch32/test-disasm-a32.cc | 36 |
3 files changed, 54 insertions, 10 deletions
diff --git a/src/aarch32/assembler-aarch32.cc b/src/aarch32/assembler-aarch32.cc index f3d62753..7e882909 100644 --- a/src/aarch32/assembler-aarch32.cc +++ b/src/aarch32/assembler-aarch32.cc @@ -68,8 +68,6 @@ void Assembler::PerformCheckIT(Condition condition) { VIXL_ASSERT(IsUsingA32() || condition.Is(al)); } else { VIXL_ASSERT(condition.Is(first_condition_)); - first_condition_ = - Condition((first_condition_.GetCondition() & 0xe) | (it_mask_ >> 3)); // For A32, AdavanceIT() is not called by the assembler. We must call it // in order to check that IT instructions are used consistently with // the following conditional instructions. @@ -3996,7 +3994,8 @@ void Assembler::crc32b(Condition cond, Register rd, Register rn, Register rm) { CheckIT(cond); if (IsUsingT32()) { // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; T1 - if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { + if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || + AllowUnpredictable())) { EmitT32_32(0xfac0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode()); AdvanceIT(); @@ -4019,7 +4018,8 @@ void Assembler::crc32cb(Condition cond, Register rd, Register rn, Register rm) { CheckIT(cond); if (IsUsingT32()) { // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; T1 - if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { + if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || + AllowUnpredictable())) { EmitT32_32(0xfad0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode()); AdvanceIT(); @@ -4042,7 +4042,8 @@ void Assembler::crc32ch(Condition cond, Register rd, Register rn, Register rm) { CheckIT(cond); if (IsUsingT32()) { // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; T1 - if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { + if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || + AllowUnpredictable())) { EmitT32_32(0xfad0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode()); AdvanceIT(); @@ -4065,7 +4066,8 @@ void Assembler::crc32cw(Condition cond, Register rd, Register rn, Register rm) { CheckIT(cond); if (IsUsingT32()) { // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; T1 - if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { + if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || + AllowUnpredictable())) { EmitT32_32(0xfad0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode()); AdvanceIT(); @@ -4088,7 +4090,8 @@ void Assembler::crc32h(Condition cond, Register rd, Register rn, Register rm) { CheckIT(cond); if (IsUsingT32()) { // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; T1 - if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { + if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || + AllowUnpredictable())) { EmitT32_32(0xfac0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode()); AdvanceIT(); @@ -4111,7 +4114,8 @@ void Assembler::crc32w(Condition cond, Register rd, Register rn, Register rm) { CheckIT(cond); if (IsUsingT32()) { // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; T1 - if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { + if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || + AllowUnpredictable())) { EmitT32_32(0xfac0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode()); AdvanceIT(); @@ -4509,7 +4513,7 @@ void Assembler::hvc(Condition cond, uint32_t imm) { CheckIT(cond); if (IsUsingT32()) { // HVC{<q>} {#}<imm16> ; T1 - if ((imm <= 65535)) { + if ((imm <= 65535) && (OutsideITBlock() || AllowUnpredictable())) { EmitT32_32(0xf7e08000U | (imm & 0xfff) | ((imm & 0xf000) << 4)); AdvanceIT(); return; diff --git a/src/aarch32/assembler-aarch32.h b/src/aarch32/assembler-aarch32.h index 9644a882..b748086f 100644 --- a/src/aarch32/assembler-aarch32.h +++ b/src/aarch32/assembler-aarch32.h @@ -59,7 +59,11 @@ class Assembler : public internal::AssemblerBase { #ifdef VIXL_DEBUG void PerformCheckIT(Condition condition); #endif - void AdvanceIT() { it_mask_ = (it_mask_ << 1) & 0xf; } + void AdvanceIT() { + first_condition_ = + Condition((first_condition_.GetCondition() & 0xe) | (it_mask_ >> 3)); + it_mask_ = (it_mask_ << 1) & 0xf; + } // Virtual, in order to be overridden by the MacroAssembler, which needs to // notify the pool manager. virtual void BindHelper(Label* label); diff --git a/test/aarch32/test-disasm-a32.cc b/test/aarch32/test-disasm-a32.cc index 99ebe245..2bb22aab 100644 --- a/test/aarch32/test-disasm-a32.cc +++ b/test/aarch32/test-disasm-a32.cc @@ -1632,6 +1632,7 @@ TEST(macro_assembler_too_large_immediate) { CLEANUP(); } + TEST(macro_assembler_Cbz) { SETUP(); @@ -1698,6 +1699,41 @@ TEST(macro_assembler_Cbz) { } +#ifdef VIXL_NEGATIVE_TESTING +TEST(assembler_crc_negative) { + SETUP(); + + ExactAssemblyScope scope(&masm, 2, CodeBufferCheckScope::kMaximumSize); + + masm.it(eq); + + MUST_FAIL_TEST_T32(crc32b(eq, r0, r1, r2), "Unpredictable instruction.\n"); + MUST_FAIL_TEST_T32(crc32cb(eq, r0, r1, r2), "Unpredictable instruction.\n"); + MUST_FAIL_TEST_T32(crc32ch(eq, r0, r1, r2), "Unpredictable instruction.\n"); + MUST_FAIL_TEST_T32(crc32cw(eq, r0, r1, r2), "Unpredictable instruction.\n"); + MUST_FAIL_TEST_T32(crc32h(eq, r0, r1, r2), "Unpredictable instruction.\n"); + MUST_FAIL_TEST_T32(crc32w(eq, r0, r1, r2), "Unpredictable instruction.\n"); + + CLEANUP(); +} +#endif + + +#ifdef VIXL_NEGATIVE_TESTING +TEST(assembler_hvc_negative) { + SETUP(); + + ExactAssemblyScope scope(&masm, 2, CodeBufferCheckScope::kMaximumSize); + + masm.it(eq); + + MUST_FAIL_TEST_T32(hvc(eq, 0), "Unpredictable instruction.\n"); + + CLEANUP(); +} +#endif + + TEST(assembler_vldm_vstm_negative) { SETUP(); |