Back to index

cell-binutils  2.17cvs20070401
Defines | Functions | Variables
tic80-dis.c File Reference
#include <stdio.h>
#include "sysdep.h"
#include "opcode/tic80.h"
#include "dis-asm.h"

Go to the source code of this file.

Defines

#define M_SI(insn, op)   ((((op)->flags & TIC80_OPERAND_M_SI) != 0) && ((insn) & (1 << 17)))
#define M_LI(insn, op)   ((((op)->flags & TIC80_OPERAND_M_LI) != 0) && ((insn) & (1 << 15)))
#define R_SCALED(insn, op)   ((((op)->flags & TIC80_OPERAND_SCALED) != 0) && ((insn) & (1 << 11)))
#define TWO_INSN(insn)   ((((insn) & (0x1F << 27)) != 0) && (((insn) & (0x1F << 22)) != 0))

Functions

static void print_operand_integer (struct disassemble_info *info, long value)
static void print_operand_float (struct disassemble_info *info, long value)
static void print_operand_control_register (struct disassemble_info *info, long value)
static void print_operand_condition_code (struct disassemble_info *info, long value)
static void print_operand_bitnum (struct disassemble_info *info, long value)
static void print_operand (struct disassemble_info *info, long value, unsigned long insn, const struct tic80_operand *operand, bfd_vma memaddr)
static int fill_instruction (struct disassemble_info *info, bfd_vma memaddr, unsigned long *insnp)
static int print_one_instruction (struct disassemble_info *info, bfd_vma memaddr, unsigned long insn, const struct tic80_opcode *opcode)
static int print_instruction (struct disassemble_info *info, bfd_vma memaddr, unsigned long insn, const struct tic80_opcode *vec_opcode)
int print_insn_tic80 (bfd_vma memaddr, struct disassemble_info *info)

Variables

static int length

Define Documentation

#define M_LI (   insn,
  op 
)    ((((op)->flags & TIC80_OPERAND_M_LI) != 0) && ((insn) & (1 << 15)))

Definition at line 96 of file tic80-dis.c.

#define M_SI (   insn,
  op 
)    ((((op)->flags & TIC80_OPERAND_M_SI) != 0) && ((insn) & (1 << 17)))

Definition at line 95 of file tic80-dis.c.

#define R_SCALED (   insn,
  op 
)    ((((op)->flags & TIC80_OPERAND_SCALED) != 0) && ((insn) & (1 << 11)))

Definition at line 97 of file tic80-dis.c.

#define TWO_INSN (   insn)    ((((insn) & (0x1F << 27)) != 0) && (((insn) & (0x1F << 22)) != 0))

Definition at line 254 of file tic80-dis.c.


Function Documentation

static int fill_instruction ( struct disassemble_info info,
bfd_vma  memaddr,
unsigned long insnp 
) [static]

Definition at line 151 of file tic80-dis.c.

