/* tc-or1k.c -- Assembler for the OpenRISC family.
   Copyright (C) 2001-2024 Free Software Foundation, Inc.
   Contributed for OR32 by Johan Rydberg, jrydberg@opencores.org

   This file is part of GAS, the GNU Assembler.

   GAS 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, or (at your option)
   any later version.

   GAS 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, see <http://www.gnu.org/licenses/> */
#include "as.h"
#include "safe-ctype.h"
#include "subsegs.h"
#include "symcat.h"
#include "opcodes/or1k-desc.h"
#include "opcodes/or1k-opc.h"
#include "cgen.h"
#include "elf/or1k.h"
#include "dw2gencfi.h"

/* Structure to hold all of the different components describing
   an individual instruction.  */

typedef struct
{
  const CGEN_INSN *     insn;
  const CGEN_INSN *     orig_insn;
  CGEN_FIELDS           fields;
#if CGEN_INT_INSN_P
  CGEN_INSN_INT         buffer [1];
#define INSN_VALUE(buf) (*(buf))
#else
  unsigned char         buffer [CGEN_MAX_INSN_SIZE];
#define INSN_VALUE(buf) (buf)
#endif
  char *                addr;
  fragS *               frag;
  int                   num_fixups;
  fixS *                fixups [GAS_CGEN_MAX_FIXUPS];
  int                   indices [MAX_OPERAND_INSTANCES];
}
or1k_insn;

const char comment_chars[]        = ";#";
const char line_comment_chars[]   = "#";
const char line_separator_chars[] = ";";
const char EXP_CHARS[]            = "eE";
const char FLT_CHARS[]            = "dD";

#define OR1K_SHORTOPTS "m:"
const char md_shortopts[] = OR1K_SHORTOPTS;

const struct option md_longopts[] =
{
  {NULL, no_argument, NULL, 0}
};
const size_t md_longopts_size = sizeof (md_longopts);

unsigned long or1k_machine = 0; /* default */

int
md_parse_option (int c ATTRIBUTE_UNUSED, const char * arg ATTRIBUTE_UNUSED)
{
  return 0;
}

void
md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
{
}

static void
ignore_pseudo (int val ATTRIBUTE_UNUSED)
{
  discard_rest_of_line ();
}

static bool nodelay = false;
static void
s_nodelay (int val ATTRIBUTE_UNUSED)
{
  nodelay = true;
}

/* The target specific pseudo-ops which we support.  */
const pseudo_typeS md_pseudo_table[] =
{
  { "align",    s_align_bytes,  0 },
  { "word",     cons,           4 },
  { "proc",     ignore_pseudo,  0 },
  { "endproc",  ignore_pseudo,  0 },
  { "nodelay",  s_nodelay,      0 },
  { NULL,       NULL,           0 }
};


void
md_begin (void)
{
  /* Initialize the `cgen' interface.  */

  /* Set the machine number and endian.  */
  gas_cgen_cpu_desc = or1k_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
                                              CGEN_CPU_OPEN_ENDIAN,
                                              CGEN_ENDIAN_BIG,
                                              CGEN_CPU_OPEN_END);
  or1k_cgen_init_asm (gas_cgen_cpu_desc);

  /* This is a callback from cgen to gas to parse operands.  */
  cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
}

void
md_assemble (char * str)
{
  static int last_insn_had_delay_slot = 0;
  or1k_insn insn;
  char *    errmsg;

  /* Initialize GAS's cgen interface for a new instruction.  */
  gas_cgen_init_parse ();

  insn.insn = or1k_cgen_assemble_insn
    (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);

  if (!insn.insn)
    {
      as_bad ("%s", errmsg);
      return;
    }

  /* Doesn't really matter what we pass for RELAX_P here.  */
  gas_cgen_finish_insn (insn.insn, insn.buffer,
                        CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);

  last_insn_had_delay_slot
    = CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
  (void) last_insn_had_delay_slot;
}


/* The syntax in the manual says constants begin with '#'.
   We just ignore it.  */

void
md_operand (expressionS * expressionP)
{
  if (* input_line_pointer == '#')
    {
      input_line_pointer ++;
      expression (expressionP);
    }
}

valueT
md_section_align (segT segment, valueT size)
{
  int align = bfd_section_alignment (segment);
  return ((size + (1 << align) - 1) & -(1 << align));
}

symbolS *
md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
{
  return 0;
}


/* Interface to relax_segment.  */

const relax_typeS md_relax_table[] =
{
/* The fields are:
   1) most positive reach of this state,
   2) most negative reach of this state,
   3) how many bytes this mode will add to the size of the current frag
   4) which index into the table to try if we can't fit into this one.  */

  /* The first entry must be unused because an `rlx_more' value of zero ends
     each list.  */
  {1, 1, 0, 0},

  /* The displacement used by GAS is from the end of the 4 byte insn,
     so we subtract 4 from the following.  */
  {(((1 << 25) - 1) << 2) - 4, -(1 << 25) - 4, 0, 0},
};

int
md_estimate_size_before_relax (fragS * fragP, segT segment ATTRIBUTE_UNUSED)
{
  return md_relax_table[fragP->fr_subtype].rlx_length;
}

/* *fragP has been relaxed to its final size, and now needs to have
   the bytes inside it modified to conform to the new size.

   Called after relaxation is finished.
   fragP->fr_type == rs_machine_dependent.
   fragP->fr_subtype is the subtype of what the address relaxed to.  */

