Commit 06c949e62a098f97bd68a7382eb1953898a11e09
1 parent
0240ded8
Implement Arm BKPT instruction.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1740 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
39 additions
and
5 deletions
linux-user/main.c
... | ... | @@ -358,14 +358,27 @@ void cpu_loop(CPUARMState *env) |
358 | 358 | } |
359 | 359 | break; |
360 | 360 | case EXCP_SWI: |
361 | + case EXCP_BKPT: | |
361 | 362 | { |
362 | 363 | /* system call */ |
363 | - if (env->thumb) { | |
364 | - insn = lduw((void *)(env->regs[15] - 2)); | |
365 | - n = insn & 0xff; | |
364 | + if (trapnr == EXCP_BKPT) { | |
365 | + if (env->thumb) { | |
366 | + insn = lduw((void *)(env->regs[15])); | |
367 | + n = insn & 0xff; | |
368 | + env->regs[15] += 2; | |
369 | + } else { | |
370 | + insn = ldl((void *)(env->regs[15])); | |
371 | + n = (insn & 0xf) | ((insn >> 4) & 0xff0); | |
372 | + env->regs[15] += 4; | |
373 | + } | |
366 | 374 | } else { |
367 | - insn = ldl((void *)(env->regs[15] - 4)); | |
368 | - n = insn & 0xffffff; | |
375 | + if (env->thumb) { | |
376 | + insn = lduw((void *)(env->regs[15] - 2)); | |
377 | + n = insn & 0xff; | |
378 | + } else { | |
379 | + insn = ldl((void *)(env->regs[15] - 4)); | |
380 | + n = insn & 0xffffff; | |
381 | + } | |
369 | 382 | } |
370 | 383 | |
371 | 384 | if (n == ARM_NR_cacheflush) { | ... | ... |
target-arm/cpu.h
target-arm/helper.c
target-arm/op.c
... | ... | @@ -885,6 +885,12 @@ void OPPROTO op_wfi(void) |
885 | 885 | cpu_loop_exit(); |
886 | 886 | } |
887 | 887 | |
888 | +void OPPROTO op_bkpt(void) | |
889 | +{ | |
890 | + env->exception_index = EXCP_BKPT; | |
891 | + cpu_loop_exit(); | |
892 | +} | |
893 | + | |
888 | 894 | /* VFP support. We follow the convention used for VFP instrunctions: |
889 | 895 | Single precition routines have a "s" suffix, double precision a |
890 | 896 | "d" suffix. */ | ... | ... |
target-arm/translate.c
... | ... | @@ -1217,6 +1217,12 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
1217 | 1217 | gen_op_addl_T0_T1_saturate(); |
1218 | 1218 | gen_movl_reg_T0(s, rd); |
1219 | 1219 | break; |
1220 | + case 7: /* bkpt */ | |
1221 | + gen_op_movl_T0_im((long)s->pc - 4); | |
1222 | + gen_op_movl_reg_TN[0][15](); | |
1223 | + gen_op_bkpt(); | |
1224 | + s->is_jmp = DISAS_JUMP; | |
1225 | + break; | |
1220 | 1226 | case 0x8: /* signed multiply */ |
1221 | 1227 | case 0xa: |
1222 | 1228 | case 0xc: |
... | ... | @@ -2183,6 +2189,13 @@ static void disas_thumb_insn(DisasContext *s) |
2183 | 2189 | gen_bx(s); |
2184 | 2190 | break; |
2185 | 2191 | |
2192 | + case 0xe: /* bkpt */ | |
2193 | + gen_op_movl_T0_im((long)s->pc - 2); | |
2194 | + gen_op_movl_reg_TN[0][15](); | |
2195 | + gen_op_bkpt(); | |
2196 | + s->is_jmp = DISAS_JUMP; | |
2197 | + break; | |
2198 | + | |
2186 | 2199 | default: |
2187 | 2200 | goto undef; |
2188 | 2201 | } | ... | ... |