- Added csr and m68k support
  - Added csr and m68k test programs
  - Fixed Makefile
This commit is contained in:
Nibble 2009-02-17 02:46:52 +01:00
parent 731472d2b9
commit dec90751a1
13 changed files with 5015 additions and 7 deletions

View file

@ -49,4 +49,14 @@ OBJ+=arch/ppc/ppc_disasm/ppc_disasm.o
# BF
OBJ+=arch/bf/asm.o
# CSR
OBJ+=arch/csr/asm.o
# ppc-disasm
OBJ+=arch/csr/csr_disasm/dis.o
# M68K
OBJ+=arch/m68k/asm.o
# mk8k-disasm
OBJ+=arch/m68k/m68k_disasm/m68k_disasm.o
include ../rules.mk

19
libr/asm/arch/csr/asm.c Normal file
View file

@ -0,0 +1,19 @@
/* radare - LGPL - Copyright 2009 nibble<.ds@gmail.com> */
#include <stdio.h>
#include <r_types.h>
#include <r_util.h>
#include <r_asm.h>
#include "csr_disasm/dis.h"
int r_asm_csr_disasm(struct r_asm_t *a, u8 *buf, u64 len)
{
r_hex_bin2str((u8*)buf, 2, a->buf_hex);
arch_csr_disasm(a->buf_asm, buf, a->pc);
memcpy(a->buf, buf, 2);
a->inst_len = 2;
return a->inst_len;
}

View file

