/* BFD library support routines for the Renesas H8/300 architecture.
   Copyright (C) 1990-2019 Free Software Foundation, Inc.
   Hacked by Steve Chamberlain of Cygnus Support.

   This file is part of BFD, the Binary File Descriptor library.

   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 3 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., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "cpu-h8300.h"

static bfd_boolean
h8300_scan (const struct bfd_arch_info *info, const char *string)
{
  if (*string != 'h' && *string != 'H')
    return FALSE;

  string++;
  if (*string != '8')
    return FALSE;

  string++;
  if (*string == '/')
    string++;

  if (*string != '3')
    return FALSE;
  string++;
  if (*string != '0')
    return FALSE;
  string++;
  if (*string != '0')
    return FALSE;
  string++;
  if (*string == '-')
    string++;

  /* In ELF linker scripts, we typically express the architecture/machine
     as architecture:machine.

     So if we've matched so far and encounter a colon, try to match the
     string following the colon.  */
  if (*string == ':')
    {
      string++;
      return h8300_scan (info, string);
    }

  if (*string == 'h' || *string == 'H')
    {
      string++;
      if (*string == 'n' || *string == 'N')
	return (info->mach == bfd_mach_h8300hn);

      return (info->mach == bfd_mach_h8300h);
    }
  else if (*string == 's' || *string == 'S')
    {
      string++;
      if (*string == 'n' || *string == 'N')
	return (info->mach == bfd_mach_h8300sn);

      if (*string == 'x' || *string == 'X')
	{
	  string++;
	  if (*string == 'n' || *string == 'N')
	    return (info->mach == bfd_mach_h8300sxn);

	  return (info->mach == bfd_mach_h8300sx);
	}

      return (info->mach == bfd_mach_h8300s);
    }
  else
    return info->mach == bfd_mach_h8300;
}

/* This routine is provided two arch_infos and works out the machine
   which would be compatible with both and returns a pointer to its
   info structure.  */

static const bfd_arch_info_type *
compatible (const bfd_arch_info_type *in, const bfd_arch_info_type *out)
{
  if (in->arch != out->arch)
    return 0;
  if (in->mach == bfd_mach_h8300sx && out->mach == bfd_mach_h8300s)
    return in;
  if (in->mach == bfd_mach_h8300s && out->mach == bfd_mach_h8300sx)
    return out;
  if (in->mach == bfd_mach_h8300sxn && out->mach == bfd_mach_h8300sn)
    return in;
  if (in->mach == bfd_mach_h8300sn && out->mach == bfd_mach_h8300sxn)
    return out;
  /* It's really not a good idea to mix and match modes.  */
  if (in->mach != out->mach)
    return 0;
  else
    return in;
}

#define N(word, addr, number, name, print, default, next)	  \
  { word, addr, 8, bfd_arch_h8300, number, name, print, 1, default, \
    compatible, h8300_scan, bfd_arch_default_fill, next, 0 }

static const bfd_arch_info_type h8300sxn_info_struct =
  N (32, 16, bfd_mach_h8300sxn, "h8300sxn", "h8300sxn", FALSE, NULL);

static const bfd_arch_info_type h8300sx_info_struct =
  N (32, 32, bfd_mach_h8300sx, "h8300sx", "h8300sx", FALSE, &h8300sxn_info_struct);

static const bfd_arch_info_type h8300sn_info_struct =
  N (32, 16, bfd_mach_h8300sn, "h8300sn", "h8300sn", FALSE, &h8300sx_info_struct);

static const bfd_arch_info_type h8300hn_info_struct =
  N (32, 16, bfd_mach_h8300hn, "h8300hn", "h8300hn", FALSE, &h8300sn_info_struct);

static const bfd_arch_info_type h8300s_info_struct =
  N (32, 32, bfd_mach_h8300s, "h8300s", "h8300s", FALSE, & h8300hn_info_struct);

static const bfd_arch_info_type h8300h_info_struct =
  N (32, 32, bfd_mach_h8300h, "h8300h", "h8300h", FALSE, &h8300s_info_struct);

const bfd_arch_info_type bfd_h8300_arch =
  N (16, 16, bfd_mach_h8300, "h8300", "h8300", TRUE, &h8300h_info_struct);

/* Pad the given address to 32 bits, converting 16-bit and 24-bit
   addresses into the values they would have had on a h8s target.  */

bfd_vma
bfd_h8300_pad_address (bfd *abfd, bfd_vma address)
{
  /* Cope with bfd_vma's larger than 32 bits.  */
  address &= 0xffffffffu;

  switch (bfd_get_mach (abfd))
    {
    case bfd_mach_h8300:
    case bfd_mach_h8300hn:
    case bfd_mach_h8300sn:
    case bfd_mach_h8300sxn:
      /* Sign extend a 16-bit address.  */
      if (address >= 0x8000)
	return address | 0xffff0000u;
      return address;

    case bfd_mach_h8300h:
      /* Sign extend a 24-bit address.  */
      if (address >= 0x800000)
	return address | 0xff000000u;
      return address;

    case bfd_mach_h8300s:
    case bfd_mach_h8300sx:
      return address;

    default:
      abort ();
    }
}
