Line 87... |
Line 87... |
# define EFN &l_none
|
# define EFN &l_none
|
# define EF(func) EFN
|
# define EF(func) EFN
|
# define EFI EFN
|
# define EFI EFN
|
#endif /* HAVE_EXECUTION */
|
#endif /* HAVE_EXECUTION */
|
|
|
CONST struct or32_opcode or32_opcodes[] = {
|
CONST struct or32_opcode or1ksim_or32_opcodes[] = {
|
|
|
{"l.j", "N", "00 0x0 NNNNN NNNNN NNNN NNNN NNNN NNNN",
|
{"l.j", "N", "00 0x0 NNNNN NNNNN NNNN NNNN NNNN NNNN",
|
EF (l_j), OR32_IF_DELAY, it_jump},
|
EF (l_j), OR32_IF_DELAY, it_jump},
|
{"l.jal", "N", "00 0x1 NNNNN NNNNN NNNN NNNN NNNN NNNN",
|
{"l.jal", "N", "00 0x1 NNNNN NNNNN NNNN NNNN NNNN NNNN",
|
EF (l_jal), OR32_IF_DELAY, it_jump},
|
EF (l_jal), OR32_IF_DELAY, it_jump},
|
Line 574... |
Line 574... |
|
|
#undef EFI
|
#undef EFI
|
#undef EFN
|
#undef EFN
|
#undef EF
|
#undef EF
|
|
|
CONST int num_opcodes =
|
static CONST int NUM_OPCODES =
|
((sizeof (or32_opcodes)) / (sizeof (struct or32_opcode))) - 1;
|
((sizeof (or1ksim_or32_opcodes)) / (sizeof (struct or32_opcode))) - 1;
|
|
|
/* Calculates instruction length in bytes. Always 4 for OR32. */
|
/* Calculates instruction length in bytes. Always 4 for OR32. */
|
int
|
int
|
insn_len (int insn_index)
|
or1ksim_insn_len (int insn_index)
|
{
|
{
|
insn_index = 0; /* Just to get rid that warning. */
|
insn_index = 0; /* Just to get rid that warning. */
|
return 4;
|
return 4;
|
}
|
}
|
|
|
/* Is individual insn's operand signed or unsigned? */
|
/* Is individual insn's operand signed or unsigned? */
|
int
|
static int
|
letter_signed (char l)
|
letter_signed (char l)
|
{
|
{
|
CONST struct or32_letter *pletter;
|
CONST struct or32_letter *pletter;
|
|
|
for (pletter = or32_letters; pletter->letter != '\0'; pletter++)
|
for (pletter = or32_letters; pletter->letter != '\0'; pletter++)
|
Line 603... |
Line 603... |
|
|
/* Simple cache for letter ranges */
|
/* Simple cache for letter ranges */
|
static int range_cache[256] = { 0 };
|
static int range_cache[256] = { 0 };
|
|
|
/* Number of letters in the individual lettered operand. */
|
/* Number of letters in the individual lettered operand. */
|
int
|
static int
|
letter_range (char l)
|
letter_range (char l)
|
{
|
{
|
CONST struct or32_opcode *pinsn;
|
CONST struct or32_opcode *pinsn;
|
char *enc;
|
char *enc;
|
int range = 0;
|
int range = 0;
|
|
|
/* Is value cached? */
|
/* Is value cached? */
|
if ((range = range_cache[(unsigned char) l]))
|
if ((range = range_cache[(unsigned char) l]))
|
return range;
|
return range;
|
|
|
for (pinsn = or32_opcodes; strlen (pinsn->name); pinsn++)
|
for (pinsn = or1ksim_or32_opcodes; strlen (pinsn->name); pinsn++)
|
{
|
{
|
if (strchr (pinsn->encoding, l))
|
if (strchr (pinsn->encoding, l))
|
{
|
{
|
for (enc = pinsn->encoding; *enc != '\0'; enc++)
|
for (enc = pinsn->encoding; *enc != '\0'; enc++)
|
if ((*enc == '0') && (*(enc + 1) == 'x'))
|
if ((*enc == '0') && (*(enc + 1) == 'x'))
|
Line 631... |
Line 631... |
|
|
printf ("\nABORT: letter_range(%c): Never used letter.\n", l);
|
printf ("\nABORT: letter_range(%c): Never used letter.\n", l);
|
exit (1);
|
exit (1);
|
}
|
}
|
|
|
/* MM: Returns index of given instruction name. */
|
|
int
|
|
insn_index (char *insn)
|
|
{
|
|
int i, found = -1;
|
|
for (i = 0; i < num_opcodes; i++)
|
|
if (!strcmp (or32_opcodes[i].name, insn))
|
|
{
|
|
found = i;
|
|
break;
|
|
}
|
|
return found;
|
|
}
|
|
|
|
/* Returns name of the specified instruction index */
|
/* Returns name of the specified instruction index */
|
CONST char *
|
CONST char *
|
insn_name (int index)
|
or1ksim_insn_name (int index)
|
{
|
{
|
if (index >= 0 && index < num_opcodes)
|
if (index >= 0 && index < NUM_OPCODES)
|
return or32_opcodes[index].name;
|
return or1ksim_or32_opcodes[index].name;
|
else
|
else
|
return "???";
|
return "???";
|
}
|
}
|
|
|
#if defined(HAVE_EXECUTION) && SIMPLE_EXECUTION
|
|
void
|
|
l_none (struct iqueue_entry *current)
|
|
{
|
|
}
|
|
#elif defined(HAVE_EXECUTION) && DYNAMIC_EXECUTION
|
|
void
|
|
l_none (struct op_queue *opq, int *param_t, int delay_slot)
|
|
{
|
|
}
|
|
#else
|
|
void
|
|
l_none ()
|
|
{
|
|
}
|
|
#endif
|
|
|
|
/*** Finite automata for instruction decoding building code ***/
|
/*** Finite automata for instruction decoding building code ***/
|
|
|
/* Find symbols in encoding. */
|
/* Find symbols in encoding. */
|
unsigned long
|
static unsigned long
|
insn_extract (param_ch, enc_initial)
|
insn_extract (param_ch, enc_initial)
|
char param_ch;
|
char param_ch;
|
char *enc_initial;
|
char *enc_initial;
|
{
|
{
|
char *enc;
|
char *enc;
|
Line 717... |
Line 686... |
|
|
#ifndef MIN
|
#ifndef MIN
|
# define MIN(x,y) ((x) < (y) ? (x) : (y))
|
# define MIN(x,y) ((x) < (y) ? (x) : (y))
|
#endif
|
#endif
|
|
|
unsigned long *automata;
|
unsigned long *or1ksim_automata;
|
int nuncovered;
|
int nuncovered;
|
int curpass = 0;
|
int curpass = 0;
|
|
|
/* MM: Struct that holds runtime build information about instructions. */
|
/* MM: Struct that holds runtime build information about instructions. */
|
struct temp_insn_struct *ti;
|
struct temp_insn_struct *or1ksim_ti;
|
|
|
|
static struct insn_op_struct *op_data;
|
|
|
struct insn_op_struct *op_data, **op_start;
|
struct insn_op_struct **or1ksim_op_start;
|
|
|
static void
|
static void
|
or32_debug (int level, const char *format, ...)
|
or32_debug (int level, const char *format, ...)
|
{
|
{
|
#if DEBUG
|
#if DEBUG
|
Line 752... |
Line 723... |
{
|
{
|
int best_first = 0, best_len = 0, i, last_match = -1, ninstr = 0;
|
int best_first = 0, best_len = 0, i, last_match = -1, ninstr = 0;
|
unsigned long cur_mask = mask;
|
unsigned long cur_mask = mask;
|
unsigned long *next;
|
unsigned long *next;
|
|
|
for (i = 0; i < num_opcodes; i++)
|
for (i = 0; i < NUM_OPCODES; i++)
|
if (ti[i].in_pass == pass)
|
if (or1ksim_ti[i].in_pass == pass)
|
{
|
{
|
cur_mask &= ti[i].insn_mask;
|
cur_mask &= or1ksim_ti[i].insn_mask;
|
ninstr++;
|
ninstr++;
|
last_match = i;
|
last_match = i;
|
}
|
}
|
|
|
or32_debug (8, "%08X %08lX\n", mask, cur_mask);
|
or32_debug (8, "%08X %08lX\n", mask, cur_mask);
|
if (ninstr == 0)
|
if (ninstr == 0)
|
return 0;
|
return 0;
|
if (ninstr == 1)
|
if (ninstr == 1)
|
{
|
{
|
/* Leaf holds instruction index. */
|
/* Leaf holds instruction index. */
|
or32_debug (8, "%i>I%i %s\n", cur - automata, last_match,
|
or32_debug (8, "%i>I%i %s\n", cur - or1ksim_automata, last_match,
|
or32_opcodes[last_match].name);
|
or1ksim_or32_opcodes[last_match].name);
|
*cur = LEAF_FLAG | last_match;
|
*cur = LEAF_FLAG | last_match;
|
cur++;
|
cur++;
|
nuncovered--;
|
nuncovered--;
|
}
|
}
|
else
|
else
|
Line 799... |
Line 770... |
or32_debug (9, "\n");
|
or32_debug (9, "\n");
|
if (!best_len)
|
if (!best_len)
|
{
|
{
|
fprintf (stderr, "%i instructions match mask 0x%08X:\n", ninstr,
|
fprintf (stderr, "%i instructions match mask 0x%08X:\n", ninstr,
|
mask);
|
mask);
|
for (i = 0; i < num_opcodes; i++)
|
for (i = 0; i < NUM_OPCODES; i++)
|
if (ti[i].in_pass == pass)
|
if (or1ksim_ti[i].in_pass == pass)
|
fprintf (stderr, "%s ", or32_opcodes[i].name);
|
fprintf (stderr, "%s ", or1ksim_or32_opcodes[i].name);
|
|
|
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
exit (1);
|
exit (1);
|
}
|
}
|
or32_debug (8, "%i> #### %i << %i (%i) ####\n", cur - automata, best_len,
|
or32_debug (8, "%i> #### %i << %i (%i) ####\n", cur - or1ksim_automata, best_len,
|
best_first, ninstr);
|
best_first, ninstr);
|
*cur = best_first;
|
*cur = best_first;
|
cur++;
|
cur++;
|
*cur = (1 << best_len) - 1;
|
*cur = (1 << best_len) - 1;
|
cur++;
|
cur++;
|
Line 822... |
Line 793... |
for (i = 0; i < (1 << (unsigned long) best_len); i++)
|
for (i = 0; i < (1 << (unsigned long) best_len); i++)
|
{
|
{
|
int j;
|
int j;
|
unsigned long *c;
|
unsigned long *c;
|
curpass++;
|
curpass++;
|
for (j = 0; j < num_opcodes; j++)
|
for (j = 0; j < NUM_OPCODES; j++)
|
if (ti[j].in_pass == pass
|
if (or1ksim_ti[j].in_pass == pass
|
&& ((ti[j].insn >> best_first) & cur_mask) ==
|
&& ((or1ksim_ti[j].insn >> best_first) & cur_mask) ==
|
(unsigned long) i
|
(unsigned long) i
|
&& ((ti[j].insn_mask >> best_first) & cur_mask) == cur_mask)
|
&& ((or1ksim_ti[j].insn_mask >> best_first) & cur_mask) == cur_mask)
|
ti[j].in_pass = curpass;
|
or1ksim_ti[j].in_pass = curpass;
|
|
|
or32_debug (9, "%08X %08lX %i\n", mask, cur_mask, best_first);
|
or32_debug (9, "%08X %08lX %i\n", mask, cur_mask, best_first);
|
c = cover_insn (cur, curpass, mask & (~(cur_mask << best_first)));
|
c = cover_insn (cur, curpass, mask & (~(cur_mask << best_first)));
|
if (c)
|
if (c)
|
{
|
{
|
or32_debug (8, "%i> #%X -> %u\n", next - automata, i,
|
or32_debug (8, "%i> #%X -> %u\n", next - or1ksim_automata, i,
|
cur - automata);
|
cur - or1ksim_automata);
|
*next = cur - automata;
|
*next = cur - or1ksim_automata;
|
cur = c;
|
cur = c;
|
}
|
}
|
else
|
else
|
{
|
{
|
or32_debug (8, "%i> N/A\n", next - automata);
|
or32_debug (8, "%i> N/A\n", next - or1ksim_automata);
|
*next = 0;
|
*next = 0;
|
}
|
}
|
next++;
|
next++;
|
}
|
}
|
}
|
}
|
Line 864... |
Line 835... |
}
|
}
|
return c;
|
return c;
|
}
|
}
|
|
|
/* Utility function, which converts parameters from or32_opcode format to more binary form.
|
/* Utility function, which converts parameters from or32_opcode format to more binary form.
|
Parameters are stored in ti struct. */
|
Parameters are stored in or1ksim_ti struct. */
|
|
|
static struct insn_op_struct *
|
static struct insn_op_struct *
|
parse_params (CONST struct or32_opcode *opcode, struct insn_op_struct *cur)
|
parse_params (CONST struct or32_opcode *opcode, struct insn_op_struct *cur)
|
{
|
{
|
char *args = opcode->args;
|
char *args = opcode->args;
|
Line 982... |
Line 953... |
cur++;
|
cur++;
|
return cur;
|
return cur;
|
}
|
}
|
|
|
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
/*!Constructs new automata based on or32_opcodes array.
|
/*!Constructs new automata based on or1ksim_or32_opcodes array.
|
|
|
@param[in] quiet If non-zero (TRUE) do not print informational messages. */
|
@param[in] quiet If non-zero (TRUE) do not print informational messages. */
|
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
void
|
void
|
build_automata (int quiet)
|
or1ksim_build_automata (int quiet)
|
{
|
{
|
int i;
|
int i;
|
unsigned long *end;
|
unsigned long *end;
|
struct insn_op_struct *cur;
|
struct insn_op_struct *cur;
|
|
|
automata =
|
or1ksim_automata =
|
(unsigned long *) malloc (MAX_AUTOMATA_SIZE * sizeof (unsigned long));
|
(unsigned long *) malloc (MAX_AUTOMATA_SIZE * sizeof (unsigned long));
|
ti =
|
or1ksim_ti =
|
(struct temp_insn_struct *) malloc (sizeof (struct temp_insn_struct) *
|
(struct temp_insn_struct *) malloc (sizeof (struct temp_insn_struct) *
|
num_opcodes);
|
NUM_OPCODES);
|
|
|
nuncovered = num_opcodes;
|
nuncovered = NUM_OPCODES;
|
|
|
#ifdef HAVE_EXECUTION
|
#ifdef HAVE_EXECUTION
|
if (!quiet)
|
if (!quiet)
|
{
|
{
|
printf ("Building automata... ");
|
printf ("Building automata... ");
|
}
|
}
|
#endif
|
#endif
|
|
|
/* Build temporary information about instructions. */
|
/* Build temporary information about instructions. */
|
for (i = 0; i < num_opcodes; i++)
|
for (i = 0; i < NUM_OPCODES; i++)
|
{
|
{
|
unsigned long ones, zeros;
|
unsigned long ones, zeros;
|
char *encoding = or32_opcodes[i].encoding;
|
char *encoding = or1ksim_or32_opcodes[i].encoding;
|
ones = insn_extract ('1', encoding);
|
ones = insn_extract ('1', encoding);
|
zeros = insn_extract ('0', encoding);
|
zeros = insn_extract ('0', encoding);
|
ti[i].insn_mask = ones | zeros;
|
or1ksim_ti[i].insn_mask = ones | zeros;
|
ti[i].insn = ones;
|
or1ksim_ti[i].insn = ones;
|
ti[i].in_pass = curpass = 0;
|
or1ksim_ti[i].in_pass = curpass = 0;
|
/*debug(9, "%s: %s %08X %08X\n", or32_opcodes[i].name,
|
/*debug(9, "%s: %s %08X %08X\n", or1ksim_or32_opcodes[i].name,
|
or32_opcodes[i].encoding, ti[i].insn_mask, ti[i].insn); */
|
or1ksim_or32_opcodes[i].encoding, or1ksim_ti[i].insn_mask, or1ksim_ti[i].insn); */
|
}
|
}
|
|
|
/* Until all are covered search for best criteria to separate them. */
|
/* Until all are covered search for best criteria to separate them. */
|
end = cover_insn (automata, curpass, 0xFFFFFFFF);
|
end = cover_insn (or1ksim_automata, curpass, 0xFFFFFFFF);
|
if (end - automata > MAX_AUTOMATA_SIZE)
|
if (end - or1ksim_automata > MAX_AUTOMATA_SIZE)
|
{
|
{
|
fprintf (stderr, "Automata too large. Increase MAX_AUTOMATA_SIZE.");
|
fprintf (stderr, "Automata too large. Increase MAX_AUTOMATA_SIZE.");
|
exit (1);
|
exit (1);
|
}
|
}
|
#ifdef HAVE_EXECUTION
|
#ifdef HAVE_EXECUTION
|
if (!quiet)
|
if (!quiet)
|
{
|
{
|
printf ("done, num uncovered: %i/%i.\n", nuncovered, num_opcodes);
|
printf ("done, num uncovered: %i/%i.\n", nuncovered, NUM_OPCODES);
|
}
|
}
|
#endif
|
#endif
|
|
|
#ifdef HAVE_EXECUTION
|
#ifdef HAVE_EXECUTION
|
if (!quiet)
|
if (!quiet)
|
Line 1045... |
Line 1016... |
}
|
}
|
#endif
|
#endif
|
op_data =
|
op_data =
|
(struct insn_op_struct *) malloc (MAX_OP_TABLE_SIZE *
|
(struct insn_op_struct *) malloc (MAX_OP_TABLE_SIZE *
|
sizeof (struct insn_op_struct));
|
sizeof (struct insn_op_struct));
|
op_start =
|
or1ksim_op_start =
|
(struct insn_op_struct **) malloc (num_opcodes *
|
(struct insn_op_struct **) malloc (NUM_OPCODES *
|
sizeof (struct insn_op_struct *));
|
sizeof (struct insn_op_struct *));
|
cur = op_data;
|
cur = op_data;
|
for (i = 0; i < num_opcodes; i++)
|
for (i = 0; i < NUM_OPCODES; i++)
|
{
|
{
|
op_start[i] = cur;
|
or1ksim_op_start[i] = cur;
|
cur = parse_params (&or32_opcodes[i], cur);
|
cur = parse_params (&or1ksim_or32_opcodes[i], cur);
|
if (cur - op_data > MAX_OP_TABLE_SIZE)
|
if (cur - op_data > MAX_OP_TABLE_SIZE)
|
{
|
{
|
fprintf (stderr,
|
fprintf (stderr,
|
"Operands table too small, increase MAX_OP_TABLE_SIZE.\n");
|
"Operands table too small, increase MAX_OP_TABLE_SIZE.\n");
|
exit (1);
|
exit (1);
|
Line 1069... |
Line 1040... |
}
|
}
|
#endif
|
#endif
|
}
|
}
|
|
|
void
|
void
|
destruct_automata ()
|
or1ksim_destruct_automata ()
|
{
|
{
|
free (ti);
|
free (or1ksim_ti);
|
free (automata);
|
free (or1ksim_automata);
|
free (op_data);
|
free (op_data);
|
free (op_start);
|
free (or1ksim_op_start);
|
}
|
}
|
|
|
/* Decodes instruction and returns instruction index. */
|
/* Decodes instruction and returns instruction index. */
|
int
|
int
|
insn_decode (unsigned int insn)
|
or1ksim_insn_decode (unsigned int insn)
|
{
|
{
|
unsigned long *a = automata;
|
unsigned long *a = or1ksim_automata;
|
int i;
|
int i;
|
while (!(*a & LEAF_FLAG))
|
while (!(*a & LEAF_FLAG))
|
{
|
{
|
unsigned int first = *a;
|
unsigned int first = *a;
|
//debug(9, "%i ", a - automata);
|
//debug(9, "%i ", a - or1ksim_automata);
|
a++;
|
a++;
|
i = (insn >> first) & *a;
|
i = (insn >> first) & *a;
|
a++;
|
a++;
|
if (!*(a + i))
|
if (!*(a + i))
|
{ /* Invalid instruction found? */
|
{ /* Invalid instruction found? */
|
//debug(9, "XXX\n", i);
|
//debug(9, "XXX\n", i);
|
return -1;
|
return -1;
|
}
|
}
|
a = automata + *(a + i);
|
a = or1ksim_automata + *(a + i);
|
}
|
}
|
i = *a & ~LEAF_FLAG;
|
i = *a & ~LEAF_FLAG;
|
//debug(9, "%i\n", i);
|
//debug(9, "%i\n", i);
|
/* Final check - do we have direct match?
|
/* Final check - do we have direct match?
|
(based on or32_opcodes this should be the only possibility,
|
(based on or1ksim_or32_opcodes this should be the only possibility,
|
but in case of invalid/missing instruction we must perform a check) */
|
but in case of invalid/missing instruction we must perform a check) */
|
if ((ti[i].insn_mask & insn) == ti[i].insn)
|
if ((or1ksim_ti[i].insn_mask & insn) == or1ksim_ti[i].insn)
|
return i;
|
return i;
|
else
|
else
|
return -1;
|
return -1;
|
}
|
}
|
|
|
static char disassembled_str[50];
|
static char disassembled_str[50];
|
char *disassembled = &disassembled_str[0];
|
char *or1ksim_disassembled = &disassembled_str[0];
|
|
|
/* Automagically does zero- or sign- extension and also finds correct
|
/* Automagically does zero- or sign- extension and also finds correct
|
sign bit position if sign extension is correct extension. Which extension
|
sign bit position if sign extension is correct extension. Which extension
|
is proper is figured out from letter description. */
|
is proper is figured out from letter description. */
|
|
|
unsigned long
|
unsigned long
|
extend_imm (unsigned long imm, char l)
|
or1ksim_extend_imm (unsigned long imm, char l)
|
{
|
{
|
unsigned long mask;
|
unsigned long mask;
|
int letter_bits;
|
int letter_bits;
|
|
|
/* First truncate all bits above valid range for this letter
|
/* First truncate all bits above valid range for this letter
|
Line 1135... |
Line 1106... |
|
|
return imm;
|
return imm;
|
}
|
}
|
|
|
unsigned long
|
unsigned long
|
or32_extract (param_ch, enc_initial, insn)
|
or1ksim_or32_extract (param_ch, enc_initial, insn)
|
char param_ch;
|
char param_ch;
|
char *enc_initial;
|
char *enc_initial;
|
unsigned long insn;
|
unsigned long insn;
|
{
|
{
|
char *enc;
|
char *enc;
|
Line 1156... |
Line 1127... |
else
|
else
|
param_pos++;
|
param_pos++;
|
}
|
}
|
|
|
#if DEBUG
|
#if DEBUG
|
printf ("or32_extract: %x ", param_pos);
|
printf ("or1ksim_or32_extract: %x ", param_pos);
|
#endif
|
#endif
|
opc_pos = 32;
|
opc_pos = 32;
|
for (enc = enc_initial; *enc != '\0';)
|
for (enc = enc_initial; *enc != '\0';)
|
if ((*enc == '0') && (*(enc + 1) == 'x'))
|
if ((*enc == '0') && (*(enc + 1) == 'x'))
|
{
|
{
|
Line 1224... |
Line 1195... |
char *dest;
|
char *dest;
|
char param_ch;
|
char param_ch;
|
char *encoding;
|
char *encoding;
|
unsigned long insn;
|
unsigned long insn;
|
{
|
{
|
int regnum = or32_extract (param_ch, encoding, insn);
|
int regnum = or1ksim_or32_extract (param_ch, encoding, insn);
|
|
|
sprintf (dest, "r%d", regnum);
|
sprintf (dest, "r%d", regnum);
|
while (*dest)
|
while (*dest)
|
dest++;
|
dest++;
|
return dest;
|
return dest;
|
Line 1241... |
Line 1212... |
char *dest;
|
char *dest;
|
char param_ch;
|
char param_ch;
|
char *encoding;
|
char *encoding;
|
unsigned long insn;
|
unsigned long insn;
|
{
|
{
|
int imm = or32_extract (param_ch, encoding, insn);
|
int imm = or1ksim_or32_extract (param_ch, encoding, insn);
|
|
|
imm = extend_imm (imm, param_ch);
|
imm = or1ksim_extend_imm (imm, param_ch);
|
|
|
if (letter_signed (param_ch))
|
if (letter_signed (param_ch))
|
{
|
{
|
if (imm < 0)
|
if (imm < 0)
|
sprintf (dest, "%d", imm);
|
sprintf (dest, "%d", imm);
|
Line 1263... |
Line 1234... |
|
|
/* Disassemble one instruction from insn to disassemble.
|
/* Disassemble one instruction from insn to disassemble.
|
Return the size of the instruction. */
|
Return the size of the instruction. */
|
|
|
int
|
int
|
disassemble_insn (insn)
|
or1ksim_disassemble_insn (insn)
|
unsigned long insn;
|
unsigned long insn;
|
{
|
{
|
return disassemble_index (insn, insn_decode (insn));
|
return or1ksim_disassemble_index (insn, or1ksim_insn_decode (insn));
|
}
|
}
|
|
|
/* Disassemble one instruction from insn index.
|
/* Disassemble one instruction from insn index.
|
Return the size of the instruction. */
|
Return the size of the instruction. */
|
|
|
int
|
int
|
disassemble_index (insn, index)
|
or1ksim_disassemble_index (insn, index)
|
unsigned long insn;
|
unsigned long insn;
|
int index;
|
int index;
|
{
|
{
|
char *dest = disassembled;
|
char *dest = or1ksim_disassembled;
|
if (index >= 0)
|
if (index >= 0)
|
{
|
{
|
struct or32_opcode const *opcode = &or32_opcodes[index];
|
struct or32_opcode const *opcode = &or1ksim_or32_opcodes[index];
|
char *s;
|
char *s;
|
|
|
strcpy (dest, opcode->name);
|
strcpy (dest, opcode->name);
|
while (*dest)
|
while (*dest)
|
dest++;
|
dest++;
|
Line 1294... |
Line 1265... |
for (s = opcode->args; *s != '\0'; ++s)
|
for (s = opcode->args; *s != '\0'; ++s)
|
{
|
{
|
switch (*s)
|
switch (*s)
|
{
|
{
|
case '\0':
|
case '\0':
|
return insn_len (insn);
|
return or1ksim_insn_len (insn);
|
|
|
case 'r':
|
case 'r':
|
dest = or32_print_register (dest, *++s, opcode->encoding, insn);
|
dest = or32_print_register (dest, *++s, opcode->encoding, insn);
|
break;
|
break;
|
|
|
Line 1319... |
Line 1290... |
/* This used to be %8x for binutils. */
|
/* This used to be %8x for binutils. */
|
sprintf (dest, ".word 0x%08lx", insn);
|
sprintf (dest, ".word 0x%08lx", insn);
|
while (*dest)
|
while (*dest)
|
dest++;
|
dest++;
|
}
|
}
|
return insn_len (insn);
|
return or1ksim_insn_len (insn);
|
}
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|