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);