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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [cpu/] [scarts_32.opc] - Rev 6

Compare with Previous | Blame | View Log

/* SCARTS_32 architecture description.  -*- Scheme -*-
   Copyright 2000, 2001 Free Software Foundation, Inc.
   Contributed by Martin Walter <mwalter@opencores.org>

   This file is part of the GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

/* This file is an addendum to scarts_32.cpu. Heavy use of C code isn't
   appropriate in .cpu files, so it resides here. This especially applies
   to assembly/disassembly where parsing/printing can be quite involved.
   Such things aren't really part of the specification of the cpu, per se,
   so .cpu files provide the general framework and .opc files handle the
   nitty-gritty details as necessary.

   Each section is delimited with start and end markers.

   <arch>-opc.h additions use: "-- opc.h"
   <arch>-opc.c additions use: "-- opc.c"
   <arch>-asm.c additions use: "-- asm.c"
   <arch>-dis.c additions use: "-- dis.c"
   <arch>-ibd.h additions use: "-- ibd.h".
*/

/* -- opc.h */
#define CGEN_DIS_HASH_SIZE 1
#define CGEN_DIS_HASH(buffer, value) 0

#define CGEN_VALIDATE_INSN_SUPPORTED
#define CGEN_VERBOSE_ASSEMBLER_ERRORS

extern int scarts_32_cgen_insn_supported(CGEN_CPU_DESC, const CGEN_INSN *);

/* -- */

/* -- opc.c */
/* -- */

/* -- asm.c */
static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");

int
scarts_32_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
{
  return (CGEN_INSN_ATTR_VALUE(insn, CGEN_INSN_MACH) & cd->machs) != 0;
}

static const char *
parse_simm8 (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
{
  const char *errmsg;
  enum cgen_parse_operand_result result_type;
  unsigned long result;

  if (strncasecmp(*strp, "lo(", 3) == 0)
  {
    bfd_vma value;

    *strp += 3;
    errmsg = cgen_parse_address(cd, strp, opindex, BFD_RELOC_SCARTS_32_LO, &result_type, &value);

    if (**strp != ')')
      return MISSING_CLOSING_PARENTHESIS;

    *strp += 1;
    if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    {
      if (value & 0x1)
        return _("immediate value must be even");

      value >>= 1;
    }

    result = value;
  }
  else if (strncasecmp(*strp, "hi(", 3) == 0)
  {
    bfd_vma value;

    *strp += 3;
    errmsg = cgen_parse_address(cd, strp, opindex, BFD_RELOC_SCARTS_32_HI, &result_type, &value);

    if (**strp != ')')
      return MISSING_CLOSING_PARENTHESIS;

    *strp += 1;
    if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    {
      if (value & 0x1)
        return _("immediate value must be even");
 
      value >>= 9;
    }

    result = value;
  }
  else if (strncasecmp(*strp, "3rd(", 4) == 0)
  {
    bfd_vma value;

    *strp += 4;
    errmsg = cgen_parse_address(cd, strp, opindex, BFD_RELOC_SCARTS_32_3RD, &result_type, &value);

    if (**strp != ')')
      return MISSING_CLOSING_PARENTHESIS;

    *strp += 1;
    if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    {
      if (value & 0x1)
        return _("immediate value must be even");

      value >>= 17;
    }

    result = value;
  }
  else if (strncasecmp(*strp, "4th(", 4) == 0)
  {
    bfd_vma value;

    *strp += 4;
    errmsg = cgen_parse_address(cd, strp, opindex, BFD_RELOC_SCARTS_32_4TH, &result_type, &value);

    if (**strp != ')')
      return MISSING_CLOSING_PARENTHESIS;

    *strp += 1;
    if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    {
      if (value & 0x1)
        return _("immediate value must be even");

      value >>= 25;
    }

    result = value;
  }
  else
  {
    if (**strp == '-')
    {
      long value;

      errmsg = cgen_parse_signed_integer(cd, strp, opindex, &value);
      result = value;
    }
    else
    {
      unsigned long value;

      errmsg = cgen_parse_unsigned_integer(cd, strp, opindex, &value);
      result = value;
    }
  }

  *valuep = ((result & 0xFF) ^ 0x80) - 0x80;
  return errmsg;
}

static const char *
parse_uimm8 (CGEN_CPU_DESC cd, const char **strp, int opindex, unsigned long *valuep)
{
  const char *errmsg;
  enum cgen_parse_operand_result result_type;
  unsigned long result;

  if (strncasecmp(*strp, "lo(", 3) == 0)
  {
    bfd_vma value;

    *strp += 3;
    errmsg = cgen_parse_address(cd, strp, opindex, BFD_RELOC_SCARTS_32_LO, &result_type, &value);
    
    if (**strp != ')')
      return MISSING_CLOSING_PARENTHESIS;
    
    *strp += 1;
    if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    {
      if (value & 0x1)
        return _("immediate value must be even");

      value >>= 1;
    }

    result = value;
  }
  else if (strncasecmp(*strp, "hi(", 3) == 0)
  {
    bfd_vma value;

    *strp += 3;
    errmsg = cgen_parse_address(cd, strp, opindex, BFD_RELOC_SCARTS_32_HI, &result_type, &value);
    
    if (**strp != ')')
      return MISSING_CLOSING_PARENTHESIS;
    
    *strp += 1;
    if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    {
      if (value & 0x1)
        return _("immediate value must be even");

      value >>= 9;
    }

    result = value;
  }
  else if (strncasecmp(*strp, "3rd(", 4) == 0)
  {
    bfd_vma value;

    *strp += 4;
    errmsg = cgen_parse_address(cd, strp, opindex, BFD_RELOC_SCARTS_32_3RD, &result_type, &value);
    
    if (**strp != ')')
      return MISSING_CLOSING_PARENTHESIS;
    
    *strp += 1;
    if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    {
      if (value & 0x1)
        return _("immediate value must be even");

      value >>= 17;
    }

    result = value;
  }
  else if (strncasecmp(*strp, "4th(", 4) == 0)
  {
    bfd_vma value;

    *strp += 4;
    errmsg = cgen_parse_address(cd, strp, opindex, BFD_RELOC_SCARTS_32_4TH, &result_type, &value);
    
    if (**strp != ')')
      return MISSING_CLOSING_PARENTHESIS;
    
    *strp += 1;
    if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    {
      if (value & 0x1)
        return _("immediate value must be even");

      value >>= 25;
    }

    result = value;
  }
  else
  {
    unsigned long value;
    
    errmsg = cgen_parse_unsigned_integer(cd, strp, opindex, &value);
    result = value;
  }

  *valuep = result & 0xFF;
  return errmsg;
}

static const char *
parse_saddr10_pcrel (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
{
  const char *errmsg;
  enum cgen_parse_operand_result result_type;
  bfd_vma value;

  errmsg = cgen_parse_address(cd, strp, opindex, BFD_RELOC_SCARTS_32_PCREL_10, &result_type, &value);
  if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  {
    if (value & 0x1)
      return _("immediate value must be even");
  }

  *valuep = ((value & 0x3FF) ^ 0x200) - 0x200;
  return errmsg;
}
/* -- */

/* -- dis.c */
/* -- */

/* -- ibd.h */
/* -- */

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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