void
md_convert_frag (bfd *   abfd ATTRIBUTE_UNUSED,
                 segT    sec  ATTRIBUTE_UNUSED,
                 fragS * fragP ATTRIBUTE_UNUSED)
{
  /* FIXME */
}


/* Functions concerning relocs.  */

/* The location from which a PC relative jump should be calculated,
   given a PC relative reloc.  */

long
md_pcrel_from_section (fixS * fixP, segT sec)
{
  if (fixP->fx_addsy != (symbolS *) NULL
      && (! S_IS_DEFINED (fixP->fx_addsy)
          || (S_GET_SEGMENT (fixP->fx_addsy) != sec)
          || S_IS_EXTERNAL (fixP->fx_addsy)
          || S_IS_WEAK (fixP->fx_addsy)))
    {
        /* The symbol is undefined (or is defined but not in this section).
         Let the linker figure it out.  */
      return 0;
    }

  return fixP->fx_frag->fr_address + fixP->fx_where;
}


/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
   Returns BFD_RELOC_NONE if no reloc type can be found.
   *FIXP may be modified if desired.  */

bfd_reloc_code_real_type
md_cgen_lookup_reloc (const CGEN_INSN *    insn ATTRIBUTE_UNUSED,
                      const CGEN_OPERAND * operand,
                      fixS *               fixP)
{
  if (fixP->fx_cgen.opinfo)
    return fixP->fx_cgen.opinfo;

  switch (operand->type)
    {
    case OR1K_OPERAND_DISP26:
      fixP->fx_pcrel = 1;
      return BFD_RELOC_OR1K_REL_26;

    default: /* avoid -Wall warning */
      return BFD_RELOC_NONE;
    }
}

/* Write a value out to the object file, using the appropriate endianness.  */

void
md_number_to_chars (char * buf, valueT val, int n)
{
  number_to_chars_bigendian (buf, val, n);
}

/* Turn a string in input_line_pointer into a floating point constant of type
   type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
   emitted is stored in *sizeP .  An error message is returned, or NULL on OK.  */

const char *
md_atof (int type, char * litP, int *  sizeP)
{
  return ieee_md_atof (type, litP, sizeP, true);
}

bool
or1k_fix_adjustable (fixS * fixP)
{
  /* We need the symbol name for the VTABLE entries.  */
  if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
      || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
    return false;

  return true;
}

#define GOT_NAME "_GLOBAL_OFFSET_TABLE_"

arelent *
tc_gen_reloc (asection * section, fixS * fixp)
{
  arelent *reloc;
  bfd_reloc_code_real_type code;

  reloc = XNEW (arelent);

  reloc->sym_ptr_ptr = XNEW (asymbol *);
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;

  if (fixp->fx_pcrel)
    {
      if (section->use_rela_p)
        fixp->fx_offset -= md_pcrel_from_section (fixp, section);
      else
        fixp->fx_offset = reloc->address;
    }
  reloc->addend = fixp->fx_offset;

  code = fixp->fx_r_type;
  switch (code)
    {
    case BFD_RELOC_16:
      if (fixp->fx_pcrel)
        code = BFD_RELOC_16_PCREL;
      break;

    case BFD_RELOC_32:
      if (fixp->fx_pcrel)
        code = BFD_RELOC_32_PCREL;
      break;

    case BFD_RELOC_64:
      if (fixp->fx_pcrel)
        code = BFD_RELOC_64_PCREL;
      break;

    default:
      break;
    }

  reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
  if (reloc->howto == NULL)
    {
      as_bad_where (fixp->fx_file, fixp->fx_line,
                    _
                    ("cannot represent %s relocation in this object file format"),
                    bfd_get_reloc_code_name (code));
      return NULL;
    }

  return reloc;
}

void
or1k_apply_fix (struct fix *f, valueT *t, segT s)
{
  gas_cgen_md_apply_fix (f, t, s);

  switch (f->fx_r_type)
    {
    case BFD_RELOC_OR1K_TLS_GD_HI16:
    case BFD_RELOC_OR1K_TLS_GD_LO16:
    case BFD_RELOC_OR1K_TLS_GD_PG21:
    case BFD_RELOC_OR1K_TLS_GD_LO13:
    case BFD_RELOC_OR1K_TLS_LDM_HI16:
    case BFD_RELOC_OR1K_TLS_LDM_LO16:
    case BFD_RELOC_OR1K_TLS_LDM_PG21:
    case BFD_RELOC_OR1K_TLS_LDM_LO13:
    case BFD_RELOC_OR1K_TLS_LDO_HI16:
    case BFD_RELOC_OR1K_TLS_LDO_LO16:
    case BFD_RELOC_OR1K_TLS_IE_HI16:
    case BFD_RELOC_OR1K_TLS_IE_LO16:
    case BFD_RELOC_OR1K_TLS_IE_PG21:
    case BFD_RELOC_OR1K_TLS_IE_LO13:
    case BFD_RELOC_OR1K_TLS_LE_HI16:
    case BFD_RELOC_OR1K_TLS_LE_LO16:
      S_SET_THREAD_LOCAL (f->fx_addsy);
      break;
    default:
      break;
    }
}

void
or1k_elf_final_processing (void)
{
  if (nodelay)
    elf_elfheader (stdoutput)->e_flags |= EF_OR1K_NODELAY;
}

/* Standard calling conventions leave the CFA at SP on entry.  */

void
or1k_cfi_frame_initial_instructions (void)
{
    cfi_add_CFA_def_cfa_register (1);
}

