From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1DNLHh-0004GO-Vw for qemu-devel@nongnu.org; Sun, 17 Apr 2005 21:42:46 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1DNLHh-0004GA-E4 for qemu-devel@nongnu.org; Sun, 17 Apr 2005 21:42:45 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1DNLC5-0002ly-2J for qemu-devel@nongnu.org; Sun, 17 Apr 2005 21:36:57 -0400 Received: from [65.74.133.9] (helo=mail.codesourcery.com) by monty-python.gnu.org with esmtp (TLS-1.0:DHE_RSA_3DES_EDE_CBC_SHA:24) (Exim 4.34) id 1DNKqd-0004LP-7n for qemu-devel@nongnu.org; Sun, 17 Apr 2005 21:14:47 -0400 From: Paul Brook Date: Mon, 18 Apr 2005 02:13:16 +0100 MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_smwYC+TEbu4WlRZ" Message-Id: <200504180213.16773.paul@codesourcery.com> Subject: [Qemu-devel] [patch] Arm singlestep mode. Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org --Boundary-00=_smwYC+TEbu4WlRZ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline The attached patch implements single-step mode for arm targets. It doesn't stop when the instruction condition fails, but I'll fix that later. Paul --Boundary-00=_smwYC+TEbu4WlRZ Content-Type: text/x-diff; charset="us-ascii"; name="patch.qemu_step_arm" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="patch.qemu_step_arm" Index: translate.c =================================================================== RCS file: /cvsroot/qemu/qemu/target-arm/translate.c,v retrieving revision 1.20 diff -u -p -r1.20 translate.c --- translate.c 17 Apr 2005 19:16:13 -0000 1.20 +++ translate.c 18 Apr 2005 01:08:50 -0000 @@ -33,6 +33,7 @@ typedef struct DisasContext { target_ulong pc; int is_jmp; struct TranslationBlock *tb; + int singlestep_enabled; } DisasContext; #define DISAS_JUMP_NEXT 4 @@ -888,6 +889,18 @@ static int disas_vfp_insn(CPUState * env return 0; } +static inline void gen_jmp (DisasContext *s, uint32_t dest) +{ + if (__builtin_expect(s->singlestep_enabled, 0)) { + /* An indirect jump so that we still trigger the debug exception. */ + gen_op_movl_T0_im(dest); + gen_bx(s); + } else { + gen_op_jmp((long)s->tb, dest); + s->is_jmp = DISAS_TB_JUMP; + } +} + static void disas_arm_insn(CPUState * env, DisasContext *s) { unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh; @@ -1469,8 +1482,7 @@ static void disas_arm_insn(CPUState * en } offset = (((int32_t)insn << 8) >> 8); val += (offset << 2) + 4; - gen_op_jmp((long)s->tb, val); - s->is_jmp = DISAS_TB_JUMP; + gen_jmp(s, val); } break; case 0xc: @@ -1957,8 +1969,7 @@ static void disas_thumb_insn(DisasContex val = (uint32_t)s->pc; offset = ((int32_t)insn << 24) >> 24; val += (offset << 1) + 2; - gen_op_jmp((long)s->tb, val); - s->is_jmp = DISAS_TB_JUMP; + gen_jmp(s, val); break; case 14: @@ -1968,8 +1979,7 @@ static void disas_thumb_insn(DisasContex val = (uint32_t)s->pc; offset = ((int32_t)insn << 21) >> 21; val += (offset << 1) + 2; - gen_op_jmp((long)s->tb, val); - s->is_jmp = DISAS_TB_JUMP; + gen_jmp(s, val); break; case 15: @@ -1985,8 +1995,7 @@ static void disas_thumb_insn(DisasContex val += offset; if (insn & (1 << 11)) { /* bl */ - gen_op_jmp((long)s->tb, val); - s->is_jmp = DISAS_TB_JUMP; + gen_jmp(s, val); } else { /* blx */ gen_op_movl_T0_im(val); @@ -2024,6 +2033,7 @@ static inline int gen_intermediate_code_ dc->is_jmp = DISAS_NEXT; dc->pc = pc_start; + dc->singlestep_enabled = env->singlestep_enabled; lj = -1; do { if (env->nb_breakpoints > 0) { @@ -2054,21 +2064,30 @@ static inline int gen_intermediate_code_ } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && !env->singlestep_enabled && (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32)); - switch(dc->is_jmp) { - case DISAS_JUMP_NEXT: - case DISAS_NEXT: - gen_op_jmp((long)dc->tb, (long)dc->pc); - break; - default: - case DISAS_JUMP: - case DISAS_UPDATE: - /* indicate that the hash table must be used to find the next TB */ - gen_op_movl_T0_0(); - gen_op_exit_tb(); - break; - case DISAS_TB_JUMP: - /* nothing more to generate */ - break; + if (__builtin_expect(env->singlestep_enabled, 0)) { + /* Make sure the pc is updated, and raise a debug exception. */ + if (dc->is_jmp == DISAS_NEXT || dc->is_jmp == DISAS_JUMP_NEXT) { + gen_op_movl_T0_im((long)dc->pc); + gen_op_movl_reg_TN[0][15](); + } + gen_op_debug(); + } else { + switch(dc->is_jmp) { + case DISAS_JUMP_NEXT: + case DISAS_NEXT: + gen_op_jmp((long)dc->tb, (long)dc->pc); + break; + default: + case DISAS_JUMP: + case DISAS_UPDATE: + /* indicate that the hash table must be used to find the next TB */ + gen_op_movl_T0_0(); + gen_op_exit_tb(); + break; + case DISAS_TB_JUMP: + /* nothing more to generate */ + break; + } } *gen_opc_ptr = INDEX_op_end; --Boundary-00=_smwYC+TEbu4WlRZ--