@ -0,0 +1,973 @@
/* sorbo '07 */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
//#include <err.h>
#include <string.h>
//#include <assert.h>
#define assert(x) if (!(x)) { eprintf("assert ##x##\n"); return; }
#include <stdarg.h>
#include <stdint.h>
#include "dis.h"
#include <r_types.h>
static struct state *get_state(void)
{
return &_state;
}
static uint16_t i2u16(struct instruction *in)
{
return *((uint16_t*)in);
}
#if 0
static void output(struct state *s, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
cons_printf(fmt, ap);
//vfprintf(s->s_out, fmt, ap);
va_end(ap);
}
#endif
static void decode_unknown(struct state *s, struct directive *d)
{
#if 0
printf("Opcode 0x%x reg %d mode %d operand 0x%x",
in->in_opcode, in->in_reg, in->in_mode, in->in_operand);
#endif
sprintf(d->d_asm, "DC\t0x%4x", i2u16(&d->d_inst));
}
static int decode_fixed(struct state *s, struct directive *d)
{
switch (i2u16(&d->d_inst)) {
case INST_NOP:
if (s->s_prefix)
return 0;
s->s_nop++;
strcpy(d->d_asm, "nop");
return 1;
case INST_BRK:
strcpy(d->d_asm, "brk");
return 1;
case INST_SLEEP:
strcpy(d->d_asm, "sleep");
return 1;
case INST_SIF:
strcpy(d->d_asm, "sif");
return 1;
case INST_BC:
strcpy(d->d_asm, "bc");
return 1;
case INST_BRXL:
strcpy(d->d_asm, "brxl");
return 1;
case INST_U:
strcpy(d->d_asm, "");
s->s_u = 1;
return 1;
case INST_RTS:
strcpy(d->d_asm, "rts");
return 1;
}
return 0;
}
static char *regname(int reg)
{
switch (reg) {
case REG_AH:
return "AH";
break;
case REG_AL:
return "AL";
break;
case REG_X:
return "X";
break;
case REG_Y:
return "Y";
break;
default:
return NULL;
}
}
static int get_num(int num, int shift)
{
int tmp;
char x;
x = (char) ((num >> shift) & 0xff);
tmp = x;
tmp <<= shift;
return tmp;
}
static int get_operand(struct state *s, struct directive *d)
{
int total = 0;
total += get_num(d->d_inst.in_operand, 0);
if (s->s_prefix)
total += get_num(s->s_prefix_val, 8);
if (s->s_prefix == 2)
total += get_num(s->s_prefix_val, 16);
return total;
}
#if 0
static int label_off(struct directive *d)
{
#if 1
// int off = get_operand(d);
int off = d->d_operand;
int lame = off & 0x80;
/* XXX WTF? */
if (!d->d_prefix) {
off = (char) (off &0xff);
} else if (d->d_prefix == 1) {
off = (short) (off & 0xffff);
if (lame)
off -= 0x100;
} else {
off = (int) (off & 0xffffff);
if (off & 0x800000)
off |= 0xff000000;
if (off & 0x8000)
off -= 0x10000;
if (lame)
off -= 0x100;
}
#endif
// int off = d->d_operand;
return d->d_off + off;
}
#endif
#if 0
static void label_add_ref(struct label *l, struct directive *d)
{
struct directive **ptr = l->l_refs;
while (*ptr) {
assert((unsigned long) ptr - (unsigned long) l->l_refs <
sizeof(l->l_refs));
ptr++;
}
*ptr = d;
l->l_refc++;
}
#endif
#if 0
/* XXX slow */
static struct label *find_label_add(struct state *s, struct directive *d)
{
int off = label_off(d);
struct label *ptr = s->s_labels.l_next;
struct label *slot = &s->s_labels;
/* find */
while (ptr) {
if (ptr->l_off == off)
return ptr;
if (ptr->l_off > off)
break;
slot = ptr;
ptr = ptr->l_next;
}
/* add */
ptr = malloc(sizeof(*ptr));
if (!ptr) {
perror("malloc()");
return NULL;
}
memset(ptr, 0, sizeof(*ptr));
sprintf(ptr->l_name, "0x%x", off); //L%d", s->s_labelno++);
ptr->l_off = off;
ptr->l_next = slot->l_next;
slot->l_next = ptr;
return ptr;
}
static void add_label(struct state *s, struct directive *d)
{
struct label *l;
l = find_label_add(s, d);
assert(l);
label_add_ref(l, d);
strcat(d->d_asm, l->l_name);
}
#endif
static int decode_known(struct state *s, struct directive *d)
{
char *op = NULL;
char *regn = NULL;
int reg = 0;
int ptr = 1;
int idx = 1;
int imm = 0;
int rel = 0;
char fmt[16];
char tmp[128];
int fmtsz;
int branch = 0;
struct instruction *in = &d->d_inst;
// int operand;
char *sign = "";
int rti = 0;
switch (in->in_opcode) {
case 0:
if (in->in_reg == 0 && in->in_mode == 0) {
if (s->s_prefix == 0)
s->s_prefix_val = 0;
s->s_prefix++;
if (s->s_prefix == 2)
s->s_prefix_val <<= 8;
#if 0
/* XXX we need to look ahead more to see if we're
* getting a branch instruction */
if (s->s_nopd && in->in_operand == 0x80)
strcpy(s->s_nopd->d_asm, "");
#endif
s->s_prefix_val |= in->in_operand << 8;
strcpy(d->d_asm, "");
return 1;
}
switch (i2u16(in) & 0xf) {
case 1:
op = "st";
regn = "FLAGS";
break;
case 2:
op = "st";
regn = "UX";
break;
case 3:
op = "st";
regn = "UY";
break;
case 5:
op = "ld";
regn = "FLAGS";
break;
case 6:
op = "ld";
regn = "UX";
break;
case 7:
op = "ld";
regn = "UY";
break;
case 0xa:
op = "st";
regn = "XH";
break;
case 0xd:
op = "rti";
regn = "";
rti = 1;
break;
case 0xe:
op = "ld";
regn = "XH";
break;
}
break;
case 1:
op = "ld";
reg = 1;
ptr = 1;
idx = 1;
imm = 1;
break;
case 2:
if (in->in_mode == DATA_MODE_IMMEDIATE) {
op = "print";
imm = 1;
reg = 1;
} else {
op = "st";
reg = 1;
ptr = 1;
idx = 1;
}
break;
case 3:
op = "add";
reg = 1;
ptr = 1;
idx = 1;
imm = 1;
break;
case 4:
op = "addc";
reg = 1;
ptr = 1;
idx = 1;
imm = 1;
break;
case 5:
op = "sub";
reg = 1;
ptr = 1;
idx = 1;
imm = 1;
break;
case 6:
op = "subc";
reg = 1;
ptr = 1;
idx = 1;
imm = 1;
break;
case 7:
op = "nadd";
reg = 1;
ptr = 1;
idx = 1;
imm = 1;
break;
case 8:
op = "cmp";
reg = 1;
ptr = 1;
idx = 1;
imm = 1;
break;
case 0x9:
switch (in->in_reg) {
case 0:
if (s->s_u)
op = "umult";
else
op = "smult";
imm = 1;
s->s_u = 0;
idx = 1;
ptr = 1;
break;
case 1:
if (s->s_u)
op = "udiv";
else
op = "sdiv";
s->s_u = 0;
imm = 1;
break;
case 2:
op = "tst";
imm = 1;
ptr = 1;
idx = 1;
break;
case 3:
branch = 1;
op = "bsr";
ptr = 1;
idx = 1;
if (in->in_mode == ADDR_MODE_RELATIVE)
rel = 1;
break;
}
break;
case 0xa:
switch (in->in_reg) {
case 0:
op = "asl";
imm = 1;
break;
case 1:
if (s->s_u)
op = "lsr";
else
op = "asr";
s->s_u = 0;
imm = 1;
idx = 1;
ptr = 1;
break;
case 2:
op = "rol";
imm = 1;
break;
case 3:
op = "ror";
imm = 1;
break;
}
break;
case 0xb:
op = "or";
reg = 1;
ptr = 1;
idx = 1;
imm = 1;
break;
case 0xc:
op = "and";
reg = 1;
ptr = 1;
idx = 1;
imm = 1;
break;
case 0xd:
op = "xor";
reg = 1;
ptr = 1;
idx = 1;
imm = 1;
break;
case 0xe:
branch = 1;
if (in->in_mode == ADDR_MODE_RELATIVE)
rel = 1;
switch (in->in_reg) {
case 0:
op = "bra";
ptr = 1;
idx = 1;
#if 0
if (s->s_nopd) {
op = "bra2"; /* XXX need bra3 support */
strcpy(s->s_nopd->d_asm, "");
}
#endif
break;
case 1:
op = "blt"; /* yummy */
break;
case 2:
op = "bpl";
break;
case 3:
op = "bmi";
break;
}
break;
case 0xf:
branch = 1;
if (in->in_mode == ADDR_MODE_RELATIVE)
rel = 1;
switch (in->in_reg) {
case 0:
op = "bne";
break;
case 1:
op = "beq";
break;
case 2:
op = "bcc";
break;
case 3:
op = "bcs";
break;
}
break;
}
if (!op)
return 0;
if (ptr && in->in_mode == DATA_MODE_IMMEDIATE)
ptr = 0;
if (branch && in->in_mode == ADDR_MODE_X_RELATIVE)
ptr = 0;
if (idx && (!(in->in_mode & 2)))
idx = 0;
if (regn) {
ptr = 1;
idx = 1;
reg = 1;
}
sprintf(d->d_asm, "%s ", op);
if (reg) {
char *r = regn;
if (!r)
r = regname(in->in_reg);
if (!rti) {
strcat(d->d_asm, r);
strcat(d->d_asm, ", ");
}
}
if (ptr) {
strcat(d->d_asm, "@");
rel = 0;
} else if (imm)
strcat(d->d_asm, "#");
if (idx && ptr)
strcat(d->d_asm, "(");
d->d_prefix = s->s_prefix;
// d->d_operand = get_operand(s, d);
#if 1
if ((branch && idx) || rti) {
d->d_operand = get_operand(s, d);
if (d->d_operand < 0) {
d->d_operand *= -1;
sign = "-";
}
}
else {
d->d_operand = s->s_prefix_val | in->in_operand;
if (d->d_operand & 0x80) {
if (d->d_prefix) {
if (!rel)
d->d_operand -= 0x100;
} else
d->d_operand |= 0xff00;
}
}
#endif
#if 0
operand = d->d_operand;
if (operand < 0)
operand *= -1;
#endif
fmtsz = 4;
if (d->d_operand & 0xff0000)
fmtsz += 2;
// can be cleaned, no need to fmtsz
snprintf(fmt, sizeof(fmt), "%s0x%%.%dX", sign, fmtsz);
snprintf(tmp, sizeof(tmp), fmt, d->d_operand);
#if 0
if (rel) {
//add_label(s, d);
/* XXX prefix */
if (s->s_nopd && strcmp(s->s_nopd->d_asm, "")) {
/* lets be conservative for now */
if (d->d_operand == 0x7F
|| d->d_operand == 0x7E)
strcpy(s->s_nopd->d_asm, "");
else
printf("\nWarning: nop before branch at %x\n",
d->d_off);
}
} else
#endif
strcat(d->d_asm, tmp);
if (idx) {
char *r = in->in_mode == DATA_MODE_INDEXED_X ? "X" : "Y";
if (regn)
r = "Y";
snprintf(tmp, sizeof(tmp), ", %s", r);
strcat(d->d_asm, tmp);
if (ptr)
strcat(d->d_asm, ")");
}
#if 0
/* XXX quirks */
if (!rel && in->in_mode == DATA_MODE_IMMEDIATE
&& ((d->d_operand & 0xff00) == 0x7F00) && d->d_operand & 0x80)
s->s_ff_quirk = 1;
if (rel && !s->s_prefix && d->d_operand == 0x7F) {
if (s->s_nopd) {
printf("w00t\n");
strcpy(s->s_nopd->d_asm, "nop");
}
printf("Warning: fucking up a branch %x\n", d->d_off);
decode_unknown(s, d);
}
#endif
return 1;
}
void csr_decode(struct state *s, struct directive *d)
{
int prefix = s->s_prefix;
if (decode_fixed(s, d))
goto out;
if (decode_known(s, d))
goto out;
decode_unknown(s, d);
out:
if (s->s_prefix == prefix)
s->s_prefix_val = s->s_prefix = 0;
}
#if 0
static void add_tabs(struct state *s, struct directive *d)
{
int outlen = 0;
int len;
char *ptr = d->d_asm;
int pos;
int wanted = 8*4;
len = strlen(ptr);
for (pos = 0; pos < len; pos++, ptr++) {
if (*ptr == '\t') {
outlen += 8 - (pos % 8);
} else
outlen++;
}
wanted -= outlen;
assert(wanted > 0);
pos = wanted / 8;
if (wanted % 8)
pos++;
while (pos--)
strcat(d->d_asm, " ");
}
#endif
#if 0
static void add_comment(struct state *s, struct directive *d)
{
char tmp[128];
add_tabs(s, d);
snprintf(tmp, sizeof(tmp), "; @0x%x 0x%x", d->d_off,
*((uint16_t*)&d->d_inst));
strcat(d->d_asm, tmp);
}
static int read_text(struct state *s, struct directive *d)
{
char tmp[128];
char *x;
unsigned int inst;
uint16_t *p;
while ((x = fgets(tmp, sizeof(tmp), s->s_in))) {
if (tmp[0] == '@')
break;
}
if (!x)
return 0;
if (sscanf(tmp, "@0x%x 0x%x", &d->d_off, &inst)
!= 2)
return 0;
p = (uint16_t*) &d->d_inst;
*p = (uint16_t) inst;
return 1;
}
#endif
static int read_bin(struct state *s, struct directive *d)
{
//int rd;
memcpy(&d->d_inst, s->s_buf, sizeof(d->d_inst));
#if 0
rd = fread(&d->d_inst, sizeof(d->d_inst), 1, s->s_in);
if (rd == -1)
err(1, "read()");
if (rd == 0)
return 0;
#endif
d->d_off = s->s_off++;
return 1;
}
struct directive *next_inst(struct state *s)
{
struct directive *d;
int rd;
d = malloc(sizeof(*d));
if (!d) {
perror("malloc()");
return NULL;
}
memset(d, 0, sizeof(*d));
#if 0
if (s->s_format)
rd = read_text(s, d);
else
#endif
rd = read_bin(s, d);
if (!rd) {
free(d);
return NULL;
}
return d;
}
#if 0
static void print_label(struct state *s, struct label *l)
{
output(s, "\n%s:\t\t\t\t\t; refs: %d\n",
l->l_name, l->l_refc);
}
#endif
#if 0
static void own(struct state *s)
{
struct directive *d;
struct directive *last = &s->s_dirs;
struct label *l;
int flush = 0;
char fname[128];
char *fnamep;
snprintf(fname, sizeof(fname), "%s", s->s_fname);
fnamep = strchr(fname, '.');
if (fnamep)
*fnamep = 0;
output(s, "\tMODULE %s\n"
"\t.CODE\n"
"\t.LARGE\n"
"\n", fname);
/* decode instructions */
s->s_off = 0;
while ((d = next_inst(s))) {
csr_decode(s, d);
if (s->s_ff_quirk) {
strcpy(last->d_asm, "DC\t0x8000");
sprintf(d->d_asm, "DC\t0x%.4x", i2u16(&d->d_inst));
s->s_ff_quirk = 0;
}
if (s->s_nopd) {
last->d_next = s->s_nopd;
last = s->s_nopd;
s->s_nopd = NULL;
s->s_nop = 0;
}
if (s->s_nop) {
assert(s->s_nopd == NULL);
s->s_nopd = d;
} else {
last->d_next = d;
last = d;
}
#if 1
if (flush++ > 10000) {
printf("@0x%.6x\r", d->d_off);
fflush(stdout);
flush = 0;
}
#endif
}
if (s->s_nopd)
last->d_next = s->s_nopd;
printf("\n");
/* print them */
d = s->s_dirs.d_next;
l = s->s_labels.l_next;
while (d) {
/* print any labels first */
while (l) {
if (l->l_off > d->d_off)
break;
print_label(s, l);
l = l->l_next;
}
add_comment(s, d);
output(s, "\t%s\n", d->d_asm);
d = d->d_next;
}
if (l) {
print_label(s, l);
assert(l->l_next == NULL);
}
output(s, "\n\tENDMOD\n");
}
#endif
// XXX lot of memory leaks
int arch_csr_disasm(char *str, unsigned char *buf, u64 seek)
{
struct state *s = get_state();
struct directive *d;
memset(s, 0, sizeof(*s));
s->s_buf = buf;
s->s_off = seek;
s->s_out = NULL;
d = next_inst(s);
if (d == NULL)
return 0;
csr_decode(s, d);
#if 0
if (s->s_ff_quirk) {
sprintf(d->d_asm, "DC\t0x%x", i2u16(&d->d_inst));
s->s_ff_quirk = 0;
}
#endif
strcpy(str, d->d_asm);
return 0;
}
#if 0
static int main(int argc, char *argv[])
{
struct state *s = get_state();
struct directive *d;
char tmp[128];
int i = 0;
unsigned char buf[128];
memset(s, 0, sizeof(*s));
memcpy(buf, "\xFF\x27\x00\x10", 4);
s->s_buf = &buf;
#if 0
if (argc < 2) {
printf("Usage: %s <file> [format]\n", argv[0]);
exit(1);
}
if (argc > 2)
s->s_format = atoi(argv[2]);
s->s_fname = argv[1];
if ((s->s_in = fopen(s->s_fname, "r")) == NULL)
err(1, "fopen()");
snprintf(tmp, sizeof(tmp), "%s.xap", s->s_fname);
s->s_out = fopen(tmp, "w");
if (!s->s_out)
err(1, "fopen()");
#endif
s->s_off = 0;
s->s_out = -1;
for(i=0;i<2;i++) {
d = next_inst(s);
decode(s, d);
if (s->s_ff_quirk) {
//strcpy(last->d_asm, "DC\tH'8000");
sprintf(d->d_asm, "DC\t0x%x", i2u16(&d->d_inst));
s->s_ff_quirk = 0;
}
printf("ASM : %s\n", d->d_asm);
}
#if 0
own(s);
fclose(s->s_in);
fclose(s->s_out);
#endif
exit(0);
}
#endif

