[GXemul-devel] GXemul ARM MSR fsxc patch
Status: Alpha
Brought to you by:
gavare
From: James P. <ji...@gm...> - 2012-06-12 00:21:23
|
Hello, I've been using GXemul to help develop a little project of mine and have noticed that the implementation of ARM MSR failed if the fields mask included the 's' or 'x' bits. Below is a patch to add basic support for these variants, which is enough to get code of the form 'MSR SPSR_fsxc' to run. Also, when writing to the CPSR, the mask should be anded with 0xff000000 if the CPU is not in a privileged mode. I've not included this in the patch as it would be a much larger change the behaviour which I don't have the set up to test fully. GXemul has been incredibly useful. Is it still under any form of active development? James Index: src/cpus/cpu_arm.cc =================================================================== --- src/cpus/cpu_arm.cc (revision 5799) +++ src/cpus/cpu_arm.cc (working copy) @@ -855,15 +855,12 @@ */ if ((iw & 0x0fb0fff0) == 0x0120f000 || (iw & 0x0fb0f000) == 0x0320f000) { - int a = (iw >> 16) & 15; debug("msr%s\t%s", condition, (iw&0x400000)? "S":"C"); debug("PSR_"); - switch (a) { - case 1: debug("ctl"); break; - case 8: debug("flg"); break; - case 9: debug("all"); break; - default:debug(" UNIMPLEMENTED (a=%i)", a); - } + if (iw & (1<<19)) debug("f"); + if (iw & (1<<18)) debug("s"); + if (iw & (1<<17)) debug("x"); + if (iw & (1<<16)) debug("c"); if (iw & 0x02000000) { int r = (iw >> 7) & 30; uint32_t b = iw & 0xff; Index: src/cpus/cpu_arm_instr.cc =================================================================== --- src/cpus/cpu_arm_instr.cc (revision 5799) +++ src/cpus/cpu_arm_instr.cc (working copy) @@ -2703,14 +2703,19 @@ imm = (imm >> 2) | ((imm & 3) << 30); ic->arg[0] = imm; ic->arg[2] = (size_t)(&cpu->cd.arm.r[rm]); - switch ((iword >> 16) & 15) { - case 1: ic->arg[1] = 0x000000ff; break; - case 8: ic->arg[1] = 0xff000000; break; - case 9: ic->arg[1] = 0xff0000ff; break; - default:if (!cpu->translation_readahead) - fatal("unimpl a: msr regform\n"); - goto bad; - } + { + uint32_t arg1 = 0; + if (iword & (1<<16)) arg1 |= 0x000000ff; + if (iword & (1<<17)) arg1 |= 0x0000ff00; + if (iword & (1<<18)) arg1 |= 0x00ff0000; + if (iword & (1<<19)) arg1 |= 0xff000000; + if (arg1==0) { + if (!cpu->translation_readahead) + fatal("msr no fields\n"); + goto bad; + } + ic->arg[1] = arg1; + } break; } if ((iword & 0x0fbf0fff) == 0x010f0000) { |