diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-07-30 19:11:16 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-07-30 19:11:16 +0200 |
commit | 4f33c88a51587681b7be1ae57cfbc43b627c6bc4 (patch) | |
tree | 25560404dc80007e5dc268811242c9071f6a1017 /sys/src/libmach/5db.c | |
parent | fcc5e75d07e5bc6cb3ddac6d9a437e7ec62d0d95 (diff) |
import updated compilers from sources
Diffstat (limited to 'sys/src/libmach/5db.c')
-rw-r--r-- | sys/src/libmach/5db.c | 73 |
1 files changed, 59 insertions, 14 deletions
diff --git a/sys/src/libmach/5db.c b/sys/src/libmach/5db.c index 848281f59..e490d11a6 100644 --- a/sys/src/libmach/5db.c +++ b/sys/src/libmach/5db.c @@ -61,7 +61,7 @@ static int arminstlen(Map*, uvlong); */ Machdata armmach = { - {0, 0, 0, 0xD}, /* break point */ + {0x70, 0x00, 0x20, 0xD1}, /* break point */ /* D1200070 */ 4, /* break point size */ leswab, /* short to local byte order */ @@ -135,18 +135,26 @@ char* addsub[2] = int armclass(long w) { - int op; + int op, done; op = (w >> 25) & 0x7; switch(op) { case 0: /* data processing r,r,r */ op = ((w >> 4) & 0xf); if(op == 0x9) { - op = 48+16; /* mul */ + op = 48+16; /* mul, swp or *rex */ + if((w & 0x0ff00fff) == 0x01900f9f) { + op = 93; /* ldrex */ + break; + } + if((w & 0x0ff00ff0) == 0x01800f90) { + op = 94; /* strex */ + break; + } if(w & (1<<24)) { op += 2; if(w & (1<<22)) - op++; /* swap */ + op++; /* swpb */ break; } if(w & (1<<23)) { /* mullu */ @@ -174,12 +182,38 @@ armclass(long w) op = (48) + ((w >> 21) & 0xf); break; case 2: /* load/store byte/word i(r) */ + if ((w & 0xffffff8f) == 0xf57ff00f) { /* barriers, clrex */ + done = 1; + switch ((w >> 4) & 7) { + case 1: + op = 95; /* clrex */ + break; + case 4: + op = 96; /* dsb */ + break; + case 5: + op = 97; /* dmb */ + break; + case 6: + op = 98; /* isb */ + break; + default: + done = 0; + break; + } + if (done) + break; + } op = (48+24) + ((w >> 22) & 0x1) + ((w >> 19) & 0x2); break; case 3: /* load/store byte/word (r)(r) */ op = (48+24+4) + ((w >> 22) & 0x1) + ((w >> 19) & 0x2); break; case 4: /* block data transfer (r)(r) */ + if ((w & 0xfe50ffff) == 0xf8100a00) { /* v7 RFE */ + op = 99; + break; + } op = (48+24+4+4) + ((w >> 20) & 0x1); break; case 5: /* branch / branch link */ @@ -188,7 +222,7 @@ armclass(long w) case 7: /* coprocessor crap */ op = (48+24+4+4+2+2) + ((w >> 3) & 0x2) + ((w >> 20) & 0x1); break; - default: + default: op = (48+24+4+4+2+2+4+4); break; } @@ -602,19 +636,16 @@ armaddr(Map *map, Rgetter rget, Instr *i) char buf[8]; ulong rn; - sprint(buf, "R%ld", (i->w >> 16) & 0xf); + snprint(buf, sizeof(buf), "R%ld", (i->w >> 16) & 0xf); rn = rget(map, buf); - if((i->w & (1<<24)) == 0) { /* POSTIDX */ - sprint(buf, "R%ld", rn); - return rget(map, buf); - } + if((i->w & (1<<24)) == 0) /* POSTIDX */ + return rn; if((i->w & (1<<25)) == 0) { /* OFFSET */ - sprint(buf, "R%ld", rn); if(i->w & (1U<<23)) - return rget(map, buf) + (i->w & BITS(0,11)); - return rget(map, buf) - (i->w & BITS(0,11)); + return rn + (i->w & BITS(0,11)); + return rn - (i->w & BITS(0,11)); } else { /* REGOFF */ ulong index = 0; uchar c; @@ -823,8 +854,22 @@ static Opcode opcodes[] = "MULL%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)", "MULAL%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)", -/* 48+24+4+4+2+2+4+4 */ +/* 48+24+4+4+2+2+4+4 = 92 */ "UNK", armunk, 0, "", + + /* new v7 arch instructions */ +/* 93 */ + "LDREX", armdpi, 0, "(R%n),R%d", + "STREX", armdpi, 0, "R%s,(R%n),R%d", + "CLREX", armunk, 0, "", + +/* 96 */ + "DSB", armunk, 0, "", + "DMB", armunk, 0, "", + "ISB", armunk, 0, "", + +/* 99 */ + "RFEV7%P%a", armbdt, 0, "(R%n)", }; static void |