View file

@ -0,0 +1,93 @@
#ifndef _INCLUDE_CSR_DIS_H_
#define _INCLUDE_CSR_DIS_H_
#include <r_types.h>
#ifndef __CYGWIN__
typedef unsigned short uint16_t ;
typedef unsigned int uint32_t ;
#endif
#define __packed __attribute__((__packed__))
struct instruction {
uint16_t in_mode:2,
in_reg:2,
in_opcode:4,
in_operand:8;
#if __sun
#warning XXX related to sunstudio :O
};
#else
} __packed;
#endif
struct directive {
struct instruction d_inst;
int d_operand;
int d_prefix;
unsigned int d_off;
char d_asm[128];
struct directive *d_next;
};
struct label {
char l_name[128];
unsigned int l_off;
struct directive *l_refs[666];
int l_refc;
struct label *l_next;
};
struct state {
int s_prefix;
unsigned int s_prefix_val;
FILE *s_in;
unsigned int s_off;
char *s_fname;
int s_u;
unsigned int s_labelno;
unsigned char * s_buf;
struct directive s_dirs;
struct label s_labels;
FILE *s_out;
int s_format;
int s_nop;
struct directive *s_nopd;
int s_ff_quirk;
} _state;
int arch_csr_disasm(char *str, unsigned char *b, u64 seek);
#define MODE_MASK 3
#define REG_SHIFT 2
#define REG_MASK 3
#define OPCODE_SHIFT 4
#define OPCODE_MASK 0xF
#define OPERAND_SHIFT 8
#define INST_NOP 0x0000
#define INST_BRK 0x0004
#define INST_SLEEP 0x0008
#define INST_U 0x0009
#define INST_SIF 0x000C
#define INST_RTS 0x00E2
#define INST_BRXL 0xfe09
#define INST_BC 0xff09
#define REG_AH 0
#define REG_AL 1
#define REG_X 2
#define REG_Y 3
#define DATA_MODE_IMMEDIATE 0
#define DATA_MODE_DIRECT 1
#define DATA_MODE_INDEXED_X 2
#define DATA_MODE_INDEXED_Y 3
#define ADDR_MODE_RELATIVE 0
#define ADDR_MODE_X_RELATIVE 2
void csr_decode(struct state *s, struct directive *d);
#endif

