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