{
  bfd_byte buffer[4];
  int status;

  /* Get the bits for the next 32 bit word and put in buffer.  */
  status = (*info->read_memory_func) (memaddr + length, buffer, 4, info);
  if (status != 0)
    {
      (*info->memory_error_func) (status, memaddr, info);
      return -1;
    }

  /* Read was successful, so increment count of bytes read and convert
     the bits into internal format.  */

  length += 4;
  if (info->endian == BFD_ENDIAN_LITTLE)
    *insnp = bfd_getl32 (buffer);

  else if (info->endian == BFD_ENDIAN_BIG)
    *insnp = bfd_getb32 (buffer);

  else
    /* FIXME: Should probably just default to one or the other.  */
    abort ();

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int print_insn_tic80 ( bfd_vma  memaddr,
struct disassemble_info info 
)

Definition at line 302 of file tic80-dis.c.

{
  unsigned long insn;
  int status;

  length = 0;
  info->bytes_per_line = 8;
  status = fill_instruction (info, memaddr, &insn);
  if (status != -1)
    status = print_instruction (info, memaddr, insn, NULL);

  return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int print_instruction ( struct disassemble_info info,
bfd_vma  memaddr,
unsigned long  insn,
const struct tic80_opcode vec_opcode 
) [static]

Definition at line 257 of file tic80-dis.c.

{
  const struct tic80_opcode *opcode;
  const struct tic80_opcode *opcode_end;

  /* Find the first opcode match in the opcodes table.  For vector
     opcodes (vec_opcode != NULL) find the first match that is not the
     previously found match.  FIXME: there should be faster ways to
     search (hash table or binary search), but don't worry too much
     about it until other TIc80 support is finished.  */

  opcode_end = tic80_opcodes + tic80_num_opcodes;
  for (opcode = tic80_opcodes; opcode < opcode_end; opcode++)
    {
      if ((insn & opcode->mask) == opcode->opcode &&
         opcode != vec_opcode)
       break;
    }

  if (opcode == opcode_end)
    {
      /* No match found, just print the bits as a .word directive.  */
      (*info->fprintf_func) (info->stream, ".word %#08lx", insn);
    }
  else
    {
      /* Match found, decode the instruction.  */
      length = print_one_instruction (info, memaddr, insn, opcode);
      if (opcode->flags & TIC80_VECTOR && vec_opcode == NULL && TWO_INSN (insn))
       {
         /* There is another instruction to print from the same opcode.
            Print the separator and then find and print the other
            instruction.  */
         (*info->fprintf_func) (info->stream, "   ||   ");
         length = print_instruction (info, memaddr, insn, opcode);
       }
    }

  return length;
}

Here is the call graph for this function:

static int print_one_instruction ( struct disassemble_info info,
bfd_vma  memaddr,
unsigned long  insn,
const struct tic80_opcode opcode 
) [static]

Definition at line 186 of file tic80-dis.c.

{
  const struct tic80_operand *operand;
  long value;
  int status;
  const unsigned char *opindex;
  int close_paren;

  (*info->fprintf_func) (info->stream, "%-10s", opcode->name);

  for (opindex = opcode->operands; *opindex != 0; opindex++)
    {
      operand = tic80_operands + *opindex;

      /* Extract the value from the instruction.  */
      if (operand->extract)
       value = (*operand->extract) (insn, NULL);

      else if (operand->bits == 32)
       {
         status = fill_instruction (info, memaddr, (unsigned long *) &value);
         if (status == -1)
           return status;
       }
      else
       {
         value = (insn >> operand->shift) & ((1 << operand->bits) - 1);

         if ((operand->flags & TIC80_OPERAND_SIGNED) != 0
             && (value & (1 << (operand->bits - 1))) != 0)
           value -= 1 << operand->bits;
       }

      /* If this operand is enclosed in parenthesis, then print
        the open paren, otherwise just print the regular comma
        separator, except for the first operand.  */
      if ((operand->flags & TIC80_OPERAND_PARENS) == 0)
       {
         close_paren = 0;
         if (opindex != opcode->operands)
           (*info->fprintf_func) (info->stream, ",");
       }
      else
       {
         close_paren = 1;
         (*info->fprintf_func) (info->stream, "(");
       }

      print_operand (info, value, insn, operand, memaddr);

      /* If we printed an open paren before printing this operand, close
        it now. The flag gets reset on each loop.  */
      if (close_paren)
       (*info->fprintf_func) (info->stream, ")");
    }

  return length;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_operand ( struct disassemble_info info,
long  value,
unsigned long  insn,
const struct tic80_operand operand,
bfd_vma  memaddr 
) [static]

Definition at line 100 of file tic80-dis.c.

{
  if ((operand->flags & TIC80_OPERAND_GPR) != 0)
    {
      (*info->fprintf_func) (info->stream, "r%ld", value);
      if (M_SI (insn, operand) || M_LI (insn, operand))
       {
         (*info->fprintf_func) (info->stream, ":m");
       }
    }
  else if ((operand->flags & TIC80_OPERAND_FPA) != 0)
    (*info->fprintf_func) (info->stream, "a%ld", value);

  else if ((operand->flags & TIC80_OPERAND_PCREL) != 0)
    (*info->print_address_func) (memaddr + 4 * value, info);

  else if ((operand->flags & TIC80_OPERAND_BASEREL) != 0)
    (*info->print_address_func) (value, info);

  else if ((operand->flags & TIC80_OPERAND_BITNUM) != 0)
    print_operand_bitnum (info, value);

  else if ((operand->flags & TIC80_OPERAND_CC) != 0)
    print_operand_condition_code (info, value);

  else if ((operand->flags & TIC80_OPERAND_CR) != 0)
    print_operand_control_register (info, value);

  else if ((operand->flags & TIC80_OPERAND_FLOAT) != 0)
    print_operand_float (info, value);

  else if ((operand->flags & TIC80_OPERAND_BITFIELD))
    (*info->fprintf_func) (info->stream, "%#lx", value);

  else
    print_operand_integer (info, value);

  /* If this is a scaled operand, then print the modifier.  */
  if (R_SCALED (insn, operand))
    (*info->fprintf_func) (info->stream, ":s");
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_operand_bitnum ( struct disassemble_info info,
long  value 
) [static]

Definition at line 80 of file tic80-dis.c.

{
  int bitnum;
  const char *tmp;

  bitnum = ~value & 0x1F;
  tmp = tic80_value_to_symbol (bitnum, TIC80_OPERAND_BITNUM);
  if (tmp != NULL)
    (*info->fprintf_func) (info->stream, "%s", tmp);
  else
    (*info->fprintf_func) (info->stream, "%d", bitnum);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_operand_condition_code ( struct disassemble_info info,
long  value 
) [static]

Definition at line 68 of file tic80-dis.c.

{
  const char *tmp;

  tmp = tic80_value_to_symbol (value, TIC80_OPERAND_CC);
  if (tmp != NULL)
    (*info->fprintf_func) (info->stream, "%s", tmp);
  else
    (*info->fprintf_func) (info->stream, "%ld", value);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_operand_control_register ( struct disassemble_info info,
long  value 
) [static]

Definition at line 56 of file tic80-dis.c.

{
  const char *tmp;

  tmp = tic80_value_to_symbol (value, TIC80_OPERAND_CR);
  if (tmp != NULL)
    (*info->fprintf_func) (info->stream, "%s", tmp);
  else
    (*info->fprintf_func) (info->stream, "%#lx", value);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_operand_float ( struct disassemble_info info,
long  value 
) [static]

Definition at line 47 of file tic80-dis.c.

{
  union { float f; long l; } fval;

  fval.l = value;
  (*info->fprintf_func) (info->stream, "%g", fval.f);
}

Here is the caller graph for this function:

static void print_operand_integer ( struct disassemble_info info,
long  value 
) [static]

Definition at line 34 of file tic80-dis.c.

{
  if ((value > 9999 || value < -9999))
    (*info->fprintf_func) (info->stream, "%#lx", value);
  else
    (*info->fprintf_func) (info->stream, "%ld", value);
}

Here is the caller graph for this function:


Variable Documentation

int length [static]

Definition at line 25 of file tic80-dis.c.