]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/libmach/5db.c
marshal(1): fix example: upas/mail -> mail (thanks fulton)
[plan9front.git] / sys / src / libmach / 5db.c
index b3d43008c89a9e4f363c16c0361a1353b70e7480..1bd661423b60942e44eb927638fb452b7d377a21 100644 (file)
@@ -93,7 +93,7 @@ armexcep(Map *map, Rgetter rget)
        case 0x13:
                return "SVC/SWI Exception";
        case 0x17:
-               return "Prefetch Abort/Data Abort";
+               return "Prefetch Abort/Breakpoint";
        case 0x18:
                return "Data Abort";
        case 0x1b:
@@ -140,6 +140,16 @@ armclass(long w)
        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 */
@@ -175,7 +185,7 @@ armclass(long w)
                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 */
@@ -489,7 +499,7 @@ static void
 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;
@@ -550,6 +560,13 @@ armb(Opcode *o, Instr *i)
        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 */
 {
@@ -663,11 +680,11 @@ armshiftval(Map *map, Rgetter rget, Instr *i)
                        }
                        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);
                }
        }
 }
@@ -768,6 +785,19 @@ armfadd(Map *map, Rgetter rget, Instr *i, uvlong pc)
        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)
 {
@@ -900,9 +930,9 @@ static Opcode opcodes[] =
        "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 */
@@ -983,6 +1013,12 @@ static Opcode opcodes[] =
 /* 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
@@ -1052,7 +1088,10 @@ format(char *mnemonic, Instr *i, char *f)
                        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':