X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=sys%2Fsrc%2Flibmach%2F5db.c;h=1bd661423b60942e44eb927638fb452b7d377a21;hb=76ed42e31ff3297f1ca9b144ccc9466b0074f92b;hp=21b788d559c5e0d6d13cc2bfe8ed108535c75dcd;hpb=ea0f58090923bd7e435c4f48eb751854a4292b9a;p=plan9front.git diff --git a/sys/src/libmach/5db.c b/sys/src/libmach/5db.c index 21b788d55..1bd661423 100644 --- a/sys/src/libmach/5db.c +++ b/sys/src/libmach/5db.c @@ -61,7 +61,7 @@ static int arminstlen(Map*, uvlong); */ 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 */ @@ -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 */ @@ -247,13 +257,14 @@ armclass(long w) 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: @@ -405,6 +416,16 @@ armdps(Opcode *o, Instr *i) 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); } @@ -478,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; @@ -539,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 */ { @@ -591,7 +619,7 @@ armcondpass(Map *map, Rgetter rget, uchar cond) 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; } @@ -652,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); } } } @@ -757,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) { @@ -889,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 */ @@ -972,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 @@ -1041,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':