Line 1... |
Line 1... |
/* Disassembly routines for TMS320C54X architecture
|
/* Disassembly routines for TMS320C54X architecture
|
Copyright 1999, 2000, 2001, 2007 Free Software Foundation, Inc.
|
Copyright 1999, 2000, 2001, 2005, 2007, 2009 Free Software Foundation, Inc.
|
Contributed by Timothy Wall (twall@cygnus.com)
|
Contributed by Timothy Wall (twall@cygnus.com)
|
|
|
This file is part of the GNU opcodes library.
|
This file is part of the GNU opcodes library.
|
|
|
This library is free software; you can redistribute it and/or modify
|
This library is free software; you can redistribute it and/or modify
|
Line 25... |
Line 25... |
#include "sysdep.h"
|
#include "sysdep.h"
|
#include "dis-asm.h"
|
#include "dis-asm.h"
|
#include "opcode/tic54x.h"
|
#include "opcode/tic54x.h"
|
#include "coff/tic54x.h"
|
#include "coff/tic54x.h"
|
|
|
static int has_lkaddr (unsigned short, const template *);
|
static int has_lkaddr (unsigned short, const insn_template *);
|
static int get_insn_size (unsigned short, const template *);
|
static int get_insn_size (unsigned short, const insn_template *);
|
static int print_instruction (disassemble_info *, bfd_vma,
|
static int print_instruction (disassemble_info *, bfd_vma,
|
unsigned short, const char *,
|
unsigned short, const char *,
|
const enum optype [], int, int);
|
const enum optype [], int, int);
|
static int print_parallel_instruction (disassemble_info *, bfd_vma,
|
static int print_parallel_instruction (disassemble_info *, bfd_vma,
|
unsigned short,
|
unsigned short,
|
const template *, int);
|
const insn_template *, int);
|
static int sprint_dual_address (disassemble_info *,char [],
|
static int sprint_dual_address (disassemble_info *,char [],
|
unsigned short);
|
unsigned short);
|
static int sprint_indirect_address (disassemble_info *,char [],
|
static int sprint_indirect_address (disassemble_info *,char [],
|
unsigned short);
|
unsigned short);
|
static int sprint_direct_address (disassemble_info *,char [],
|
static int sprint_direct_address (disassemble_info *,char [],
|
Line 49... |
Line 49... |
print_insn_tic54x (bfd_vma memaddr, disassemble_info *info)
|
print_insn_tic54x (bfd_vma memaddr, disassemble_info *info)
|
{
|
{
|
bfd_byte opbuf[2];
|
bfd_byte opbuf[2];
|
unsigned short opcode;
|
unsigned short opcode;
|
int status, size;
|
int status, size;
|
const template* tm;
|
const insn_template* tm;
|
|
|
status = (*info->read_memory_func) (memaddr, opbuf, 2, info);
|
status = (*info->read_memory_func) (memaddr, opbuf, 2, info);
|
if (status != 0)
|
if (status != 0)
|
{
|
{
|
(*info->memory_error_func) (status, memaddr, info);
|
(*info->memory_error_func) (status, memaddr, info);
|
Line 84... |
Line 84... |
|
|
return size * 2;
|
return size * 2;
|
}
|
}
|
|
|
static int
|
static int
|
has_lkaddr (unsigned short memdata, const template *tm)
|
has_lkaddr (unsigned short memdata, const insn_template *tm)
|
{
|
{
|
return (IS_LKADDR (memdata)
|
return (IS_LKADDR (memdata)
|
&& (OPTYPE (tm->operand_types[0]) == OP_Smem
|
&& (OPTYPE (tm->operand_types[0]) == OP_Smem
|
|| OPTYPE (tm->operand_types[1]) == OP_Smem
|
|| OPTYPE (tm->operand_types[1]) == OP_Smem
|
|| OPTYPE (tm->operand_types[2]) == OP_Smem
|
|| OPTYPE (tm->operand_types[2]) == OP_Smem
|
Line 97... |
Line 97... |
|| OPTYPE (tm->operand_types[1]) == OP_Lmem));
|
|| OPTYPE (tm->operand_types[1]) == OP_Lmem));
|
}
|
}
|
|
|
/* always returns 1 (whether an insn template was found) since we provide an
|
/* always returns 1 (whether an insn template was found) since we provide an
|
"unknown instruction" template */
|
"unknown instruction" template */
|
const template*
|
const insn_template*
|
tic54x_get_insn (disassemble_info *info, bfd_vma addr,
|
tic54x_get_insn (disassemble_info *info, bfd_vma addr,
|
unsigned short memdata, int *size)
|
unsigned short memdata, int *size)
|
{
|
{
|
const template *tm = NULL;
|
const insn_template *tm = NULL;
|
|
|
for (tm = tic54x_optab; tm->name; tm++)
|
for (tm = tic54x_optab; tm->name; tm++)
|
{
|
{
|
if (tm->opcode == (memdata & tm->mask))
|
if (tm->opcode == (memdata & tm->mask))
|
{
|
{
|
Line 133... |
Line 133... |
if (size) *size = get_insn_size (memdata, tm);
|
if (size) *size = get_insn_size (memdata, tm);
|
return tm;
|
return tm;
|
}
|
}
|
}
|
}
|
}
|
}
|
for (tm = (template *) tic54x_paroptab; tm->name; tm++)
|
for (tm = (insn_template *) tic54x_paroptab; tm->name; tm++)
|
{
|
{
|
if (tm->opcode == (memdata & tm->mask))
|
if (tm->opcode == (memdata & tm->mask))
|
{
|
{
|
if (size) *size = get_insn_size (memdata, tm);
|
if (size) *size = get_insn_size (memdata, tm);
|
return tm;
|
return tm;
|
Line 147... |
Line 147... |
if (size) *size = 1;
|
if (size) *size = 1;
|
return &tic54x_unknown_opcode;
|
return &tic54x_unknown_opcode;
|
}
|
}
|
|
|
static int
|
static int
|
get_insn_size (unsigned short memdata, const template *insn)
|
get_insn_size (unsigned short memdata, const insn_template *insn)
|
{
|
{
|
int size;
|
int size;
|
|
|
if (insn->flags & FL_PAR)
|
if (insn->flags & FL_PAR)
|
{
|
{
|
Line 378... |
Line 378... |
info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
|
info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
|
break;
|
break;
|
case OP_CC3:
|
case OP_CC3:
|
{
|
{
|
const char *code[] = { "eq", "lt", "gt", "neq" };
|
const char *code[] = { "eq", "lt", "gt", "neq" };
|
sprintf (operand[i], code[CC3 (opcode)]);
|
|
|
/* Do not use sprintf with only two parameters as a
|
|
compiler warning could be generated in such conditions. */
|
|
sprintf (operand[i], "%s", code[CC3 (opcode)]);
|
info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
|
info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
|
break;
|
break;
|
}
|
}
|
case OP_123:
|
case OP_123:
|
{
|
{
|
Line 467... |
Line 470... |
static int
|
static int
|
print_parallel_instruction (info, memaddr, opcode, ptm, size)
|
print_parallel_instruction (info, memaddr, opcode, ptm, size)
|
disassemble_info *info;
|
disassemble_info *info;
|
bfd_vma memaddr;
|
bfd_vma memaddr;
|
unsigned short opcode;
|
unsigned short opcode;
|
const template *ptm;
|
const insn_template *ptm;
|
int size;
|
int size;
|
{
|
{
|
print_instruction (info, memaddr, opcode,
|
print_instruction (info, memaddr, opcode,
|
ptm->name, ptm->operand_types, size, 0);
|
ptm->name, ptm->operand_types, size, 0);
|
info->fprintf_func (info->stream, " || ");
|
info->fprintf_func (info->stream, " || ");
|