/* scfidw2gen.c - Support for emission of synthesized Dwarf2 CFI.
   Copyright (C) 2023 Free Software Foundation, Inc.

   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 GAS; see the file COPYING.  If not, write to the Free
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
   02110-1301, USA.  */

#include "as.h"
#include "ginsn.h"
#include "scfi.h"
#include "dw2gencfi.h"
#include "subsegs.h"
#include "scfidw2gen.h"

#if defined (TARGET_USE_SCFI) && defined (TARGET_USE_GINSN)

static bool scfi_ignore_warn_once;

static void
dot_scfi_ignore (int ignored ATTRIBUTE_UNUSED)
{
  gas_assert (flag_synth_cfi);

  if (!scfi_ignore_warn_once)
    {
      as_warn (_("SCFI ignores most user-specified CFI directives"));
      scfi_ignore_warn_once = true;
    }
  ignore_rest_of_line ();
}

static void
scfi_process_cfi_label (void)
{
  char *name;
  ginsnS *ginsn;

  name = read_symbol_name ();
  if (name == NULL)
    return;

  /* Add a new ginsn.  */
  ginsn = ginsn_new_phantom (symbol_temp_new_now ());
  frch_ginsn_data_append (ginsn);

  scfi_op_add_cfi_label (ginsn, name);
  /* NB: Can't free NAME here since it will be used later.  Free it in
     handle_scfi_dot_cfi after it is unused.  */

  demand_empty_rest_of_line ();
}

static void
scfi_process_cfi_signal_frame (void)
{
  ginsnS *ginsn;

  ginsn = ginsn_new_phantom (symbol_temp_new_now ());
  frch_ginsn_data_append (ginsn);

  scfi_op_add_signal_frame (ginsn);
}

static void
dot_scfi (int arg)
{
  switch (arg)
    {
      case CFI_label:
	scfi_process_cfi_label ();
	break;
      case CFI_signal_frame:
	scfi_process_cfi_signal_frame ();
	break;
      default:
	abort ();
    }
}

const pseudo_typeS scfi_pseudo_table[] =
  {
    { "cfi_sections", dot_cfi_sections, 0 }, /* No ignore.  */
    { "cfi_signal_frame", dot_scfi, CFI_signal_frame }, /* No ignore.  */
    { "cfi_label", dot_scfi, CFI_label }, /* No ignore.  */
    { "cfi_startproc", dot_scfi_ignore, 0 },
    { "cfi_endproc", dot_scfi_ignore, 0 },
    { "cfi_fde_data", dot_scfi_ignore, 0 },
    { "cfi_def_cfa", dot_scfi_ignore, 0 },
    { "cfi_def_cfa_register", dot_scfi_ignore, 0 },
    { "cfi_def_cfa_offset", dot_scfi_ignore, 0 },
    { "cfi_adjust_cfa_offset", dot_scfi_ignore, 0 },
    { "cfi_offset", dot_scfi_ignore, 0 },
    { "cfi_rel_offset", dot_scfi_ignore, 0 },
    { "cfi_register", dot_scfi_ignore, 0 },
    { "cfi_return_column", dot_scfi_ignore, 0 },
    { "cfi_restore", dot_scfi_ignore, 0 },
    { "cfi_undefined", dot_scfi_ignore, 0 },
    { "cfi_same_value", dot_scfi_ignore, 0 },
    { "cfi_remember_state", dot_scfi_ignore, 0 },
    { "cfi_restore_state", dot_scfi_ignore, 0 },
    { "cfi_window_save", dot_scfi_ignore, 0 },
    { "cfi_negate_ra_state", dot_scfi_ignore, 0 },
    { "cfi_escape", dot_scfi_ignore, 0 },
    { "cfi_personality", dot_scfi_ignore, 0 },
    { "cfi_personality_id", dot_scfi_ignore, 0 },
    { "cfi_lsda", dot_scfi_ignore, 0 },
    { "cfi_val_encoded_addr", dot_scfi_ignore, 0 },
    { "cfi_inline_lsda", dot_scfi_ignore, 0 },
    { "cfi_val_offset", dot_scfi_ignore, 0 },
    { NULL, NULL, 0 }
  };

