Commit 2ae23e75045095151c3b754e7e4e36b23f053264

Authored by pbrook
1 parent 3b7f5d47

Fix Arm msr spsr bug.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1761 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 11 additions and 8 deletions
target-arm/translate.c
@@ -1033,7 +1033,7 @@ static inline void gen_mulxy(int x, int y) @@ -1033,7 +1033,7 @@ static inline void gen_mulxy(int x, int y)
1033 } 1033 }
1034 1034
1035 /* Return the mask of PSR bits set by a MSR instruction. */ 1035 /* Return the mask of PSR bits set by a MSR instruction. */
1036 -static uint32_t msr_mask(DisasContext *s, int flags) { 1036 +static uint32_t msr_mask(DisasContext *s, int flags, int spsr) {
1037 uint32_t mask; 1037 uint32_t mask;
1038 1038
1039 mask = 0; 1039 mask = 0;
@@ -1045,8 +1045,11 @@ static uint32_t msr_mask(DisasContext *s, int flags) { @@ -1045,8 +1045,11 @@ static uint32_t msr_mask(DisasContext *s, int flags) {
1045 mask |= 0xff0000; 1045 mask |= 0xff0000;
1046 if (flags & (1 << 3)) 1046 if (flags & (1 << 3))
1047 mask |= 0xff000000; 1047 mask |= 0xff000000;
1048 - /* Mask out undefined bits and state bits. */  
1049 - mask &= 0xf89f03df; 1048 + /* Mask out undefined bits. */
  1049 + mask &= 0xf90f03ff;
  1050 + /* Mask out state bits. */
  1051 + if (!spsr)
  1052 + mask &= ~0x01000020;
1050 /* Mask out privileged bits. */ 1053 /* Mask out privileged bits. */
1051 if (IS_USER(s)) 1054 if (IS_USER(s))
1052 mask &= 0xf80f0200; 1055 mask &= 0xf80f0200;
@@ -1138,8 +1141,8 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -1138,8 +1141,8 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
1138 if (shift) 1141 if (shift)
1139 val = (val >> shift) | (val << (32 - shift)); 1142 val = (val >> shift) | (val << (32 - shift));
1140 gen_op_movl_T0_im(val); 1143 gen_op_movl_T0_im(val);
1141 - if (gen_set_psr_T0(s, msr_mask(s, (insn >> 16) & 0xf),  
1142 - (insn & (1 << 22)) != 0)) 1144 + i = ((insn & (1 << 22)) != 0);
  1145 + if (gen_set_psr_T0(s, msr_mask(s, (insn >> 16) & 0xf, i), i))
1143 goto illegal_op; 1146 goto illegal_op;
1144 } else if ((insn & 0x0f900000) == 0x01000000 1147 } else if ((insn & 0x0f900000) == 0x01000000
1145 && (insn & 0x00000090) != 0x00000090) { 1148 && (insn & 0x00000090) != 0x00000090) {
@@ -1152,11 +1155,11 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -1152,11 +1155,11 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
1152 if (op1 & 1) { 1155 if (op1 & 1) {
1153 /* PSR = reg */ 1156 /* PSR = reg */
1154 gen_movl_T0_reg(s, rm); 1157 gen_movl_T0_reg(s, rm);
1155 - if (gen_set_psr_T0(s, msr_mask(s, (insn >> 16) & 0xf),  
1156 - (op1 & 2) != 0)) 1158 + i = ((op1 & 2) != 0);
  1159 + if (gen_set_psr_T0(s, msr_mask(s, (insn >> 16) & 0xf, i), i))
1157 goto illegal_op; 1160 goto illegal_op;
1158 } else { 1161 } else {
1159 - /* reg = CPSR */ 1162 + /* reg = PSR */
1160 rd = (insn >> 12) & 0xf; 1163 rd = (insn >> 12) & 0xf;
1161 if (op1 & 2) { 1164 if (op1 & 2) {
1162 if (IS_USER(s)) 1165 if (IS_USER(s))