Back to index

cell-binutils  2.17cvs20070401
Classes | Typedefs | Functions | Variables
m88k-dis.c File Reference
#include "sysdep.h"
#include "dis-asm.h"
#include "opcode/m88k.h"
#include "opintl.h"
#include "libiberty.h"

Go to the source code of this file.

Classes

struct  HASHTAB

Typedefs

typedef struct HASHTAB HASHTAB

Functions

static void init_disasm (void)
static void printop (struct disassemble_info *info, const OPSPEC *opptr, unsigned long inst, bfd_vma pc, int first)
static int m88kdis (bfd_vma pc, unsigned long instruction, struct disassemble_info *info)
int print_insn_m88k (bfd_vma memaddr, struct disassemble_info *info)

Variables

const INSTAB instructions []
HASHTABhashtable [HASHVAL] = {0}

Class Documentation

struct HASHTAB

Definition at line 30 of file m88k-dis.c.

Collaboration diagram for HASHTAB:
Class Members
const INSTAB * instr
struct HASHTAB * next

Typedef Documentation


Function Documentation

static void init_disasm ( void  ) [static]

Definition at line 532 of file m88k-dis.c.

{
  unsigned int hashvalue, hashsize;
  struct HASHTAB *hashentries;
  unsigned int i;

  hashsize = sizeof (instructions) / sizeof (INSTAB);

  hashentries = xmalloc (hashsize * sizeof (struct HASHTAB));

  for (i = 0; i < HASHVAL; i++)
    hashtable[i] = NULL;

  for (i = 0; i < hashsize; i++)
    {
      hashvalue = (instructions[i].opcode) % HASHVAL;
      hashentries[i].instr = &instructions[i];
      hashentries[i].next = hashtable[hashvalue];
      hashtable[hashvalue] = &hashentries[i];
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int m88kdis ( bfd_vma  pc,
unsigned long  instruction,
struct disassemble_info info 
) [static]

Definition at line 691 of file m88k-dis.c.

{
  static int ihashtab_initialized = 0;
  unsigned int opcode;
  const HASHTAB *entry_ptr;
  int opmask;
  unsigned int class;

  if (! ihashtab_initialized)
    {
      init_disasm ();
      ihashtab_initialized = 1;
    }

  /* Create the appropriate mask to isolate the opcode.  */
  opmask = DEFMASK;
  class = instruction & DEFMASK;
  if ((class >= SFU0) && (class <= SFU7))
    {
      if (instruction < SFU1)
       opmask = CTRLMASK;
      else
       opmask = SFUMASK;
    }
  else if (class == RRR)
    opmask = RRRMASK;
  else if (class == RRI10)
    opmask = RRI10MASK;

  /* Isolate the opcode.  */
  opcode = instruction & opmask;

  /* Search the hash table with the isolated opcode.  */
  for (entry_ptr = hashtable[opcode % HASHVAL];
       (entry_ptr != NULL) && (entry_ptr->instr->opcode != opcode);
       entry_ptr = entry_ptr->next)
    ;

  if (entry_ptr == NULL)
    (*info->fprintf_func) (info->stream, "word\t%08lx", instruction);
  else
    {
      (*info->fprintf_func) (info->stream, "%s", entry_ptr->instr->mnemonic);
      printop (info, &(entry_ptr->instr->op1), instruction, pc, 1);
      printop (info, &(entry_ptr->instr->op2), instruction, pc, 0);
      printop (info, &(entry_ptr->instr->op3), instruction, pc, 0);
    }

  return 4;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int print_insn_m88k ( bfd_vma  memaddr,
struct disassemble_info info 
)

Definition at line 747 of file m88k-dis.c.

{
  bfd_byte buffer[4];
  int status;

  /* Instruction addresses may have low two bits set. Clear them.  */
  memaddr &=~ (bfd_vma) 3;

  status = (*info->read_memory_func) (memaddr, buffer, 4, info);
  if (status != 0)
    {
      (*info->memory_error_func) (status, memaddr, info);
      return -1;
    }

  return m88kdis (memaddr, bfd_getb32 (buffer), info);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void printop ( struct disassemble_info info,
const OPSPEC opptr,
unsigned long  inst,
bfd_vma  pc,
int  first 
) [static]

Definition at line 576 of file m88k-dis.c.

{
  int extracted_field;
  char *cond_mask_sym;

  if (opptr->width == 0)
    return;

  if (! first)
    {
      switch (opptr->type)
       {
       case REGSC:
       case CONT:
         break;
       default:
         (*info->fprintf_func) (info->stream, ",");
         break;
       }
    }

  switch (opptr->type)
    {
    case CRREG:
      (*info->fprintf_func) (info->stream, "cr%d",
                          UEXT (inst, opptr->offset, opptr->width));
      break;

    case FCRREG:
      (*info->fprintf_func) (info->stream, "fcr%d",
                          UEXT (inst, opptr->offset, opptr->width));
      break;

    case REGSC:
      (*info->fprintf_func) (info->stream, "[r%d]",
                          UEXT (inst, opptr->offset, opptr->width));
      break;

    case REG:
      (*info->fprintf_func) (info->stream, "r%d",
                          UEXT (inst, opptr->offset, opptr->width));
      break;

    case XREG:
      (*info->fprintf_func) (info->stream, "x%d",
                          UEXT (inst, opptr->offset, opptr->width));
      break;

    case HEX:
      extracted_field = UEXT (inst, opptr->offset, opptr->width);
      if (extracted_field == 0)
       (*info->fprintf_func) (info->stream, "0");
      else
       (*info->fprintf_func) (info->stream, "0x%02x", extracted_field);
      break;

    case DEC:
      extracted_field = UEXT (inst, opptr->offset, opptr->width);
      (*info->fprintf_func) (info->stream, "%d", extracted_field);
      break;

    case CONDMASK:
      extracted_field = UEXT (inst, opptr->offset, opptr->width);
      switch (extracted_field & 0x0f)
       {
       case 0x1: cond_mask_sym = "gt0"; break;
       case 0x2: cond_mask_sym = "eq0"; break;
       case 0x3: cond_mask_sym = "ge0"; break;
       case 0xc: cond_mask_sym = "lt0"; break;
       case 0xd: cond_mask_sym = "ne0"; break;
       case 0xe: cond_mask_sym = "le0"; break;
       default: cond_mask_sym = NULL; break;
       }
      if (cond_mask_sym != NULL)
       (*info->fprintf_func) (info->stream, "%s", cond_mask_sym);
      else
       (*info->fprintf_func) (info->stream, "%x", extracted_field);
      break;
                       
    case PCREL:
      (*info->print_address_func)
       (pc + (4 * (SEXT (inst, opptr->offset, opptr->width))),
        info);
      break;

    case CONT:
      (*info->fprintf_func) (info->stream, "%d,r%d",
                          UEXT (inst, opptr->offset, 5),
                          UEXT (inst, (opptr->offset) + 5, 5));
      break;

    case BF:
      (*info->fprintf_func) (info->stream, "%d<%d>",
                          UEXT (inst, (opptr->offset) + 5, 5),
                          UEXT (inst, opptr->offset, 5));
      break;

    default:
      /* xgettext:c-format */
      (*info->fprintf_func) (info->stream, _("# <dis error: %08lx>"), inst);
    }
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 522 of file m88k-dis.c.

Definition at line 38 of file m88k-dis.c.