void
scfi_dot_cfi_startproc (const symbolS *start_sym)
{
  if (frchain_now->frch_cfi_data != NULL)
    {
      as_bad (_("SCFI: missing previous SCFI endproc marker"));
      return;
    }

  cfi_new_fde ((symbolS *)start_sym);

  cfi_set_sections ();

  frchain_now->frch_cfi_data->cur_cfa_offset = 0;

  /* By default, SCFI machinery assumes .cfi_startproc is used without
     parameter simple.  */
  tc_cfi_frame_initial_instructions ();

  if ((all_cfi_sections & CFI_EMIT_target) != 0)
    tc_cfi_startproc ();
}

void
scfi_dot_cfi_endproc (const symbolS *end_sym)
{
  struct fde_entry *fde_last;

  if (frchain_now->frch_cfi_data == NULL)
    {
      as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
      return;
    }

  fde_last = frchain_now->frch_cfi_data->cur_fde_data;
  cfi_set_last_fde (fde_last);

  cfi_end_fde ((symbolS *)end_sym);

  if ((all_cfi_sections & CFI_EMIT_target) != 0)
    tc_cfi_endproc (fde_last);
}

void
scfi_dot_cfi (int arg, unsigned reg1, unsigned reg2, offsetT offset,
	      const char *name, const symbolS *advloc)
{
  if (frchain_now->frch_cfi_data == NULL)
    {
      as_bad (_("CFI instruction used without previous .cfi_startproc"));
      return;
    }

  /* If the last address was not at the current PC, advance to current.  */
  if (frchain_now->frch_cfi_data->last_address != advloc)
    cfi_add_advance_loc ((symbolS *)advloc);

  switch (arg)
    {
    case DW_CFA_offset:
      cfi_add_CFA_offset (reg1, offset);
      break;

    case DW_CFA_val_offset:
      cfi_add_CFA_val_offset (reg1, offset);
      break;

    case CFI_rel_offset:
      cfi_add_CFA_offset (reg1,
			  offset - frchain_now->frch_cfi_data->cur_cfa_offset);
      break;

    case DW_CFA_def_cfa:
      cfi_add_CFA_def_cfa (reg1, offset);
      break;

    case DW_CFA_register:
      cfi_add_CFA_register (reg1, reg2);
      break;

    case DW_CFA_def_cfa_register:
      cfi_add_CFA_def_cfa_register (reg1);
      break;

    case DW_CFA_def_cfa_offset:
      cfi_add_CFA_def_cfa_offset (offset);
      break;

    case CFI_adjust_cfa_offset:
      cfi_add_CFA_def_cfa_offset (frchain_now->frch_cfi_data->cur_cfa_offset
				  + offset);
      break;

    case DW_CFA_restore:
      cfi_add_CFA_restore (reg1);
      break;

    case DW_CFA_remember_state:
      cfi_add_CFA_remember_state ();
      break;

    case DW_CFA_restore_state:
      cfi_add_CFA_restore_state ();
      break;

    case CFI_label:
      cfi_add_label (name);
      break;

    case CFI_signal_frame:
      frchain_now->frch_cfi_data->cur_fde_data->signal_frame = 1;
      break;

/*
    case DW_CFA_undefined:
      for (;;)
	{
	  reg1 = cfi_parse_reg ();
	  cfi_add_CFA_undefined (reg1);
	  SKIP_WHITESPACE ();
	  if (*input_line_pointer != ',')
	    break;
	  ++input_line_pointer;
	}
      break;

    case DW_CFA_same_value:
      reg1 = cfi_parse_reg ();
      cfi_add_CFA_same_value (reg1);
      break;

    case CFI_return_column:
      reg1 = cfi_parse_reg ();
      cfi_set_return_column (reg1);
      break;

    case DW_CFA_GNU_window_save:
      cfi_add_CFA_insn (DW_CFA_GNU_window_save);
      break;

*/
    default:
      abort ();
    }
}

#endif
