Re: [hatari-devel] Code execution discontinuities and detecting them?

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


Hi,

On keskiviikko 27 helmikuu 2013, Eero Tamminen wrote:
> On keskiviikko 27 helmikuu 2013, Nicolas Pomarède wrote:
> > Le 27/02/2013 15:50, Eero Tamminen a écrit :
> > > That is missing family enumation for the BRA instruction.
> > > Could you add it for old and WinUAE CPU cores?
> > 
> > No, I can't add it, it's really related to the cpu emulation in
> > cpuemu.c, where BRA itself doesn't exist (BRA is a special case of Bcc
> > where cc is always true)
> > 
> > For this case, you would need to check OpcodeFamily == i_Bcc and then
> > check the condition bits yourself in the current opcode.
> 
> If it's included into i_Bcc, that's fine.

Attached is a patch to do the change which adds also FPU branch
& trap detection.  But I cannot apply it as default WinUAE core
doesn't support OpcodeFamily. :-/


	- Eero
diff -r 0fa9f7d4d7f0 src/debug/profile.c
--- a/src/debug/profile.c	Wed Feb 27 13:23:25 2013 +0200
+++ b/src/debug/profile.c	Wed Feb 27 22:49:50 2013 +0200
@@ -757,39 +758,41 @@
 	return cpu_profile.enabled;
 }
 
-static calltype_t cpu_opcode_type(Uint16 opcode, Uint32 prev_pc, Uint32 pc)
+/* return branch type based on caller instruction type */
+static calltype_t cpu_opcode_type(int prev_family, Uint32 prev_pc, Uint32 pc)
 {
-	/* JSR, BSR (should be most common) */
-	if ((opcode & 0xffc0) == 0x4e80 ||
-	    (opcode & 0xff00) == 0x6100) {
+	switch (prev_family) {
+
+	case i_JSR:
+	case i_BSR:
 		return CALL_SUBROUTINE;
-	}
-	/* RTS, RTR, RTD */
-	if (opcode == 0x4e75 ||
-	    opcode == 0x4e77 ||
-	    opcode == 0x4e74) {
+
+	case i_RTS:
+	case i_RTR:
+	case i_RTD:
 		return CALL_SUBRETURN;
-	}
-	/* TRAP, TRAPV, STOP, ILLEGAL, CHK, BKPT */
-	if ((opcode & 0xfff0) == 0x4e40 ||
-	     opcode == 0x4e76 ||
-	     opcode == 0x4afc ||
-	     opcode == 0x4e72 ||
-	    (opcode & 0xf1c0) == 0x4180 ||
-	    (opcode & 0xfff8) == 0x4848) {
+
+	case i_JMP:	/* often used also for "inlined" function calls... */
+	case i_Bcc:	/* both BRA & BCC */
+	case i_FBcc:
+	case i_DBcc:
+	case i_FDBcc:
+		return CALL_BRANCH;
+
+	case i_TRAP:
+	case i_TRAPV:
+	case i_TRAPcc:
+	case i_FTRAPcc:
+	case i_STOP:
+	case i_ILLG:
+	case i_CHK:
+	case i_CHK2:
+	case i_BKPT:
 		return CALL_EXCEPTION;
-	}
-	/* RTE */
-	if (opcode == 0x4e73) {
+
+	case i_RTE:
 		return CALL_EXCRETURN;
 	}
-	/* JMP (potentially static functions), DBCC, BRA, BCC (loop labels) */
-	if ((opcode & 0xffc0) == 0x4ec0 ||
-	    (opcode & 0xf0f8) == 0x50c8 ||
-	    (opcode & 0xff00) == 0x6000 ||
-	   ((opcode & 0xf000) == 0x6000 && (opcode & 0xf00) > 0x100)) {
-		return CALL_BRANCH;
-	}
 	/* just moved to next instruction? */
 	if (prev_pc < pc && (pc - prev_pc) <= 10) {
 		return CALL_NEXT;
@@ -811,13 +814,11 @@
 #endif
 	Uint32 pc, prev_pc, idx, cycles;
 	cpu_profile_item_t *prev;
-	Uint16 opcode;
 
 	prev_pc = cpu_profile.prev_pc;
 	cpu_profile.prev_pc = pc = M68000_GetPC();
-	opcode = STMemory_ReadWord(prev_pc);
 	if (cpu_profile.sites) {
-		calltype_t flag = cpu_opcode_type(opcode, prev_pc, pc);
+		calltype_t flag = cpu_opcode_type(LastOpcodeFamily, prev_pc, pc);
 		update_caller_info(false, pc, cpu_profile.sites, cpu_profile.callsite, prev_pc, flag);
 	}
 
@@ -844,11 +845,14 @@
 	cycles = CurrentInstrCycles + nWaitStateCycles;
 #endif
 	/* catch too large (and negative) cycles, ignore STOP instruction */
-	if (unlikely(cycles > 256 && opcode != 0x4e72)) {
+	if (unlikely(cycles > 256 && LastOpcodeFamily != i_STOP)) {
 		fprintf(stderr, "WARNING: cycles %d > 512 at 0x%x\n",
 			cycles, prev_pc);
 	}
 #if DEBUG
+	if (unlikely(LastOpcodeFamily == 0)) {
+		fprintf(stderr, "WARNING: LastOpcodeFamily is zero (=i_ILLG) for instruction at 0x%x\n", prev_pc);
+	}
 	if (unlikely(cycles == 0)) {
 		Uint32 nextpc;
 		Disasm(debugOutput, prev_pc, &nextpc, 1);


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/