diff --git a/qemu/target/arm/internals.h b/qemu/target/arm/internals.h index 5bb1ad0e61..622a862bfa 100644 --- a/qemu/target/arm/internals.h +++ b/qemu/target/arm/internals.h @@ -1125,7 +1125,7 @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features, valid |= CPSR_Q; /* V5TE in reality*/ } if ((features >> ARM_FEATURE_V6) & 1) { - valid |= CPSR_E | CPSR_GE; + valid |= CPSR_GE; } if ((features >> ARM_FEATURE_THUMB2) & 1) { valid |= CPSR_IT; diff --git a/tests/unit/test_arm.c b/tests/unit/test_arm.c index 538a91c0e2..e54c1e689f 100644 --- a/tests/unit/test_arm.c +++ b/tests/unit/test_arm.c @@ -956,6 +956,37 @@ static void test_arm_cp15_c1_c0_2(void) OK(uc_close(uc)); } +static void test_arm_be_flags(void) +{ + uc_engine *uc; + /* + subs pc, lr, #4 //<------ mind the 's' == update flags + nop + nop + nop + */ + const uint8_t code[] = { 0xe2, 0x5e, 0xf0, 0x04, 0xe3, 0x20, 0xf0, 0x00, 0xe3, 0x20, 0xf0, 0x00, 0x20, 0xf0, 0x00 }; + uint32_t reg; + + // Initialize emulator in ARM BE mode + OK(uc_open(UC_ARCH_ARM, UC_MODE_ARM|UC_MODE_BIG_ENDIAN, &uc)); + OK(uc_mem_map(uc, code_start, 4096, UC_PROT_ALL)); + OK(uc_mem_write(uc, code_start, code, sizeof(code))); + + // Set LR + reg = code_start + 0x0c; + OK(uc_reg_write(uc, UC_ARM_REG_LR, ®)); + + // Run + OK(uc_emu_start(uc, code_start, code_start + sizeof(code), 0, 3)); + + // Check CPSR.E, should be set + OK(uc_reg_read(uc, UC_ARM_REG_CPSR, ®)); + TEST_CHECK((!!(reg&(1<<9)))==1); + + OK(uc_close(uc)); +} + TEST_LIST = {{"test_arm_nop", test_arm_nop}, {"test_arm_thumb_sub", test_arm_thumb_sub}, {"test_armeb_sub", test_armeb_sub}, @@ -985,4 +1016,5 @@ TEST_LIST = {{"test_arm_nop", test_arm_nop}, {"test_arm_tcg_opcode_cmp", test_arm_tcg_opcode_cmp}, {"test_arm_thumb_tcg_opcode_cmn", test_arm_thumb_tcg_opcode_cmn}, {"test_arm_cp15_c1_c0_2", test_arm_cp15_c1_c0_2}, + {"test_arm_be_flags", test_arm_be_flags}, {NULL, NULL}};