*/
Machdata armmach =
{
- {0x70, 0x00, 0x20, 0xD1}, /* break point */ /* D1200070 */
+ {0x70, 0x00, 0x20, 0xE1}, /* break point */ /* E1200070 */
4, /* break point size */
leswab, /* short to local byte order */
case 0x13:
return "SVC/SWI Exception";
case 0x17:
- return "Prefetch Abort/Data Abort";
+ return "Prefetch Abort/Breakpoint";
case 0x18:
return "Data Abort";
case 0x1b:
op = (w >> 25) & 0x7;
switch(op) {
case 0: /* data processing r,r,r */
+ if((w & 0x0ff00080) == 0x01200000) {
+ op = (w >> 4) & 0x7;
+ if(op == 7)
+ op = 124; /* bkpt */
+ else if (op > 0 && op < 4)
+ op += 124; /* bx, blx */
+ else
+ op = 92; /* unk */
+ break;
+ }
op = ((w >> 4) & 0xf);
if(op == 0x9) {
op = 48+16; /* mul, swp or *rex */
if(w & (1<<4))
op += 32;
else
- if((w & (31<<7)) || (w & (1<<5)))
+ if(w & (31<<7 | 3<<5))
op += 16;
break;
case 1: /* data processing i,r,r */
op = 108;
break;
case 7:
- if(((w >> 19) & 0x1) == 0)
+ if(((w >> 19) & 0x1) == 0){
if(((w >> 17) & 0x1) == 0)
op = 109 + ((w >> 16) & 0x4) +
((w >> 15) & 0x2) +
((w >> 7) & 0x1);
else if(((w >> 16) & 0x7) == 0x7)
op = 117;
+ }
else
switch((w >> 16) & 0x7){
case 0:
return;
}
}
+ if(i->rd == 15) {
+ if(i->op == 120) {
+ format("MOVW", i, "PSR, %x");
+ return;
+ } else
+ if(i->op == 121) {
+ format("MOVW", i, "%x, PSR");
+ return;
+ }
+ }
format(o->o, i, o->a);
}
armhwby(Opcode *o, Instr *i)
{
i->store = ((i->w >> 23) & 0x2) | ((i->w >>21) & 0x1);
- i->imm = (i->w & 0xf) | ((i->w >> 8) & 0xf);
+ i->imm = (i->w & 0xf) | ((i->w >> 4) & 0xf0);
if (!(i->w & (1 << 23)))
i->imm = - i->imm;
i->rn = (i->w >> 16) & 0xf;
format(o->o, i, o->a);
}
+static void
+armbpt(Opcode *o, Instr *i)
+{
+ i->imm = ((i->w >> 4) & 0xfff0) | (i->w &0xf);
+ format(o->o, i, o->a);
+}
+
static void
armco(Opcode *o, Instr *i) /* coprocessor instructions */
{
case 10: return n == v;
case 11: return n != v;
case 12: return !z && (n == v);
- case 13: return z && (n != v);
+ case 13: return z || (n != v);
case 14: return 1;
case 15: return 0;
}
}
return ROR(v, s);
case 7: /* RORREG */
- sprint(buf, "R%ld", (s>>1)&0xF);
- s = rget(map, buf);
- if(s == 0 || (s & 0xF) == 0)
+ sprint(buf, "R%ld", s >> 1);
+ s = rget(map, buf) & 0x1F;
+ if(s == 0)
return v;
- return ROR(v, s & 0xF);
+ return ROR(v, s);
}
}
}
return rget(map, buf) + armshiftval(map, rget, i);
}
+static uvlong
+armfbx(Map *map, Rgetter rget, Instr *i, uvlong pc)
+{
+ char buf[8];
+ int r;
+
+ if(!armcondpass(map, rget, (i->w>>28)&0xf))
+ return pc+4;
+ r = (i->w >> 0) & 0xf;
+ sprint(buf, "R%d", r);
+ return rget(map, buf);
+}
+
static uvlong
armfmovm(Map *map, Rgetter rget, Instr *i, uvlong pc)
{
"SWPB", armdpi, 0, "R%s,(R%n),R%d",
/* 48+16+4 */
- "MOV%u%C%p", armhwby, 0, "R%d,(R%n%UR%M)",
+ "MOV%u%C%p", armhwby, 0, "R%d,(R%n%UR%s)",
"MOV%u%C%p", armhwby, 0, "R%d,%I",
- "MOV%u%C%p", armhwby, armfmov, "(R%n%UR%M),R%d",
+ "MOV%u%C%p", armhwby, armfmov, "(R%n%UR%s),R%d",
"MOV%u%C%p", armhwby, armfmov, "%I,R%d",
/* 48+24 */
/* 122 */
"MOV%f%C", armvstdi, 0, "F%d,%I",
"MOV%f%C", armvstdi, 0, "%I,F%d",
+
+/* 124 */
+ "BKPT%C", armbpt, 0, "$#%i",
+ "BX%C", armdps, armfbx, "(R%s)",
+ "BXJ%C", armdps, armfbx, "(R%s)",
+ "BLX%C", armdps, armfbx, "(R%s)",
};
static void
break;
case 'm':
- bprint(i, "%lud", (i->w>>7) & 0x1f);
+ n = (i->w>>7) & 0x1f;
+ if (n == 0 && (i->w & (3<<5)) != 0)
+ n = 32;
+ bprint(i, "%d", n);
break;
case 'h':