OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_58/] [gen_or1k_isa/] [sources/] [opcode/] [or32.c] - Diff between revs 676 and 703

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 676 Rev 703
Line 367... Line 367...
 
 
  printf("letter_signed(%c): Unknown letter.\n", l);
  printf("letter_signed(%c): Unknown letter.\n", l);
  return 0;
  return 0;
}
}
 
 
 
/* Simple cache for letter ranges */
 
static int range_cache[256] = {0};
 
 
/* Number of letters in the individual lettered operand. */
/* Number of letters in the individual lettered operand. */
int
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? */
 
  if (range = range_cache[(unsigned char)l]) return range;
 
 
  for(pinsn = or32_opcodes; strlen(pinsn->name); pinsn++)
  for(pinsn = 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'))
              enc += 2;
              enc += 2;
            else if (*enc == l)
            else if (*enc == l)
              range++;
              range++;
          return range;
          return range_cache[(unsigned char)l] = range;
        }
        }
    }
    }
 
 
  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.  */
/* MM: Returns index of given instruction name.  */
Line 766... Line 773...
  unsigned long *a = automata;
  unsigned long *a = 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 - 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 = 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 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 ((ti[i].insn_mask & insn) == ti[i].insn)
    return i;
    return i;
Line 795... Line 802...
 
 
/* 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
static unsigned long
extend_imm(unsigned long imm, char l)
extend_imm(unsigned long imm, char l)
{
{
  unsigned long mask;
  unsigned long mask;
  int letter_bits;
  int letter_bits;
 
 
Line 895... Line 902...
  return ret;
  return ret;
}
}
 
 
/* Print register. Used only by print_insn. */
/* Print register. Used only by print_insn. */
 
 
static void
static char *
or32_print_register (param_ch, encoding, insn)
or32_print_register (dest, param_ch, encoding, insn)
 
     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 = or32_extract(param_ch, encoding, insn);
 
 
   sprintf (disassembled, "%sr%d", disassembled, regnum);
  sprintf (dest, "r%d", regnum);
 
  while (*dest) dest++;
 
  return dest;
}
}
 
 
/* Print immediate. Used only by print_insn. */
/* Print immediate. Used only by print_insn. */
 
 
static void
static char *
or32_print_immediate (param_ch, encoding, insn)
or32_print_immediate (dest, param_ch, encoding, insn)
 
     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 = or32_extract (param_ch, encoding, insn);
Line 921... Line 932...
  imm = extend_imm(imm, param_ch);
  imm = extend_imm(imm, param_ch);
 
 
  if (letter_signed(param_ch))
  if (letter_signed(param_ch))
    {
    {
      if (imm < 0)
      if (imm < 0)
        sprintf (disassembled, "%s%d", disassembled, imm);
        sprintf (dest, "%d", imm);
      else
      else
        sprintf (disassembled, "%s0x%x", disassembled, imm);
        sprintf (dest, "0x%x", imm);
    }
    }
  else
  else
    sprintf (disassembled, "%s%#x", disassembled, imm);
    sprintf (dest, "%#x", imm);
 
  while (*dest) dest++;
 
  return dest;
}
}
 
 
/* 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)
disassemble_insn (insn)
     unsigned long insn;
     unsigned long insn;
{
{
  int index;
  int index;
  index = insn_decode (insn);
  return disassemble_index (insn, insn_decode (insn));
 
}
 
 
 
/* Disassemble one instruction from insn index.
 
   Return the size of the instruction.  */
 
 
 
int
 
disassemble_index (insn, index)
 
     unsigned long insn;
 
     int index;
 
{
 
  char *dest = disassembled;
  if (index >= 0)
  if (index >= 0)
    {
    {
      struct or32_opcode const *opcode = &or32_opcodes[index];
      struct or32_opcode const *opcode = &or32_opcodes[index];
      char *s;
      char *s;
 
 
      sprintf(disassembled, "%s ", opcode->name);
      strcpy (dest, opcode->name);
 
      while (*dest) dest++;
 
      *dest++ = ' ';
 
      *dest = 0;
 
 
      for (s = opcode->args; *s != '\0'; ++s)
      for (s = opcode->args; *s != '\0'; ++s)
        {
        {
          switch (*s)
          switch (*s)
            {
            {
            case '\0':
            case '\0':
              return 4;
              return insn_len (insn);
 
 
            case 'r':
            case 'r':
              or32_print_register(*++s, opcode->encoding, insn);
              dest = or32_print_register(dest, *++s, opcode->encoding, insn);
              break;
              break;
 
 
            default:
            default:
              if (strchr (opcode->encoding, *s))
              if (strchr (opcode->encoding, *s))
                or32_print_immediate (*s, opcode->encoding, insn);
                dest = or32_print_immediate (dest, *s, opcode->encoding, insn);
              else
              else {
                sprintf(disassembled, "%s%c", disassembled, *s);
                *dest++ = *s;
 
                *dest = 0;
 
              }
            }
            }
        }
        }
    }
    }
  else
  else
    {
    {
      /* This used to be %8x for binutils.  */
      /* This used to be %8x for binutils.  */
      sprintf(disassembled, "%s.word 0x%08x", disassembled, insn);
      sprintf(dest, ".word 0x%08x", insn);
 
      while (*dest) dest++;
    }
    }
  return insn_len (insn);
  return insn_len (insn);
}
}
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.