33
libr/asm/arch/m68k/asm.c Normal file
View file

@ -0,0 +1,33 @@
/* radare - LGPL - Copyright 2009 nibble<.ds@gmail.com> */
#include <stdio.h>
#include <string.h>
#include <r_types.h>
#include <r_util.h>
#include <r_asm.h>
#include "m68k_disasm/m68k_disasm.h"
int r_asm_m68k_disasm(struct r_asm_t *a, u8 *buf, u64 len)
{
m68k_word bof[4];
m68k_word iaddr = (m68k_word)a->pc;
char opcode[256];
char operands[256];
struct DisasmPara_68k dp;
/* initialize DisasmPara */
memcpy(bof, buf, 4);
dp.opcode = opcode;
dp.operands = operands;
dp.iaddr = &iaddr;
dp.instr = bof;
M68k_Disassemble(&dp);
sprintf(a->buf_asm, "%s %s", opcode, operands);
r_hex_bin2str((u8*)bof, 4, a->buf_hex);
memcpy(a->buf, bof, 4);
a->inst_len = 4;
return a->inst_len;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,510 @@
/* $VER: m68k_disasm.h V0.4 (18.04.2002)
*
* Disassembler module for the M680x0 microprocessor family
* Copyright (c) 1999-2002 Frank Wille
* Based on NetBSD's m68k/m68k/db_disasm.c by Christian E. Hopps.
*
* Copyright (c) 1994 Christian E. Hopps
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Christian E. Hopps.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* v0.4 (18.04.2002) phx
* FETOXM1 was missing.
* v0.1 (26.06.2000) phx
* Made the interface compatible to PPC disassembler module.
* Included/fixed missing PACK, CMPM, SBCD, CALLM instructions.
* v0.0 (06.03.1999) phx
* File created.
*/
#ifndef M68K_DISASM_H
#define M68K_DISASM_H
/* version/revision */
#define M68KDISASM_VER 0
#define M68KDISASM_REV 4
typedef unsigned short m68k_word; /* pointer to 16-bit instruction word */
#define ENCB(b7,b6,b5,b4,b3,b2,b1,b0) \
((b7 << 7) | (b6 << 6) | (b5 << 5) | (b4 << 4) | \
(b3 << 3) | (b2 << 2) | (b1 << 1) | (b0))
#define ENCW(b15,b14,b13,b12,b11,b10,b9,b8,b7,b6,b5,b4,b3,b2,b1,b0) \
((ENCB(b15,b14,b13,b12,b11,b10,b9,b8) << 8) |\
ENCB(b7,b6,b5,b4,b3,b2,b1,b0))
/*
* Group Bit-manip (0000)
*/
#define ANDITOCCR_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1)
#define ANDIROSR_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1)
#define EORITOCCR_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1)
#define EORITOSR_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1)
#define ORITOCCR_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1)
#define ORITOSR_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1)
#define ANDITOCCR_INST ENCW(0,0,0,0, 0,0,1,0, 0,0,1,1, 1,1,0,0)
#define ANDIROSR_INST ENCW(0,0,0,0, 0,0,1,0, 0,1,1,1, 1,1,0,0)
#define EORITOCCR_INST ENCW(0,0,0,0, 1,0,1,0, 0,0,1,1, 1,1,0,0)
#define EORITOSR_INST ENCW(0,0,0,0, 1,0,1,0, 0,1,1,1, 1,1,0,0)
#define ORITOCCR_INST ENCW(0,0,0,0, 0,0,0,0, 0,0,1,1, 1,1,0,0)
#define ORITOSR_INST ENCW(0,0,0,0, 0,0,0,0, 0,1,1,1, 1,1,0,0)
#define RTM_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 0,0,0,0)
#define RTM_INST ENCW(0,0,0,0, 0,1,1,0, 1,1,0,0, 0,0,0,0)
/* Note: bit eight being 1 here allows these to be check before all else */
/* Note: for movp bits 5-3, specify a mode An, which all the other
* bit 8 set commands do not, so have check first. */
#define MOVEP_MASK ENCW(1,1,1,1, 0,0,0,1, 0,0,1,1, 1,0,0,0)
#define MOVEP_INST ENCW(0,0,0,0, 0,0,0,1, 0,0,0,0, 1,0,0,0)
#define BCHGD_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,0,0, 0,0,0,0)
#define BCLRD_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,0,0, 0,0,0,0)
#define BSETD_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,0,0, 0,0,0,0)
#define BTSTD_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,0,0, 0,0,0,0)
#define BCHGD_INST ENCW(0,0,0,0, 0,0,0,1, 0,1,0,0, 0,0,0,0)
#define BCLRD_INST ENCW(0,0,0,0, 0,0,0,1, 1,0,0,0, 0,0,0,0)
#define BSETD_INST ENCW(0,0,0,0, 0,0,0,1, 1,1,0,0, 0,0,0,0)
#define BTSTD_INST ENCW(0,0,0,0, 0,0,0,1, 0,0,0,0, 0,0,0,0)
#define BCHGS_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define BCLRS_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define BSETS_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define BTSTS_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define BCHGS_INST ENCW(0,0,0,0, 1,0,0,0, 0,1,0,0, 0,0,0,0)
#define BCLRS_INST ENCW(0,0,0,0, 1,0,0,0, 1,0,0,0, 0,0,0,0)
#define BSETS_INST ENCW(0,0,0,0, 1,0,0,0, 1,1,0,0, 0,0,0,0)
#define BTSTS_INST ENCW(0,0,0,0, 1,0,0,0, 0,0,0,0, 0,0,0,0)
#define CAS2_MASK ENCW(1,1,1,1, 1,1,0,1, 1,1,1,1, 1,1,1,1)
#define CAS2_INST ENCW(0,0,0,0, 1,1,0,0, 1,1,1,1, 1,1,0,0)
#define CAS_MASK ENCW(1,1,1,1, 1,0,0,1, 1,1,0,0, 0,0,0,0)
#define CHK2_MASK ENCW(1,1,1,1, 1,0,0,1, 1,1,0,0, 0,0,0,0)
#define CMP2_MASK ENCW(1,1,1,1, 1,0,0,1, 1,1,0,0, 0,0,0,0)
#define CAS_INST ENCW(0,0,0,0, 1,0,0,0, 1,1,0,0, 0,0,0,0)
#define CHK2_INST ENCW(0,0,0,0, 0,0,0,0, 1,1,0,0, 0,0,0,0)
#define CMP2_INST ENCW(0,0,0,0, 0,0,0,0, 1,1,0,0, 0,0,0,0)
/* close ties with Bxxx but bit eight here is 0 and there 1 */
/* also above (cas,chk2,cmp2) bits 7-6 here are size and never 11 */
#define ADDI_MASK ENCW(1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0)
#define ANDI_MASK ENCW(1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0)
#define CMPI_MASK ENCW(1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0)
#define EORI_MASK ENCW(1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0)
#define MOVES_MASK ENCW(1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0)
#define ORI_MASK ENCW(1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0)
#define SUBI_MASK ENCW(1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0)
#define CALLM_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define ADDI_INST ENCW(0,0,0,0, 0,1,1,0, 0,0,0,0, 0,0,0,0)
#define ANDI_INST ENCW(0,0,0,0, 0,0,1,0, 0,0,0,0, 0,0,0,0)
#define CMPI_INST ENCW(0,0,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0)
#define EORI_INST ENCW(0,0,0,0, 1,0,1,0, 0,0,0,0, 0,0,0,0)
#define MOVES_INST ENCW(0,0,0,0, 1,1,1,0, 0,0,0,0, 0,0,0,0)
#define ORI_INST ENCW(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0)
#define SUBI_INST ENCW(0,0,0,0, 0,1,0,0, 0,0,0,0, 0,0,0,0)
#define CALLM_INST ENCW(0,0,0,0, 0,1,1,0, 1,1,0,0, 0,0,0,0)
/*
* Group misc. (0100)
*/
#define BGND_MASK 0xffff
#define ILLEGAL_MASK 0xffff
#define MOVEFRC_MASK 0xffff
#define MOVETOC_MASK 0xffff
#define NOP_MASK 0xffff
#define RESET_MASK 0xffff
#define RTD_MASk 0xffff
#define RTE_MASK 0xffff
#define RTR_MASK 0xffff
#define RTS_MASK 0xffff
#define STOP_MASK 0xffff
#define TRAPV_MASK 0xffff
#define BGND_INST ENCW(0,1,0,0, 1,0,1,0, 1,1,1,1, 1,0,1,0)
#define ILLEGAL_INST ENCW(0,1,0,0, 1,0,1,0, 1,1,1,1, 1,1,0,0)
#define MOVEFRC_INST ENCW(0,1,0,0, 1,1,1,0, 0,1,1,1, 1,0,1,0)
#define MOVETOC_INST ENCW(0,1,0,0, 1,1,1,0, 0,1,1,1, 1,0,1,1)
#define NOP_INST ENCW(0,1,0,0, 1,1,1,0, 0,1,1,1, 0,0,0,1)
#define RESET_INST ENCW(0,1,0,0, 1,1,1,0, 0,1,1,1, 0,0,0,0)
#define RTD_INST ENCW(0,1,0,0, 1,1,1,0, 0,1,1,1, 0,1,0,0)
#define RTE_INST ENCW(0,1,0,0, 1,1,1,0, 0,1,1,1, 0,0,1,1)
#define RTR_INST ENCW(0,1,0,0, 1,1,1,0, 0,1,1,1, 0,1,1,1)
#define RTS_INST ENCW(0,1,0,0, 1,1,1,0, 0,1,1,1, 0,1,0,1)
#define STOP_INST ENCW(0,1,0,0, 1,1,1,0, 0,1,1,1, 0,0,1,0)
#define TRAPV_INST ENCW(0,1,0,0, 1,1,1,0, 0,1,1,1, 0,1,1,0)
#define SWAP_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,0,0,0)
#define SWAP_INST ENCW(0,1,0,0, 1,0,0,0, 0,1,0,0, 0,0,0,0)
#define BKPT_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,0,0,0)
#define EXTBW_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,0,0,0)
#define EXTWL_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,0,0,0)
#define EXTBL_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,0,0,0)
#define LINKW_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,0,0,0)
#define LINKL_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,0,0,0)
#define MOVEFRUSP_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,0,0,0)
#define MOVETOUSP_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,0,0,0)
#define UNLK_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 1,0,0,0)
#undef BKPT_INST
#define BKPT_INST ENCW(0,1,0,0, 1,0,0,0, 0,1,0,0, 1,0,0,0)
#define EXTBW_INST ENCW(0,1,0,0, 1,0,0,0, 1,0,0,0, 0,0,0,0)
#define EXTWL_INST ENCW(0,1,0,0, 1,0,0,0, 1,1,0,0, 0,0,0,0)
#define EXTBL_INST ENCW(0,1,0,0, 1,0,0,1, 1,1,0,0, 0,0,0,0)
#define LINKW_INST ENCW(0,1,0,0, 1,1,1,0, 0,1,0,1, 0,0,0,0)
#define LINKL_INST ENCW(0,1,0,0, 1,0,0,0, 0,0,0,0, 1,0,0,0)
#define MOVETOUSP_INST ENCW(0,1,0,0, 1,1,1,0, 0,1,1,0, 0,0,0,0)
#define MOVEFRUSP_INST ENCW(0,1,0,0, 1,1,1,0, 0,1,1,0, 1,0,0,0)
#define UNLK_INST ENCW(0,1,0,0, 1,1,1,0, 0,1,0,1, 1,0,0,0)
#define TRAP_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,1,1, 0,0,0,0)
#define TRAP_INST ENCW(0,1,0,0, 1,1,1,0, 0,1,0,0, 0,0,0,0)
#define DIVSL_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define DIVUL_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define JMP_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define JSR_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define MOVEFRCCR_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define MOVETOCCR_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define MOVEFRSR_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define MOVETOSR_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define MULSL_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define MULUL_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define NBCD_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define PEA_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define TAS_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define DIVSL_INST ENCW(0,1,0,0, 1,1,0,0, 0,1,0,0, 0,0,0,0)
#define DIVUL_INST DIVSL_INST
#define JMP_INST ENCW(0,1,0,0, 1,1,1,0, 1,1,0,0, 0,0,0,0)
#define JSR_INST ENCW(0,1,0,0, 1,1,1,0, 1,0,0,0, 0,0,0,0)
#define MOVEFRCCR_INST ENCW(0,1,0,0, 0,0,1,0, 1,1,0,0, 0,0,0,0)
#define MOVETOCCR_INST ENCW(0,1,0,0, 0,1,0,0, 1,1,0,0, 0,0,0,0)
#define MOVEFRSR_INST ENCW(0,1,0,0, 0,0,0,0, 1,1,0,0, 0,0,0,0)
#define MOVETOSR_INST ENCW(0,1,0,0, 0,1,1,0, 1,1,0,0, 0,0,0,0)
#define MULSL_INST ENCW(0,1,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0)
#define MULUL_INST MULSL_INST
#define NBCD_INST ENCW(0,1,0,0, 1,0,0,0, 0,0,0,0, 0,0,0,0)
#define PEA_INST ENCW(0,1,0,0, 1,0,0,0, 0,1,0,0, 0,0,0,0)
#define TAS_INST ENCW(0,1,0,0, 1,0,1,0, 1,1,0,0, 0,0,0,0)
#define MOVEM_MASK ENCW(1,1,1,1, 1,0,1,1, 1,0,0,0, 0,0,0,0)
#define MOVEM_INST ENCW(0,1,0,0, 1,0,0,0, 1,0,0,0, 0,0,0,0)
#define CLR_MASK ENCW(1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0)
#define NEG_MASK ENCW(1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0)
#define NEGX_MASK ENCW(1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0)
#define NOT_MASK ENCW(1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0)
#define TST_MASK ENCW(1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0)
#define CLR_INST ENCW(0,1,0,0, 0,0,1,0, 0,0,0,0, 0,0,0,0)
#define NEG_INST ENCW(0,1,0,0, 0,1,0,0, 0,0,0,0, 0,0,0,0)
#define NEGX_INST ENCW(0,1,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0)
#define NOT_INST ENCW(0,1,0,0, 0,1,1,0, 0,0,0,0, 0,0,0,0)
/* Note: very similatr to MOVEM but bit 9 differentiates. */
#define TST_INST ENCW(0,1,0,0, 1,0,1,0, 0,0,0,0, 0,0,0,0)
#define LEA_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,0,0, 0,0,0,0)
#define LEA_INST ENCW(0,1,0,0, 0,0,0,1, 1,1,0,0, 0,0,0,0)
#define CHK_MASK ENCW(1,1,1,1, 0,0,0,1, 0,1,0,0, 0,0,0,0)
#define CHK_INST ENCW(0,1,0,0, 0,0,0,1, 0,0,0,0, 0,0,0,0)
/*
* Group bitfield/Shift/Rotate. (1110)
*/
#define BFCHG_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define BFCLR_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define BFEXTS_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define BFEXTU_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define BFFFO_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define BFINS_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define BFSET_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define BFTST_MASK ENCW(1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define BFCHG_INST ENCW(1,1,1,0, 1,0,1,0, 1,1,0,0, 0,0,0,0)
#define BFCLR_INST ENCW(1,1,1,0, 1,1,0,0, 1,1,0,0, 0,0,0,0)
#define BFEXTS_INST ENCW(1,1,1,0, 1,0,1,1, 1,1,0,0, 0,0,0,0)
#define BFEXTU_INST ENCW(1,1,1,0, 1,0,0,1, 1,1,0,0, 0,0,0,0)
#define BFFFO_INST ENCW(1,1,1,0, 1,1,0,1, 1,1,0,0, 0,0,0,0)
#define BFINS_INST ENCW(1,1,1,0, 1,1,1,1, 1,1,0,0, 0,0,0,0)
#define BFSET_INST ENCW(1,1,1,0, 1,1,1,0, 1,1,0,0, 0,0,0,0)
#define BFTST_INST ENCW(1,1,1,0, 1,0,0,0, 1,1,0,0, 0,0,0,0)
#define AS_TYPE 0x0
#define LS_TYPE 0x1
#define RO_TYPE 0x3
#define ROX_TYPE 0x2
/*
* Group DBcc/TRAPcc/ADDQ/SUBQ (0101)
*/
#define DBcc_MASK ENCW(1,1,1,1, 0,0,0,0, 1,1,1,1, 1,0,0,0)
#define TRAPcc_MASK ENCW(1,1,1,1, 0,0,0,0, 1,1,1,1, 1,0,0,0)
#define Scc_MASK ENCW(1,1,1,1, 0,0,0,0, 1,1,0,0, 0,0,0,0)
#define ADDQ_MASK ENCW(1,1,1,1, 0,0,0,1, 0,0,0,0, 0,0,0,0)
#define SUBQ_MASK ENCW(1,1,1,1, 0,0,0,1, 0,0,0,0, 0,0,0,0)
#define DBcc_INST ENCW(0,1,0,1, 0,0,0,0, 1,1,0,0, 1,0,0,0)
#define TRAPcc_INST ENCW(0,1,0,1, 0,0,0,0, 1,1,1,1, 1,0,0,0)
#define Scc_INST ENCW(0,1,0,1, 0,0,0,0, 1,1,0,0, 0,0,0,0)
#define ADDQ_INST ENCW(0,1,0,1, 0,0,0,0, 0,0,0,0, 0,0,0,0)
#define SUBQ_INST ENCW(0,1,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,0)
/*
* Group ADD/ADDX (1101)
*/
#define ADDX_MASK ENCW(1,1,1,1, 0,0,0,1, 0,0,1,1, 0,0,0,0)
#define ADDX_INST ENCW(1,1,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,0)
#define ADD_MASK ENCW(1,1,1,1, 0,0,0,0, 0,0,0,0, 0,0,0,0)
#define ADD_INST ENCW(1,1,0,1, 0,0,0,0, 0,0,0,0, 0,0,0,0)
/*
* Group SUB/SUBX (1001)
*/
#define SUBX_MASK ENCW(1,1,1,1, 0,0,0,1, 0,0,1,1, 0,0,0,0)
#define SUBX_INST ENCW(1,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,0)
#define SUB_MASK ENCW(1,1,1,1, 0,0,0,0, 0,0,0,0, 0,0,0,0)
#define SUB_INST ENCW(1,0,0,1, 0,0,0,0, 0,0,0,0, 0,0,0,0)
/*
* Group CMP/CMPA/EOR (1011)
*/
#define CMPA_MASK ENCW(1,1,1,1, 0,0,0,0, 1,1,0,0, 0,0,0,0)
#define CMPA_INST ENCW(1,0,1,1, 0,0,0,0, 1,1,0,0, 0,0,0,0)
#define CMP_MASK ENCW(1,1,1,1, 0,0,0,1, 0,0,0,0, 0,0,0,0)
#define CMP_INST ENCW(1,0,1,1, 0,0,0,0, 0,0,0,0, 0,0,0,0)
#define CMPM_MASK ENCW(1,1,1,1, 0,0,0,1, 0,0,1,1, 1,0,0,0)
#define CMPM_INST ENCW(1,0,1,1, 0,0,0,1, 0,0,0,0, 1,0,0,0)
#define EOR_MASK ENCW(1,1,1,1, 0,0,0,1, 0,0,0,0, 0,0,0,0)
#define EOR_INST ENCW(1,0,1,1, 0,0,0,1, 0,0,0,0, 0,0,0,0)
/*
* Group branch. (0110)
*/
#define BRA_MASK ENCW(1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0)
#define BSR_MASK ENCW(1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0)
#define Bcc_MASK ENCW(1,1,1,1, 0,0,0,0, 0,0,0,0, 0,0,0,0)
#define BRA_INST ENCW(0,1,1,0, 0,0,0,0, 0,0,0,0, 0,0,0,0)
#define BSR_INST ENCW(0,1,1,0, 0,0,0,1, 0,0,0,0, 0,0,0,0)
#define Bcc_INST ENCW(0,1,1,0, 0,0,0,0, 0,0,0,0, 0,0,0,0)
/*
* Group SBCD/DIVx/OR (1000)
*/
#define PACKA_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,1,1, 1,0,0,0)
#define PACKD_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,1,1, 1,0,0,0)
#define PACKA_INST ENCW(1,0,0,0, 0,0,0,1, 0,1,0,0, 1,0,0,0)
#define PACKD_INST ENCW(1,0,0,0, 0,0,0,1, 0,1,0,0, 0,0,0,0)
#define UNPKA_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,1,1, 1,0,0,0)
#define UNPKD_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,1,1, 1,0,0,0)
#define UNPKA_INST ENCW(1,0,0,0, 0,0,0,1, 1,0,0,0, 1,0,0,0)
#define UNPKD_INST ENCW(1,0,0,0, 0,0,0,1, 1,0,0,0, 0,0,0,0)
#define SBCDA_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,1,1, 1,0,0,0)
#define SBCDD_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,1,1, 1,0,0,0)
#define SBCDA_INST ENCW(1,0,0,0, 0,0,0,1, 0,0,0,0, 1,0,0,0)
#define SBCDD_INST ENCW(1,0,0,0, 0,0,0,1, 0,0,0,0, 0,0,0,0)
#define DIVSW_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,0,0, 0,0,0,0)
#define DIVUW_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,0,0, 0,0,0,0)
#define DIVSW_INST ENCW(1,0,0,0, 0,0,0,1, 1,1,0,0, 0,0,0,0)
#define DIVUW_INST ENCW(1,0,0,0, 0,0,0,0, 1,1,0,0, 0,0,0,0)
#define OR_MASK ENCW(1,1,1,1, 0,0,0,0, 0,0,0,0, 0,0,0,0)
#define OR_INST ENCW(1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0)
/*
* Group AND/MUL/ABCD/EXG (1100)
*/
#define ABCDA_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,1,1, 1,0,0,0)
#define ABCDD_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,1,1, 1,0,0,0)
#define ABCDA_INST ENCW(1,1,0,0, 0,0,0,1, 0,0,0,0, 1,0,0,0)
#define ABCDD_INST ENCW(1,1,0,0, 0,0,0,1, 0,0,0,0, 0,0,0,0)
#define MULSW_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,0,0, 0,0,0,0)
#define MULUW_MASK ENCW(1,1,1,1, 0,0,0,1, 1,1,0,0, 0,0,0,0)
#define MULSW_INST ENCW(1,1,0,0, 0,0,0,1, 1,1,0,0, 0,0,0,0)
#define MULUW_INST ENCW(1,1,0,0, 0,0,0,0, 1,1,0,0, 0,0,0,0)
#define EXG_MASK ENCW(1,1,1,1, 0,0,0,1, 0,0,1,1, 0,0,0,0)
#define EXG_INST ENCW(1,1,0,0, 0,0,0,1, 0,0,0,0, 0,0,0,0)
#define AND_MASK ENCW(1,1,1,1, 0,0,0,0, 0,0,0,0, 0,0,0,0)
#define AND_INST ENCW(1,1,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0)
#define ENCFT(b5,b4,b3,b2,b1,b0) ENCB(0,0,b5,b4,b3,b2,b1,b0)
#define FABS ENCFT(0,1,1,0,0,0)
#define FACOS ENCFT(0,1,1,1,0,0)
#define FADD ENCFT(1,0,0,0,1,0)
#define FASIN ENCFT(0,0,1,1,0,0)
#define FATAN ENCFT(0,0,1,0,1,0)
#define FATANH ENCFT(0,0,1,1,0,1)
#define FCMP ENCFT(1,1,1,0,0,0)
#define FCOS ENCFT(0,1,1,1,0,1)
#define FCOSH ENCFT(0,1,1,0,0,1)
#define FDIV ENCFT(1,0,0,0,0,0)
#define FETOX ENCFT(0,1,0,0,0,0)
#define FETOXM1 ENCFT(0,0,1,0,0,0)
#define FGETEXP ENCFT(0,1,1,1,1,0)
#define FGETMAN ENCFT(0,1,1,1,1,1)
#define FINT ENCFT(0,0,0,0,0,1)
#define FINTRZ ENCFT(0,0,0,0,1,1)
#define FLOG10 ENCFT(0,1,0,1,0,1)
#define FLOG2 ENCFT(0,1,0,1,1,0)
#define FLOGN ENCFT(0,1,0,1,0,0)
#define FLOGNP1 ENCFT(0,0,0,1,1,0)
#define FMOD ENCFT(1,0,0,0,0,1)
#define FMOVE ENCFT(0,0,0,0,0,0)
#define FMUL ENCFT(1,0,0,0,1,1)
#define FNEG ENCFT(0,1,1,0,1,0)
#define FREM ENCFT(1,0,0,1,0,1)
#undef FSCALE
#define FSCALE ENCFT(1,0,0,1,1,0)
#define FSGLDIV ENCFT(1,0,0,1,0,0)
#define FSGLMUL ENCFT(1,0,0,1,1,1)
#define FSIN ENCFT(0,0,1,1,1,0)
#define FSINH ENCFT(0,0,0,0,1,0)
#define FSQRT ENCFT(0,0,0,1,0,0)
#define FSUB ENCFT(1,0,1,0,0,0)
#define FTAN ENCFT(0,0,1,1,1,1)
#define FTANH ENCFT(0,0,1,0,0,1)
#define FTENTOX ENCFT(0,1,0,0,1,0)
#define FTST ENCFT(1,1,1,0,1,0)
#define FTWOTOX ENCFT(0,1,0,0,0,1)
enum getmod_flag { GETMOD_BEFORE = -1, GETMOD_AFTER = -2 };
enum opcode_flags {
CPU_000 = 0x1, CPU_010 = 0x2, CPU_020 = 0x4, CPU_030 = 0x8,
CPU_040 = 0x10, FPU_881 = 0x40, FPU_882 = 0x80, FPU_040 = 0x100,
MMU_851 = 0x400, MMU_030 = 0x800, MMU_040 = 0x1000,
CPU_ANY = CPU_000 | CPU_010 | CPU_020 | CPU_030 | CPU_040,
FPU_ANY = FPU_881 | FPU_882 | FPU_040,
MMU_ANY = MMU_851 | MMU_030 | MMU_040,
CPU_020UP = CPU_020 | CPU_030 | CPU_040
};
enum mod_types {
DR_DIR = 0,
AR_DIR, AR_IND, AR_INC, AR_DEC,
AR_DIS, AR_IDX, MOD_SPECIAL
};
enum sizes { SIZE_BYTE = sizeof(char), SIZE_WORD = sizeof(short),
SIZE_LONG = sizeof(long), SIZE_SINGLE = 5, SIZE_QUAD = 6,
SIZE_DOUBLE = SIZE_QUAD, SIZE_EXTENDED = 7, SIZE_PACKED = 8 };
/* Disassembler structure, the interface to the application */
struct DisasmPara_68k {
m68k_word *instr; /* pointer to instruction to disassemble */
m68k_word *iaddr; /* instr.addr., usually the same as instr */
char *opcode; /* buffer for opcode, min. 16 chars. */
char *operands; /* operand buffer, min. 128 chars. */
int radix; /* base 2, 8, 10, 16 ... */
/* call-back functions for symbolic debugger support */
unsigned long (*get_areg)(int); /* returns current value of reg. An */
char *(*find_symbol)(unsigned long,unsigned long *);
/* finds closest symbol to addr and */
/* returns (positive) difference and name */
/* changed by disassembler: */
unsigned char type; /* type of instruction, see below */
unsigned char flags; /* additional flags */
char reserved;
char areg; /* address reg. for displacement (PC=-1) */
int displacement; /* branch- or d16-displacement */
};
struct dis_buffer {
struct DisasmPara_68k *dp; /* link to DisasmPara */
short *val; /* (real) pointer to memory. */
short *sval; /* simulated memory pointer for address calculations (phx) */
char *dasm; /* actual dasm. */
char *casm; /* current position in dasm. */
char *info; /* extra info. */
char *cinfo; /* current position in info. */
int used; /* length used. */
int mit; /* use mit syntax. */
};
typedef struct dis_buffer dis_buffer_t;
#define ISBITSET(val,b) ((val) & (1 << (b)))
#define BITFIELD_MASK(sb,eb) (((1 << ((sb) + 1))-1) & (~((1 << (eb))-1)))
#define BITFIELD(val,sb,eb) ((BITFIELD_MASK(sb,eb) & (val)) >> (eb))
#define OPCODE_MAP(x) (BITFIELD(x,15,12))
#ifdef __STDC__
#define IS_INST(inst,val) ((inst ## _MASK & (val)) == inst ## _INST)
#else
#define IS_INST(inst,val) ((inst/**/_MASK & (val)) == inst/**/_INST)
#endif
#define PRINT_FPREG(dbuf, reg) addstr(dbuf, fpregs[reg])
#define PRINT_DREG(dbuf, reg) addstr(dbuf, dregs[reg])
#define PRINT_AREG(dbuf, reg) addstr(dbuf, aregs[reg])
#define NBBY 256 /*@@@*/
#ifndef INT_MAX
#define INT_MAX 0x7fffffff;
#endif
#define DB_STGY_PROC 0 /*@@@*/
#define DB_STGY_ANY 0 /*@@@*/
/* common Unix typedefs used in m68k_disasm.c */
#if !defined(_SYS_TYPES_H)
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
#endif
typedef unsigned long vm68k_offset_t;
typedef unsigned long db_expr_t; /*@@@*/
typedef const char *db_sym_t; /*@@@*/
/* m68k_disasm.o prototypes */
#ifndef M68K_DISASM_C
extern m68k_word *M68k_Disassemble(struct DisasmPara_68k *);
#if 0
extern void get_modregstr_moto(dis_buffer_t *dbuf, int bit, int mod,
int sz, int dd);
extern void get_modregstr_mit(dis_buffer_t *dbuf, int bit, int mod,
int sz, int dd));
extern u_long get_areg_val(int reg);
#endif
#endif
#endif /* M68K_DISASM_H */

