From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JizMf-0001aP-NK for qemu-devel@nongnu.org; Mon, 07 Apr 2008 17:58:57 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JizMa-0001a5-6A for qemu-devel@nongnu.org; Mon, 07 Apr 2008 17:58:56 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JizMa-0001Zy-3J for qemu-devel@nongnu.org; Mon, 07 Apr 2008 17:58:52 -0400 Received: from mtaout03-winn.ispmail.ntl.com ([81.103.221.49]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1JizMZ-0000BY-GO for qemu-devel@nongnu.org; Mon, 07 Apr 2008 17:58:51 -0400 Received: from aamtaout03-winn.ispmail.ntl.com ([81.103.221.35]) by mtaout03-winn.ispmail.ntl.com with ESMTP id <20080407220232.PJHP11232.mtaout03-winn.ispmail.ntl.com@aamtaout03-winn.ispmail.ntl.com> for ; Mon, 7 Apr 2008 23:02:32 +0100 Received: from miranda.arrow ([213.107.26.151]) by aamtaout03-winn.ispmail.ntl.com with ESMTP id <20080407220507.EWKM26699.aamtaout03-winn.ispmail.ntl.com@miranda.arrow> for ; Mon, 7 Apr 2008 23:05:07 +0100 Received: from sdb by miranda.arrow with local (Exim 4.63) (envelope-from ) id 1JizMS-00068N-CE for qemu-devel@nongnu.org; Mon, 07 Apr 2008 22:58:44 +0100 Date: Mon, 7 Apr 2008 22:58:44 +0100 From: Stuart Brady Subject: Re: [Qemu-devel] Instruction trace for ARM target Message-ID: <20080407215844.GA23472@miranda.arrow> References: <1207164499.9736.32.camel@goffart-laptop> <20080403141313.GA15754@miranda.arrow> <1207321851.6968.12.camel@goffart-laptop> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1207321851.6968.12.camel@goffart-laptop> 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 On Fri, Apr 04, 2008 at 05:10:51PM +0200, Klaus Goffart wrote: > Am Donnerstag, den 03.04.2008, 15:13 +0100 schrieb Stuart Brady: > > Calling gen_op_dump_pc() adds the code > > needed to call helper_dump_pc() to the translation block that is > > currently being generated. > > Just to make sure I picked it up right. The call of gen_op_dump_pc() > during translation adds the op_dump_pc() to the generated micro > instruction stream of the translation block. That's right. > When the TB is executed, the op_dump_pc() operation is called Well, op_dump_pc() is never called, as its code is instead copied into the generated TB, but I think that's what you meant anyway. > calling helper_dump_pc() with PARAM1. PARAM1 in op_dump_pc() is the > first parameter passed to gen_op_dump_pc(), i.e. s->pc. So the pc > values to be traced are included into the micro instruction stream > and printed at execution time, right? That's correct. It would be better to avoid an immediate load of the emulated PC for each instruction -- with dyngen, doing so would not be very practical, as we'd really prefer to hold the emulated PC in an extra register -- but with TCG, that shouldn't really be a problem. > > If by 'actual pc value', you mean the PC in the CPUState ('env'), then > > I'm very surprised that this would appear to produce correct output. > > No, my helper_dump_pc() looks like this: > > void helper_dump_pc(target_ulong pc) > { > if (logfile) > { > fputc('#', logfile); > fwrite(&pc, sizeof(pc), 1, logfile); > insn = ldl_code(pc); > fwrite(&insn, sizeof(insn), 1, logfile); > } > } Okay, that looks roughly correct -- although if you plan for anyone else to use that code, it would be preferable to produce the same output on big-endian and little-endian machines. > > Well, you'd certainly have to generate extra ops to mark instructions as > > executed, as instruction fetches occur at translation time. > > OK, so conditional instructions are skipped by a jump to the next > instruction if the condition code fails. This is what I found in the > documentation. In the code it looks like this jump is also a micro > operation. Therefore, an op should be placed right after the jump_op > that marks the last dumped instruction as executed. Is this what you > meant? Actually, I'd forgotten about ARM's conditional execution, and was talking about conditional branches. I expect that translated code can still be generated after a conditional branch, but never executed, as a result of that branch always (or perhaps never) being taken. What I meant was that you cannot mark instructions as executed by adding extra code to ldl_code(), but thanks to conditional execution, that was already rather more obvious than I had realised. Placing the dump_pc op after the jump op sounds correct, but you'll also need to deal with unconditional instructions, and conditional branches. Bear in mind that the program counter is incremented after ldl_code() is called, though. I wonder, does a branch count as 'executed' if and only if it is taken? What about branches with static 'taken' or 'not taken' prediction? Cheers, -- Stuart Brady