View file

@ -26,7 +26,8 @@ int r_asm_ppc_disasm(struct r_asm_t *a, u8 *buf, u64 len)
PPC_Disassemble(&dp, a->big_endian);
r_hex_bin2str((u8*)bof, 4, a->buf_hex);
sprintf(a->buf_asm, "%s %s", opcode, operands);
memcpy(a->buf, buf, 4);
memcpy(a->buf, bof, 4);
a->inst_len = 4;
return 4;
return a->inst_len;
}

View file

@ -57,6 +57,14 @@ int r_asm_set_arch(struct r_asm_t *a, int arch)
a->r_asm_disasm = &r_asm_bf_disasm;
a->r_asm_asm = NULL;
break;
case R_ASM_ARCH_CSR:
a->r_asm_disasm = &r_asm_csr_disasm;
a->r_asm_asm = NULL;
break;
case R_ASM_ARCH_M68K:
a->r_asm_disasm = &r_asm_m68k_disasm;
a->r_asm_asm = NULL;
break;
default:
a->r_asm_disasm = NULL;
a->r_asm_asm = NULL;

View file

@ -1,6 +1,6 @@
LDFLAGS=-L../../util -lr_util -L../ -lr_asm
LDFLAGS_BIN=${LDFLAGS} -lr_bin -L../../bin
all: disasm_x86 disasm_arm disasm_mips disasm_sparc disasm_ppc disasm_bf asm_x86 rasm2 realloc_x86 aop_x86
all: disasm_x86 disasm_arm disasm_mips disasm_sparc disasm_ppc disasm_csr disasm_m68k disasm_bf asm_x86 rasm2 realloc_x86
disasm_x86:
${CC} -g -I ../../include disasm_x86.c ${LDFLAGS} -o disasm_x86
@ -17,6 +17,12 @@ disasm_sparc:
disasm_ppc:
${CC} -g -I ../../include disasm_ppc.c ${LDFLAGS} -o disasm_ppc
disasm_csr:
${CC} -g -I ../../include disasm_csr.c ${LDFLAGS} -o disasm_csr
disasm_m68k:
${CC} -g -I ../../include disasm_m68k.c ${LDFLAGS} -o disasm_m68k
disasm_bf:
${CC} -g -I ../../include disasm_bf.c ${LDFLAGS} -o disasm_bf
@ -29,8 +35,5 @@ rasm2:
realloc_x86:
${CC} -g -I ../../include realloc_x86.c ${LDFLAGS_BIN} -o realloc_x86
aop_x86:
${CC} -g -I ../../include aop_x86.c ${LDFLAGS_BIN} -o aop_x86
clean:
rm -f disasm_x86 disasm_arm disasm_mips disasm_sparc disasm_ppc disasm_bf asm_x86 rasm2 realloc_x86 aop_x86
rm -f disasm_x86 disasm_arm disasm_mips disasm_sparc disasm_ppc disasm_csr disasm_m68k disasm_bf asm_x86 rasm2 realloc_x86

32
libr/asm/t/disasm_csr.c Normal file
View file

@ -0,0 +1,32 @@
/* radare - LGPL - Copyright 2009 nibble<.ds@gmail.com> */
#include <stdio.h>
#include <stdlib.h>
#include <r_types.h>
#include <r_asm.h>
int main()
{
struct r_asm_t a;
u8 *buf = "\xd2\xa1\x88\xe2";
int ret = 0;
u64 idx = 0, len = 4;
r_asm_init(&a);
r_asm_set_arch(&a, R_ASM_ARCH_CSR);
r_asm_set_bits(&a, 32);
r_asm_set_big_endian(&a, R_FALSE);
r_asm_set_syntax(&a, R_ASM_SYN_INTEL);
while (idx < len) {
r_asm_set_pc(&a, 0x000089d8 + idx);
ret = r_asm_disasm(&a, buf+idx, len-idx);
printf("DISASM %s HEX %s\n", a.buf_asm, a.buf_hex);
idx += ret;
}
return 0;
}

32
libr/asm/t/disasm_m68k.c Normal file
View file

@ -0,0 +1,32 @@
/* radare - LGPL - Copyright 2009 nibble<.ds@gmail.com> */
#include <stdio.h>
#include <stdlib.h>
#include <r_types.h>
#include <r_asm.h>
int main()
{
struct r_asm_t a;
u8 *buf = "\x8b\x10\x85\xd2";
int ret = 0;
u64 idx = 0, len = 4;
r_asm_init(&a);
r_asm_set_arch(&a, R_ASM_ARCH_M68K);
r_asm_set_bits(&a, 32);
r_asm_set_big_endian(&a, R_FALSE);
r_asm_set_syntax(&a, R_ASM_SYN_INTEL);
while (idx < len) {
r_asm_set_pc(&a, 0x000089d8 + idx);
ret = r_asm_disasm(&a, buf+idx, len-idx);
printf("DISASM %s HEX %s\n", a.buf_asm, a.buf_hex);
idx += ret;
}
return 0;
}

View file

@ -94,4 +94,10 @@ int r_asm_ppc_disasm(struct r_asm_t *a, u8 *buf, u64 len);
/* arch/bf/asm.c */
int r_asm_bf_disasm(struct r_asm_t *a, u8 *buf, u64 len);
/* arch/csr/asm.c */
int r_asm_csr_disasm(struct r_asm_t *a, u8 *buf, u64 len);
/* arch/m68k/asm.c */
int r_asm_m68k_disasm(struct r_asm_t *a, u8 *buf, u64 len);
#endif